Spring Cloud 三、Ribbon 负载均衡/ discoveryClient 获取注册服务Ip+端口, 使用 RestTemplate 实现Rpc调用

一、注入RestTemplate 及Ribbon 说明?

SpringCloud中Ribbon负载均衡客户端,会从eureka注册中心服务器端上获取服务注册信息列表,缓存到本地。让后在本地实现轮训负载均衡策略, 既在客户端实现负载均衡。

如下示例开启 Ribbon:
@LoadBalanced 注解等于开启Ribbon 功能,让restTemplate 具有负载均衡效果
放入启动类即可

  /**
     * TODO   RestTemplate =  rest,http风格的,api调用工具
     *
     * @return org.springframework.web.client.RestTemplate
     * @date 2019/12/6 0006 12:02
     */
    @Bean              //注入springboot容器
    @LoadBalanced      //让RestTemplate在请求时拥有客户端负载均衡的能力
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

使用restTemplate

@Autowired
private RestTemplate restTemplate;
//使用
String result = restTemplate.getForObject(memberUrl, String.class);

二、Ribbon与Nginx 的区别?

1、Nginx是客户端所有请求统一交给nginx,由nginx进行实现负载均衡请求转发,属于服务器端负载均衡。
既请求有nginx服务器端进行转发。
2、Ribbon 是本地实现轮训负载均衡策略, 既在客户端实现负载均衡
3、Nginx适合于服务器端实现负载均衡 比如Tomcat ,
4、Ribbon适合与在微服务中RPC远程调用实现本地服务负载均衡,比如Dubbo、SpringCloud中都是采用本地负载均衡。

三、 使用discoveryClient 获取 eureka 注册数据

  @Autowired
  private DiscoveryClient discoveryClient;

  
    /**
     * TODO    获取注册中心的数据
     *
     * @return java.util.List<java.lang.String>
     * @date 2019/12/7 0007 8:43
     */
    @RequestMapping("/getServiceDesc")
    public List<String> getServiceDesc() {
        List<ServiceInstance> list = discoveryClient.getInstances("app-member");
        List<String> services = new ArrayList<>();
        for (ServiceInstance serviceInstance : list) {
            if (serviceInstance != null) {
                services.add(serviceInstance.getUri().toString());
            }
        }
        return services;
    }

四、 自定义本地负载均衡

1、先注释掉 / 删除掉@LoadBalanced ,让restTemplate 不具备负载均衡能力
在这里插入图片描述
2、自定义负载均衡逻辑

    /**
     * rpc 调用工具
     */
    @Autowired
    private RestTemplate restTemplate;
    /**
     * 获取注册中心数据对象
     */
    @Autowired
    private DiscoveryClient discoveryClient;
    /**
     * 请求数(这里不安全,建议使用原子类)
     */
    private int requestCount = 1;


  @RequestMapping("/getorder")
    public String getOrder() {
        // 通过serviceId+取模算法获得注册中心的服务地址
        String serviceUrl = getServiceUrl();
        // url + 接口
        String memberUrl = serviceUrl + "/getMember";
        // rpc 调用
        String result = restTemplate.getForObject(memberUrl, String.class);
        System.out.println("会员服务调用订单服务,result:" + result);
        return result;
    }


    /**
     * TODO   使用取模算法轮训,根据请求数
     *
     * @return java.lang.String
     * @date 2019/12/7 0007 8:55
     */
    private String getServiceUrl() {
        List<ServiceInstance> instances = discoveryClient.getInstances("app-member");
        if (instances == null || instances.size() == 0) {
            return null;
        }
        int size = instances.size();
        int index = requestCount % size;
        requestCount++;
        return instances.get(index).getUri().toString();
    }
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页