当前位置: 首页 > news >正文

使用Java代码自定义Ribbon配置

很多场景下,需要实现不同的微服务采用不同的策略,例如修改Ribbon的负载均衡规则等。Spring Cloud允许使用Java代码自定义Ribbon的配置。

在Spring Cloud中,Ribbon默认配置如下

IClientConfig:Ribbon 的客户端配置,默认采用 com.netflix.client.config.DefaultClientConfigImpl 实现。
IRule:Ribbon 的负载均衡策略,默认采用 com.netflix.loadbalancer.ZoneAvoidanceRule 实现,该策略能够在多区域环境下选择最佳区域的实例进行访问
IPing:Ribbon 的实例检查策略,默认采用 com.netflix.loadbalancer.NoOpPing 实现,该检查策略是一个特殊的实现,实际上他并不会检查实例是否可用,而是始终返回 true ,默认认为所有服务实例都是可以使用
ServerList<Server>:服务实例清单的维护机制,默认采用 com.netflix.loadbalancer.ConfigurationBasedServerList 实现。
ServerListFilter<Server>:服务实例清单过滤机制,默认采用 org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter 实现,该策略能够优先过滤出与请求调用方处理同区域的服务实现
ILoadBalancer:负载均衡器,默认采用 com.netflix.loadbalancer.ZoneAwareLoadBalancer 实现,他具备了区域感知的能力

现使用Java代码自定义Ribbon配置,模拟mima-cloud-producer 服务采用轮询的方式访问,mima-cloud-producer2服务采用随机的方式访问。
mima-cloud-producer 服务启动如下节点:

http://localhost:9905/
http://localhost:9906/

mima-cloud-producer2 服务启动如下节点:

http://localhost:9907/
http://localhost:9908/

打开浏览器,多次访问 http://192.168.1.100:8803/ribbon/get/1,运行效果如下:

host:PC-20161120GHGR,port:9906,serviceId=mima-cloud-producer,uri=http://PC-20161120GHGR:9906
host:PC-20161120GHGR,port:9908,serviceId=mima-cloud-producer2,uri=http://PC-20161120GHGR:9908
=============
host:PC-20161120GHGR,port:9905,serviceId=mima-cloud-producer,uri=http://PC-20161120GHGR:9905
host:PC-20161120GHGR,port:9908,serviceId=mima-cloud-producer2,uri=http://PC-20161120GHGR:9908
=============
host:PC-20161120GHGR,port:9906,serviceId=mima-cloud-producer,uri=http://PC-20161120GHGR:9906
host:PC-20161120GHGR,port:9908,serviceId=mima-cloud-producer2,uri=http://PC-20161120GHGR:9908
=============
host:PC-20161120GHGR,port:9905,serviceId=mima-cloud-producer,uri=http://PC-20161120GHGR:9905
host:PC-20161120GHGR,port:9908,serviceId=mima-cloud-producer2,uri=http://PC-20161120GHGR:9908
=============
host:PC-20161120GHGR,port:9906,serviceId=mima-cloud-producer,uri=http://PC-20161120GHGR:9906
host:PC-20161120GHGR,port:9907,serviceId=mima-cloud-producer2,uri=http://PC-20161120GHGR:9907
=============
host:PC-20161120GHGR,port:9905,serviceId=mima-cloud-producer,uri=http://PC-20161120GHGR:9905
host:PC-20161120GHGR,port:9907,serviceId=mima-cloud-producer2,uri=http://PC-20161120GHGR:9907
=============
host:PC-20161120GHGR,port:9906,serviceId=mima-cloud-producer,uri=http://PC-20161120GHGR:9906
host:PC-20161120GHGR,port:9908,serviceId=mima-cloud-producer2,uri=http://PC-20161120GHGR:9908
=============

从运行结果来看,可以发现mima-cloud-producer服务采用轮询的方式,mima-cloud-producer2服务采用随机的方式。

1、创建Ribbon配置类
1.1、ConsumerRibbonClientConfig——Ribbon配置类,采用轮询的策略

package com.mimaxueyuan.consumer.config;

import org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.DummyPing;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.PollingServerListUpdater;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerList;
import com.netflix.loadbalancer.ServerListFilter;
import com.netflix.loadbalancer.ServerListUpdater;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;

