前面我们已经完成了注册中心和服务提供者两个基础组件. 接着介绍使用 Spring Cloud Ribbon 在客户端负载均衡的调用服务.
ribbon 是一个客户端负载均衡器, 可以简单的理解成类似于 nginx 的负载均衡模块的功能.
主流的 LB 方案可分成两类:
一种是集中式 LB, 即在服务的消费方和提供方之间使用独立的 LB 设施 (可以是硬件, 如 F5, 也可以是软件, 如 nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方;
另一种是进程内 LB, 将 LB 逻辑集成到消费方, 消费方从服务注册中心获知有哪些地址可用, 然后自己再从这些地址中选择出一个合适的服务器. Ribbon 就属于后者, 它只是一个类库, 集成于消费方进程, 消费方通过它来获取到服务提供方的地址.
Ribbon 的架构图: 如下:
1. 首先我们先在原来的基础上新建一个 Ribbon 模块, 如下图:
现在我们单独使用 ribbon, 在 Ribbon 模块下添加依赖, 如下图所示:
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-ribbon</artifactId>
- <version>1.4.0.RELEASE</version>
- </dependency>
修改 application.yml 文件, 如下所示:
- server:
- port: 8082
- spring:
- application:
- name: Ribbon-Consumer
- #providers 这个是自己命名的, ribbon,listOfServer 这两个是规定的
- providers:
- ribbon:
- listOfServers: localhost:8080,localhost:8081
在 Ribbon 模块下新建一个测试类如下代码 * Created by cong on 2018/5/8. */
- @RestController
- public class ConsumerController {
- // 注入负载均衡客户端
- @Autowired
- private LoadBalancerClient loadBalancerClient;
- @RequestMapping("/consumer")
- public String helloConsumer() throws ExecutionException, InterruptedException {
- // 这里是根据配置文件的那个 providers 属性取的
- ServiceInstance serviceInstance = loadBalancerClient.choose("providers");
- // 负载均衡算法默认是轮询, 轮询取得服务
- URI uri = URI.create(String.format("http://%s:%s", serviceInstance.getHost(), serviceInstance.getPort()));
- return uri.toString();
- }
运行结果如下:
- server:
- port: 8082
- spring:
- application:
- name: Ribbon-Consumer
- #providers 这个是自己命名的, ribbon,listOfServer 这两个是规定的
- providers:
- ribbon:
- listOfServers: localhost:8080,localhost:8081
- ## 如果不想选用默认的轮询的负载均衡算法, 在这里做如下配置
- package hjc;
- import com.netflix.loadbalancer.IRule;
- import com.netflix.loadbalancer.RandomRule;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
- import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
- import org.springframework.cloud.client.loadbalancer.LoadBalanced;
- import org.springframework.context.annotation.Bean;
- import org.springframework.web.client.RestTemplate;
- @SpringBootApplication
- public class RibbonApplication {
- public static void main(String[] args) {
- SpringApplication.run(RibbonApplication.class, args);
- }
- @Bean
- public IRule ribbonRule(){
- return new RandomRule();
- }
- }
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-eureka</artifactId>
- <version>1.3.5.RELEASE</version>
- </dependency>
- server:
- port: 8082
- spring:
- application:
- name: Ribbon-Consumer
- eureka:
- # 客户端
- client:
- # 注册中心地址
- service-url:
- defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/
- @SpringBootApplication
- @EnableDiscoveryClient
- public class RibbonApplication {
- public static void main(String[] args) {
- SpringApplication.run(RibbonApplication.class, args);
- }
- @Bean
- @LoadBalanced
- public RestTemplate restTemplate(){
- return new RestTemplate();
- }
- }
- provider1:
- package hjc.hello;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- /**
- * Created by cong on 2018/5/8.
- */
- @RestController
- public class HelloController {
- @RequestMapping("/hello")
- public String hello(){
- return "hello1";
- }
- }
- package hjc.hello;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
- /**
- * Created by cong on 2018/5/8.
- */
- @RestController
- public class HelloController {
- @RequestMapping("/hello")
- public String hello(){
- return "hello2";
- }
- }
- /**
- * Created by cong on 2018/5/8.
- */
- @RestController
- public class ConsumerController {
- @Autowired
- private RestTemplate restTemplate;
- @RequestMapping("/consumer")
- public String helloConsumer() throws ExecutionException, InterruptedException {
- return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody();
- }
来源: https://www.cnblogs.com/huangjuncong/p/9022055.html