当前位置:网站首页>Microservice practice | load balancing component and source code analysis
Microservice practice | load balancing component and source code analysis
2022-07-02 09:10:00 【_ Time boiled the rain】
Last one Micro service practice | Teach you how to develop load balancing components
List of articles
Preface
In the last article, we developed a load balancing component by ourselves , Realize the load balancing function of random algorithm , If you want to implement other algorithms , You also need to modify the code to add corresponding functions . This article , We will introduce a simpler implementation of load balancing , Use **@LoadBalanced** Annotation realizes the function of load balancing .
Project practice
Create project
alike , Our project still has one registry Registry Center , One provider Service providers , Next , Let's revise it again consumer Service consumer code :
/** * @Author: official account : The programmer 965 * @create 2022-06-06 **/
@EnableEurekaClient
@SpringBootApplication
@RestController
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
@Autowired
DiscoveryClient discoveryClient;
@Autowired
RestTemplate restTemplate;
@GetMapping("/hello2")
public String hello2(String name) {
String returnInfo = restTemplate.getForObject( "http://provider/hello?name={1}", String.class, name);
return returnInfo;
}
}
In this version , alike , Or create RestTemplate Bean object , The difference is that the above only increases @LoadBalanced annotation .
Start project validation

It still returns the result correctly !
It's amazing , It's much simpler than the load balancing component we developed ourselves , Only in the restTemplate() A method is added above @LoadBalanced annotation , How can it be achieved ? Nonsense , To find out , Pick up the source code !
Source code analysis
First , Click on @LoadBalanced Comment in , Nothing special , So we are thinking ,Spring Creating Bean At instance time , Where does annotation work ? what ? I do not know! ? Turn to this article :
Liver for two weeks , A picture unlocks Spring Core source code
By reviewing Spring Start up and Bean Life cycle creation process , We will find that add @LoadBalancer After the note , When the project starts, it will load LoadBalancerAutoConfiguration This configuration class ( adopt spring-cloud-commons Under the bag spring.factories). Check the source code of this configuration class , It is found that it has a static inner class LoadBalancerInterceptorConfig, A load balancing interceptor is created inside :LoadBalancerInterceptor, The interceptor contains a loadBalancerClient Parameters :
@ConditionalOnMissingClass({
"org.springframework.retry.support.RetryTemplate"})
static class LoadBalancerInterceptorConfig {
LoadBalancerInterceptorConfig() {
}
@Bean
public LoadBalancerInterceptor ribbonInterceptor(LoadBalancerClient loadBalancerClient, LoadBalancerRequestFactory requestFactory) {
return new LoadBalancerInterceptor(loadBalancerClient, requestFactory);
}
@Bean
@ConditionalOnMissingBean
public RestTemplateCustomizer restTemplateCustomizer(final LoadBalancerInterceptor loadBalancerInterceptor) {
return (restTemplate) -> {
List<ClientHttpRequestInterceptor> list = new ArrayList(restTemplate.getInterceptors());
list.add(loadBalancerInterceptor);
restTemplate.setInterceptors(list);
};
}
}
Let's continue to click LoadBalancerInterceptor Class entry , Find out intercept Method , The method is called LoadBalancerClient Of execute Method ,
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {
URI originalUri = request.getURI();
String serviceName = originalUri.getHost();
Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));
}
LoadBalancerClient It's an interface , Click in and we find that its implementation class is RibbonLoadBalancerClient, View its inheritance relationship :
Through the method name in the interface , We can guess ,choose The method is to select one of the services in the list ,reconstructURI The method is to reconstruct the request URI.
Choose services
choose The method is in RibbonLoadBalancerClient Implement
public ServiceInstance choose(String serviceId, Object hint) {
Server server = this.getServer(this.getLoadBalancer(serviceId), hint);
return server == null ? null : new RibbonLoadBalancerClient.RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server));
}
In this method , First call getServer Method get service , This method will eventually call ILoadBalancer Interface chooseServer Method , and ILoadBalancer The implementation class of the interface defaults to ZoneAwareLoadBalancer.
ZoneAwareLoadBalancer Inherited from DynamicServerListLoadBalancer , And in the DynamicServerListLoadBalancer In the construction method of , Called this.restOfInit(clientConfig); stay restOfInit In this method , adopt this.updateListOfServers() To get the list of services ;
And in the chooseServer () In the method , According to the load balancing algorithm , Select one of the services and return :
BaseLoadBalancer zoneLoadBalancer = this.getLoadBalancer(zone);
server = zoneLoadBalancer.chooseServer(key);
Address replacement
Select one of the service information , How to change the interface from http://provider/hello Turn into http://localhost:8003/hello Well ? Remember what we said above reconstructURI Methods? ? By configuring the class LoadBalancerAutoConfiguration After loading , It will inject LoadBalancerInterceptor Interceptor , The interceptor will intercept our request , And process the request address , The specific implementation of the refactoring method is LoadBalancerContext Class reconstructURIWithServer In the method
public URI reconstructURIWithServer(Server server, URI original) {
String host = server.getHost();
int port = server.getPort();
String scheme = server.getScheme();
if (host.equals(original.getHost()) && port == original.getPort() && scheme == original.getScheme()) {
return original;
} else {
if (scheme == null) {
scheme = original.getScheme();
}
if (scheme == null) {
scheme = (String)this.deriveSchemeAndPortFromPartialUri(original).first();
}
try {
StringBuilder sb = new StringBuilder();
sb.append(scheme).append("://");
if (!Strings.isNullOrEmpty(original.getRawUserInfo())) {
sb.append(original.getRawUserInfo()).append("@");
}
sb.append(host);
if (port >= 0) {
sb.append(":").append(port);
}
sb.append(original.getRawPath());
if (!Strings.isNullOrEmpty(original.getRawQuery())) {
sb.append("?").append(original.getRawQuery());
}
if (!Strings.isNullOrEmpty(original.getRawFragment())) {
sb.append("#").append(original.getRawFragment());
}
URI newURI = new URI(sb.toString());
return newURI;
} catch (URISyntaxException var8) {
throw new RuntimeException(var8);
}
}
}
You can see that in this method , Send the original request address original, Replaced by the selected service IP And port . And finally call the interface method of the service .
See here , Think about the content of our last chapter , Is it the same as the same ?
summary
By adding @LoadBalanced annotation , It simply realizes the function of load balancing , Is not so much Ribbon A powerful , than Spring A powerful ,Spring Throughout the context creation process , Open one interface after another at different times , This provides traversal for the inheritance of various components , At the same time, it also further promotes Spring The rapid development of Ecology .
边栏推荐
- C language implementation of mine sweeping game
- Introduction to the basic concept of queue and typical application examples
- C Baidu map, Gaode map, Google map (GPS) longitude and latitude conversion
- 远程连接IBM MQ报错AMQ4036解决方法
- Mysql安装时mysqld.exe报`应用程序无法正常启动(0xc000007b)`
- 1、 QT's core class QObject
- Avoid breaking changes caused by modifying constructor input parameters
- Ora-12514 problem solving method
- 分布式服务架构精讲pdf文档:原理+设计+实战,(收藏再看)
- C4D quick start tutorial - Chamfer
猜你喜欢