//自定义ribbon策略可以覆盖RibbonClientConfiguration中的默认配置。
//RibbonClientConfiguration每个方法都可以被覆盖
//自定义的Ribbon配置不能放在SpringApplication的同级或下级目录中会覆盖所有的Ribbon客户端配置,所有的客户端都使用了相同的配置。
//自定义的Ribbon配置不能放在ComponentScan的目录中否则次配置会覆盖所有的Ribbon客户端配置,所有的客户端都使用了相同的配置。
@Configuration
public class ConsumerRibbonClientConfig {

    public static final int DEFAULT_CONNECT_TIMEOUT = 1000;
    public static final int DEFAULT_READ_TIMEOUT = 1000;
    
    @Bean
    public IRule ribbonRule(IClientConfig config) {
     //轮询策略 ZoneAvoidanceRule rule
= new ZoneAvoidanceRule(); rule.initWithNiwsConfig(config); return rule; } // 检测服务是否存活 @Bean public IPing ribbonPing(IClientConfig config) { return new DummyPing(); } /* 服务列保, 覆盖此方法,必须在yml/properties文件中配置服务列表 @Bean public ServerList<Server> ribbonServerList(IClientConfig config) { ConfigurationBasedServerList serverList = new ConfigurationBasedServerList(); serverList.initWithNiwsConfig(config); return serverList; } */ //服务列表更新器 @Bean public ServerListUpdater ribbonServerListUpdater(IClientConfig config) { return new PollingServerListUpdater(config); } //负载均衡器 @Bean public ILoadBalancer ribbonLoadBalancer(IClientConfig config, ServerList<Server> serverList, ServerListFilter<Server> serverListFilter, IRule rule, IPing ping, ServerListUpdater serverListUpdater) { return new ZoneAwareLoadBalancer<>(config, rule, ping, serverList, serverListFilter, serverListUpdater); } //此接口允许过滤配置或动态获得的具有良好特性的候选服务器列表。 @Bean public ServerListFilter<Server> ribbonServerListFilter(IClientConfig config) { ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter(); filter.initWithNiwsConfig(config); return filter; } }

1.2、ConsumerRibbonClientConfig2——Ribbon配置类,采用随机的策略

package com.mimaxueyuan.consumer.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;

//自定义ribbon策略可以覆盖RibbonClientConfiguration中的默认配置。
//RibbonClientConfiguration每个方法都可以被覆盖
//自定义的Ribbon配置不能放在SpringApplication的同级或下级目录中会覆盖所有的Ribbon客户端配置,所有的客户端都使用了相同的配置。
//自定义的Ribbon配置不能放在ComponentScan的目录中否则次配置会覆盖所有的Ribbon客户端配置,所有的客户端都使用了相同的配置。
@Configuration
public class ConsumerRibbonClientConfig2 {
    
    @Bean
    public IRule ribbonRule(IClientConfig config) {
        // 负载均衡规则,改为随机
        return new RandomRule();
    }
}

2、RibbonConsumerApplication——Ribbon启动类,及指定Ribbon的配置类

package com.mimaxueyuan.consumer.robbin;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.web.client.RestTemplate;

import com.mimaxueyuan.consumer.config.ConsumerRibbonClientConfig;
import com.mimaxueyuan.consumer.config.ConsumerRibbonClientConfig2;

@SpringBootApplication
//@EnableEurekaClient
@EnableDiscoveryClient
//name=服务提供者的instanceName,configuration指定Ribbon的配置类
//@RibbonClient(name="mima-cloud-producer",configuration=ConsumerRibbonClientConfig.class)
@RibbonClients(
        //配置defaultConfiguration会报空指针异常,有知道的同学麻烦告诉下
        //defaultConfiguration=RibbonClientConfiguration.class, 
        value= {
    @RibbonClient(name="mima-cloud-producer",configuration=ConsumerRibbonClientConfig.class),
    @RibbonClient(name="mima-cloud-producer2",configuration=ConsumerRibbonClientConfig2.class)
})
public class RibbonConsumerApplication {

