微服务:SpringCloud 注册中心(Eureka)+ 源码分析est

比眉伴天荒 2023-02-10 15:26 144阅读 0赞

一、没有注册中心的模拟微服务

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70

这里有四个项目,其中三个是服务提供者,这三个服务提供者通过@RestController暴露rest接口,供消费者去调用。消费者可以用java代码编写get或者post请求,我们通常用的是RestTmplate,这个spring为我们提供好的类,特别好用!正常情况下,我们就可以很顺利的调用这些服务了。这个是没有问题的!

小伙伴们可能要问,这能调用。我们直接搞就行了,为啥还用注册中心呢?多此一举?

我们来考虑这样几个问题:(1)在我们调用提供者的接口的时候,是不是要将他们的url编写到消费者代码中呢,比如

  1. restTemplate.getForObject("http://192.128.0.1:9002/product/1", Product.class);

如果服务换ip了,换端口了,肿么办?

(2)为了实现系统的高可用,我们部署同一服务的多个服务提供者怎么办?也就是说提供服务A的有两个系统,你又怎么达到负载均衡?

这两个问题没有很好的办法解决吧?


二、注册中心

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 1

当服务提供者启动的时候,会像注册中心注册一个信息,“hello 注册中心,帮我注册一下好吗,我的ip是…,我要注册的服务是…”。这个时候注册中心就有了服务提供者的信息,当消费者启动的时候也会向注册中心注册信息,指定注册的要调用的服务。同时拿到服务的信息,消费者拿到对应的信息之后,存了一个小小的备份,当调用的时候,直接调用服务。就是图中最黑的那根线。

服务注册中心(下称注册中心)是微服务架构非常重要的一个组件,在微服务架构里主要起到了协调者

的一个作用。注册中心一般包含如下几个功能:

(1) 服务发现:服务注册/ 反注册:保存服务提供者和服务调用者的信息 。服务订阅/ 取消订阅:服务调用者订阅服务提供者的信息,最好有实时推送的功能。服务路由(可选):具有筛选整合服务提供者的能力。

(2) 服务配置: 配置订阅:服务提供者和服务调用者订阅微服务相关的配置。配置下发:主动将配置推送给服务提供者和服务调用者。

(3)服务健康检测 :检测服务提供者的健康情况。

常见的注册中心: Zookeeper、Eureka、Consul 、Nacos。

我们主要研究的是 Eureka。


三、Eureka注册中心

服务提供者会向Eureka注册一个自己的信息,Eureka会保存所有的信息到内存中,提供者还会每30s向Eureka发送一次心跳,表明“我还活着”,如果长时间收不到服务的心跳,认为宕机,从内存中删除信息。

服务消费者启动的时候会向注册中心获取所有服务的信息,调用的时候直接调用。可能兆成信息不一致的情况。

四、搭建注册中心

1、创建一个父工程

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.springcloud.demo</groupId>
  7. <artifactId>SpringCloudDemo</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <modules>
  10. <module>order_service</module>
  11. <module>product_service</module>
  12. <module>eureka_server</module>
  13. </modules>
  14. <parent>
  15. <groupId>org.springframework.boot</groupId>
  16. <artifactId>spring-boot-starter-parent</artifactId>
  17. <version>2.1.6.RELEASE</version>
  18. </parent>
  19. <properties>
  20. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  21. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  22. <java.version>1.8</java.version>
  23. </properties>
  24. <dependencies>
  25. <dependency>
  26. <groupId>org.springframework.boot</groupId>
  27. <artifactId>spring-boot-starter-web</artifactId>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.springframework.boot</groupId>
  31. <artifactId>spring-boot-starter-logging</artifactId>
  32. </dependency>
  33. <dependency>
  34. <groupId>org.springframework.boot</groupId>
  35. <artifactId>spring-boot-starter-test</artifactId>
  36. <scope>test</scope>
  37. </dependency>
  38. <dependency>
  39. <groupId>org.projectlombok</groupId>
  40. <artifactId>lombok</artifactId>
  41. <version>1.18.4</version>
  42. <scope>provided</scope>
  43. </dependency>
  44. </dependencies>
  45. <dependencyManagement>
  46. <dependencies>
  47. <dependency>
  48. <groupId>org.springframework.cloud</groupId>
  49. <artifactId>spring-cloud-dependencies</artifactId>
  50. <version>Greenwich.RELEASE</version>
  51. <type>pom</type>
  52. <scope>import</scope>
  53. </dependency>
  54. </dependencies>
  55. </dependencyManagement>
  56. <repositories>
  57. <repository>
  58. <id>spring-milestones</id>
  59. <name>Spring Milestones</name>
  60. <url>https://repo.spring.io/milestone</url>
  61. <snapshots>
  62. <enabled>false</enabled>
  63. </snapshots>
  64. </repository>
  65. </repositories>
  66. <build>
  67. <plugins>
  68. <plugin>
  69. <groupId>org.springframework.boot</groupId>
  70. <artifactId>spring-boot-maven-plugin</artifactId>
  71. </plugin>
  72. </plugins>
  73. </build>
  74. </project>

