🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# Spring cloud ribbon 和 Eureka – 客户端负载均衡器示例 > 原文: [https://howtodoinjava.com/spring-cloud/spring-boot-ribbon-eureka/](https://howtodoinjava.com/spring-cloud/spring-boot-ribbon-eureka/) 在此 Spring 云教程中,学习在 Spring Boot / Cloud 项目中使用 Netflix Ribbon 使用**客户端负载平衡**。 学习构建基于微服务的应用程序,这些应用程序使用 **Ribbon** 作为客户端负载平衡器,并使用 **eureka** 作为注册表服务。 了解如何在负载均衡器下动态添加微服务的新实例。 ## 1\. 传统的服务器端负载均衡 服务器端负载平衡涉及单片应用程序,在这些应用程序中,负载平衡器后面的应用程序实例数量有限。 我们将 war / ear 文件部署到多个服务器实例中,这些实例基本上是已部署了相同应用程序的服务器池,并在其前面放置了负载均衡器。 负载平衡器具有公共 IP 和 DNS。 客户端使用该公共 IP / DNS 发出请求。 负载平衡器决定将内部应用程序服务器请求转发到哪个请求。 它主要使用轮询或粘性会话算法。 我们称其为服务器端负载平衡。 #### 1.1. 微服务架构中的问题 通常,服务器端负载平衡是一项手动工作,我们需要手动将实例添加/删除到负载平衡器才能工作。 因此,理想情况下,我们要失去当今随需应变的可伸缩性,以自动发现和配置何时分拆任何新实例。 另一个问题是制定故障转移策略以为客户提供无缝的体验。 最后,我们需要一个单独的服务器来承载负载均衡器实例,这会对成本和维护产生影响。 ## 2\. 客户端负载平衡 为了克服传统负载平衡的问题,客户端负载平衡成为了现实。 它们作为内置组件驻留在应用程序中,并与应用程序捆绑在一起,因此我们不必将它们部署在单独的服务器中。 现在,让我们可视化全局。 在微服务架构中,我们将不得不开发许多微服务,并且每个微服务在生态系统中可能具有多个实例。 为了克服这种复杂性,我们已经有了使用**服务发现模式**的流行解决方案。 在 SpringBoot 应用程序中,我们在服务发现空间中提供了两个选项,例如 Eureka,Consul,动物园管理员等。 现在,如果一个微服务想要与另一个微服务进行通信,则通常会使用发现客户端来查找服务注册表,并且 Eureka 服务器会将该目标微服务的所有实例返回给调用者服务。 然后,调用者服务负责选择要发送请求的实例。 在这里,客户端负载平衡成为现实,它会自动处理这种情况下的复杂性,并以负载平衡的方式委派给适当的实例。 注意,我们可以指定要使用的负载平衡算法。 ## 3\. Netflix Ribbon – 客户端负载平衡器 Spring Cloud 系列的 Netflix Ribbon 提供了这种功能来设置客户端负载平衡以及服务注册表组件。 Spring Boot 具有非常好的配置 Ribbon 客户端负载平衡器的简便方法。 它提供以下功能 1. 负载均衡 2. 容错能力 3. 异步和响应模型中的多种协议(HTTP,TCP,UDP)支持 4. 缓存和批处理 要获取 Ribbon 二进制文件,请转到 [maven 中心](https://search.maven.org/#search%7Cga%7C1%7Cribbon)。 这是在 Maven 中添加依赖项的示例: `pom.xml` ```java <dependency> <groupId>com.netflix.ribbon</groupId> <artifactId>ribbon</artifactId> <version>2.2.2</version> </dependency> ``` ## 4\. Netflix Ribbon 示例 #### 4.1. 技术栈 * Java,Eclipse,Maven 作为开发环境 * Spring-boot 和 Cloud 作为应用程序框架 * Eureka 即服务注册表服务器 * Ribbon 作为客户端负载均衡器 我们将创建以下组件,并查看整个生态系统如何在分布式环境中进行协调。 * 使用 Spring 运行的两个微服务。 一个需要根据业务需求调用另一个 * Eureka 服务注册服务器 * 调用微服务中的 Ribbon 通过服务发现以负载平衡的方式调用其他服务 * 以负载平衡的方式调用服务,而无需发现服务 #### 4.2. 创建后端微服务 我们将使用 Spring boot 创建一个简单的微服务,并将公开简单的 REST 端点。 使用`spring-boot-web`和**服务发现客户端**依赖关系创建一个名为`ribbon-server`的简单 Spring Boot 项目,以将其托管在 Web 服务器中,并公开一个 Rest 控制器进行测试。 为此,我们需要转到 https://start.spring.io/ 并提供 Maven 坐标并选择依赖项。 下载包含框架项目的 zip 文件。 然后,一旦解压缩到合适的文件夹中,我们就需要将其导入 eclipse 中。 ![](https://img.kancloud.cn/2a/ea/2aea6bc6c4f6ac15a38d1161aa0a2d20_1354x626.jpg) 从 Spring Initializer 生成的项目 ###### 4.2.1. 创建 REST 端点 编写一个 Rest 控制器,并如下所示公开一个 Rest 端点。 `MyRestController.java` ```java package com.example.ribbonserver; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class MyRestController { @Autowired Environment environment; @GetMapping("/") public String health() { return "I am Ok"; } @GetMapping("/backend") public String backend() { System.out.println("Inside MyRestController::backend..."); String serverPort = environment.getProperty("local.server.port"); System.out.println("Port : " + serverPort); return "Hello form Backend!!! " + " Host : localhost " + " :: Port : " + serverPort; } } ``` ###### 4.2.2 启用发现客户端 注册此服务到 eureka,我们需要在应用程序类中添加`@EnableDiscoveryClient`。 另外,我们需要在应用程序属性文件中添加以下条目。 `RibbonServerApplication.java` ```java package com.example.ribbonserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class RibbonServerApplication { public static void main(String[] args) { SpringApplication.run(RibbonServerApplication.class, args); } } ``` `application.properties` ```java spring.application.name=server server.port = 9090 eureka.client.serviceUrl.defaultZone= http://${registry.host:localhost}:${registry.port:8761}/eureka/ eureka.client.healthcheck.enabled= true eureka.instance.leaseRenewalIntervalInSeconds= 1 eureka.instance.leaseExpirationDurationInSeconds= 2 ``` #### 4.3. Eureka 服务注册表服务器 创建服务发现服务器。 这也很容易。 只是我们需要使用 Eureka 服务器作为依赖项来创建上述的 spring boot 项目,并执行以下配置。 ###### 4.3.1. Eureka 服务器配置 准备好 Spring Boot 服务并将其导入 Eclipse 后,在 Spring Boot 应用程序类中添加`@EnableEurekaServer`注解,并在应用程序属性文件中添加以下配置。 `RibbonEurekaServerApplication.java` ```java package com.example.ribboneurekaserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class RibbonEurekaServerApplication { public static void main(String[] args) { SpringApplication.run(RibbonEurekaServerApplication.class, args); } } ``` `application.properties` ```java spring.application.name= ${springboot.app.name:eureka-serviceregistry} server.port = ${server-port:8761} eureka.instance.hostname= ${springboot.app.name:eureka-serviceregistry} eureka.client.registerWithEureka= false eureka.client.fetchRegistry= false eureka.client.serviceUrl.defaultZone: http://${registry.host:localhost}:${server.port}/eureka/ ``` #### 4.4. 创建另一个微服务 遵循上一节的内容,创建另一个名为`ribbon-client`的服务,并增加了权限`spring-cloud-starter-netflix-ribbon`。 下载后,将项目导入 eclipse 中并执行以下配置。 ###### 4.4.1. 碳带配置 在应用程序类中,添加两个注解`@RibbonClient`和`@EnableDiscoveryClient`,以启用 Ribbon 和 Eureka 客户端进行服务注册。 `RibbonClientApplication.java` ```java package com.example.ribbonclient; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.ribbon.RibbonClient; @EnableDiscoveryClient @SpringBootApplication @RibbonClient(name = "server", configuration = RibbonConfiguration.class) public class RibbonClientApplication { public static void main(String[] args) { SpringApplication.run(RibbonClientApplication.class, args); } } ``` 在`application.properties`中,我们需要进行以下配置。 在这里`server.ribbon.listOfServers`被禁用,我们可以启用它以手动将服务器添加到此负载均衡器。 我们将在“测试”部分中对此进行检查。 其他属性不言自明。 `application.properties` ```java spring.application.name=client server.port=8888 eureka.client.serviceUrl.defaultZone= http://${registry.host:localhost}:${registry.port:8761}/eureka/ eureka.client.healthcheck.enabled= true eureka.instance.leaseRenewalIntervalInSeconds= 1 eureka.instance.leaseExpirationDurationInSeconds= 2 server.ribbon.eureka.enabled=true #server.ribbon.listOfServers=localhost:9090,localhost:9091,localhost:9092 server.ribbon.ServerListRefreshInterval=1000 #logging.level.root=TRACE ``` 现在,我们需要为 Ribbon 创建另一个配置类,以提及**负载平衡算法和运行状况检查**。 现在,我们将使用 Ribbon 所提供的默认值,但是在此类中,我们可以很好地覆盖它们并添加我们的自定义逻辑。 `RibbonConfiguration.java` ```java package com.example.ribbonclient; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.AvailabilityFilteringRule; import com.netflix.loadbalancer.IPing; import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.PingUrl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; public class RibbonConfiguration { @Autowired IClientConfig config; @Bean public IPing ribbonPing(IClientConfig config) { return new PingUrl(); } @Bean public IRule ribbonRule(IClientConfig config) { return new AvailabilityFilteringRule(); } } ``` ## 5\. 测试应用程序 #### 5.1. 启动组件 执行最终的构建使用命令`mvn clean install`,并检查构建是否成功。 如果有任何错误,则需要进行修复。 一旦成功完成所有 Maven 项目的构建,我们将一个接一个地启动服务。 首先是 Eureka,然后是后端微服务,最后是前端微服务。 要启动每个微服务,我们将使用`'java -jar -Dserver.port=XXXX target/YYYYY.jar'`命令。 #### 5.2. 部署后端微服务的多个实例 为此,我们需要为此使用不同的端口,以在特定端口中启动服务,我们需要以这种方式传递该端口。 `java -jar -Dserver.port=XXXX target/YYYYY.jar`。 我们将在端口 9090、9091 和 9092 端口中创建此服务的 3 个实例。 #### 5.3. 验证 Eureka 服务器 现在,在浏览器中转到`http://localhost:8761/`,并检查 eureka 服务器正在运行,并且所有微服务都已注册了所需数量的实例。 #### 5.4. 检查客户端负载平衡是否正常 在前端微服务中,我们使用`RestTemplate`调用后端微服务。 使用`@LoadBalanced`注解,将剩余温度作为客户端负载平衡器启用。 现在转到浏览器,打开客户端微服务 REST 端点`http://localhost:8888/client/frontend`,看看响应来自任何后端实例。 要了解此后端服务器正在返回其运行端口,我们也在客户端微服务响应中也显示了该端口。 尝试刷新此 URL 几次,然后注意到后端服务器的端口不断变化,这意味着客户端负载平衡正在工作。 现在尝试添加更多后端服务器实例,并检查是否也在 eureka 服务器中注册并最终在 Ribbon 中考虑,因为一旦将在 eureka 中注册,Ribbon 也会自动将请求发送到新实例。 #### 5.5. 使用硬编码后端进行测试,而无需发现服务 转到前端微服务`application.properties`文件并启用它。 `application.properties` ```java server.ribbon.listOfServers=localhost:9090,localhost:9091,localhost:9092 server.ribbon.eureka.enabled=false ``` 现在测试客户端网址。 您将仅从注册的实例获得响应。 现在,如果您在其他端口中启动后端微服务的新实例,Ribbon 将不会向新实例发送请求,除非我们在 Ribbon 中手动注册。 如果您在测试时遇到困难,我也建议您从所有应用程序中删除所有与 eureka 相关的配置,并停止 eureka 服务器。 希望您也不会在测试中遇到任何困难。 ## 6\. 总结 因此,我们已经看到了在 SpringBoot 微服务开发中可以轻松地将 Ribbon 和 Eureka 一起使用。 因此,下次如果您需要这种要求,则可以使用这种方法。 如果您对此有任何疑问,请在下面评论。 [下载源码](https://howtodoinjava.com/wp-content/uploads/2018/10/spring-boot-ribbon.zip) 学习愉快! 参考文献: [Spring Cloud Ribbon 文档](https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-ribbon.html)