Spring Cloud loadBalancer使用

使用loadbalancer

springcloud-2020.0.*版本后逐渐移除了netflix的组件(ribbon, hystrix),现在SpringCloud不是与某一个类库绑定,而是提供了一套抽象,这样就可以在保持接口不变的情况下切换实现方案,新版本负载算法使用loadbalancer实现

切换负载算法

  • 默认负载算法 RoundRobinLoadBalancer

@Configuration(proxyBeanMethods = false)@ConditionalOnDiscoveryEnabledpublic class LoadBalancerClientConfiguration {private static final int REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER = 193827465;@Bean@ConditionalOnMissingBeanpublic ReactorLoadBalancer reactorServiceInstanceLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);}

  • 模仿 RoundRobinLoadBalancer 写自定义的负载均衡类

public class MyLoadBalancer implements ReactorServiceInstanceLoadBalancer {private static final Log log = LogFactory.getLog(RoundRobinLoadBalancer.class);final AtomicInteger position;/**轮询间隔*/final Integer interval = 3;final String serviceId;ObjectProvider serviceInstanceListSupplierProvider;public MyLoadBalancer(ObjectProvider serviceInstanceListSupplierProvider,String serviceId) {this(serviceInstanceListSupplierProvider, serviceId, new Random().nextInt(1000));}public MyLoadBalancer(ObjectProvider serviceInstanceListSupplierProvider,String serviceId, int seedPosition) {this.serviceId = serviceId;this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;this.position = new AtomicInteger(seedPosition);}@SuppressWarnings(“rawtypes”)@Overridepublic Mono choose(Request request) {ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);return supplier.get(request).next().map(serviceInstances -> processInstanceResponse(supplier, serviceInstances));}private Response processInstanceResponse(ServiceInstanceListSupplier supplier,List serviceInstances) {Response serviceInstanceResponse = getInstanceResponse(serviceInstances);if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer());}return serviceInstanceResponse;}private Response getInstanceResponse(List instances) {if (instances.isEmpty()) {if (log.isWarnEnabled()) {log.warn(“No servers available for service: ” + serviceId);}return new EmptyResponse();}int pos = this.position.incrementAndGet() & Integer.MAX_VALUE;ServiceInstance instance = instances.get(pos / interval % instances.size());log.info(“instance:”+instance.getInstanceId());return new DefaultResponse(instance);}}

  • 自定义负载配置类

public class MybanlancerConfiguration {/** * 自定义负载 * @author Noodles * @date 2022/5/24 21:40 */@BeanReactorLoadBalancer myloadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new MyLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);}}

如果要提供自定义的ServiceInstanceListSupplier 就在此类中加入自定义的bean即可,如下所示

@Bean public ServiceInstanceListSupplier myDiscoveryClientServiceInstanceListSupplier( ConfigurableApplicationContext context) { return ServiceInstanceListSupplier.builder().withDiscoveryClient().build(context); }

  • 配置自定义负载均衡的服务,其中 “NOODLES_PROVIDER” 为注册到注册中心的serviceId

@Configuration@LoadBalancerClients(value = {@LoadBalancerClient(name = “NOODLES-PROVIDER”, configuration = MybanlancerConfiguration.class) })public class LoadBalanceConfig {Logger logger = LoggerFactory.getLogger(LoadBalanceConfig.class);@LoadBalanced@BeanWebClient.Builder webClientBuilder() {return WebClient.builder();}}

代码实现

  • spring-cloud-parent -> noodles-consumer
  • spring-cloud-parent -> spring-cloud-mygateway

参考资料

  • https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#spring-cloud-loadbalancer

扩展知识

  • Spring 接口 BeanPostProcessor
  • 代理设计模式
郑重声明:本文内容及图片均整理自互联网,不代表本站立场,版权归原作者所有,如有侵权请联系管理员(admin#wlmqw.com)删除。
(0)
用户投稿
上一篇 2022年6月17日
下一篇 2022年6月17日

相关推荐

  • 110W人围观!幻塔2.2版本前瞻开播,玩法拟态地图全有新花样?

    近日,备受关注的《幻塔》2.2版本前瞻直播终于和玩家见面了。2.2版本从一开始就给了《幻塔》玩家 不一样的感觉,这次的2.2版本除了预告与先导PV外,还特意还安排了一场前瞻直播,并…

    2022年9月7日
  • 遥望天长大地,我与上汽大众全新途昂、新途观L毅然迈进

    JUELUO·畅享之旅 只有“自驾”,能把辽阔的空间和漫长的时间浇灌给你,能把一切“旷野之美”传递给你,能把无数的期待和美好对比着收获和美景一起呈现给你。 因此,自驾出行才是阅读世…

    2022年8月9日
  • 元气骑士:速刷百万蓝币,金刀1分钟达成,这些“特性”你相信吗

    “碧海潮生龙影现,石岸萧落一曲长”大家好!我是爱游戏爱《元气骑士》的老宅。 众所周知,在《元气骑士》这款手游中,共有4种不同的货币机制,它们分别是:金币、蓝币、小鱼干以及现金充值。…

    2022年7月28日
  • 暴龙电竞专访XSG、卡卡西:失误少点,运营更好点,目标是冠军

    在永劫无间职业联赛NBPL总决赛即将开战前,暴龙电竞专访了“三连冠”战队XSG、卡卡西选手! Q:恭喜XSG拿下三连周决赛,怎么评价对于NBPL四周周决赛的表现? XSG、卡卡西:…

    2022年8月3日
  • 欧盟亚马逊蓝牙音响RoHS、reach、ce、weee认证要求

    提及产品: 1.便携式蓝牙音箱 2.启用Wi-Fi的蓝牙音箱 3.蓝牙免提音箱 4.立体声耳机 蓝牙音箱RoHS认证指令: RoHS(有害物质限制指令)对于在欧盟出售的蓝牙音箱来说…

    2022年8月6日
  • 索尼PS5新版本:更小更薄并非Slim版 造型变化巨大

    2020年年底,索尼推出次世代游戏机Playstation 5,其大改的外观自发布以后颇受争议,尤其是光驱版本不对称式的设计,让不少玩家吐槽。如今两年过去,玩家一直希望索尼可以推出…

    2022年11月9日
  • 爆破模式玩法

    爆破模式就是对于爆破点的争夺,防守方要设立防线,阻止进攻方接近爆破点,进攻方要突破阻线,抵达爆破点,安置炸药。 当C4被打掉之后防守方要守住C4,阻止进攻方拿到C4,进攻方要想法重…

    2022年8月10日
  • 不仅流畅度拉满,功能体验更是细节满满!OPPO手机系统太加分

    如果你问我目前国产手机里哪款系统最好用,ColorOS绝对会是我的首选。目前大多数OPPO手机系统都已经升级到了最新的ColorOS 12,该系统不仅在UI、安全、流畅等多个维度都…

    2022年7月9日
  • 理解 RAFT 分布式共识算法

    理解 RAFT 分布式共识算法——第 1 部分 为什么我们需要共识 我们大多数人在我们的编程生涯中至少使用过一次关系数据库,如 MySQL、Oracle。当您INSERT或UPDA…

    2022年6月24日
  • 那些年我们一起玩过的游戏

    1.《和平精英》 《和平精英》是由腾讯光子工作室群自研打造 的反恐军事竞赛体验类型国产手游, 该作于2019年5月8日正式公测。 该游戏采用虚幻4引擎研发,沿袭端游《绝地求生》 的…

    2022年8月18日

联系我们

联系邮箱:admin#wlmqw.com
工作时间:周一至周五,10:30-18:30,节假日休息