2、创建子工程eureka_server子工程

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>SpringCloudDemo</artifactId>
  7. <groupId>com.springcloud.demo</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>eureka_server</artifactId>
  12. <dependencies>
  13. <dependency>
  14. <groupId>org.springframework.cloud</groupId>
  15. <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
  16. </dependency>
  17. </dependencies>
  18. </project>

配置文件

  1. #模拟两个EurekaServer
  2. #端口9000 , 8000
  3. #两个server需要相互注册
  4. spring:
  5. application:
  6. name: eureka-server
  7. server:
  8. port: 9000 #端口
  9. #配置eureka server
  10. eureka:
  11. instance:
  12. hostname: localhost
  13. client:
  14. register-with-eureka: false #是否将自己注册到注册中心
  15. fetch-registry: false #是否从eureka中获取注册信息
  16. service-url: #配置暴露给Eureka Client的请求地址
  17. defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

启动类

  1. package com.springcloud.demo;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
  5. /**
  6. * @author Shubo Dai
  7. * @description 注册中心启动类
  8. */
  9. @SpringBootApplication
  10. @EnableEurekaServer
  11. public class EurekaServerApplication {
  12. public static void main(String[] args) {
  13. SpringApplication.run(EurekaServerApplication.class,args);
  14. }
  15. }

启动注册中心!

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 2

药药切克闹,是不是特别简单?

五、注册服务到注册中心

再新创建一个 项目,叫做product_service。这里我之前是用的jpa查询的数据库,这块的具体的信息我就不再展示了。可以去了解一下jpa好吧。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>SpringCloudDemo</artifactId>
  7. <groupId>com.springcloud.demo</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>product_service</artifactId>
  12. <dependencies>
  13. <dependency>
  14. <groupId>mysql</groupId>
  15. <artifactId>mysql-connector-java</artifactId>
  16. <version>5.1.32</version>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.springframework.boot</groupId>
  20. <artifactId>spring-boot-starter-data-jpa</artifactId>
  21. </dependency>
  22. <!--引入EurekaClient-->
  23. <dependency>
  24. <groupId>org.springframework.cloud</groupId>
  25. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  26. </dependency>
  27. </dependencies>
  28. </project>
  29. server:
  30. port: 9011 #端口
  31. spring:
  32. application:
  33. name: service-product #服务名称
  34. datasource:
  35. driver-class-name: com.mysql.jdbc.Driver
  36. url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8
  37. username: root
  38. password:
  39. jpa:
  40. database: MySQL
  41. show-sql: true
  42. open-in-view: true
  43. #配置Eureka
  44. eureka:
  45. client:
  46. service-url:
  47. defaultZone: http://localhost:9000/eureka/ #多个eurekaserver之间用,隔开
  48. instance:
  49. prefer-ip-address: true #使用ip地址注册

eureka配置信息,这里面指定注册中心的地址和使用什么进行注册。

  1. package com.springcloud.demo;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.boot.autoconfigure.domain.EntityScan;
  5. import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
  6. /**
  7. * @author Shubo Dai
  8. * @description 提供者服务类,@EnableEurekaClient、@EnableDiscoveryClient标识激活eureka客户端
  9. */
  10. @SpringBootApplication
  11. @EntityScan("com.springcloud.demo.entity")
  12. @EnableEurekaClient
  13. public class ProductApplication {
  14. public static void main(String[] args) {
  15. SpringApplication.run(ProductApplication.class,args);
  16. }
  17. }

启动之后,显示注册成功

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 3

20200521120513990.png

这里实际上还有dao、service、controller,可以自己想怎么写怎么写,这里不展开了!!!!

