《Spring Colud》 Eureka 服务治理详解与高可用分布式搭建

这篇笔记主要讲述利用spring cloud eureka来进行服务管理、高可用和负载均衡。

一、什么是Eureka

    Eureka是Netflix开源的一个RESTful服务,主要用于服务的注册发现。Eureka由两个组件组成:Eureka服务器和Eureka客户端。Eureka服务器用作服务注册服务器。Eureka客户端是一个java客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。Netflix在其生产环境中使用的是另外的客户端,它提供基于流量、资源利用率以及出错状态的加权负载均衡。

    在我看来,Eureka的吸引力来源于以下几点:

  • 开源:大家可以对实现一探究竟,甚至修改源码。
  • 可靠:经过Netflix多年的生产环境考验,使用应该比较靠谱省心
  • 功能齐全:不但提供了完整的注册发现服务,还有Ribbon等可以配合使用的服务。
  • 基于Java:对于Java程序员来说,使用起来,心里比较有底。
  • spring cloud:可以使用Spring Cloud, 与Eureka进行了很好的集成,使用起来非常方便。

二、搭建服务注册中心

1、创建maven项目eureka-server,修改pom.xml文件如下:

 
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  3.  
  4. <modelVersion>4.0.0</modelVersion>

  5. <artifactId>eureka-server</artifactId>

  6. <packaging>jar</packaging>

  7. <name>eureka-server Maven Webapp</name>

  8. <url>http://maven.apache.org</url>

  9.  
  10. <properties>

  11. <start-class>learn.eureka.server.ApplicationEurekaServer</start-class>

  12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

  13. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

  14. <java.version>1.8</java.version>

  15. <maven.compiler.source>1.8</maven.compiler.source>

  16. <maven.compiler.target>1.8</maven.compiler.target>

  17. <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>

  18. </properties>

  19.  
  20. <parent>

  21. <groupId>org.springframework.boot</groupId>

  22. <artifactId>spring-boot-starter-parent</artifactId>

  23. <version>1.5.10.RELEASE</version>

  24. </parent>

  25.  
  26. <dependencies>

  27.  
  28. <!-- 全栈web开发模块,包括嵌入式Tomcat、Spring MVC -->

  29. <dependency>

  30. <groupId>org.springframework.boot</groupId>

  31. <artifactId>spring-boot-starter-web</artifactId>

  32. </dependency>

  33. <!-- eureka 服务注册 服务端依赖文件-->

  34. <dependency>

  35. <groupId>org.springframework.cloud</groupId>

  36. <artifactId>spring-cloud-starter-eureka-server</artifactId>

  37. <version>1.3.1.RELEASE</version>

  38. </dependency>

  39. <!-- 测试 -->

  40. <dependency>

  41. <groupId>junit</groupId>

  42. <artifactId>junit</artifactId>

  43. <version>4.12</version>

  44. <scope>test</scope>

  45. </dependency>

  46. </dependencies>

  47.  
  48. <dependencyManagement>

  49. <dependencies>

  50. <dependency>

  51. <groupId>org.springframework.cloud</groupId>

  52. <artifactId>spring-cloud-config</artifactId>

  53. <version>1.3.1.RELEASE</version>

  54. <type>pom</type>

  55. <scope>import</scope>

  56. </dependency>

  57. <dependency>

  58. <groupId>org.springframework.cloud</groupId>

  59. <artifactId>spring-cloud-netflix</artifactId>

  60. <version>1.3.1.RELEASE</version>

  61. <type>pom</type>

  62. <scope>import</scope>

  63. </dependency>

  64. </dependencies>

  65. </dependencyManagement>

  66.  
  67. <build>

  68. <finalName>eureka-server</finalName>

  69. <plugins>

  70. <plugin>

  71. <groupId>org.springframework.boot</groupId>

  72. <artifactId>spring-boot-maven-plugin</artifactId>

  73. </plugin>

  74. </plugins>

  75. </build>

  76. </project>

