restTemplate loadbalance 负载均衡使用demo 案例 原理以及全网最细源码解析

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
应用型负载均衡 ALB,每月750个小时 15LCU
简介: restTemplate loadbalance 负载均衡使用demo 案例 原理以及全网最细源码解析

restTemplate 是spring 提供的http请求工具,类似于httpclient,

默认情况下与其他的http 工具类没有区别

但是当添加了@Loadbalance 注解之后,则具备了负载均衡功能,可以通过服务名找到对应的ip:port进行访问

闲话少说,我们直接上demo

注册templete loadbalance bean

如果引入了spring cloud 默认会注册 loadbalance resttemplate

@Bean
  @LoadBalanced
  public RestTemplate restTemplate(){
    return new RestTemplate();
  }

使用方式 post 使用demo案例

我这里是用的spring cloud nacos ,针对工作流回调函数传入服务名进行负载均衡调用

@Autowired
    private  RestTemplate restTemplate;
    /***
     * 
     * @param serverName 服务名
     * @param event 回调事件
     * @param vars 回调参数j'son
     * @return R<String> 返回结果
     * 
     */
    @Override
    public R<String> call(String serverName,String event, String vars) {
        log.info("serverName:{},event:{},vars:{}",serverName,event,vars);
        String url = "http://"+serverName+"/workflow/callback/event";
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add(SecurityConstants.FROM, SecurityConstants.FROM_IN);
        HttpEntity<Void> httpEntity = new HttpEntity<>(null, httpHeaders);
        MultiValueMap<String, String> requestMap = new LinkedMultiValueMap<>();
        requestMap.add("event", event);
        requestMap.add("dataMapString", vars);
        ResponseEntity<R> r =  restTemplate.exchange(url, HttpMethod.POST,httpEntity,R.class,requestMap);
        return R.ok();
    }

接收端

/**
     * 工作流回调接口
     *
     * @param event         事件名称
     * @param dataMapString 传递参数
     *                      dataMapString 参数如下:
     *                      flag :审批结果 "审批,驳回,终止"
     *                      username: 该流程提交者用户名
     *                      busi_id: startSubmit 返回的流程业务id,与业务挂钩的主键
     *                      nodeId: 节点Id
     *                      assignee: 分配的审批人
     *                      auditer: 真正完成审批人
     *                      comment: 审批意见
     */
    @Inner
    @RequestMapping("/event")
    @ApiOperation(value = "工作流各种回调事件接口", tags = "工作流各种回调事件接口")
    public R callBack(String event,String dataMapString) {
        System.out.println("event:" + event + ",dataMapString:" + dataMapString);
        //流程相关参数
        Map<String, String> params = JSON.parseObject(dataMapString, new TypeReference<Map<String, String>>() {
        });
        //流程节点分到了具体审批人后回调事件
        if (WorkflowCallBackEvent.EVENT_ASSIGNEE.equals(event)) {
            return R.ok();
        }else{
            return R.failed();
        }
     }

redistemplete 执行loadbanlace 运行流程与源码分析

为了大家方便理解,我画了一个简单的运行泳道图,主要分为两个部分,第一是启动部分,如下图:f9747bad90b740b4ba1b1ac7324eb7d3.png

启动部分源码分析

整体流程描述


1. 通过LoadBalancerAutoConfiguration 加载所有带有@LoadBalanced 注解的restTemplate

2. 初始化 执行 loadBalancedRestTemplateInitializerDeprecated 方法内部遍历执行 customizer.customize(restTemplate)

3. customizer.customize(restTemplate) 其实就是执行 之前注入的bean RestTemplateCustomizer,然后执行restTemplate.setInterceptors(list)



初始化完毕

详细步骤源码分析

1. 通过LoadBalancerAutoConfiguration 加载所有带有@LoadBalanced 注解的restTemplate

重点,为什么是加载了有@LoadBalanced 注解的restTemplate 而不是所有的restTemplate ,因为@LoadBalanced 内有一个@Qualifier 元注解

因此有@LoadBalanced 注解的restTemplate 就绑成了一个整体注入到了spring 中管理