六、消费者通过注册中心调用提供者

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>SpringCloudDemo</artifactId>
  7. <groupId>com.springcloud.demo</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>order_service</artifactId>
  12. <dependencies>
  13. <dependency>
  14. <groupId>mysql</groupId>
  15. <artifactId>mysql-connector-java</artifactId>
  16. <version>5.1.32</version>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.springframework.boot</groupId>
  20. <artifactId>spring-boot-starter-data-jpa</artifactId>
  21. </dependency>
  22. <!--引入EurekaClient-->
  23. <dependency>
  24. <groupId>org.springframework.cloud</groupId>
  25. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  26. </dependency>
  27. </dependencies>
  28. </project>
  29. server:
  30. port: 9002 #端口
  31. spring:
  32. cloud:
  33. loadbalancer:
  34. retry:
  35. enabled: true # 开启Spring Cloud的重试功能
  36. application:
  37. name: service-order #服务名称
  38. datasource:
  39. driver-class-name: com.mysql.jdbc.Driver
  40. url: jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=utf8
  41. username: root
  42. password: 111111
  43. jpa:
  44. database: MySQL
  45. show-sql: true
  46. open-in-view: true
  47. #配置Eureka
  48. eureka:
  49. client:
  50. service-url:
  51. defaultZone: http://localhost:9000/eureka/,http://localhost:8000/eureka/
  52. instance:
  53. prefer-ip-address: true #使用ip地址注册
  54. package com.springcloud.demo;
  55. import org.springframework.boot.SpringApplication;
  56. import org.springframework.boot.autoconfigure.SpringBootApplication;
  57. import org.springframework.boot.autoconfigure.domain.EntityScan;
  58. import org.springframework.context.annotation.Bean;
  59. import org.springframework.web.client.RestTemplate;
  60. /**
  61. * @ClassName OrderApplication
  62. * @Description
  63. * @Author 戴书博
  64. * @Date 2020/5/21 10:23
  65. * @Version 1.0
  66. **/
  67. @SpringBootApplication
  68. @EntityScan("com.springcloud.demo.entity")
  69. public class OrderApplication {
  70. @Bean
  71. public RestTemplate restTemplate() {
  72. return new RestTemplate();
  73. }
  74. public static void main(String[] args) {
  75. SpringApplication.run(OrderApplication.class,args);
  76. }
  77. }
  78. package com.springcloud.demo.controller;
  79. import com.springcloud.demo.entity.Product;
  80. import org.springframework.beans.factory.annotation.Autowired;
  81. import org.springframework.cloud.client.ServiceInstance;
  82. import org.springframework.cloud.client.discovery.DiscoveryClient;
  83. import org.springframework.web.bind.annotation.PathVariable;
  84. import org.springframework.web.bind.annotation.RequestMapping;
  85. import org.springframework.web.bind.annotation.RequestMethod;
  86. import org.springframework.web.bind.annotation.RestController;
  87. import org.springframework.web.client.RestTemplate;
  88. import java.util.List;
  89. @RestController
  90. @RequestMapping("/order")
  91. public class OrderController {
  92. @Autowired
  93. private RestTemplate restTemplate;
  94. @Autowired
  95. private DiscoveryClient discoveryClient;
  96. @RequestMapping(value = "/buy/{id}",method = RequestMethod.GET)
  97. public Product findById(@PathVariable Long id) {
  98. List<ServiceInstance> list = discoveryClient.getInstances("service-product");
  99. ServiceInstance serviceInstance = list.get(0);
  100. Product product = restTemplate.getForObject("http://"+serviceInstance.getHost()+":"
  101. +serviceInstance.getPort()
  102. +"/product/1",Product.class);
  103. return product;
  104. }
  105. }

启动服务试一下。

注册中心

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 4

可以调用成功!!!

20200521133356426.png

七、注册中心的高可用

如果我们只有一个注册中心的话,那么这个注册中心宕机了,怎么办?为了保证高可用,那么我们可以搞成一个eureka集群。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 5

在注册中心一块我们只需要修改配置文件就可以了,比如两个注册中心的端口:8000、9000。需要相互获取信息、将自己注册到对应的注册中心中。

8000端口的配置文件:

  1. #模拟两个EurekaServer
  2. #端口9000 , 8000
  3. #两个server需要相互注册
  4. spring:
  5. application:
  6. name: eureka-server
  7. server:
  8. port: 9000 #端口
  9. #配置eureka server
  10. eureka:
  11. client:
  12. service-url: #配置暴露给Eureka Client的请求地址
  13. defaultZone: http://127.0.0.1:8000/eureka/

9000端口的配置文件:

  1. #模拟两个EurekaServer
  2. #端口9000 , 8000
  3. #两个server需要相互注册
  4. spring:
  5. application:
  6. name: eureka-server
  7. server:
  8. port: 8000 #端口
  9. #配置eureka server
  10. eureka:
  11. client:
  12. service-url: #配置暴露给Eureka Client的请求地址
  13. defaultZone: http://127.0.0.1:9000/eureka/

服务注册到多个注册中心

实际上由于两个注册中心之间相互都是交换信息的,所以在一个注册上,另一个也会同步。当然我们也可以配置两个都注册。

  1. eureka:
  2. client:
  3. service-url:
  4. defaultZone: http://localhost:9000/eureka/,http://localhost:8000/eureka/

完善配置

  1. eureka:
  2. client:
  3. service-url:
  4. defaultZone: http://localhost:9000/eureka/ #多个eurekaserver之间用,隔开
  5. instance:
  6. prefer-ip-address: true #使用ip地址注册
  7. instance-id: ${spring.cloud.client.ip-address}:${server.port} #向注册中心中注册服务id
  8. lease-renewal-interval-in-seconds: 5 #发送心跳的间隔
  9. lease-expiration-duration-in-seconds: 10 #续约到期的时间

