• 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的实现类。
  • 相关阅读:
    Windows XP下 Android开发环境 搭建
    Android程序的入口点
    在eclipse里 新建android项目时 提示找不到proguard.cfg
    64位WIN7系统 下 搭建Android开发环境
    在eclipse里 新建android项目时 提示找不到proguard.cfg
    This Android SDK requires Android Developer Toolkit version 20.0.0 or above
    This Android SDK requires Android Developer Toolkit version 20.0.0 or above
    Android requires compiler compliance level 5.0 or 6.0. Found '1.4' instead
    Windows XP下 Android开发环境 搭建
    Android程序的入口点
  • 原文地址:https://www.cnblogs.com/zou-rong/p/12582137.html
Copyright © 2020-2023  润新知