09382e67e86944339e38e8dbb108507f.png

3b3547906dc74b338a9777760dd009be.png

2. 初始化 执行 loadBalancedRestTemplateInitializerDeprecated 方法内部遍历执行 customizer.customize(restTemplate)


9a5609d6969045eaa1cab63f22faeb6e.png

3. customizer.customize(restTemplate) 其实就是执行 之前注入的bean RestTemplateCustomizer,然后执行restTemplate.setInterceptors(list);

811a692b4b494c8bb030d8f045fbce6f.png

setInterceptors(list) 其实就是注入了RetryLoadBalancerInterceptor ,现在完成后也就是将含有loadbalance 注解的resttemplate 注入了interceptor

redistemplete 执行exchange 负载均衡源码分析(参照上面流程图)

整体流程描述

1. redistemplete 执行 exchange,然后内部 exchange->execute->doExecute

2. 然后 createRequest 然后通过 getRequestFactory 创建request

3. getRequestFactory 会根据是否内部注册了拦截器来返回不同的factory, 有拦截会返回InterceptingClientHttpRequestFactory ,没有会返回SimpleClientHttpRequestFactory

4. InterceptingClientHttpRequestFactory 会创建返回InterceptingClientHttpRequest,SimpleClientHttpRequestFactory 会创建返回SimpleBufferingAsyncClientHttpRequest

5. SimpleBufferingAsyncClientHttpRequest 会正常和httpclient 一样执行execute,暂不多说,主要来说InterceptingClientHttpRequest ,这个是负责负载均衡的

6. InterceptingClientHttpRequest 执行execute ,内部会先执行拦截器也就是之前启动注入的RetryLoadBalancerInterceptor

7. RetryLoadBalancerInterceptor 内部会执行 RibbonLoadBalancerClient 的choose 方法用NamedContextFactory 将服务名从注册中心获取实例转为ip:port 的ServiceInstance

8. 然后 RetryLoadBalancerInterceptor 会拿着得到的ServiceInstance 正常执行http请求得到 ClientHttpResponse

9. 返回response 全部流程结束

详细步骤源码分析

1. redistemplete 执行 exchange,然后内部 exchange->execute->doExecute


927f6929b7404f7e91548d99e6f91a3d.png


d0cc92b3ebf3473c93a2d579efaba42b.png

2. 然后 createRequest 然后通过 getRequestFactory 创建request


4825b8d973fc49599b82a7b445a9a880.png


68fc21b2c791448b9d9d30e5d577536b.png

3. getRequestFactory 会根据是否内部注册了拦截器来返回不同的factory, 有拦截会返回InterceptingClientHttpRequestFactory ,没有会返回SimpleClientHttpRequestFactory

510f40c28fa04b39a35db78612da0a68.png


9ae0b80c408b4f0cb95c5a4305fc9676.png

4. InterceptingClientHttpRequestFactory 会创建返回InterceptingClientHttpRequest,SimpleClientHttpRequestFactory 会创建返回SimpleBufferingAsyncClientHttpRequest

2ad10ae012e8456eb6b317d312afe68b.png


bd21ebda0041427b984d7cb5d5e6a28b.png

5. SimpleBufferingAsyncClientHttpRequest 会正常和httpclient 一样执行execute,暂不多说,主要来说InterceptingClientHttpRequest ,这个是负责负载均衡的

b4cda9249e4440d09c2a03a5d6042fb4.png

f81b78334ded45c4a4ab99fd0baeb66b.png

6. InterceptingClientHttpRequest 执行execute ,内部会先执行拦截器也就是之前启动注入的RetryLoadBalancerInterceptor

34491e0e779c46f781d4dd32edf0418f.png

7. RetryLoadBalancerInterceptor 内部会执行 RibbonLoadBalancerClient 的choose 方法用 NamedContextFactory 将服务名从注册中心获取实例转为ip:port 的ServiceInstance

47b351fb1c694c34b4b23076c43d5a8a.png

61ca379889a344b1800bb54b40155912.png


4a30fef79eb04cbfb8e2c1ef69c9f563.png