2、创建启动类,并添加注解@EnableEurekaServer ,说明该服务为服务注册服务端微服务。

 
  1. @SpringBootApplication

  2. @EnableEurekaServer

  3. public class ApplicationEurekaServer {

  4. public static void main(String[] args) {

  5. SpringApplication.run(ApplicationEurekaServer.class , args);

  6. }

  7. }

配置application.yml文件

3、启动之后在浏览器访问:http://localhost:1112 (我指定的端口是1112),得到如下界面表示启动成功。

peer1是该eureka服务端的项目名称,该名称在application.yml中设置:

 
  1. spring:

  2. application:

  3. name: peer2

 eureka 会默认把自己也当作服务注册,这在以后做高可用的时候会用到。

  • eureka.client.register-with-eureka: 由于该应用为注册中心,所以设置为 false, 代表不向注册中心注册自己。
  • eureka.client.fe七ch-registry: 由于注册中心的职责就是维护服务实例,它并不需要去检索服务, 所以也设置为 false。 

三、注册服务提供者到服务注册中心

1、创建service-user项目,仿照(二)中(1)pom.xml构建maven项目。同时替换eureka服务端为客户端依赖。如下:

 
  1. 修改如下内容

  2. <!-- eureka 服务注册 服务端依赖文件-->

  3. <dependency>

  4. <groupId>org.springframework.cloud</groupId>

  5. <artifactId>spring-cloud-starter-eureka-server</artifactId>

  6. <version>1.3.1.RELEASE</version>

  7. </dependency>

  8. 为:

  9. <dependency>

  10. <groupId>org.springframework.cloud</groupId>

  11. <artifactId>spring-cloud-starter-eureka</artifactId>

  12. <version>1.3.1.RELEASE</version>

  13. </dependency>

修改后完整pom文件如下:

 
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  3.  
  4. <modelVersion>4.0.0</modelVersion>

  5. <artifactId>service-user</artifactId>

  6. <packaging>jar</packaging>

  7. <name>service-user Maven Webapp</name>

  8. <url>http://maven.apache.org</url>

  9.  
  10. <parent>

  11. <groupId>org.springframework.boot</groupId>

  12. <artifactId>spring-boot-starter-parent</artifactId>

  13. <version>1.5.10.RELEASE</version>

  14. </parent>

  15.  
  16. <properties>

  17. <start-class>com.learning.ServiceUserApplication</start-class>

  18. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

  19. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

  20. <java.version>1.8</java.version>

  21. <maven.compiler.source>1.8</maven.compiler.source>

  22. <maven.compiler.target>1.8</maven.compiler.target>

  23. <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>

  24. </properties>

  25.  
  26. <dependencyManagement>

  27. <dependencies>

  28. <dependency>

  29. <groupId>org.springframework.cloud</groupId>

  30. <artifactId>spring-cloud-config</artifactId>

  31. <version>1.3.1.RELEASE</version>

  32. <type>pom</type>

  33. <scope>import</scope>

  34. </dependency>

  35. <dependency>

  36. <groupId>org.springframework.cloud</groupId>

  37. <artifactId>spring-cloud-netflix</artifactId>

  38. <version>1.3.1.RELEASE</version>

  39. <type>pom</type>

  40. <scope>import</scope>

  41. </dependency>

  42. </dependencies>

  43. </dependencyManagement>

  44.  
  45. <dependencies>

  46. <!-- json 模块-->

  47. <dependency>

  48. <groupId>com.alibaba</groupId>

  49. <artifactId>fastjson</artifactId>

  50. <version>1.2.24</version>

  51. </dependency>

  52.  
  53. <!-- 全栈web开发模块,包括嵌入式Tomcat、Spring MVC -->

  54. <dependency>

  55. <groupId>org.springframework.boot</groupId>

  56. <artifactId>spring-boot-starter-web</artifactId>

  57. </dependency>

  58. <!--SpringBoot 测试模块-->

  59. <dependency>

  60. <groupId>org.springframework.boot</groupId>

  61. <artifactId>spring-boot-starter-test</artifactId>

  62. <version>1.5.9.RELEASE</version>

  63. <scope>test</scope>

  64. </dependency>

  65.  
  66. <!-- 该模块构建用于监控的端点 -->

  67. <dependency>

  68. <groupId> org.springframework.boot</groupId>

  69. <artifactId>spring-boot-starter-actuator</artifactId>

  70. </dependency>

  71.  
  72. <dependency>

  73. <groupId>org.springframework.cloud</groupId>

  74. <artifactId>spring-cloud-starter-eureka</artifactId>

  75. <version>1.3.1.RELEASE</version>

  76. </dependency>

  77.  
  78. <dependency>

  79. <groupId>junit</groupId>

  80. <artifactId>junit</artifactId>

  81. <version>4.12</version>

  82. <scope>test</scope>

  83. </dependency>

  84.  
  85. </dependencies>

  86.  
  87. <build>

  88. <finalName>service-user</finalName>

  89. <plugins>

  90. <plugin>

  91. <groupId>org.springframework.boot</groupId>

  92. <artifactId>spring-boot-maven-plugin</artifactId>

  93. </plugin>

  94. <!-- 测试出错不影响项目编辑 -->

  95. <plugin>

  96. <groupId>org.apache.maven.plugins</groupId>

  97. <artifactId>maven-surefire-plugin</artifactId>

  98. <configuration>

  99. <testFailureIgnore>true</testFailureIgnore>

  100. </configuration>

  101. </plugin>

  102. </plugins>

  103. </build>

  104. </project>

