SpringCloud笔记(一)服务注册与服务发现

向右看齐 2022-04-03 10:30 455阅读 0赞

目录

1、Spring Cloud概述

2、环境搭建

2.1 搭建注册中心eureka-server

pom.xml

application.yml

启动类:

2.2 注册服务提供者springcloud-producer

pom.xml

application.yml

Controller:

启动类:

2.3 服务消费者 SpringCloud-Consumer

pom.xml

application.yml

Controller:

启动类:

3、负载均衡测试

4、服务注册与发现原理


1、Spring Cloud概述

Spring Cloud是一个基于Spring Boot实现的微服务架构开发工具。它为微服务架构中涉及的配置管理、服务治理、断路器、只能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等操作提供了一种简单的开发方式。

Spring Cloud包含了多个子项目:

Spring Cloud Config:配置管理工具,支持使用Git存储配置内容,可以使用它搭建分布式配置中心。

Spring Cloud Netflix:核心组件,对多个Netflix OSS开源套件进行整合。

  1. Eureka:服务治理组件,包含服务注册中心、服务注册与发现机制的实现。
  2. Hystrix:容错管理组件,实现断路器模式,帮助服务依赖出现的延迟和未故障提供强大的容错能力。
  3. Ribbon:客户端负载均衡的服务调用组件。
  4. Feign:基于RibbonHystrix的声明式服务调用组件
  5. Zuul:网关组件,提供智能路由、访问过滤等功能。

Spring Cloud Bus:时间、消息总线,用于传播集群中的状态变化或事件,以触发后续的处理,比如用来动态刷新配置等。

Spring Cloud Consul:服务发现与配置管理工具。

Spring Cloud Stream:通过Redis、Rabbit或者Kafka实现的消息微服务,通过简单点的声明式模型来发送和接收消息。

Spring Cloud Sleuth: Spring Cloud应用的分布式跟踪实现,可以完美整合Zipkin。

Spring Cloud Starters:Spring Cloud的基础组件,它是基于Spring Boot风格项目的基础依赖模块。

……

2、环境搭建

在此博客中使用Eureka作为注册中心,实现服务的注册与发现,项目结构如下:

20181221194613230.png

2.1 搭建注册中心eureka-server

pom.xml

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.1.1.RELEASE</version>
  5. <relativePath/> <!-- lookup parent from repository -->
  6. </parent>
  7. <groupId>com.lzj</groupId>
  8. <artifactId>euraker-server</artifactId>
  9. <version>0.0.1-SNAPSHOT</version>
  10. <packaging>jar</packaging>
  11. <name>euraker-server</name>
  12. <description>this is a register server</description>
  13. <properties>
  14. <java.version>1.8</java.version>
  15. <spring-cloud.version>Greenwich.M3</spring-cloud.version>
  16. </properties>
  17. <dependencies>
  18. <dependency>
  19. <groupId>org.springframework.cloud</groupId>
  20. <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
  21. </dependency>
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter-test</artifactId>
  25. <scope>test</scope>
  26. </dependency>
  27. </dependencies>
  28. <dependencyManagement>
  29. <dependencies>
  30. <dependency>
  31. <groupId>org.springframework.cloud</groupId>
  32. <artifactId>spring-cloud-dependencies</artifactId>
  33. <version>${spring-cloud.version}</version>
  34. <type>pom</type>
  35. <scope>import</scope>
  36. </dependency>
  37. </dependencies>
  38. </dependencyManagement>
  39. <build>
  40. <plugins>
  41. <plugin>
  42. <groupId>org.springframework.boot</groupId>
  43. <artifactId>spring-boot-maven-plugin</artifactId>
  44. </plugin>
  45. </plugins>
  46. </build>
  47. <repositories>
  48. <repository>
  49. <id>spring-milestones</id>
  50. <name>Spring Milestones</name>
  51. <url>https://repo.spring.io/milestone</url>
  52. <snapshots>
  53. <enabled>false</enabled>
  54. </snapshots>
  55. </repository>
  56. </repositories>

application.yml

  1. #端口号
  2. server:
  3. port: 8100
  4. eureka:
  5. instance:
  6. #注册到本地地址
  7. hostname: 127.0.0.1
  8. client:
  9. serviceUrl:
  10. #客户端访问的路径
  11. defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  12. #自己就是注册中心,不需要注册自己
  13. register-with-eureka: false
  14. #自己就是注册中心,不需要检索自己
  15. fetch-registry: false

启动类:

  1. @SpringBootApplication
  2. @EnableEurekaServer //开启eurekaServer
  3. public class EurakerServerApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(EurakerServerApplication.class, args);
  6. }
  7. }

此时将注册中心运行起来,测试搭建是否成功。

通过访问:http://localhost:8100 看到如下界面,则表示搭建成功,不过此时并没有注册任何服务。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pob3VqaWFuX0xpdQ_size_16_color_FFFFFF_t_70

2.2 注册服务提供者springcloud-producer

