LoadBalancer负载均衡

411 阅读2分钟

1.LoadBalancer负载均衡

  负载均衡是指将负载分摊到多个执行单元上,常见的负载均衡有两种方式。一种独立进程单元,通过负载均衡策略,将请求转发到不同的执行单元上。
  例如下图Nginx。例如客户端发送请求,请求下单业务到Nginx,进行方向代理,代理得哪个微服务节点是由负载均衡算法来决定的.

image.png   springCloud原有的客户端负载均衡方案Ribbon已经被废弃,取而代之的是SpringCloud LoadBalancer,LoadBalancer是Spring Cloud Commons的一个子项目,他属于上述的第二种方式,是将负载均衡逻辑封装到客户端中,并且运行在客户端的进程里。

  在Spring Cloud构件微服务系统中,LoadBalancer作为服务消费者的负载均衡器,有两种使用方式,一种是和RestTemplate相结合,另一种是和Feign相结合,Feign已经默认集成了LoadBalancer

1.1 LoadBalancer整合RestTemplate

  1. 配置文件 在application.yml配置文件中,使用spel指定端口,表示存在port参数使用port参数,不存在使用默认9001端口, 启动支付服务时,可以通过指定-Dport=9000,指定支付服务使用不同端口启动,具体参考后面内容。
  port: ${port:9001}
  1. PaymentController 在提供支付服务时,把端口打印出来,方便查看测试效果。代码如下。
@RequestMapping("/payment")
public class PaymentController {

    @Value("${server.port}")
    private String serverPort;

    @GetMapping("/{id}")
    public ResponseEntity<Payment> payment(@PathVariable("id") Integer id) {
        Payment payment = new Payment(id, "支付成功,服务端口=" + serverPort);
        return ResponseEntity.ok(payment);
    }

}
  1. OrderApplication 在产生RestTemplate实例时,使用@LoadBalanced注解,开启负载均衡。
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
  1. OrderController 在OrderController中,使用serviceId调用支付服务,此时LoadBalancer负载均衡生效,从多个服务提供者节点轮询选择一个使用。
    public ResponseEntity<Payment> getPaymentById(@PathVariable("id") Integer id) {

        String url = "http://cloud-payment-service/payment/" + id;
        Payment payment = restTemplate.getForObject(url, Payment.class);

        return ResponseEntity.ok(payment);
    }
  1. 启动并测试 启动两个支付微服务工程,端口分别是9000和9001,因为application.yml配置文件中使用${port:9001}配置端口,其中9000节点启动配置

image.png 另一个支付节点,不指定-Dport,使用默认9001端口启动,这时准备了2个支付微服务节点。Eureka注册效果如下

image.png 接下来在浏览器多次访问http://localhost:9002/order/payment/123456时,负载均衡器起了作用,结果9000,9001轮流出现。

image.png

image.png

1.2 LoadBlancerClient简介

负载均衡的核心类为LoadBalancerClient,LoadBalancerClient可以获取负载均衡的服务提供者实例信息。在OrderController增加演示代码如下。

    private LoadBalancerClient loadBalancerClient;

    @GetMapping("/test-load-balancer")
    public String testLoadBalancer() {
        ServiceInstance instance = loadBalancerClient.choose("cloud-payment-service");
        return instance.getHost() + ":" + instance.getPort();
    }

重启工程,浏览器访http://localhost:9002/order/test-load-balancer发现浏览器轮流显示如下内容

localhost:9000
localhost:9001