2、创建启动类,并添加注解@EnableEurekaClient ,说明该服务为服务注册服务端微服务。

 
  1. /**

  2. * @author [email protected]

  3. * @date 2018/2/22 18:22

  4. */

  5. @EnableEurekaClient

  6. @SpringBootApplication

  7. public class ServiceUserApplication {

  8. public static void main(String[] args) {

  9. SpringApplication.run(ServiceUserApplication.class , args);

  10. }

  11. }

配置application.yml文件

 
  1. server:

  2. port: 8001

  3. spring:

  4. application:

  5. name: service-user

  6. eureka:

  7. client:

  8. service-url:

  9. # defaultZone: http://peer2:1112/eureka/, http://peer1:1111/eureka/

  10. defaultZone: http://localhost:1112/eureka/

  11. healthcheck:

  12. enabled: true #使用health端点来代替心跳表明服务是否可用,反应到eureka server ui上服务的UP还是DOWN

  13. instance:

  14. lease-expiration-duration-in-seconds: 30 #租期更新时间间隔(默认30秒)

  15. lease-renewal-interval-in-seconds: 10 #租期更新时间间隔(默认30秒)

  16. info:

  17. app:

  18. name: "@project.name@" #从pom.xml中获取

  19. description: "@project.description@"

  20. version: "@project.version@"

  21. spring-boot-version: "@project.parent.version@"

3、启动之后在浏览器访问:http://localhost:1111(我指定的端口是1111),得到如下界面表示启动成功。

四、高可用注册中心

    在微服务这样的分布式架构中,我们需要考虑单节点的故障。eureka server在设计之出就对该问题进行了解决。在eureka中,服务的提供者同时也是服务的消费者,在第一个eureka server服务端中我们通过。

 
  1. eureka.client.register-with-eureka=false

  2. eureka.client.fetch-registry=false

来设置服务注册中心不将自己注册到服务中心,而eureka的高可用就是将自己当作服务提供者注册到服务注册中心。

    我们以(二)中的服务注册中心为基础,来搭建高可用服务注册中心。

