Ribbon

78 阅读2分钟

1.什么是Ribbon

目前主流的负载方案分为以下两种:

集中式负载均衡,在消费者和服务提供方中间使用独立的代理方式进行负载,有硬件的(比如F5),也有软件的(比如 Nginx)。
客户端根据自己的请求情况做负载均衡,Ribbon 就属于客户端自己做负载均衡。
Spring Cloud Ribbon是基于Netflix Ribbon 实现的一套客户端的负载均衡工具,Ribbon客户端组件提供一系列的完善的配置,如超时,重试等。通过Load Balancer获取到服务提供的所有机器实例,Ribbon会自动基于某种规则(轮询,随机)去调用这些服务。Ribbon也可以实现我们自己的负载均衡算法。

1.1 客户端的负载均衡

例如spring cloud中的ribbon,客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择 一个服务器,然后进行访问,这是客户端负载均衡;即在客户端就进行负载均衡算法分配。 image.png

1.2服务端的负载均衡

例如Nginx,通过Nginx进行负载均衡,先发送请求,然后通过负载均衡算法,在多个服务器之间选择一个进行访问;即在服务器端再进行负载均衡算法分配

image.png

1.3 常见负载均衡算法

  • 随机,通过随机选择服务进行执行,一般这种方式使用较少;
  • 轮训,负载均衡默认实现方式,请求来之后排队处理;
  • 加权轮训,通过对服务器性能的分型,给高配置,低负载的服务器分配更高的权重,均衡各个 服务器的压力;
  • 地址Hash,通过客户端请求的地址的HASH值取模映射进行服务器调度。
  • 最小链接数,即使请求均衡了,压力不一定会均衡,最小连接数法就是根据服务器的情况,比
  • 如请求积压数等参数,将请求分配到当前压力最小的服务器上。

1.4 Ribbon模块

image.png

1.5 Ribbon使用

编写一个客户端来调用接口

import com.google.common.collect.Lists;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.LoadBalancerBuilder;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.reactive.LoadBalancerCommand;
import com.netflix.loadbalancer.reactive.ServerOperation;
import rx.Observable;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

public class RibbonDemo {
    public static void main(String[] args) {
// 服务列表
        List<Server> serverList = Lists.newArrayList(
                new Server("localhost", 8020),
                new Server("localhost", 8021));
        // 构建负载实例
        ILoadBalancer loadBalancer = LoadBalancerBuilder.newBuilder()
                .buildFixedServerListLoadBalancer(serverList);
        // 调用 5 次来测试效果 13 for (int i = 0; i < 5; i++) {
        String result = LoadBalancerCommand.<String>builder()
                .withLoadBalancer(loadBalancer).build().submit(new ServerOperation<String>() {
            @Override
            public Observable<String> call(Server server) {
                String addr = "http://" + server.getHost() + ":" +
                        server.getPort() + "/order/findOrderByUserId/1";
                System.out.println(" 调用地址:" + addr);
                URL url = null;
                try {
                    url = new URL(addr);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");
                    conn.connect();
                    InputStream in = conn.getInputStream();
                    byte[] data = new byte[in.available()];
                    in.read(data);
                    return Observable.just(new String(data));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
        }).toBlocking().first();
        System.out.println(" 调用结果:" + result);
    }
}

上述这个例子主要演示了 Ribbon 如何去做负载操作,调用接口用的最底层的 HttpURLConnection。 image.png

2. Spring Cloud快速整合Ribbon

  1. 引入依赖
<!‐‐添加ribbon的依赖‐‐>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring‐cloud‐starter‐netflix‐ribbon</artifactId>
</dependency>

nacos-discovery依赖了ribbon,可以不用再引入ribbon依赖

image.png

image.png

//TODO