技术标签: springcloud ribbon Spring
Ribbon自定义负载均衡策略有两种方式,一是JavaConfig,一是通过配置文件(yml或properties文件)。
假设我有包含A和B服务在内的多个微服务,它们均注册在一个Eureka上,信息如下:
我希望当访问服务A时候,2个服务(端口分别是8087和8081)每两次一换,比如访问两次8087,再访问两次8081,如此反复。
当访问服务B时,与A类似,不过是3次一换。
当访问其他服务时,采用随机规则,即RandomRule,而不是默认策略1
使用这种方式,总共分3步(以服务A的规则为例):
@Primary
2,重写逻辑须要根据实际需求来定,详见下面的代码IRule
的Bean,此处我们选RandomRule
@RibbonClients
(只有一种自定义规则,则使用@RibbonClient
),添加不适用公共规则的其他自定义规则import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import org.springframework.context.annotation.Primary;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@Primary
public class SvcARule extends AbstractLoadBalancerRule {
private AtomicInteger total = new AtomicInteger();
private AtomicInteger index = new AtomicInteger();
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
}
Server server = null;
while (server == null) {
if (Thread.interrupted()) {
return null;
}
List<Server> upList = lb.getReachableServers();
List<Server> allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
if (total.get() < 2) {
server = upList.get(index.get());
total.incrementAndGet();
} else {
total.set(0);
index.set(index.incrementAndGet() % upList.size());
}
if (server == null) {
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
server = null;
Thread.yield();
}
return server;
}
@Override
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
// TODO Auto-generated method stub
}
}
略,只需要把if (total.get() < 2)
改成if (total.get() < 3)
即可
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.yan.ribbon.rule.SvcARule;
import com.yan.ribbon.rule.SvcBRule;
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.Configuration;
@Configuration
@RibbonClients(
value = {
@RibbonClient(name = "SVCA", configuration = SvcARule.class),
@RibbonClient(name = "SVCB", configuration = SvcBRule.class)
},
defaultConfiguration = LBConfig.class)
public class LBConfig {
@Bean
public IRule commonRule() {
return new RandomRule();
}
}
通过postman多次访问服务A、B和C,得到日志如下:
2019-03-19 20:22:09.511 INFO 13372 --- [nio-8004-exec-4] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-03-19 20:22:09.511 INFO 13372 --- [nio-8004-exec-4] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2019-03-19 20:22:09.519 INFO 13372 --- [nio-8004-exec-4] o.s.web.servlet.DispatcherServlet : Completed initialization in 8 ms
2019-03-19 20:22:09.693 INFO 13372 --- [nio-8004-exec-4] c.n.u.concurrent.ShutdownEnabledTimer : Shutdown hook installed for: NFLoadBalancer-PingTimer-SVCA
2019-03-19 20:22:09.708 INFO 13372 --- [nio-8004-exec-4] c.netflix.loadbalancer.BaseLoadBalancer : Client: SVCA instantiated a LoadBalancer: DynamicServerListLoadBalancer:{
NFLoadBalancer:name=SVCA,current list of Servers=[],Load balancer stats=Zone stats: {
},Server stats: []}ServerList:null
2019-03-19 20:22:09.712 INFO 13372 --- [nio-8004-exec-4] c.n.l.DynamicServerListLoadBalancer : Using serverListUpdater PollingServerListUpdater
2019-03-19 20:22:09.729 INFO 13372 --- [nio-8004-exec-4] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client SVCA initialized: DynamicServerListLoadBalancer:{
NFLoadBalancer:name=SVCA,current list of Servers=[YanWei:8087, YanWei:8081],Load balancer stats=Zone stats: {
defaultzone=[Zone:defaultzone; Instance count:2; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]
},Server stats: [[Server:YanWei:8087; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
, [Server:YanWei:8081; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@7f0246c6
"svcA:8087===>\nname:xixi\ntype:haha"
"svcA:8087===>\nname:xixi\ntype:haha"
"svcA:8081===>\nname:xixi\ntype:haha"
"svcA:8081===>\nname:xixi\ntype:haha"
"svcA:8087===>\nname:xixi\ntype:haha"
"svcA:8087===>\nname:xixi\ntype:haha"
"svcA:8081===>\nname:xixi\ntype:haha"
"svcA:8081===>\nname:xixi\ntype:haha"
"svcA:8087===>\nname:xixi\ntype:haha"
"svcA:8087===>\nname:xixi\ntype:haha"
"svcA:8081===>\nname:xixi\ntype:haha"
"svcA:8081===>\nname:xixi\ntype:haha"
2019-03-19 20:22:37.173 INFO 13372 --- [nio-8004-exec-5] c.n.u.concurrent.ShutdownEnabledTimer : Shutdown hook installed for: NFLoadBalancer-PingTimer-SVCB
2019-03-19 20:22:37.174 INFO 13372 --- [nio-8004-exec-5] c.netflix.loadbalancer.BaseLoadBalancer : Client: SVCB instantiated a LoadBalancer: DynamicServerListLoadBalancer:{
NFLoadBalancer:name=SVCB,current list of Servers=[],Load balancer stats=Zone stats: {
},Server stats: []}ServerList:null
2019-03-19 20:22:37.177 INFO 13372 --- [nio-8004-exec-5] c.n.l.DynamicServerListLoadBalancer : Using serverListUpdater PollingServerListUpdater
2019-03-19 20:22:37.178 INFO 13372 --- [nio-8004-exec-5] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client SVCB initialized: DynamicServerListLoadBalancer:{
NFLoadBalancer:name=SVCB,current list of Servers=[YanWei:8086, YanWei:8082],Load balancer stats=Zone stats: {
defaultzone=[Zone:defaultzone; Instance count:2; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]
},Server stats: [[Server:YanWei:8082; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
, [Server:YanWei:8086; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@485ed210
"svcB:8086===>\nname:xixi\ntype:haha"
"svcB:8086===>\nname:xixi\ntype:haha"
"svcB:8086===>\nname:xixi\ntype:haha"
"svcB:8082===>\nname:xixi\ntype:haha"
"svcB:8082===>\nname:xixi\ntype:haha"
"svcB:8082===>\nname:xixi\ntype:haha"
"svcB:8086===>\nname:xixi\ntype:haha"
"svcB:8086===>\nname:xixi\ntype:haha"
"svcB:8086===>\nname:xixi\ntype:haha"
"svcB:8082===>\nname:xixi\ntype:haha"
"svcB:8082===>\nname:xixi\ntype:haha"
"svcB:8082===>\nname:xixi\ntype:haha"
"svcB:8086===>\nname:xixi\ntype:haha"
"svcB:8086===>\nname:xixi\ntype:haha"
2019-03-19 20:23:01.319 INFO 13372 --- [nio-8004-exec-8] c.n.u.concurrent.ShutdownEnabledTimer : Shutdown hook installed for: NFLoadBalancer-PingTimer-SVCC
2019-03-19 20:23:01.320 INFO 13372 --- [nio-8004-exec-8] c.netflix.loadbalancer.BaseLoadBalancer : Client: SVCC instantiated a LoadBalancer: DynamicServerListLoadBalancer:{
NFLoadBalancer:name=SVCC,current list of Servers=[],Load balancer stats=Zone stats: {
},Server stats: []}ServerList:null
2019-03-19 20:23:01.320 INFO 13372 --- [nio-8004-exec-8] c.n.l.DynamicServerListLoadBalancer : Using serverListUpdater PollingServerListUpdater
2019-03-19 20:23:01.322 INFO 13372 --- [nio-8004-exec-8] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client SVCC initialized: DynamicServerListLoadBalancer:{
NFLoadBalancer:name=SVCC,current list of Servers=[YanWei:8083, YanWei:8085],Load balancer stats=Zone stats: {
defaultzone=[Zone:defaultzone; Instance count:2; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]
},Server stats: [[Server:YanWei:8083; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
, [Server:YanWei:8085; Zone:defaultZone; Total Requests:0; Successive connection failure:0; Total blackout seconds:0; Last connection made:Thu Jan 01 08:00:00 CST 1970; First connection made: Thu Jan 01 08:00:00 CST 1970; Active Connections:0; total failure count in last (1000) msecs:0; average resp time:0.0; 90 percentile resp time:0.0; 95 percentile resp time:0.0; min resp time:0.0; max resp time:0.0; stddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@77b35c9
"svcC:8085===>\nname:xixi\ntype:haha"
"svcC:8083===>\nname:xixi\ntype:haha"
"svcC:8085===>\nname:xixi\ntype:haha"
"svcC:8085===>\nname:xixi\ntype:haha"
"svcC:8083===>\nname:xixi\ntype:haha"
"svcC:8085===>\nname:xixi\ntype:haha"
"svcC:8085===>\nname:xixi\ntype:haha"
配置文件方式须要遵守以下格式:
<serviceName>.ribbon.<key>=<value>
几个变量解释如下:
serviceName
就是服务名
key
是指Ribbon为实现不同领域(我们这里只说IRule,其实还有IPing等)所指定的关联类名,这里我需要自定义IRule
,其关联类名,也就是所谓的key
,是NFLoadBalancerRuleClassName
3
value
是我所要指定的自定义规则,比如,SvcB的负载均衡策略SvcBRule
因此,在配置文件中添加如下配置:
svcB:
ribbon:
NFLoadBalancerRuleClassName: com.yan.ribbon.rule.SvcBRule
重新启动Ribbon服务后,发现此配置并没有生效,原因有两个:
一是我的服务名字写的是svcB
,理由是我的配置spring.appliaction.name=svcB
,但是使用Ribbon调用时使用了http://SVCB/...
,SVCB是大写的,所以没有得到期望的效果4
二是我已经有了用来替换默认规则的LBConfig,使得IRule的默认配置没有生效,因为查看源码org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration
中对于IRule的定义如下:
@Bean
@ConditionalOnMissingBean
public IRule ribbonRule(IClientConfig config) {
if (this.propertiesFactory.isSet(IRule.class, name)) {
return this.propertiesFactory.get(IRule.class, config, name);
}
ZoneAvoidanceRule rule = new ZoneAvoidanceRule();
rule.initWithNiwsConfig(config);
return rule;
}
由于我自定义的commonRule
已经存在了,所以此处不会触发,更不会走到判断那一步,就是说,我的上面的关于SvcB的自定义规则的配置,是没有什么地方去读的,因此,为了方便演示,直接将LBConfig全部注掉,再次重启后,把访问Uri中的大写改成一致的svcB
,发现对于服务B的配置生效了,但是没有指定的服务,全部都采用了默认的策略ZoneAvoidanceRule
。
配置文件方式,比较麻烦,且不能-没必要也懒得研究如何-修改默认规则,而JavaConfig可以完美替代,因此我选JavaConfig。
关于Ribbon中对于IRule的实现,总共有如下几种,其简略说明也附注如下:
对应类为ZoneAvoidanceRule,直译过来是区域回避规则,我也不知道为啥这样叫:D ︎
如果不加此注解,会报错,内容是找类型为IRule的Bean,但是找到了俩,一个commonRule,一个svcARule。如果你不嫌麻烦,可以选择网上流行的较为复杂的形式,比如springcloud-04-自定义ribbon的配置方式 ︎
可以在类org.springframework.cloud.netflix.ribbon.PropertiesFactory
中查看 ︎
这个Eureka也要背锅,因为使用服务名来进行服务间调用,是被大小写是被兼容过的,导致我这边疏忽大意了,还是要细心的好。 ︎
关注上方“深度学习技术前沿”,选择“星标公众号”,资源干货,第一时间送达!作者 : Maxence Poutord原文:New Frontend 网站如果你觉得 git 很迷惑人,那..._git高级学习
Oracle OCP笔记(31)使用闪回功能 Oracle的闪回功能受到3个数据库结构之一的支持: 撤消数据、闪回恢复区和回收站。 撤消表空间中的撤销数据不仅支持事务回滚,也支持大多数闪回表操作。Flashback Data Archives允许查询先前版本的表行,它在撤销表空间之外的一个或多个表空间中提供一个区域,支持的保留期比撤销表空间还长。闪回日志保存在闪回恢复区
测试用例常见的设计方法有:等价类划分法、边界值分析法、错误推测法、判定表法、正交实验法。 一.等价类划分法 顾名思义,等价类划分,就是将测试的范围划分成几个互不相交的子集,他们的并集是全集,从每个子集选出若干个有代表性的值作为测试用例。 例如,我们要测试一个用户名是否合法,用户名的定义为:8位数字组成的字符。 我们可以先划分子集:空用户名,1-7位数字,8位数字,9位或以上数字,非数字。..._测试用例设计方法举例
daemon not running. starting it now on port 5037 ** daemon started successfully *** daemon still not runningerror: cannot connect to daemon根本解决方法: 设置环境变量ANDROID_ADB_SERVER_PORT 值为不常用的值参考链接 : https://blog.csdn.net/a1809032425/article/details/906142._daemon started successfully * ** daemon still not running error: cannot conn
首先登录GitHub官网进入网站首页,点击右上角的头像,如下图所示在选项中找到Setting点击进入设置。在页面左方的列表中找到Account选项,点击后会在页面右方找到change username按钮,如下图所示点击chang username后会弹出提示点击提示下方的按钮即可。然后就可以修改用户名了。在输入框输入新的用户名,点击修改按钮即可成功修改用户名啦。...
我们经常会遇到在要搭建的系统环境上查询.Net Framework 的版本号信息,本文整理出来两种查询方法和详细的版本号比对表供大家参考使用。_查看server .net版本
前言在学习php的时候需要经常对mysql数据库进行增删改查操作,为了减少冗余代码,我们把数据操作的方法封装成一个php类。在不同的业务场景需要用到数据库表的数据操作时,只需在php文件开头引入我们的数据库辅助类,调用不用的数据操作方法,传相应的参数即可实现数据的增删改查。我们封装的数据库辅助类,主要有以下几个关键方法:02GetTotal用途: 获取当前查询SQL的总记录数。参数:查询sql字符..._php7.4 mysql 辅助类
引言前面写了一篇Tensorflow2与PaddlePaddle小白入门级写法对比的今天来看一下所谓的专家入门写法对比(这里的专家不是本人说的,出自Tensorflow官网,求生欲满满:https://tensorflow.google.cn/overview?hl=en)数据加载器Tensorflow2import tensorflow as tf# 加载数据集(train_images, train_labels), (test_images, test_labels) = \
一、线程并发同步概念线程同步其核心就在于一个“同”。所谓“同”就是协同、协助、配合,“同步”就是协同步调昨,也就是按照预定的先后顺序进行运行,即“你先,我等, 你做完,我再做”。线程同步,就是当线程发出一个功能调用时,在没有得到结果之前,该调用就不会返回,其他线程也不能调用该方法。就一般而言,我们在说同步、异步的时候,特指那些需要其他组件来配合或者需要一定时间来完成的任务。在多线程编程...
那些年我们一起追过的缓存写法(二)引言感谢园子里的同学对上一篇的支持,很高兴楼主的一些经验及想法能够对大家有一些帮助。上次主要讨论缓存读写这块各种代码实现。本篇是就上次的问题接着来,继续看那些年我们各种缓存用法。目录一:缓存预热二:多级缓存 2.1 介绍 2.2 线程缓存 2.3 内存缓存 2.4 文件缓存
目的:QToolButton的clicked()信号只能连接到某个槽函数,当用户动态配置添加一个或者多个按钮到主界面的QToolBar,并且每个按钮被点击后执行不同的行为时,clicked()信号显然就无法满足需求了,因为你不知道是哪个QToolButton被点击了。实现方式:自定义按钮继承自QToolButton,重新实现void QWidget::mouseReleaseE_qtoolbutton事件
拼多多砍价只要人多,都能成功。1、拼多多砍价要的就是人脉,假设你朋友多,成功率很大,但是有这种人脉的究竟不是许多,所以许多时分有朋友砍到还有几十块钱的时分基本上就抛弃了,这就需求更多的人脉,假设你人脉无限多,能够直接关闭走人。2、初次砍价的朋友,都有一颗猎奇的心都想砍到0元,刚开始小编规劝我们,先拿价格比较低的,比方几十元的产品练手,这样成功率都是很高的。3、拼多多主张砍价的时间是比较要害的,小编经过总结,一般的晚上9-10点,主张砍价这个时间比较适合,因为这时候我们基本上都有时间,该忙的都忙好_拼多多砍价原理