C4D quick start tutorial - Chamfer
![[go practical basis] how to bind and use URL parameters in gin](/img/63/84717b0da3a55d7fda9d57c8da2463.png)
[go practical basis] how to bind and use URL parameters in gin

数构(C语言--代码有注释)——第二章、线性表(更新版)
![[staff] the lines and spaces of the staff (the nth line and the nth space in the staff | the plus N line and the plus N space on the staff | the plus N line and the plus N space below the staff | the](/img/dc/c0ea188ef353ded86759dbe9b29df3.jpg)
[staff] the lines and spaces of the staff (the nth line and the nth space in the staff | the plus N line and the plus N space on the staff | the plus N line and the plus N space below the staff | the

Qt——如何在QWidget中设置阴影效果

Talk about the secret of high performance of message queue -- zero copy technology

commands out of sync. did you run multiple statements at once

Avoid breaking changes caused by modifying constructor input parameters

C language - Blue Bridge Cup - 7 segment code
![[go practical basis] gin efficient artifact, how to bind parameters to structures](/img/c4/44b3bda826bd20757cc5afcc5d26a9.png)
[go practical basis] gin efficient artifact, how to bind parameters to structures
随机推荐
一篇详解带你再次重现《统计学习方法》——第二章、感知机模型
概率还不会的快看过来《统计学习方法》——第四章、朴素贝叶斯法
Right click menu of QT
【Go实战基础】gin 如何绑定与使用 url 参数
Win10 uses docker to pull the redis image and reports an error read only file system: unknown
Minecraft install resource pack
win10使用docker拉取redis镜像报错read-only file system: unknown
Essay: RGB image color separation (with code)
ORA-12514问题解决方法
NPOI 导出Word 字号对应
盘点典型错误之TypeError: X() got multiple values for argument ‘Y‘
Minecraft plug-in service opening
[go practical basis] how to set the route in gin
oracle删除表空间及用户
[staff] time mark and note duration (staff time mark | full note rest | half note rest | quarter note rest | eighth note rest | sixteenth note rest | thirty second note rest)
CSDN Q & A_ Evaluation
概念到方法,绝了《统计学习方法》——第三章、k近邻法
图像变换,转置
Gocv image cutting and display
统计字符串中各类字符的个数