1、我们准备创建peer1、peer2两个服务注册中心来提供服务,即两个节点。首先,我们在hosts文件中队peer1、peer2进行一下ip映射。在/etc/hosts文件中添加对peerl  peer2的转换, 让上面配置的host形式的serviceUrl能在本地正确访间到; Windows系统路径为C:\Windows\System32\drivers\etc\hosts。 

2、创建application-peer1.yml文件,作为peer1的服务注册中心。详细yml内容如下:

 
  1. spring:

  2. application:

  3. name: peer1

  4. profiles:

  5. active: peer1 # 多平台打包部署启动,用来启动时指定使用的配置文件

  6. server:

  7. port: 1111

  8. eureka:

  9. server:

  10. enable-self-preservation: false #关闭自我保护,服务关闭后从列表中踢除,默认true,开启自我保护

  11. eviction-interval-timer-in-ms: 60000 # 清理间隔(单位毫秒,默认是60*1000)

  12. client:

  13. enabled: true

  14. register-with-eureka: true # 允许注册自己到服务注册中心

  15. fetch-registry: true #默认是true,允许服务定时任务定时刷新服务列表

  16. registry-fetch-interval-seconds: 60 # 定时任务执行时间,每隔60s刷新服务列表

  17. service-url:

  18. defaultZone: http://peer2:1112/eureka/ # 需要注册到的服务中心的地址

  19. instance:

  20. hostname: peer1 # 给主机命名

3、创建application-peer2.yml文件,作为peer2的服务注册中心。详细yml内容如下:

 
  1. spring:

  2. application:

  3. name: peer2

  4. profiles:

  5. active: peer2 # 多平台打包部署启动,用来启动时指定使用的配置文件

  6. server:

  7. port: 1112

  8. eureka:

  9. server:

  10. enable-self-preservation: false # 关闭自我保护,服务关闭后从列表中踢除,默认是true,开启自我保护

  11. eviction-interval-timer-in-ms: 60000 # 清理间隔(单位毫秒,默认是60*1000)

  12. client:

  13. enabled: true

  14. register-with-eureka: true

  15. fetch-registry: true

  16. service-url:

  17. defaultZone: http://peer1:1111/eureka/

  18. instance:

  19. hostname: peer2

4、启动

    使用maven打包之后,我们可以通过如下命令分别启动peer1和peer2.

 
  1. java -jar eureka-server.jar --spring.profiles.active=peer1

  2. java -jar eureka-server.jar --spring.profiles.active=peer2

首先我们访问http://localhost:1111

我们发现,服务注册peer1、peer2都注册到peer1中了,我们在访问Http://localhost:1112,

服务注册peer1、peer2同样也注册到peer2中了。

5、现在我们使用前边说的service-user服务,同时向两个服务注册中心peer1、peer2注册。然后启动。yml配置如下:

 
  1. server:

  2. port: 8001

  3.  
  4. spring:

  5. application:

  6. name: service-user

  7. eureka:

  8. client:

  9. service-url:

  10. defaultZone: http://peer2:1112/eureka/, http://peer1:1111/eureka/

  11. healthcheck:

  12. enabled: true #使用health端点来代替心跳表明服务是否可用,反应到eureka server ui上服务的UP还是DOWN

  13. instance:

  14. lease-expiration-duration-in-seconds: 30 #租期更新时间间隔(默认30秒)

  15. lease-renewal-interval-in-seconds: 10 #租期更新时间间隔(默认30秒)

  16. info:

  17. app:

  18. name: "@project.name@" #从pom.xml中获取

  19. description: "@project.description@"

  20. version: "@project.version@"

  21. spring-boot-version: "@project.parent.version@"

启动之后访问:http://localhost:8001

我们可以看到两个注册中心都有这个项目。至此,一个简单的高可用服务注册中心已经完成。

五、搭建服务消费者,

     我们将依赖前边的两个项目,高可用peer和服务提供者service-user来搭建服务消费者。