    @Bean
    // 需要使用负载均衡,必须与Bean一同使用
    @LoadBalanced
    public RestTemplate balanceRestTemplate() {
        return new RestTemplate();
    }
    
    //需要多个RestTemplate, 有的RestTemplate使用负载均衡,有的不使用,不使用的不增加@LoadBalanced注解
    @Primary
    @Bean
    public RestTemplate noBalanceRestTemplate() {
        return new RestTemplate();
    }
    

    public static void main(String[] args) {
        SpringApplication.run(RibbonConsumerApplication.class, args);
    }

}

3、RibbonConfigController——Ribbon测试类

package com.mimaxueyuan.consumer.robbin.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
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.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class RibbonConfigController {

    // 注入restTemplate, 这个类已经在RibbonConsumerApplication中初始化,并且使用负载均衡
    @Autowired //默认按照类型注入,如果需要按照名字注入需要使用@Qualifier注解
    @LoadBalanced //使用带有负载均衡的RestTemplate
    private RestTemplate balanceRestTemplate;

    // 以下注入负载均衡客户端LoadBalancerClient是一个接口,下面只有一个RibbonLoadBalancerClient实现类
    @Autowired
    private LoadBalancerClient loadBalancerClient;
    @Autowired
    private RibbonLoadBalancerClient ribbonLoadBalancerClient;

    /**
     * ribbon使用
     *
     * @author Kevin
     * @Title: ribbon 
     * @param id
     * @return
     * @return: String
     */
    @GetMapping("/ribbon/get/{id}")
    public String ribbon(@PathVariable("id") String id) {
        ServiceInstance instance = loadBalancerClient.choose("mima-cloud-producer");
        System.out.println("host:" + instance.getHost() + ",port:" + instance.getPort() + ",serviceId=" + instance.getServiceId() + ",uri=" + instance.getUri());
        instance = ribbonLoadBalancerClient.choose("mima-cloud-producer2");
        System.out.println("host:" + instance.getHost() + ",port:" + instance.getPort() + ",serviceId=" + instance.getServiceId() + ",uri=" + instance.getUri());
        System.out.println("=============");
        return "ribbon's demo,please to see console output";
    }
    
}

 

相关文章:

  • CephFS 文件系统应用
  • 第二冲刺阶段第十三天
  • 近似推断---期望传播
  • 联合国儿童基金会投资六家区块链初创企业,目标是解决“全球性挑战”
  • MaxCompute新功能发布
  • 127.0.0.1 和 0.0.0.0 地址的区别
  • k8s环境部署及使用方式
  • Django2.0——中间件
  • 蔚来总裁秦力洪:不要贴标签说ES8不好 短期压力是做好服务
  • 菜鸟问题
  • python之dict与set实现原理之hash算法
  • onLoad onShow
  • CSS利用@font-face使用自定义字符和图标
  • [译] 时间序列异常检测算法
  • Vue优化首页加载速度 CDN引入
  • Angular 响应式表单之下拉框
  • CODING 缺陷管理功能正式开始公测
  • Fundebug计费标准解释:事件数是如何定义的?
  • javascript面向对象之创建对象
  • Java基本数据类型之Number
  • JDK 6和JDK 7中的substring()方法
  • js ES6 求数组的交集,并集,还有差集
  • leetcode98. Validate Binary Search Tree
  • MaxCompute访问TableStore(OTS) 数据
  • Object.assign方法不能实现深复制
  • Web Storage相关
  • 闭包,sync使用细节
  • 反思总结然后整装待发
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 基于webpack 的 vue 多页架构
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 通信类
  • 我从编程教室毕业
  • 我有几个粽子,和一个故事
  • 无服务器化是企业 IT 架构的未来吗?
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 原生Ajax
  • 仓管云——企业云erp功能有哪些?
  • #include<初见C语言之指针(5)>
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (11)MATLAB PCA+SVM 人脸识别
  • (2)STL算法之元素计数
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (八十八)VFL语言初步 - 实现布局
  • (第61天)多租户架构(CDB/PDB)
  • (二)PySpark3:SparkSQL编程
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (理论篇)httpmoudle和httphandler一览
  • (力扣)1314.矩阵区域和
  • (三)终结任务
  • (十八)三元表达式和列表解析
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (转)http协议