• SpringCloud之Ribbon负载均衡


    上述案例中,我们启动了一个msg-service,然后通过DiscoveryClient来获取服务实例信息,然后获取ip和端口来访问。

    但是实际环境中,我们往往会开启很多个user-service的集群。此时我们获取的服务列表中就会有多个,到底该访问哪一个呢?

    一般这种情况下我们就需要编写负载均衡算法,在多个实例列表中进行选择。

    不过Eureka中已经帮我们集成了负载均衡组件:Ribbon,简单修改代码即可使用。

     

    什么是Ribbon:


      

    Ribbon的使用步骤 

    一、首先启动两个msg-server服务

    二、开启Ribbon负载均衡

      因为Eureka中已经集成了Ribbon,所以我们无需引入新的依赖。直接修改代码:

      在RestTemplate的配置方法上添加@LoadBalanced注解:

       修改调用方式,不再手动获取ip和端口,而是直接通过服务名称调用:

    package com.itcast.controller;
    
    import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
    import com.netflix.ribbon.proxy.annotation.Hystrix;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.cloud.client.discovery.DiscoveryClient;
    import org.springframework.cloud.netflix.hystrix.EnableHystrix;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.List;
    
    /**
     * @Classname MsgController
     * @Description TODO
     * @Date 2020/12/18 10:21
     * @Created by Administrator
     */
    @Controller
    public class MsgController {
    
        @Autowired
        RestTemplate restTemplate;
    
        @Autowired
        DiscoveryClient discoveryClient;
    
        @RequestMapping("hello")
        @ResponseBodypublic String hello(){
            String url="http://msg-server/hello";
            String forObject = restTemplate.getForObject(url, String.class);
            return forObject;
        }
    }

    修改负载均衡规则

    user-service:
      ribbon:
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

    重试机制

      Eureka的服务治理强调了CAP原则中的AP,即可用性和可靠性。它与Zookeeper这一类强调CP(一致性,可靠性)的服务治理框架最大的区别在于:Eureka为了实现更高的服务可用性,牺牲了一定的一致性,极端情况下它宁愿接收故障实例也不愿丢掉健康实例,正如我们上面所说的自我保护机制。

      但是,此时如果我们调用了这些不正常的服务,调用就会失败,从而导致其它服务不能正常工作!这显然不是我们愿意看到的。

      因此Spring Cloud 整合了Spring Retry 来增强RestTemplate的重试能力,当一次服务调用失败后,不会立即抛出异常,而是再次重试另一个服务。

    spring:
      cloud:
        loadbalancer:
          retry:
            enabled: true # 开启Spring Cloud的重试功能
    user-service:
      ribbon:
        ConnectTimeout: 250 # Ribbon的连接超时时间
        ReadTimeout: 1000 # Ribbon的数据读取超时时间
        OkToRetryOnAllOperations: true # 是否对所有操作都进行重试
        MaxAutoRetriesNextServer: 1 # 切换实例的重试次数
        MaxAutoRetries: 1 # 对当前实例的重试次数

      根据如上配置,当访问到某个服务超时后,它会再次尝试访问下一个服务实例,如果不行就再换一个实例,如果不行,则返回失败。切换次数取决于MaxAutoRetriesNextServer参数的值。

      附:引入spring-retry依赖

    <dependency>
        <groupId>org.springframework.retry</groupId>
        <artifactId>spring-retry</artifactId>
    </dependency>
  • 相关阅读:
    DSA——基数排序
    cannot instantiate the type
    DSA——从尾到头打印链表笔记
    DSA——AVL平衡二叉树
    Leetcode——438. Find All Anagrams in a String【java】【没搞清楚呢】
    Leetcode——415. Add Strings【java】
    Leetcode——387. First Unique Character in a String【java】
    Leetcode——344. Reverse String
    Leetcode——205-Isomorphic Strings(同构字符串)【待反思周末】
    DSA——Shell排序算法
  • 原文地址:https://www.cnblogs.com/sun-10387834/p/14167911.html
Copyright © 2020-2023  润新知