zoukankan      html  css  js  c++  java
  • Ribbon负载均衡

    因为在导入Eureka客户端依赖的时候,也会一并加载Ribbon的依赖,所以无需重新添加依赖

    第一步:在服务消费方注入RestTemplate时添加LoadBalanced注解

    package com.company;

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.cloud.netflix.ribbon.RibbonClient;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;

    @EnableDiscoveryClient
    @SpringBootApplication
    public class ConsumerApplication {

    public static void main(String[] args) {
    SpringApplication.run(ConsumerApplication.class);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
    return new RestTemplate();
    }
    }

    第二步:改变使用服务ID的方式。这样会在这个注入的RestTemplate对象上添加拦截器,拦截器的名称叫LoadBalancerInterceptor,在使用的时候就很方便了。

    package com.company.controller;

    import com.company.pojo.User;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.cloud.client.discovery.DiscoveryClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;

    import java.util.List;

    @RestController
    @RequestMapping("/consumer")
    public class ConsumerController {

    @Autowired
    private RestTemplate template;

    @Autowired
    private DiscoveryClient client;//ureka客户端

    @GetMapping("/{id}")
    public User getUserById(@PathVariable("id")Long id){
         //url变量中的user-service就是服务id
    String url="http://user-service/user/"+id;
    return template.getForObject(url,User.class);
    }
    }

    拦截器

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //

    package org.springframework.cloud.client.loadbalancer;

    import java.io.IOException;
    import java.net.URI;
    import org.springframework.http.HttpRequest;
    import org.springframework.http.client.ClientHttpRequestExecution;
    import org.springframework.http.client.ClientHttpRequestInterceptor;
    import org.springframework.http.client.ClientHttpResponse;
    import org.springframework.util.Assert;

    public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {
    private LoadBalancerClient loadBalancer;
    private LoadBalancerRequestFactory requestFactory;

    public LoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory) {
    this.loadBalancer = loadBalancer;
    this.requestFactory = requestFactory;
    }

    public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) {
    this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));
    }

    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
    URI originalUri = request.getURI();
    String serviceName = originalUri.getHost();
    Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
    return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));
    }
    }

    最终调用RibbonLoadBalancerClient中的execute方法,将服务ID替换为IP:端口

    追踪this.getServer(loadBalance,hint)追到BaseLoadBalancer

     

      

      

     

     可以看到默认使用的是轮询,debug的结果也是如此。

    看一下自带的轮询规则实现类

    可以通过配置来修改轮询规则,在服务消费方application.yaml文件添加

    user-service:
    ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    #格式是:{服务名称}.ribbon.NFLoadBalancerRuleClassName,值就是IRule的实现类。
  • 相关阅读:
    自定义全局样式
    ionic错误
    ionic 创建某个文件下的page
    获取高度
    页面加载完成
    css中有些属性的前面会加上“*”或“_(兼容IE浏览器)
    【Visual Studio】error C2220: 警告被视为错误
    H264格式(转)
    什么是信令?什么是信令网?(转)
    XMPP协议实现原理介绍(转)
  • 原文地址:https://www.cnblogs.com/zou-rong/p/12582137.html
Copyright © 2011-2022 走看看