一、什么是Ribbon。

  Ribbon是Netfix发布的负载均衡器,它有助于控制HTTP和TCP客户端的行为。为Ribbon配置服务提供者地址列表后,Ribbon就可基于某种负载均衡算法,自动的去帮助服务消费者去请求。Ribbon默认为我们提供了很多的负载均衡算法,例如轮询、随机等。当然,我们也可为Ribbon实现自定义的负载均衡算法。

  在实际环境中,当获取的服务列表中就会有多个时,需要编写负载均衡算法,在多个实例列表中进行选择。Eureka中已经帮我们集成了负载均衡组件:Ribbon,简单修改代码即可使用。

二、使用Ribbon实现负载均衡。

  1、启动两个服务实例。

 

   2、Eureka 监控面板。

 

   3、开启负载均衡。

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

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

@SpringBootApplication
@EnableDiscoveryClient // 开启Eureka客户端
public class ConsumerDemoApplication {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
    }
    public static void main(String[] args) {
        SpringApplication.run(ConsumerDemoApplication.class, args);
    }
}

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

@Service
public class UserService {
    @Autowired
    private RestTemplate restTemplate;

    // Eureka客户端,可以获取到服务实例信息。
    @Autowired
    private DiscoveryClient discoveryClient;// Eureka客户端,可以获取到服务实例信息

    public List<User> queryListByIds(List<Long> ids) {
        List<User> users = new ArrayList<>();
        // 地址直接写服务名称
        String baseUrl = "http://user-service/user/";
        for (Long id : ids) {
            // 多次查询
            users.add(this.restTemplate.getForObject(baseUrl + id, User.class));
            // 每次间隔500毫秒
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return users;
    }
}

  3.3、启动并访问 http://localhost:8082/consumer?ids=1,2

 

 

  4、负载均衡策略。

  Ribbon默认的负载均衡的策略是简单的轮询。

  拦截器中是使用RibbonLoadBalanceClient来进行负载均衡的,其中有一个方法choose就是负载均衡的实例方法。

  编写测试类,注入choose方法的类对象,然后测试:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConsumerDemoApplication.class)
public class LoadBalanceTest {

    @Autowired
    RibbonLoadBalancerClient client;

    @Test
    public void test(){
        for (int i = 0; i < 100; i++) {
            ServiceInstance instance = this.client.choose("user-service");
            System.out.println(instance.getHost() + ":" + instance.getPort());
        }
    }
}

  结果:

 

   定义负载均衡的规则接口为IRule,它有以下实现。

 

  SpringBoot也帮我们提供了修改负载均衡规则的配置入口,格式是:{服务名称}.ribbon.NFLoadBalancerRuleClassName,值就是IRule的实现类。

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

  变为随机:

 

 5、重试机制。

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

  但是,突然停掉某个服务,因为服务剔除的延迟,消费者并不会立即得到最新的服务列表,此时如果我们调用了这些不正常的服务,调用就会失败,从而导致其它服务不能正常工作!

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

  只需要简单配置即可实现Ribbon的重试:

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>

  重启user-consumer,测试,发现即使user-service宕机,也能通过另一台服务实例获取结果。

原文地址:http://www.cnblogs.com/sfwu/p/16875402.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性