8. 然后 RetryLoadBalancerInterceptor 会拿着得到的ServiceInstance 正常执行http请求得到 ClientHttpResponse

2f6b43374d0c4e9b94b097ce8f5b176a.png

9. 返回response 全部流程结束

注意点:如果resttemplate 加了@loadbalance 注解,那么就不可以在用ip:port 形式的url请求了,只能用servername 形式,不然会报错


相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
2月前
|
NoSQL Java Linux
《docker高级篇(大厂进阶):2.DockerFile解析》包括:是什么、DockerFile构建过程解析、DockerFile常用保留字指令、案例、小总结
《docker高级篇(大厂进阶):2.DockerFile解析》包括:是什么、DockerFile构建过程解析、DockerFile常用保留字指令、案例、小总结
262 75
|
20天前
|
机器学习/深度学习 自然语言处理 搜索推荐
自注意力机制全解析:从原理到计算细节,一文尽览!
自注意力机制(Self-Attention)最早可追溯至20世纪70年代的神经网络研究,但直到2017年Google Brain团队提出Transformer架构后才广泛应用于深度学习。它通过计算序列内部元素间的相关性,捕捉复杂依赖关系,并支持并行化训练,显著提升了处理长文本和序列数据的能力。相比传统的RNN、LSTM和GRU,自注意力机制在自然语言处理(NLP)、计算机视觉、语音识别及推荐系统等领域展现出卓越性能。其核心步骤包括生成查询(Q)、键(K)和值(V)向量,计算缩放点积注意力得分,应用Softmax归一化,以及加权求和生成输出。自注意力机制提高了模型的表达能力,带来了更精准的服务。
|
2月前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
2月前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
2月前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
2月前
|
存储 物联网 大数据
探索阿里云 Flink 物化表:原理、优势与应用场景全解析
阿里云Flink的物化表是流批一体化平台中的关键特性,支持低延迟实时更新、灵活查询性能、无缝流批处理和高容错性。它广泛应用于电商、物联网和金融等领域,助力企业高效处理实时数据,提升业务决策能力。实践案例表明,物化表显著提高了交易欺诈损失率的控制和信贷审批效率,推动企业在数字化转型中取得竞争优势。
103 16
|
14天前
|
自然语言处理 数据处理 索引
mindspeed-llm源码解析(一)preprocess_data
mindspeed-llm是昇腾模型套件代码仓,原来叫"modelLink"。这篇文章带大家阅读一下数据处理脚本preprocess_data.py(基于1.0.0分支),数据处理是模型训练的第一步,经常会用到。
33 0
|
2月前
|
网络协议 安全 网络安全
探索网络模型与协议:从OSI到HTTPs的原理解析
OSI七层网络模型和TCP/IP四层模型是理解和设计计算机网络的框架。OSI模型包括物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,而TCP/IP模型则简化为链路层、网络层、传输层和 HTTPS协议基于HTTP并通过TLS/SSL加密数据,确保安全传输。其连接过程涉及TCP三次握手、SSL证书验证、对称密钥交换等步骤,以保障通信的安全性和完整性。数字信封技术使用非对称加密和数字证书确保数据的机密性和身份认证。 浏览器通过Https访问网站的过程包括输入网址、DNS解析、建立TCP连接、发送HTTPS请求、接收响应、验证证书和解析网页内容等步骤,确保用户与服务器之间的安全通信。
125 3
|
2月前
|
安全 搜索推荐 数据挖掘
陪玩系统源码开发流程解析,成品陪玩系统源码的优点
我们自主开发的多客陪玩系统源码,整合了市面上主流陪玩APP功能,支持二次开发。该系统适用于线上游戏陪玩、语音视频聊天、心理咨询等场景,提供用户注册管理、陪玩者资料库、预约匹配、实时通讯、支付结算、安全隐私保护、客户服务及数据分析等功能,打造综合性社交平台。随着互联网技术发展,陪玩系统正成为游戏爱好者的新宠,改变游戏体验并带来新的商业模式。
|
3月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
121 2

推荐镜像

更多