博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【RPC】一步一步实现基于netty+zookeeper的RPC框架(三)
阅读量:4079 次
发布时间:2019-05-25

本文共 3259 字,大约阅读时间需要 10 分钟。

上一篇写完咱们已经具备服务注册发现/通信/通过接口调用功能了,本篇带来负载均衡策略。

RPC框架中,负载均衡策略提供,其实就是根据配置,选择不同的负载策略,常见的有随机/轮询/权重几种负载策略,本篇就带大家来实现它。

这里还是贴出github代码地址,想直接看代码的可以直接下载运行:https://github.com/whiteBX/wrpc

首先这里主要用到了设计模式中的策略模式,定义一个负载策略处理器:

public interface BalanceProcessor {
/** * 处理接口 * @param urlList * @return */ String process(String appCode, List
urlList);}

下面来实现轮询模式的策略处理:

public class RoundRobinBalanceProcessor implements BalanceProcessor {
private ConcurrentMap
counterMap = new ConcurrentHashMap
(); public String process(String appCode, List
urlList) {
AtomicInteger counter = counterMap.get(appCode); if (counter == null) {
counterMap.putIfAbsent(appCode, new AtomicInteger()); } counter = counterMap.get(appCode); int current = getAndIncrement(counter); return urlList.get(current % urlList.size()); } /** * 通过CAS获取不超过最大数的顺序int * * @param ai * @return */ private Integer getAndIncrement(AtomicInteger ai) {
while (true) {
int current = ai.get(); int next = current >= Integer.MAX_VALUE ? 0 : current + 1; if (ai.compareAndSet(current, next)) {
return current; } } }}

这边代码比较简单,主要用到了java并发包的一些东西,通过一个自增数对数组长度取余即可以实现轮询模式。另外这里默认我们线上的服务器数量不是会经常变化的,所以urlList的内容其实是很少变化的,轮询在大部分时间内是不会被破坏的。

下面来看随机模式,这个很简单:

public class RandomProcessor implements BalanceProcessor {
public String process(String appCode, List
urlList) {
return urlList.get((int) (Math.random() * urlList.size())); }}

接下来来看策略上下文处理:

public class BalanceContext {
private BalanceProcessor roundRobinProcessor = new RoundRobinBalanceProcessor(); private BalanceProcessor randomProcessor = new RandomProcessor(); /** * 获取URL * * @param urlList * @return */ public String getUrl(String appCode, List
urlList, BalanceMode balanceMode) {
switch (balanceMode) {
case ROUND_ROBIN: return roundRobinProcessor.process(appCode, urlList); case RANDOM: return randomProcessor.process(appCode, urlList); default: return null; } }}

然后是改造原有获取url的部分代码,调用我们的策略处理类:

/** * 负载上下文处理器 */private BalanceContext balanceContext = new BalanceContext();/** 负载模式,后续引入spring则从配置文件中读取 */private static String balanceMode = "RANDOM";/** * 获取URL * * @param appCode * @return */public String getUrl(String appCode) {
// 初始化url if (urlList.size() == 0) {
initUrlList(appCode); } // 随机返回一条,此处以后优化为负载均衡策略 if (urlList.size() > 0) {
return balanceContext.getUrl(appCode, urlList, BalanceMode.valueOf(balanceMode)); } else {
System.out.println("目前没有服务提供者"); return null; }}

之后大家可以自行测试一下,采用轮询模式的话,获取到的处理服务器会依次轮询所有注册的服务,而采用随机模式则会随机选中服务器进行处理。这里就不贴测试结果了。

另外由于时间关系这里没有写权重的策略,这里先说一下原理,其实很简单的。

权重模式,根据配置,比如5台机器,配置权重依次为40,10,15,25,10.那么只需要在总数100中去随机一个随机数,命中了1-40则选取机器1,命中了41-50则选取机器2,其他同理。另外这里针对可能临时加机器的情况,配置没有及时更新进去的话,对于新机器可以设置默认权重,比如这时新加了一台机器,默认权重设置为10的话,则当前权重算法变为在总数110中随机,随机到101-110则会选取新增加的机器去处理请求即可。

到这里就实现了RPC框架的负载均衡.

后续将一步一步实现调用链路Trace记录/限流等功能,欢迎持续关注!

转载地址:http://lhsni.baihongyu.com/

你可能感兴趣的文章
cubli我觉得不管是工作还是读研发文章还是读博,都用得到,我觉得可以弄弄。
查看>>
当初校赛智能车是这么实现用按键更改PID参数的
查看>>
当初校赛智能车的程序我还是有保存一些的。
查看>>
semaphore就是信号量的意思,以后看见信号量相关的函数不用怕,函数命名都是有规则的,查词典就可以了。
查看>>
一些信号量的函数里面其实就是调用的消息队列的函数实现的!怪不得华清的老师说先讲消息队列其他都弄懂了。
查看>>
ACfly工程Freertos层面上解析
查看>>
Python并非为AI而生,Golang将统治人工智能的下一个十年?
查看>>
每获取一次信号量就对应着要释放一次信号量,这也是为什么你在ACfly工程里面看到这么多次释放信号量的原因。
查看>>
真正面试的底气还是来自于你真正吃透了几本书几个东西,而不是几个高大上的项目。
查看>>
互斥信号量和二值信号量的区别在于优先级翻转,注意了,有区别,之前一直以为差不多。
查看>>
我目前觉得嵌入式面试(STM32方向)需要准备的一些东西
查看>>
现在明白为什么无名飞控的STM32工程里面有个DSP文件夹了
查看>>
确实是读一个硕士机会平台高些
查看>>
20道嵌入式工程师面试题(附答案)
查看>>
面试积累——嵌入式软件工程师面试题(非常经典)
查看>>
这些网站有一些嵌入式面试题合集
查看>>
我觉得刷题是有必要的,不然小心实际被问的时候懵逼,我觉得你需要刷个50份面试题。跟考研数学疯狂刷卷子一样!
查看>>
我觉得嵌入式面试三要素:基础吃透+项目+大量刷题,缺一不可。不刷题是不行的。而且得是大量刷,刷出感觉套路,别人做题都做得是固定题型套路条件反射了,你还在那慢慢理解慢慢推是不行的,也是考研的教训。
查看>>
嵌入式面试题错题集(我自己做的)
查看>>
ACfly飞控用STlink下载的接口,接线,并用STlink(SWD)下载程序
查看>>