我们在服务提供者设置下面三行配置。

第一个是在注册中心配置一个名称ip+端口号。

20200521143835339.png

第二个是发送心跳的时间默认是30s。

第三个是默认的宕机时间,到了这个时间提供者未向注册中心发送心跳就会认为提供者宕机。

关闭自我保护机制

在eureka内部存在一个自我保护机制,这个机制会统计其他提供者发送心跳的次数和认为宕机的次数。如果发现打部门提供者的心跳都结束了,那么就不再剔除服务。一般测试阶段关闭这个自我保护机制。

  1. eureka:
  2. defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  3. server:
  4. enable-self-preservation: false #关闭自我保护
  5. eviction-interval-timer-in-ms: 4000 #剔除服务间隔

最后一个配置是4s执行一次定时任务剔除已经宕机的提供者服务。

8、源码分析

服务端

(1)**EnableEurekaServer**注解作用

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 6

我们首先来看一下@EnableEurekaServer注解。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 7

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 8

这个类注入了一个Marker对象。 这个对象是实例化核心配置类的前提条件。

(2)**自动装载核心配置类**

首先你必须要了解springboot自动加载机制https://blog.csdn.net/weixin_44588495/article/details/106310221

202005241320092.png

我们来查看这个类EurekaServerAutoConfiguration

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 9

现在我们展开来说这个Eureka服务端的自动配置类:

(1)这个配置类实例化的前提条件是上下文中存在 EurekaServerMarkerConfifiguration.Marker 这个 bean,解释了上面的问题。

(2)通过@EnableConfifigurationProperties({ EurekaDashboardProperties.class, InstanceRegistryProperties.class })导入了两个配置类:

EurekaDashboardProperties : 配置 EurekaServer的管控台

InstanceRegistryProperties : 配置期望续约数量和默认的通信数量

(3) 通过 @Import({EurekaServerInitializerConfifiguration.class}) 引入启动配置类

看一下EurekaServerInitializerConfiguration这个类

(3)EurekaServerInitializerConfifiguration

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 10

可以看到 EurekaServerInitializerConfifiguration 实现了 SmartLifecycle ,也就意味着 Spring 容器启动时 会去执行start() 方法。加载所有的 EurekaServer 的配置。

(4)**EurekaServerAutoConfifiguration**

20200524132359157.png

注入了一个controller。实例化了EurekaServer的管控台的Controller类 EurekaController

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 11

实际上这个controller跟我们平时写的差不多,他的作用就是配合页面完成控制台相关功能。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 12

注意一下这个方法,再点进去!

20200524132824963.png

是两个包名,实际上就是eureka去扫描包下面的类。查看类是否含有@Path、@Provider、@Produce等注解。

(5)暴露的服务端接口

对应扫描的包

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 13

通过扫描这些类生成web的接口,供客户端调用。比如连接等等。这些类都是通过Jersey发布的供客户端调用的服务接口。

jerseyApplication 方法,在容器中存放了一个 jerseyApplication 对象, jerseyApplication() 方法里的 东西和Spring 源码里扫描 @Component 逻辑类似,扫描 @Path 和 @Provider 标签,然后封装成 beandefifinition,封装到 Application 的 set 容器里。通过 fifilter 过滤器来过滤 url 进行映射到对象的 Controller。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 14

(6)服务端接受客户端的注册

在 ApplicationResource.addInstance() 方法中可以看到

20200524145145617.png

我们来看注册的这个方法!!

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 15

(7)接受客户端续约

在 InstanceResource 的 renewLease 方法中完成客户端的心跳(续约)处理,其中最关键的方法就是

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 16

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 17

(8)服务剔除

在 AbstractInstanceRegistry.postInit() 方法,在此方法里开启了一个每 60 秒调用一次 EvictionTask.evict()的定时器。

客户端

(1)自动装载

每个服务我们都只在配置文件中配置了一些信息,然后就能够注册到注册中心等之类的。我们来看一下客户端为我们加载了哪些配置类?

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 18

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 19

看一下里面这个方法,就是创建了一个注册中心客户端到ioc中

20200524135417488.png

找到这个类。里面参数的clientConfig,其实就是我们在配置文件中配置的信息。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 20

(2)服务注册

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 21

实际上这里面是发送了一个http的请求去请求注册中心注册。

(2)服务下架

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 22

(3)心跳续约

在 com.netflflix.discovery.DiscoveryClient.HeartbeatThread 中定义了续约的操作 , 我们查看 renew() 方法;

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU4ODQ5NQ_size_16_color_FFFFFF_t_70 23

源码:git@gitee.com:Zesystem/springclouddemoerueka.git

发表评论

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

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

相关阅读