1、首先,我们在service-user中提供一个供注册的接口,如下:

 
  1. /**

  2. * @author [email protected]

  3. * @date 2018/2/22 18:23

  4. */

  5. @RestController

  6. @RequestMapping("service/user")

  7. public class UserController {

  8. Logger logger = LoggerFactory.getLogger(UserController.class);

  9. @Autowired

  10. private HttpServletRequest request;

  11.  
  12. @RequestMapping(value = "public/login" , method = {RequestMethod.GET} ,produces = {MediaType.APPLICATION_JSON_VALUE})

  13. public ResponseEntity<String> login(

  14. @RequestParam String account ,

  15. @RequestParam String password

  16. ){

  17. System.out.println(" request ::::::::: " +account+" == "+password);

  18. JSONObject jsonObject = new JSONObject();

  19. if("xuebin".equals(account) && "123456".equals(password)){

  20. jsonObject.put("status","success");

  21. }else {

  22. jsonObject.put("status","error");

  23. }

  24. return new ResponseEntity<String>(jsonObject.toJSONString() , HttpStatus.OK);

  25. }

  26. }

2、创建consumer项目,并注册到服务注册中心。

(1)、创建maven项目,命名为consumer。修改pom.xml文件如下:

 
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  3. <modelVersion>4.0.0</modelVersion>

  4. <artifactId>consumer</artifactId>

  5. <packaging>jar</packaging>

  6. <name>consumer</name>

  7. <url>http://maven.apache.org</url>

  8.  
  9. <properties>

  10. <start-class>com.learning.ApplicationConsumer</start-class>

  11. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

  12. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

  13. <java.version>1.8</java.version>

  14. <maven.compiler.source>1.8</maven.compiler.source>

  15. <maven.compiler.target>1.8</maven.compiler.target>

  16. <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>

  17. </properties>

  18. <parent>

  19. <groupId>org.springframework.boot</groupId>

  20. <artifactId>spring-boot-starter-parent</artifactId>

  21. <version>1.5.10.RELEASE</version>

  22. </parent>

  23. <dependencies>

  24. <!-- 全栈web开发模块,包括嵌入式Tomcat、Spring MVC -->

  25. <dependency>

  26. <groupId>org.springframework.boot</groupId>

  27. <artifactId>spring-boot-starter-web</artifactId>

  28. </dependency>

  29. <!--SpringBoot 测试模块-->

  30. <dependency>

  31. <groupId>org.springframework.boot</groupId>

  32. <artifactId>spring-boot-starter-test</artifactId>

  33. <version>1.5.9.RELEASE</version>

  34. <scope>test</scope>

  35. </dependency>

  36.  
  37. <!-- 该模块构建用于监控的端点 -->

  38. <dependency>

  39. <groupId> org.springframework.boot</groupId>

  40. <artifactId>spring-boot-starter-actuator</artifactId>

  41. </dependency>

  42.  
  43. <dependency>

  44. <groupId>org.springframework.cloud</groupId>

  45. <artifactId>spring-cloud-starter-eureka</artifactId>

  46. <version>1.3.1.RELEASE</version>

  47. </dependency>

  48.  
  49. <dependency>

  50. <groupId>junit</groupId>

  51. <artifactId>junit</artifactId>

  52. <version>4.12</version>

  53. <scope>test</scope>

  54. </dependency>

  55. <dependency>

  56. <groupId>org.springframework.boot</groupId>

  57. <artifactId>spring-boot-test</artifactId>

  58. <version>1.5.9.RELEASE</version>

  59. </dependency>

  60. <dependency>

  61. <groupId>org.springframework</groupId>

  62. <artifactId>spring-test</artifactId>

  63. <version>4.3.13.RELEASE</version>

  64. </dependency>

  65. <dependency>

  66. <groupId>junit</groupId>

  67. <artifactId>junit</artifactId>

  68. <version>4.12</version>

  69. </dependency>

  70. </dependencies>

  71. <build>

  72. <finalName>consumer</finalName>

  73. <plugins>

  74. <plugin>

  75. <groupId>org.springframework.boot</groupId>

  76. <artifactId>spring-boot-maven-plugin</artifactId>

  77. </plugin>

  78. <!-- 测试出错不影响项目编辑 -->

  79. <plugin>

  80. <groupId>org.apache.maven.plugins</groupId>

  81. <artifactId>maven-surefire-plugin</artifactId>

  82. <configuration>

  83. <testFailureIgnore>true</testFailureIgnore>

  84. </configuration>

  85. </plugin>

  86. </plugins>

  87. </build>

  88. </project>

