Ribbon 负载均衡

前面提到的负载,其实就是由Ribbon实现。
当消费方发起请求时,先到Ribbon,然后Ribbon去到Eureka-server,拉取对应服务列表,然后根据负载策略,选择服务。

查看LoadBalancerInterceptor.java
实现了ClientHttpRequestInterceptor的intercept方法,代表会拦截客户请求的HTTP请求。

//拦截到RestTemplate发起的请求
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {
        URI originalUri = request.getURI();
        //获取请求URL
        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));
        //loadBalancer.execute就是到Eureka拉取服务列表
    }

查看到LoadBalancerClient是一个接口,而它的实现就有Ribbon
Ribbon 负载均衡
查看execut方法

public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint) throws IOException {
        ILoadBalancer loadBalancer = this.getLoadBalancer(serviceId);
        //执行后得到一个DynamicServerListLoadBalance对象,动态服务列表均衡器,其属性allServerList就有服务列表信息,所以此步骤是去Eureka拉取服务
        Server server = this.getServer(loadBalancer, hint);
        //进行负载,查看getServer是调用了ZoneAwareLoadBalancer的chooseServer方法,进一步调用父类BaseLoadBalancer的chooseServer,执行了rule.choose()方法
        if (server == null) {
            throw new IllegalStateException("No instances available for " + serviceId);
        } else {
            RibbonLoadBalancerClient.RibbonServer ribbonServer = new RibbonLoadBalancerClient.RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server));
            return this.execute(serviceId, (ServiceInstance)ribbonServer, (LoadBalancerRequest)request);
        }
    }

在父类BaseLoadBalancer中调用的以下方法

return this.rule.choose(key);
//从DynamicServerListLoadBalance中按规则选择一个

通过Ctrl+H,查看rule的实现类,有随机RandomRule和轮循RoundRobinRule,而默认是Zone
Ribbon 负载均衡

Ribbon 负载均衡
整体逻辑为:

  1. 消费方发起请求。
  2. 被LoadBalancerIntercepot负载均衡拦截器拦截。
  3. 拦截后交给RibbonLoadBanlanceClient。
  4. RibbonLoadBanlanceClient获取服务名称交给DynamicServerListLoadBalance处理
  5. DynamicServerListLoadBalance拉Eureka中拉取服务。
  6. 拉取到的服务根据Irule规则进行选择。
  7. 再将返回值返回给RibbonLoadBanlanceClient,最后由RibbonLoadBanlanceClient修改URL,发起请求。
上一篇:CAS5.3版本单点登录服务器的搭建


下一篇:【转】什么是CT使用的水模、体模