Spring Cloud 微服务项目实战
姚秋辰(姚半仙)
PayPal 研发经理
15862 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 38 讲
结束语 (1讲)
Spring Cloud 微服务项目实战
15
15
1.0x
00:00/00:00
登录|注册

11 | Loadbalancer 实战:通过自定义负载均衡策略实现金丝雀测试

你好,我是姚秋辰。
上一课我们学习了如何借助 Nacos 的服务发现机制获取可用服务节点列表,并发起远程服务调用。在服务调用的环节里,还有一处细节需要你思考一下:Nacos 通过服务发现拿到了所有的可用服务节点列表,但服务请求只能发给一个节点,你知道服务调用是根据什么规则选择目标节点的吗?
“小孩子才做选择,大人全都要”,Nacos 就是这个全都要的大人。服务列表都被它拿到了手里,但如果要完成一次完整的服务调用,它还需要一个小孩子帮忙做选择,这个做选择题的小孩就是客户端负载均衡组件 Spring Cloud Loadbalancer,它根据负载均衡规则,从 Nacos 获取的服务列表中选取服务调用的目标地址。
那么,Loadbalancer 背后是如何工作的呢?今天我就带你了解 Spring Cloud 御用负载均衡器 Loadbalancer 的原理。通过这节课,你可以收获以下内容。
负载均衡的作用:了解负载均衡的两大门派,它们分别是网关层负载均衡和客户端负载均衡。你还会理解客户端负载均衡在微服务架构中的优势;
Loadbalancer 工作原理:了解 Loadbalancer 如何运用 @Loadbalanced 注解进行加载;
自定义负载均衡策略:了解 Loadbalancer 的自定义扩展点,在实战项目中实现金丝雀测试。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了如何通过自定义负载均衡策略实现金丝雀测试。首先,文章解释了Spring Cloud Loadbalancer的工作原理,包括@Loadbalanced注解的使用和负载均衡过滤器的注入过程。然后,文章提到了Loadbalancer提供的内置负载均衡策略以及如何实现自定义负载均衡策略来进行金丝雀测试。金丝雀测试是一种灰度测试,通过将代码改动部署到极个别的几台机器上,实现在极小规模范围内进行线上测试。文章详细介绍了CanaryRule负载均衡规则的编写过程,包括如何识别测试流量和对测试流量进行负载均衡。接着,文章讲解了配置CanaryRule负载均衡策略以及在WebClient请求的Header中传入测试流量标记的方法。最后,文章指出了金丝雀测试的实现原理和方法对技术人员的成长具有重要意义,鼓励读者不要在技术学习上给自己设界,而是多去了解更多技术框架的全貌,积累到一定程度之后,这些努力都会在未来某一个时刻给你回报。整体而言,本文内容深入浅出,适合读者快速了解负载均衡策略的实现原理和金丝雀测试的应用场景。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Spring Cloud 微服务项目实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(24)

  • 最新
  • 精选
  • peter
    老师我有个关于代理的问题:一般用nginx将请求转发到后端多个应用服务器上。现在用了API网关,由API网关将请求转发到后端应用服务器上。这样的话,API网关和nginx的功能就重复了,就不需要nginx了,对吗? 尤其对于中小公司,服务器数量不是很多,nginx就足够了,或者用API网关就足够了,两者选一个就够了啊。

    作者回复: 还是需要nginx的,微服务网关和nginx扮演的角色不一样,nginx作为高性能反向代理,性能上是完爆任何微服务网关的。而且一般公司会根据安全策略设置多层LVS+Nginx网关,比如secure zone, unsecure zone等等,内部网络拓扑非常复杂,这里依然需要nginx来扮演网关的角色。 而微服务网关,比如后面我们要看到的spring cloud gateway,往往扮演的角色是在外部网关和内部微服务之间的桥梁,通常不会作为最外层网关直接承接外部用户流量

    2022-01-06
    3
    10
  • Geek_0b93c0
    集群优先代码 private Response<ServiceInstance> getSameClusterService(Request request, List<ServiceInstance> instances) { String clusterName = environment.resolvePlaceholders("${spring.cloud.nacos.discovery.cluster-name:}"); List<ServiceInstance> instanceList = instances.stream().filter(v -> { Map<String, String> metadata = v.getMetadata(); String serviceClusterName = metadata.get("nacos.cluster"); return clusterName.equals(serviceClusterName); }).collect(Collectors.toList()); //有同集群下服务 RoundRobin算法挑选 if (CollectionUtils.isNotEmpty(instanceList)){ return getRoundRobinInstance(instanceList); }else { return getRoundRobinInstance(instances); } }

    作者回复: perfect, 从metadata这个属性里可以读到很多data做各种定制

    2022-05-31
    9
  • 与路同飞
    现在公司所有api服务都是注册到api网关上去了。api网关替我们做了负载均衡和路由规则。那业务团队是不是就不需要引用负载均衡组件了

    作者回复: api网关只负责网关->微服务的链路,但是基于服务发现构建的微服务架构里,微服务之间互相调用是不经过网关的

    2022-01-20
    2
    9
  • 何衍其
    // 当前服务的集群名称 String clusterName = environment.resolvePlaceholders("${spring.cloud.nacos.discovery.cluster-name:}"); // 服务实列所属集群名称 serviceInstance.getMetadata().get("nacos.cluster");

    作者回复: 非常正确,metadata里面包罗万象

    2022-04-13
    2
    8
  • ~
    说一下思考题我的思路: 从 CanaryRule 就可以看出来了,其实实现负载均衡的逻辑就在getRoundRobinInstance中,我们只需要改造这里就可以了。我的想法是设置一个缓存(map 也好,其他的也好),存放上次选择出的 serverInstance,如果是第一次选择,那么使用老逻辑选出一个,如果上次选择的服务已经不可用了,就从缓存中清除,重新选一个就可以了。 补充2点: 1. 怎么判断一个服务是否可用?其实在这里的代码中,传入的 List<ServiceInstance> 参数就是从 nacos 中获取到的可用服务的列表。那么只需要判断缓存中存放的 serviceInstance 是否也在 list 中就可以了。具体怎么获取到可用服务列表的,需要进一步查看源码才能了解。 2. 仅做一个猜想,不具有实际意义,老师如果能解答也再好不过了:能否直接在获取可用服务列表那步就直接确定一个服务?其他的逻辑也是如此。就算可行其实设计上也是不合理的,因为获取可用服务的代码就应该只负责相关逻辑,负载均衡代码就应该只管负载均衡。提出这个猜想只不过是想对源码有进一步了解,设计上还是各司其职更合理。 以上就是我的思考,附上代码(超过字数限制了,放在我的留言的回复里了),如果有问题,欢迎指出问题~

    作者回复: 同学是一个爱思考的三好学生,非常不错。我思考题里面埋了一个机关是“集群优先”,所以这里还需要判定一下当前instance所属的集群是否与当前这台服务器一致,当前服务的集群可以从配置文件中读取,而instance的集群其实被封装到了每个instance的metadata里,可以从中读取并比较

    2022-01-16
    3
    5
  • Yarnbo
    姚总好,学习了您的本节课受益匪浅。虽然照葫芦画瓢也实现了“优先调用同一个 Cluster 的服务器”,但是这样做的意义有哪些,能结合您的经验介绍下吗?(我能盲猜到的是,假如服务以集群为基本单元提供服务能力,将来方便弹性扩展机器)

    作者回复: 同学都说出正确答案了,没错,其实“优先调用同一个cluster”是一种最简单的单元化能力。假设前置网关能根据用户location等条件做单元调用(淘系用户就分单元/中心机房等等),比如说江浙沪的用户请求进上海机房,相对应的全链路缓存都构建再同一个机房,那么将打到单元A的流量只在内部做流转能降低请求响应时间

    2022-09-29归属地:上海
    1
  • 二饼
    Nacos-服务管理-服务列表-开发环境 `coupon-template-serv` 只有一个实例,不是两个,我又把前面的文章看了一遍,没有发现什么地方又说定义了两个实例,和示例代码比对了一下配置文件没看出什么问题,请教一下老师我这是什么造成的?

    作者回复: 同学要在本地换一个端口再启动一个coupon-template-serv服务,确保有两个同名但占用端口不同的服务启动并注册

    2022-08-21归属地:上海
    2
    1
  • 胖子菜
    dubbo整合了nacos后,因为我用的最新版本的nacos没有自带ribbon,我又引入了loadbalancer依赖,我想问下dubbo有负载均衡机制,loadbancer也有,他们冲突么,谁会生效呢

    作者回复: 我一般是直接用dubbo原生的负载均衡策略,spring cloud自带的loadbalancer其实功能性还不如ribbon,内置的负载均衡策略也没得比,完全是为了去netflix化搞的这么个玩意儿

    2022-05-07
    1
  • 靠人品去赢
    像金丝雀这些线上验证,会产生线上数据,万一没搞好打标打错了或者没配置好,导入到正常服务的机器上没有到金丝雀上,怎么辨别消除影响呢?

    作者回复: 万一打标错了,一个最好的方案就是扣打标的那个人的年终奖吧。 金丝雀可以只打线上测试流量,下单商品也打上测试标,即使产生影响也不影响线上真实客户

    2022-04-01
    1
  • rrbbt
    老师能详细讲一下这句话吗?没太看懂,为什么不应用到全局?不加@Configuration就能不应用到全局吗?===========[原文]"因为我不希望把这个负载均衡策略应用到全局,所以我没有为这个配置类添加 @Configuration 注解"

    作者回复: configuration注解内部包含了Component注解,加上之后这个类就会在被spring容器“盯上”,进而将里面声明的bean初始化后作用于全局。所以我在代码中使用了一种“指定配置项”的方式,让这个类只服务于指定的service

    2023-06-24归属地:山东
收起评论
显示
设置
留言
24
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部