首先,这只是我个人的一点质疑,可能是因为我自己菜没有领悟到作者的意思,也正因此,想发出来跟大家一起探讨.

在昨晚,我因为在编写自己的开源项目的负载均衡模块(这是我开源项目的介绍:https://www.cnblogs.com/yangfeiORfeiyang/p/9621909.html),所以去看了下Netflix的RibbonLoadbalancer的源码,然后它是这样做的

首先定义一个ILoadBalancer接口,这个接口是干嘛的呢?大家可以想象为一个自动饮料机,我们想要饮料的时候,按一个按键(chooseServer(Object key)),投一个硬币(当然它的几个源码实现类里,这个key其实没有多少意义),就能获得我们想要的饮料,由此来看,大家可以将它抽象为一个对我们隐藏了内部细节的容器

下面再来看一个接口,这个接口是干什么的呢?将注释里的英文翻译下,就是这个接口是定义负载均衡的规则的,最典型的负载均衡规则就是轮询啊,根据响应时间进行自动权重啊(根据响应时间这个,它的源码里是有实现类的ResponseTimeWeightedRule不过被标记为了过时类,也就是不推荐我们使用)

好了,接下来就是我认为它不合理的地方了,请看下面这个实现了IRule的抽象类,请注意它的成员变量,它封装了ILoadbalancer类

请大家想象一个场景,现在你想去一个超市买水果,你有可能走路去,有可能骑车去,也有可能做公交车,不管怎样,去超市买水果这是一个没有细节的概念,为什么没有细节呢?因为我们不知道你会以什么样的方式去,此时你会以什么样的方式去就是一个可能会发生变化的变量.

那么对比到我们的代码里,ILoadBalancer就是你要去超市买水果,这是一个没有变化的,封闭了细节的概念,试问你在自动饮料机买饮料的时候知道饮料机内部经历了什么样的变化吗?而IRule就是我们是以什么样的方式去超市了,此时它是可能会发生变化的,因为我们有可能用轮询算法,有可能用权重算法,但不管用什么,它们最终都会取出一个Server.,这个结果是不会改变的,也就代表

我们的ILoadBalancer是不会改变的,那么你将ILoadBalancer封装到IRule里是什么意思呢?我"个人"认为,正确的做法应该是这样的:

好吧,我继续看了一会又发现一个问题,这个问题也在验证了我的想法是对的

很明显,作者自己也知道,IRule应该是ILoadbalancer的细节

what???敢情您饶了一大圈最后又绕回去了呀.我们再看看rule.choose(key)里的具体内容

额额额,你调来调去最后又调回来了...

不过,有一行代码让我感觉到了作者的高并发编程水平真的不错...

首先这个nextServerCyclicCounter是个AtomticInteger类.

我们先说说为什么作者不直接nextServerCyclicCounter.getAndIncrement(),然后取模呢?因为如果要getAndIncrement的话,那么会导致一个问题,那么就是我就要写出这样的代码

if(nextServerCyclicCounter.get()==服务数量){

nextServerCyclicCounter.set(0)

}

但是这样就有一个问题,那就是虽然AtomticInteger类的每个操作都是原子性的,但是加起来就不是了,也就是说,假设有两个线程,一个A,一个B.

第一步:线程A刚刚进入了判断,还没来得及设置为0,CPU时间片就被抢了

第二步:线程B也进来了,那么他们拿到的将是同样的数据.连续两次设置为0.当然可能会有N个线程进来N次设置为0

而用这个方法呢?就不会有这个问题了,它等于是拿到当前值,然后再拿预期值,之后,看看当前值是否发生了改变,改变的话就重新获取,是的话就将预期值换成当前值并返回预期值(比较换值这个过程借助了unsafe类保证了是原子性的),没错,这里最妙的就是这个死循环包含的代码,它等于是每次重新拿最新的值去试(因为AtomticInteger类里的value字段上了volatile关键字),完美的避开了我们上述的问题.

正当我感叹这个作者实在是高的时候...我看了下译文

额,好吧,我也算是受到了您的启发,学到了一手,哈哈哈

完毕~欢迎大家说出我不对的地方...

最新文章

  1. ubuntu14.04禁用自动待机保持屏幕亮度
  2. Please Call Me NIO
  3. 大熊君学习html5系列之------History API(SPA单页应用的必备------重构完结版)
  4. 查看apache、linux、kernel、nginx等版本
  5. JS给文本框赋值后,在页面后台取不到文本框值的解决方法
  6. vs c++系统函数 计时器和暂停
  7. crossplatform---Node.js Applications with VS Code
  8. Catching Fish[HDU1077]
  9. 【转】越狱的 iPhone、iPad 通过网站实现一键安装 ipa 格式的 APP 应用
  10. CSS3实现的player播放按钮
  11. 编译XSIP过程中环境配置
  12. C语言第一次实验报告————PTA实验1.2.3内容
  13. Java进阶(四十三)线程与进程的区别
  14. VUE-利用OSS BrowserJS-SDK实现阿里OSS前端上传
  15. coreseek/sphinx中的匹配模式
  16. 不同浏览器中scrollHeight的比较
  17. ABP框架系列之十八:(Data-Transfer-Objects-数据转换对象)
  18. Hibernate中得fetch
  19. hdoj1257(DP-LIS/贪心)
  20. Flask系列03--Flask的路由 app.route中的参数, 动态参数路由

热门文章

  1. 单调栈2 POJ3250 类似校内选拔I题
  2. 分布式文件系统ceph介绍
  3. 生成随机ID且唯一
  4. 快学UiAutomator UiDevice API 详解
  5. POI写入word doc 03 模板的实例
  6. Java中的线程--并发库中的集合
  7. (转发)IOS高级开发~Runtime(一)
  8. ios之UIPopoverController
  9. java面试宝典第二弹
  10. linux终端颜色控制