(2)、创建配置文件application.yml,并设置相关参数如下:

 
  1. server:

  2. port: 8201

  3. spring:

  4. application:

  5. name: consumer

  6. eureka:

  7. client:

  8. service-url:

  9. defaultZone: http://peer2:1112/eureka/, http://peer1:1111/eureka/

  10. healthcheck:

  11. enabled: true #使用health端点来代替心跳表明服务是否可用,反应到eureka server ui上服务的UP还是DOWN

  12. instance:

  13. lease-expiration-duration-in-seconds: 30 #租期更新时间间隔(默认30秒)

  14. lease-renewal-interval-in-seconds: 10 #租期更新时间间隔(默认30秒)

  15. info:

  16. app:

  17. name: "@project.name@" #从pom.xml中获取

  18. description: "@project.description@"

  19. version: "@project.version@"

  20. spring-boot-version: "@project.parent.version@"

(3)、创建启动类,并设置为eureka客户端,详细代码如下:

 
  1. @SpringBootApplication

  2. @EnableEurekaClient

  3. public class ApplicationConsumer {

  4.  
  5. @Bean

  6. @LoadBalanced

  7. RestTemplate restTemplate(){

  8. return new RestTemplate();

  9. }

  10.  
  11. public static void main(String[] args) {

  12. SpringApplication.run(ApplicationConsumer.class , args);

  13. }

  14. }

(4)、创建UserController控制类并创建restful接口,提供rpc服务。详细代码如下:

 
  1. /**

  2. * 用户控制类

  3. * @author [email protected]

  4. * @date 2018/2/22 17:52

  5. */

  6. @Controller

  7. @RequestMapping("/api/user")

  8. public class UserController {

  9. Logger logger = LoggerFactory.getLogger(UserController.class);

  10.  
  11. @Autowired

  12. private UserService userService;

  13. @ResponseBody

  14. @RequestMapping(value = {"/public/v1/login"}, method = {RequestMethod.POST, RequestMethod.GET}, produces = {MediaType.APPLICATION_JSON_VALUE})

  15. public ResponseEntity<String> login(

  16. @RequestParam String account ,

  17. @RequestParam String password

  18. ){

  19. String user = userService.login(account , password);

  20. return new ResponseEntity<String>(user , HttpStatus.OK);

  21. }

  22. }

创建UserService接口:

 
  1. /**

  2. * @author [email protected]

  3. * @date 2018/2/22 18:09

  4. */

  5. public interface UserService {

  6. public String login(String account , String password);

  7. }

创建UserServiceImpl接口实现类:

 
  1. /**

  2. * @author [email protected]

  3. * @date 2018/2/22 18:11

  4. */

  5. @Service

  6. public class UserServiceImpl implements UserService {

  7.  
  8. Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

  9. @Autowired

  10. private RestTemplate restTemplate;

  11. @Override

  12. public String login(String account, String password) {

  13. logger.debug(" 登陆 account=%s ; password=%s " , account , password);

  14. // 注意,这里我们使用的时服务注册中的服务名,不是ip。在分部署环境下,服务多了,管理ip会很混乱,使用项目名访问,简单明了。这也是出现服务治理的主要原因。

  15. String host = "http://SERVICE-USER/";

  16. return restTemplate.getForEntity(host+"service/user/public/login?account="

  17. +account+"&password="+password , String.class).getBody();

  18. }

  19. }