pom.xml

  1. <!--pom文件中主要部分:netflix-eureka-client-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. </dependency>
  6. <dependency>
  7. = <groupId>org.springframework.cloud</groupId>
  8. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  9. </dependency>

application.yml

  1. spring:
  2. application:
  3. name: app-producer
  4. server:
  5. port: 8000
  6. eureka:
  7. client:
  8. service-url:
  9. defaultZone: http://localhost:8100/eureka/
  10. register-with-eureka: true
  11. fetch-registry: true

Controller:

  1. @RestController
  2. public class ProducerController {
  3. @Value("${server.port}")
  4. private String port;
  5. @RequestMapping("/getMember")
  6. public String getMember() {
  7. return "this is a member service" + port;
  8. }
  9. }

启动类:

  1. @SpringBootApplication
  2. @EnableEurekaClient //启动会员服务
  3. public class SpringcloudProducerApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(SpringcloudProducerApplication.class, args);
  6. }
  7. }

当SpringCloud Producer启动后,会在注册中心看到有该服务名称。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pob3VqaWFuX0xpdQ_size_16_color_FFFFFF_t_70 1

此时可以通过浏览器直接访问该服务:http://localhost:8000/getMember

20181221200257372.png

2.3 服务消费者 SpringCloud-Consumer

现在有了注册中心,有了服务的提供者,现在再启动一个服务消费者,在Spring Cloud-Consumer中通过RPC远程调用技术调用SpringCloud-Producer中的服务(一个服务既可以当做提供者又可以当做消费者)。

pom.xml

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.cloud</groupId>
  7. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  8. </dependency>

application.yml

  1. spring:
  2. application:
  3. name: app-consumer
  4. server:
  5. port: 8001
  6. eureka:
  7. client:
  8. service-url:
  9. defaultZone: http://localhost:8100/eureka/ #注册中心地址
  10. register-with-eureka: true
  11. fetch-registry: true

Controller:

  1. @RestController
  2. public class OrderController {
  3. @Autowired
  4. private RestTemplate restTemplate;
  5. @RequestMapping("/getorder")
  6. public String getOrder() {
  7. // order 使用rpc 远程调用技术 调用 会员服务restTemplate
  8. String memberUrl = "http://app-producer/getMember";
  9. String result = restTemplate.getForObject(memberUrl, String.class);
  10. System.out.println("会员服务调用订单服务,result:" + result);
  11. return result;
  12. }
  13. }

启动类:

  1. @SpringBootApplication
  2. @EnableEurekaClient
  3. public class SpringcloudConsumerApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(SpringcloudConsumerApplication.class, args);
  6. }
  7. @Bean
  8. @LoadBalanced //让RestTemplate在请求时拥有客户端负载均衡的能力
  9. public RestTemplate restTemplate() {
  10. return new RestTemplate();
  11. }
  12. //不加@LoadBalanced 将出现无法解析app-producer地址的错误:java.net.UnknownHostException
  13. }

在进行远程调用时,采用了RestTemplate方式,这种方式底层采用的是Ribbon本地负载均衡,(还有一个Feign远程调用技术更常用,在以后的博客中会介绍到Feign客户端调用方式)。当使用RestTemplate时,需要自己注入一个bean对象,并且在该对象上面加上@LoadBalance开启本地负载均衡,否则会造成服务名称无法解析的错误:java.net.UnknownHostException

当两个服务都启动时,此时注册中心信息如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pob3VqaWFuX0xpdQ_size_16_color_FFFFFF_t_70 2

现在访问springcloud-consumet的getOrder接口,以此进行远程调用。

浏览器访问:http://localhost:8001/getorder

20181221201849154.png

说明底层通过RestTemplate完成了远程调用。

3、负载均衡测试

修改springcloud-producer的端口号为8002,重新再启动一个,模拟一个服务的集群。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pob3VqaWFuX0xpdQ_size_16_color_FFFFFF_t_70 3

可以看到APP-PRODUCER有两个服务实例,分别运行在8000端口和8002端口。

当访问http://localhost:8001/getorder时,Ribbon底层会自动实现负载均衡。

20181221230457843.png

20181221230523327.png

4、服务注册与发现原理

a、首先启动eureka注册中心

b、启动springcloud-producer或springcloud-consumer后,会将服务别名、服务所在的地址和端口号以键值对的形式注册到eureka注册中心,如:

key:APP-PRODUCER value:127.0.0.1:8000, 127.0.0.1:8002

并且每隔一段时间发送心跳包维持连接

c、当通过springcloud-consumer进行远程调用时,首先通过服务别名(APP-PRODUCER)去注册中心查找对应的键,获取对应的值(value:127.0.0.1:8000, 127.0.0.1:8002),当获取到值的时候,首先缓存在本地JVM中,并且缓存的值默认每隔30s刷新一次。之后通过本地负载均衡选取一个服务,底层通过HttpClient技术进行远程调用。

项目源码:https://github.com/liuzhoujian/springcloud-eureka

发表评论

表情:
评论列表 (有 0 条评论,455人围观)

还没有评论,来说两句吧...

相关阅读