近期博主在参与一个 Spring Cloud 搭建,版本为 Hoxton.SR12,服务注册发现组件为 Nacos 的老项目时,发现项目负载均衡组件 Ribbon 的负载均衡规则在某些场景下不够完美,比如新版本上线,需要重启服务。因此写了这边文章与大家分享。
在微服务架构中,负载均衡是实现高可用性、高性能和可伸缩性的关键组件,正确地选择和配置负载均衡规则对于整个系统的性能和稳定性都至关重要。Ribbon 是一个常见的负载均衡框架,在 Netflix 的微服务架构中发挥了重要作用。然而,在某些场景下,Ribbon 默认的负载均衡规则并不能满足我们的需求。
默认情况下 Ribbon 是通过定时任务每隔30秒去获取服务注册中心的服务列表,这样就会造成如果某个服务已经下线,但是 Ribbon 没有及时刷新服务列表,依然会去调用这个已经下线的服务,造成用户请求异常。因此,我们需要替换掉这些默认规则,使用更加灵活和强大的负载均衡规则,例如 NacosRule。本文将介绍在服务提供者为 Nacos的环境下,如何将 Ribbon 默认的负载均衡规则替换为 NacosRule 并进行相应的配置。
在微服务架构中,服务提供者通常会有多个实例,且这些实例的性能和运行状态可能会有所不同。为了让请求能够平均地分配给不同的实例,我们需要使用负载均衡算法。Ribbon 默认的负载均衡规则是轮询,即每个请求按顺序分配给不同的服务实例。这种方式对于服务提供者的实例性能和状态均匀分布的情况下适用,但是如果某个实例出现问题,例如响应时间过长或者宕机,仍然会受到一定比例的请求,这显然不是我们期望的结果。
NacosRule 是由 Nacos 的 spring-cloud-starter-alibaba-nacos-discovery
依赖中针对 Ribbon 提供的更为灵活和高效的负载均衡规则(在高版本已经移除 Ribbon 的相关配置)。官方对它的说明如下。
/**
* Supports preferentially calling the ribbon load balancing rules of the same cluster
* instance.
*
* @author itmuch.com
*/
public class NacosRule extends AbstractLoadBalancerRule {
}
用中文说就是支持优先调用同一集群实例的ribbon负载均衡规则。说人话就是它能够支持同一机房里的服务相互访问,避免跨机房调用。
跨机房访问会因为机房之间的物理距离太远,造成请求延时过高的问题。
NacosRule 的主要特点如下:
可以看到 NacosRule 在解决跨机房访问的延迟问题上,还解决了我们服务发布时,不能及时感知服务下线的问题。
我们可以通过在Ribbon客户端的配置中进行相应的设置,将默认的 Ribbon 负载均衡规则替换为 NacosRule。以下是示例代码:
@Configuration
public class RibbonConfiguration {
@Bean
public IRule ribbonRule() {
// 将Ribbon默认的轮询规则替换为NacosRule
return new NacosRule();
}
}
在这里,我们通过 @Configuration 注解定义了一个Java配置类,并在其中创建了一个名为 ribbonRule 的 Bean 对象,其类型为 IRule。我们通过返回 NacosRule 来替换 Ribbon 默认的负载均衡规则。这样,在调用服务时,Ribbon 就会使用 NacosRule 中的负载均衡算法来选择服务实例。
本文介绍了如何将 Ribbon 默认的负载均衡规则替换为 NacosRule,并进行相应的配置。大家也可以选择升级到 Spring Cloud 的高版本中,使用 spring-cloud-starter-loadbalancer
组件解决这个问题。
关注公众号【waynblog】每周分享技术干货、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力!
最近我们都在讨论build系统,我们看了一些技巧可以让你的Mavenbuild更快。结论和反映都势不可挡。由于我们提供的技巧,更多的人都很高兴能加快他们完成自己的项目。现在,让我们看一下怎么处理gradle编译项目。编译的项目一般都是标准编译的,也都是独一无二的。几乎所有的项目都增加了其自身的复杂性。所有的东西都不同但是有一个东西是相同的:编译会占用你的时间,加快编译会影响你的开发效率,让你的项目工作更加顺畅。事不宜迟,让我们来看看什么是Gradle,和它的理念:加速Gradle编译这篇文章主要是由MadisPink大力提倡的:SqueezingtheLastDropofPerformanceOutofYourGradleBuilds.Madis是JRebel的Android工程师,所以如果你是一个搞Android的,我建议你应该试一下。Madis热衷于这些,但是你不会观察到有关他太多。对于一个测试项目我们用Madis用过的代码:一个Android项目demoiosched(http://github.com/google/iosched)。不要害怕,gradle对于Android项目
随着互联网技术的飞速发展,各类线上业务蓬勃发展,软件系统如雨后春笋般呈现在我们面前。为了提高系统的性能和可靠性,将应用服务进行拆分微服务化。作为系统入口的API网关也逐渐成为了标配。今天我们一起来看看API网关的设计思路,需要承载了哪些功能?以及如何选择流行的API网关?什么是API网关既然需要API网关为我所用,首先就让我们来了解一下什么是API网关。什么是API网关网关一词最早出现在网络设备,比如两个相互独立的局域网之间通过路由器进行通信,中间的路由被称之为网关。任何一个应用系统如果需要被其他系统调用,就需要暴露API,这些API代表着一个一个的功能点。 如果两个系统中间通信,在系统之间加上一个中介者协助API的调用,这个中介者就是API网关。对接两个系统的API网关当然,API网关可以放在两个系统之间,同时也可以放在客户端与服务端之间。对接客户端和服务端的API网关知道了API网关的基本定义,再来看看为什么我们要使用它。为何要使用API网关网关作为系统的唯一入口,也就是说,进入系统的所有请求都需要经过API网关。当系统外部的应用或者客户端访问系统的时候,都会遇到这样的情况:系统要
ACM思维题训练集合 Thereisaboardwithagridconsistingofnrowsandmcolumns,therowsarenumberedfrom1fromtoptobottomandthecolumnsarenumberedfrom1fromlefttoright.Inthisgridwewilldenotethecellthatliesonrownumberiandcolumnnumberjas(i, j).Agroupofsixnumbers(a, b, c, d, x0, y0),where0 ≤ a, b, c, d,isacross,andthereisasetofcellsthatareassignedtoit.Cell(x, y)belongstothissetifatleastoneoftwoconditionsarefulfilled:|x0 - x| ≤ aand|y0 - y| ≤ b |x0 - x| ≤ cand|y0 - y| ≤ d Thepictureshowsthecross(0, 1, 1, 0, 2, 3)onthegrid
大数据文摘出品来源:medium编译:青柠如果你很着急、只是想要模板,可以直接跳到底部(但这样一点不酷),准备酷的人,迈出成为README大师的第一步吧!(绝对不是点击诱饵)假如你刚刚创建了很棒的项目,并在GitHub上共享了它。你认为现在你只需坐等世界告诉你这个项目有多酷。毕竟,在过去的一个月中,你为这个极具挑战性的项目付出了不懈的努力,对吗?好吧,让我们退后一步,从检查项目的开发人员或用户的角度来看。尽管你知道自己的项目有多酷,也知道它是如何解决一个(直到你出现之前)尚未解决的紧迫问题,但是看你项目的人想知道你构建了一个什么样的世界。如果没有人知道如何使用你的软件,那情况非常糟糕。如果人们不知道你的软件是做什么的,就不会使用它或为它做出贡献,并且很可能会在开源软件的海洋中找到更清晰明了的东西。这就是README文件的用处!好的README文档就像是项目的外观。这是一个人在你的项目中首先要看的东西,它提供了软件的简要介绍。美观实用的README文档可以使你的项目脱颖而出,并引起开发人员社区的关注。这将帮助他们了解你的项目,以及它要如何使用、为什么他们应该做出贡献。“哇,伙计!太棒啦!
Envoy除了支持静态配置之外,还支持动态配置,而且动态配置也是Envoy重点关注的功能,本节我们将学习如何将Envoy静态配置转换为动态配置,从而允许Envoy自动更新。1.Envoy动态配置前面的章节中,我们都是直接使用的静态配置,但是当我们需要更改配置的时候就比较麻烦了,需要重启Envoy代理才会生效。要解决这个问题,我们可以将静态配置更改成动态配置,当我们使用动态配置的时候,更改了配置,Envoy将会自动去重新加载配置。Envoy支持不同的模块进行动态配置,可配置的有如下几个API:EDS:端点发现服务(EDS)可以让Envoy自动发现上游集群的成员,这使得我们可以动态添加或者删除处理流量请求的服务。CDS:集群发现服务(CDS)可以让Envoy通过该机制自动发现在路由过程中使用的上游集群。RDS:路由发现服务(RDS)可以让Envoy在运行时自动发现HTTP连接管理过滤器的整个路由配置,这可以让我们来完成诸如动态更改流量分配或者蓝绿发布之类的功能。VHDS:虚拟主机发现服务(VHDS)允许根据需要与路由配置本身分开请求属于路由配置的虚拟主机。该API通常用于路由配置中有大量虚
在AS3编程中,免不了要使用Object和Dictionary,实际上本人很多时候是使用Vector或者Dictionary的.因为,Vector的效率是最高的,而Object和Dictionary次之,这里我只讲Object和Dictionary的遍历. 以Key进行的遍历: Object->for(var$key:*inObj){ trace("Key->"+$key); trace("Obj元素->"+Obj[$key]); //当然可以保存$key若Obj当中的Key为Uint则: varmyKey:uint=$keyasuint; }复制 Dictionary->for(var$key:StringinDic){ trace("Key->"+$key); trace("Dic元素->"+Dic[$key]); varmyKey:String=$key; }复制 这里假设Dic中的Key为String 以Item进行遍历 Object->fo
转载自:https://www.jianshu.com/p/4ea0404c1327前言MyBatis是一个被广泛应用的持久化框架。一个简单的使用示例如下所示,先创建会话工厂,然后从会话工厂中打开会话,通过class类型和配置生成Mapper接口的代理实现,最后使用Mapper进行持久化操作。本文将从MyBatis中的SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession和Mapper几个方面入手简单分析MyBatis的实现原理。在后面的系列文章中会进一步具体分析核心类的细节实现。SqlSessionFactoryBuilderSqlSessionFactoryBuilder使用Builder模式去生成SqlSessionFactory,因此只提供了多个build方法。这些方法可以接受XML配置文件的Reader或InputStream输入流,也可以传入environment指定环境或传入Properties作为属性。在build方法的实现中,首先根据传入的输入流、environment和Properties构建XMLConfigBu
如果这是第二次看到我的文章,欢迎右侧扫码订阅我哟~ ? 本文长度为2728字,建议阅读8分钟。 坚持原创,每一篇都是用心之作~ 前面聊完的2个章节「数据一致性」和「高可用」其实本质是一个通过提升复杂度让整体更完善的方式。接下去我们开始聊一些让系统更简单,更容易维护的东西——「易伸缩」,首当其冲的第一篇文章就是「stateless」,也叫「无状态」。z哥带你先来认识一下「状态」是什么。一、初识「状态」之前在「负载均衡」的第四篇(分布式系统关注点——做了「负载均衡」就可以随便加机器了吗?)中提到过一个例子,我们再翻出来一下。开发Z哥对运维Y弟喊:“Y弟,现在系统好卡,刚上了一波活动,赶紧帮我加几台机器上去顶一下。” Y弟回复说:“没问题,分分钟搞定”。 然后就发现数据库的压力迅速上升,DBA就吼了:“Z哥,你丫的搞什么呢?数据库要被你弄垮了”。 然后客服那边接框也爆炸了,越来越多的用户说刚登陆后没多久,操作着就退出了,接着登陆,又退出了,到底还做不做生意了。 这个案例中的问题,产生的根本原因是因为系统中存在着大量「有状态」的业务处理过程。二、「有状态」和「无状态」 N.Wirth曾经
微信上线了“小游戏”,用户无需下载即可在微信中玩跳一跳、中国象棋、坦克大作战等15款H5游戏。这些小游戏是通过微信小程序实现的,用户只要下载微信6.6.1版都可以体验小游戏。对此,磐石之心有以下几点思考。首先,腾讯已不惧苹果恐吓。记得在小程序刚发布的时候,腾讯曾表示暂时不开放小程序的游戏开发能力。这被认为是在与苹果做妥协,因为苹果AppStore近7成收入来自游戏APP。前不久,苹果同意不再向部分应用开发商收取“过路费”,允许不经过苹果而完成公众号文章、新媒体文章、问答平台、微博等的赞赏。但是对游戏的“过路费”仍然并未放开,所以目前小游戏的应用内支付只能在安卓平台实现。从承诺不做游戏,到现在通过小程序全面进军H5游戏,这说明微信已经强大到不惧苹果的威胁了。因为在中国,用户对微信的依赖程度远远超过了对苹果手机的依赖,而且苹果iPhone8和iPhoneX两款新手机销量不佳,苹果颓势已现。其次,微信地位遭遇挑战,迫切控制流量入口。微信小程序推出“小游戏”还透露出微信迫切想要控制流量入口,因为微信正面临多个抢夺流量的强大竞争对手。其一,今日头条等信息流媒体平台。由于公众号进入门槛低、充斥着大
作者:李光,现任职于腾讯社交网络运营部/织云产品团队,负责织云监控告警平台规划与运维新产品开发工作,具有多年业务运维、运营规划经验。概述本文作为监控告警产品的专题系列的第二篇文章,主要讨论的是IAAS层的监控(服务器状态与性能、网络设备状态与性能、网络流量分析等等),从前文所述的监控类型来说,IAAS层一般来说属于基础监控层面。IaaSIaaS、PaaS、SaaS这三个概念想必大家是耳熟能详了,其实就是云计算的三个分层,Infrastructure-as-a-Service(IaaS)基础设施即服务,Platform-as-a-Service(PaaS)平台即服务,Software-as-a-Service(SaaS)软件即服务。IaaS层其实就是一些显性可见的资源对象,如运维小伙伴经常接触的服务器、网络设备与存储设备等等。用一座大厦类比的话IAAS层就好比是负责了最基础的水电通信等能力。上层的服务都是依赖于IaaS层,假定IaaS层管理不好,那么PaaS与SaaS的高效与可控管理其实也是非常难,甚至可以说空谈了。IaaS层的不稳定会直接导致企业对外的服务质量大打折扣。笔者以前在负责手
VirtualTree 揭开华丽的外衣,关注问题的本质. 这就是虚树在做的事情,所以虚树不虚,反而是虚伪原树中最实在的部分,所以它更应该被称作"实树".它在实际问题中常常回答完问题后就转瞬即逝,所以给人的印象就是镜花水月一般的虚无飘渺,现实中敢讲真话的人也有很多就这虚树一样消失了,这或许就是人们称其为"虚树"的原因吧. 定义 一棵树,多次询问,每次询问给出一些关键点,需要对整棵树遍历才能找到答案,但是所有询问的关键点总数有限制. 这时就可以每次关于关键点建立原树的虚树,只保留和关键点数量同阶数量的节点,对虚树进行遍历求得询问的结果. 结合一道经典题展开对虚树的学习. SDOI2011消耗战 简化为一棵边带权的树,每次询问把根节点和\(k\)个关键点断开所需要的最小花费. 朴素的做法是每个点\(i\)有一个值\(f_i\)表示把\(i\)子树中所有关键点和\(i\)断开连接的最小花费,每次决策是否断开\(i\)到它每个儿子的边.总复杂度\(O(nm)\). 接下来引入虚树的做法.首先把根节点也设为关键点,因为询问是关于它的,假设我们只把关键点和关键点两两的LCA提出来,将剩下的点都删
题意:给你一个n*n的矩阵,初始时,(x,y)的值为x+y。可能有两类操作,一类是对某一行求和,并将这一行置零;另一类是对某一列求和,并将这一列置零。 维护四个值:一个是列标号之和,一个是当前存在的列数,一个是行标号之和,另一个是当前存在的行数。 询问某一行的时候,只需要输出列标号之和+该行行号*当前存在列数,然后行数减一,行标号之和减去该行标号即可。列同理。注意不要重复删了。 #include<cstdio> usingnamespacestd; typedeflonglongll; intn,m; llsumx,sumy; intx,y; boolvis[2][1000005]; intmain(){ freopen("adjustment.in","r",stdin); freopen("adjustment.out","w",stdout); charop[5]; intt; scanf("%d%d",&n,&m); sumx=sumy=(ll)n*(ll)(n+1)/2ll; x=y=n; for(inti=1;i<=m;+
一、查找 '调用工作表函数查找 Subt1()'判断是否存在,并查找所在行数 DimhaoAsInteger DimicountAsInteger icount=Application.WorksheetFunction.CountIf(Sheets("库存明细表").[b:b],[g3]) Ificount>0Then MsgBox"该入库单号码已经存在,请不要重复输入" MsgBoxApplication.WorksheetFunction.Match([g3],Sheets("库存明细表").[b:b],0) EndIf EndSub '使用find方法 Subt2() DimrAsInteger,r1AsInteger DimicountAsInteger icount=Application.WorksheetFunction.CountIf(Sheets("库存明细表").[b:b],[g3]) Ificount>0Then r=Sheets("库存明细表").[b:b].Find(Range("g3"),lookat:=xlwbole).Row'
链接:https://ac.nowcoder.com/acm/contest/33785/F 来源:牛客网 在旅途的终点,你终于看到了大魔王小X。 小X准备玩一个游戏,这个游戏规则如下: 对于一个含有n个数的数组a。小X必须执行如下操作t次: 选择数组中的某一个数,给它加上1。 经过这样t次操作后得到的数组b。小X的得分是数组b中所有数的乘积。 显然,在不同的操作过程后,最终可能获得不同的数组b。我们称两个数组是不同的,当且仅当这两个数组中至少有一个数不同,即两个数组p,q不同当且仅当存在i使得pi≠qi。 如果小X在所有不同的数组b中随机取一个作为最终结果,那么他的期望得分是多少? 题目要求的是期望得分,等于对\(n\)个数进行\(t\)次操作,能带来的得分总和除以操作的种类数。操作的种类我们可以看做球盒模型(\(t\)相同的球放进\(n\)个不同的盒子,可空)答案为\(C_{n+t-1}^{n-1}\),于是只需要求得得分总和即可。 考虑令\(f_{i,j}\)表示对前\(i\)个数进行\(j\)次操作能获得的不同的得分之和,状态转移的时候我们枚举在第\(i\)个数进行次\(
procedureWMQUERYENDSESSON(varAMessage:TWMQueryEndSession);messageWM_QUERYENDSESSION; //达到多少秒 functionLeaveTimeBySeconds:Cardinal; 实现: procedureWMQUERYENDSESSON(varAMessage:TWMQueryEndSession); begin ShowMessage('要关机了'); end; functionLeaveTimeBySeconds:Cardinal; var _last:tagLASTINPUTINFO; begin _last.cbSize:=SizeOf(tagLASTINPUTINFO); GetLastInputInfo(_last); Result:=(GetTickCount-_last.dwTime)div1000; end; 复制
1.SVN是什么 SVN是ApacheSubversion的缩写,是一个开放源代码的版本控制系。这些数据放置在一个中央资料档案库(repository)中。这个档案库很像一个普通的文件服务器,不过它会记住每一次文件的变动。这样你就可以把档案恢复到旧的版本,或是浏览文件的变动历史。 2.SVN一些概念 基本概念 repository(版本库):文件统一存放的地方。 checkout(检出):当你手上没有源文件的时候,你需要从repository提取一份。 commit(提交):当你已经修改了文件,你就需要Commit到repository。 update(更新):当你已经Checkout了一份文件,Update一下,你的文件就会与服务器同步。 文件状态 绿色勾——文件正常。 红色叹号——文件被修改。 黄色叹号——修改文件之前,并没有先更新最新版本,而是直接在旧版本上修改,同时修改的内容,刚好跟他人修改的内容有冲突。 蓝色问号——新增文件资源,新增资源可以是文件、图片、代码等。 版本结构 trunk——主开发目录 branches——分支开发目录 tags——存档目录(不允许修改
Android全局异常处理 在做android项目开发时,大家都知道如果程序出错了,会弹出来一个强制退出的弹出框,这个本身没什么问题,但是这个UI实在是太丑了,别说用户接受不了,就连我们自己本身可能都接受不了。虽然我们在发布程序时总会经过仔细的测试,但是难免会碰到预料不到的错误。 今天就来自定义一个程序出错时的处理,类似iphone的闪退。(虽然闪退也是用户不愿意看到的,但是在用户体验上明显比那个原生的弹窗好多了) 简历怎么写 一份好的简历往往事半功倍。笔者平均一年一跳的工作经历,看起来是非常糟糕的,那为什么还能有很多的面试邀约呢?Boss直聘上往往有很多RD在要简历,他们往往是用人部门的leader,因此,突出的职业技能以及过往一年所做的工作尤为重要。下面是我的技能清单。 熟悉面向对象编程,熟悉Java、kotlin等开发语言,对并发、JVM等有一定的了解 熟悉Android开发,了解Android版本差异 熟悉自定义View、动画等技巧,熟悉消息、事件分发等机制 熟悉Android性能优化,能够合理利用工具处理工作中遇到的性能问题 熟悉NDK编程、熟悉JNI 熟悉常用的开源框架
jenkins当中邮件插件: EmailExtensionPlugin jenkins基本使用和邮件配置请参考测试派文章:http://testingpai.com/article/1609225132204 本文着重来讲解: 1)在邮件正文当中,引用邮件插件提供的变量 2)自定义邮件正文的html模板。 最终要达到的效果为: 第一步:查看EmailExtensionPlugin提供的可用变量 1)在Job的【构建后操作】中选择【EditableEmailNotification】 2)翻到【EditableEmailNotification】的最底部,找到【ContentTokenReference】.点最右边的问号,会显示所有可用的变量。 3)【ContentTokenReference】变量说明 3.1)与测试结果有关的变量: ${FAILED_TESTS}:显示失败的用例详情 ${TEST_COUNTS,var="TYPE"}:显示用例数量。TYPE分为4个维度:总数(total),通过(pass),失败(fail),跳过(ski
使用flex的好处 1.弹性布局可以让程序自己等比例分配 2.弹性布局快速实现一行显示且不脱标 3.弹性布局中的元素居中,通过属性即可实现 1.简述: ①flex是FlexibleBox的缩写意为弹性布局为盒模型提供最大灵活性 ②任何一个容器都可以指定为flex布局 ③父元素使用flex布局后,子元素的,float,clear,vertical-align都将失效 2.概念: ①采用flex布局的元素称为容器,flex布局中的子元素称为项目 ②容器默认存在两条轴:水平的主轴垂直的交叉轴 3.特性: 在此之前先了解一下flex特性 只要给父元素设置display:flex就可以让项目在一行上显示这也是伸缩盒子的特点(面试可能会问哦) 在伸缩盒子中所有的子元素都是按照主轴的方向排列显示的 .box{ display:flex; } 复制 3.容器的属性 flex-direction flex-wrap flex-flow justify-content align-items align-content 1.flex-d
依赖倒置原则 所谓依赖倒置原则(DependenceInversionPrinciple)就是要依赖于抽象,不要依赖于具体。简单的说就是对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。 面向过程的开发,上层调用下层,上层依赖于下层,当下层剧烈变化时,上层也要跟着变化,这就会导致模块的复用性降低而且大大提高了开发的成本。 面向对象的开发很好的解决了这个问题,一般的情况下抽象的变化概率很小,让用户程序依赖于抽象,实现的细节也依赖于抽象。即使实现细节不断变化,只要抽象不变,客户程序就不需要变化。这大大降低了客户程序域实现细节的耦合度。 比如一个合资汽车公司现在要求开发一个自动驾驶系统,只要汽车上安装上这个系统,就可以实现无人驾驶,该系统可以在福特车系列和本田车系列上使用。面向过程的结构图: &nb