(5)、启动consumer服务,继续查看peer1和peer2,我们会发现,consumer项目也存在与里边。

(6)、访问登陆接口 http://localhost:8201/api/user/public/v1/login?account=xuebin&password=123456

访问成功,

六、创建多节点服务提供者

我们以上一节service-user服务提供者来搭建多节点,application-dev1.yml和application-dev2.yml。

application-dev_1.yml如下:

 
  1. server:

  2. port: 8001

  3.  
  4. spring:

  5. application:

  6. name: service-user

  7. eureka:

  8. client:

  9. service-url:

  10. defaultZone: http://peer2:1112/eureka/, http://peer1:1111/eureka/

  11. # defaultZone: http://localhost:1111/eureka/

  12. healthcheck:

  13. enabled: true #使用health端点来代替心跳表明服务是否可用,反应到eureka server ui上服务的UP还是DOWN

  14. instance:

  15. lease-expiration-duration-in-seconds: 30 #租期更新时间间隔(默认30秒)

  16. lease-renewal-interval-in-seconds: 10 #租期更新时间间隔(默认30秒)

  17. info:

  18. app:

  19. name: "@project.name@" #从pom.xml中获取

  20. description: "@project.description@"

  21. version: "@project.version@"

  22. spring-boot-version: "@project.parent.version@"

application-dev_2.yml如下:

 
  1. server:

  2. port: 8002

  3.  
  4. spring:

  5. application:

  6. name: service-user

  7. eureka:

  8. client:

  9. service-url:

  10. defaultZone: http://peer2:1112/eureka/, http://peer1:1111/eureka/

  11. healthcheck:

  12. enabled: true #使用health端点来代替心跳表明服务是否可用,反应到eureka server ui上服务的UP还是DOWN

  13. instance:

  14. lease-expiration-duration-in-seconds: 30 #租期更新时间间隔(默认30秒)

  15. lease-renewal-interval-in-seconds: 10 #租期更新时间间隔(默认30秒)

  16. info:

  17. app:

  18. name: "@project.name@" #从pom.xml中获取

  19. description: "@project.description@"

  20. version: "@project.version@"

  21. spring-boot-version: "@project.parent.version@"

编译打包之后,分别以如下方式启动该服务:

 
  1. java -jar service-user.jar --spring.profiles.active=dev_1

  2. java -jar service-user.jar --spring.profiles.active=dev_2

然后连续多次访问http://localhost:8201/api/user/public/v1/login?account=xuebin&password=123456接口,看控制台:

Spring cloud封装实现的route类型filter,默认使用了ribbon对eureka 服务发现的负载均衡client。

通过日志我们可以看到,Ribbon作为后端负载均衡器,默认采用roundRobin方式轮询选择server。它一共提供了7种负载均衡策略:

策略名 策略声明 策略描述 实现说明
BestAvailableRule public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule 选择一个最小的并发请求的server 逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server
AvailabilityFilteringRule public class AvailabilityFilteringRule extends PredicateBasedRule 过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值) 使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态
WeightedResponseTimeRule public class WeightedResponseTimeRule extends RoundRobinRule 根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。 一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成status时,使用roubine策略选择server。
RetryRule public class RetryRule extends AbstractLoadBalancerRule 对选定的负载均衡策略机上重试机制。 在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
RoundRobinRule public class RoundRobinRule extends AbstractLoadBalancerRule roundRobin方式轮询选择server 轮询index,选择index对应位置的server
RandomRule public class RandomRule extends AbstractLoadBalancerRule 随机选择一个server 在index上随机,选择index对应位置的server
ZoneAvoidanceRule public class ZoneAvoidanceRule extends PredicateBasedRule 复合判断server所在区域的性能和server的可用性选择server 使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。

猜你喜欢

转载自blog.csdn.net/wjq008/article/details/81463570
今日推荐