Ribbon入门

Ribbon

当一个服务需要提供多个的时候,负载均衡策略就成为了一个问题。我们可以使用随机、轮询、hash等方式实现负载均衡的策略。

Ribbon是一个为客户端提供负载均衡功能的服务,它内部提供了一个叫做ILoadBalance的接口代表负载均衡器的操作,比如有添加服务器操作、选择服务器操作、获取所有的服务器列表、获取可用的服务器列表等等。

使用Eureka时存在的问题

  • 当部署多个相同微服务的时候,如何实现负载均衡?
  • 微服务间互相通讯的时候,必须硬编码的形式获取服务的地址。

Ribbon简介

Ribbon是Netflix发布的云中间层服务开源项目,其主要功能是提供客户端实现负载均衡算法。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,Ribbon是一个客户端负载均衡器,我们可以在配置文件中Load Balancer后面的所有机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。

下图展示了Eureka使用Ribbon时的大致架构:

Ribbon入门案例

在服务调用方consumer添加Ribbon依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

实现方式1:

修改web层的

    /***
     * 注入discoveryClient 注意是Spring的包
     */
    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/{id}")
    public Employee getEmployeeById(@PathVariable Integer id) {
        //获取实例列表
        List<ServiceInstance> instancesList = discoveryClient.getInstances("emp-provider");
        //获取实例
        ServiceInstance instance = instancesList.get(0);
        //获取主机地址
        String hostName = instance.getHost();
        //获取端口号
        int port = instance.getPort();
        //拼接url
        String url = "http://" + hostName + ":" + port + "/employee/" + id;
        //调用接口
        Employee employee = restTemplate.getForObject(url, Employee.class);
        //返回结果
        return employee;
    }

改为

    @Autowired
    private RibbonLoadBalancerClient client;

    @GetMapping("/{id}")
    public Employee getEmployeeById(@PathVariable Integer id) {
        //轮询获取实例
        ServiceInstance instance = client.choose("emp-provider");
        //获取主机地址
        String hostName = instance.getHost();
        //获取端口号
        int port = instance.getPort();
        //拼接url
        String url = "http://" + hostName + ":" + port + "/employee/" + id;
        //调用接口
        Employee employee = restTemplate.getForObject(url, Employee.class);
        //返回结果
        return employee;
    }

方法2:修改配置类,在restTemplate方法上加入@LoadBalanced注解

package cn.rayfoo.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @Author: rayfoo@qq.com
 * @Date: 2020/7/2 2:29 下午
 * @Description:
 */
@Configuration
public class RestTemplateConfiguration {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

修改web层代码为

package cn.rayfoo.controller;

import cn.rayfoo.bean.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
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;

/**
 * @Author: rayfoo@qq.com
 * @Date: 2020/7/2 2:30 下午
 * @Description:
 */
@RestController
@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    private RestTemplate restTemplate;


    private static final String REST_URL_PREFIX = "http://emp-provider";


    @GetMapping("/{id}")
    public Employee getEmployeeById(@PathVariable Integer id) {
        String url = REST_URL_PREFIX + "/employee/" + id;
        //调用接口
        Employee employee = restTemplate.getForObject(url, Employee.class);
        //返回结果
        return employee;
    }

}

此时就通过服务名称自动通过轮询策略拿到项目的url,无需关心服务器的地址和端口号。

Ribbon负载均衡策略

Ribbon支持自定义的负载均衡策略和算法,但一般轮询就够我们使用,无需手动实现。

参考:参考博客

更详细的介绍:地址

posted @ 2020-06-21 11:55  张瑞丰  阅读(205)  评论(0)    收藏  举报