Ribbon

Ribbon 是一个具有内置软件负载平衡器的进程间通信(远程过程调用)库。

主要使用模型涉及具有各种序列化方案支持的 REST 调用。

Ribbon 是一个客户端 IPC 库,在云中经过实战测试。

它提供以下功能

  • 负载均衡

  • 容错

  • 异步和反应模型中的多协议(HTTP、TCP、UDP)支持

  • 缓存和批处理

快速开始

安装

要获取功能区二进制文件,请转到 maven central。

这是在 Maven 中添加依赖项的示例:

<dependency>
    <groupId>com.netflix.ribbon</groupId>
    <artifactId>ribbon</artifactId>
    <version>2.2.2</version>
</dependency>

例子

Access HTTP resource using template

HttpResourceGroup httpResourceGroup = Ribbon.createHttpResourceGroup("movieServiceClient",
            ClientOptions.create()
                    .withMaxAutoRetriesNextServer(3)
                    .withConfigurationBasedServerList("localhost:8080,localhost:8088"));
HttpRequestTemplate<ByteBuf> recommendationsByUserIdTemplate = httpResourceGroup.newTemplateBuilder("recommendationsByUserId", ByteBuf.class)
            .withMethod("GET")
            .withUriTemplate("/users/{userId}/recommendations")
            .withFallbackProvider(new RecommendationServiceFallbackHandler())
            .withResponseValidator(new RecommendationServiceResponseValidator())
            .build();
Observable<ByteBuf> result = recommendationsByUserIdTemplate.requestBuilder()
                        .withRequestProperty("userId", "user1")
                        .build()
                        .observe();

Access HTTP resource using annotations

public interface MovieService {
    @Http(
            method = HttpMethod.GET,
            uri = "/users/{userId}/recommendations",
            )
    RibbonRequest<ByteBuf> recommendationsByUserId(@Var("userId") String userId);
}

MovieService movieService = Ribbon.from(MovieService.class);
Observable<ByteBuf> result = movieService.recommendationsByUserId("user1").observe();

Create an AWS-ready load balancer with Eureka dynamic server list and zone affinity enabled

IRule rule = new AvailabilityFilteringRule();
ServerList<DiscoveryEnabledServer> list = new DiscoveryEnabledNIWSServerList("MyVIP:7001");
ServerListFilter<DiscoveryEnabledServer> filter = new ZoneAffinityServerListFilter<DiscoveryEnabledServer>();
ZoneAwareLoadBalancer<DiscoveryEnabledServer> lb = LoadBalancerBuilder.<DiscoveryEnabledServer>newBuilder()
        .withDynamicServerList(list)
        .withRule(rule)
        .withServerListFilter(filter)
        .buildDynamicServerListLoadBalancer();   
DiscoveryEnabledServer server = lb.chooseServer();      

Use LoadBalancerCommand to load balancing IPC calls made by HttpURLConnection (full example)

CommandBuilder.<String>newBuilder()
        .withLoadBalancer(LoadBalancerBuilder.newBuilder().buildFixedServerListLoadBalancer(serverList))
        .build(new LoadBalancerExecutable<String>() {
            @Override
            public String run(Server server) throws Exception {
                URL url = new URL("http://" + server.getHost() + ":" + server.getPort() + path);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                return conn.getResponseMessage();
            }
        }).execute();

模块

功能区:在其他功能区模块和 Hystrix 之上集成负载平衡、容错、缓存/批处理的 API

Ribbon-loadbalancer:可以独立使用或与其他模块一起使用的负载平衡器 API

Ribbon-eureka:使用 Eureka 客户端为云提供动态服务器列表的 API

Ribbon-transport:使用具有负载平衡功能的 RxNetty 支持 HTTP、TCP 和 UDP 协议的传输客户端

ribbon-httpclient:建立在与负载均衡器集成的 Apache HttpClient 之上的 REST 客户端(已弃用并被ribbon 模块取代)

功能区示例:示例

功能区核心:客户端配置 API 和其他共享 API

项目状态:维护中

Ribbon 由多个组件组成,其中一些在内部用于生产,一些随着时间的推移被非 OSS 解决方案取代。

这是因为 Netflix 开始转向更加组件化的 RPC 架构,专注于单一职责模块。

因此,此时每个 Ribbon 组件都会受到不同程度的关注。

更具体地说,以下是 Ribbon 的组成部分以及我们团队对它们的关注程度:

ribbon-core: deployed at scale in production
ribbon-eureka: deployed at scale in production
ribbon-evcache: not used
ribbon-guice: not used
ribbon-httpclient: we use everything not under com.netflix.http4.ssl. Instead, we use an internal solution developed by our cloudsecurity team
ribbon-loadbalancer: deployed at scale in production
ribbon-test: this is just an internal integration test suite
ribbon-transport: not used
ribbon: not used

即使对于生产中部署的组件,我们也将它们封装在 Netflix 内部 http 客户端中,并且由于它们已经稳定了一段时间,因此我们不会添加新功能。任何新功能都已添加到 Ribbon 之上的内部包装器中(例如请求跟踪和指标)。我们还没有努力使 Ribbon 下的这些组件与 Netflix 无关。

认识到这些现实和不足,我们将 Ribbon 置于维护模式。这意味着如果外部用户提交了一个大的功能请求,在内部我们不会高度重视它。但是,如果有人要自己完成工作并提交完整的拉取请求,我们很乐意审核并接受。相反,我们的团队已开始在 gRPC 之上构建 RPC 解决方案。我们进行这种转换有两个主要原因:多语言支持和通过请求拦截器实现更好的可扩展性/可组合性。这是我们目前的计划。

我们目前定期为 gRPC 代码库做出贡献。为了帮助我们的团队在生产中迁移到基于 gRPC 的解决方案(并对其进行实战测试),我们还添加了负载平衡和发现拦截器,以实现与 Ribbon 和 Eureka 提供的功能相同的功能。拦截器目前是 Netflix 内部的。当我们达到这种信心水平时,我们希望开源这种新方法。我们预计这不会在 2016 年第三季度之前发生。

参考资料

https://github.com/Netflix/ribbon