当前位置:网站首页>Microservice practice | teach you to develop load balancing components hand in hand
Microservice practice | teach you to develop load balancing components hand in hand
2022-07-02 09:10:00 【_ Time boiled the rain】
Last one Micro service practice | The original ecosystem realizes the discovery and invocation of services
Preface
In the last article, we realized the discovery and invocation of services in an original way , But in a clustered environment , The purpose of load balancing is not achieved , This article , We will write our own load balancer , To realize the load balancing function of service invocation .
Custom load balancing
review
First , Let's first review the code in the last article :
@GetMapping("/hello")
public String hello(String name) {
List<ServiceInstance> list = discoveryClient.getInstances("provider");
ServiceInstance instance = list.get(0);
String host = instance.getHost();
int port = instance.getPort();
String returnInfo = restTemplate.getForObject("http://" + host + ":" + port + "/hello?name={1}", String.class, name);
return returnInfo;
}
Let's go through discoveryClient Got one of the services of the registry ip And port , And then use restTemplate Call its getForObjec() Method to call the interface .
By tracing the source code of this method , We find that it will eventually be called doExecute() Method , Source code is as follows :
@Nullable
protected <T> T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor) throws RestClientException {
Assert.notNull(url, "URI is required");
Assert.notNull(method, "HttpMethod is required");
ClientHttpResponse response = null;
Object var14;
try {
ClientHttpRequest request = this.createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
response = request.execute();
this.handleResponse(url, method, response);
var14 = responseExtractor != null ? responseExtractor.extractData(response) : null;
} catch (IOException var12) {
String resource = url.toString();
String query = url.getRawQuery();
resource = query != null ? resource.substring(0, resource.indexOf(63)) : resource;
throw new ResourceAccessException("I/O error on " + method.name() + " request for \"" + resource + "\": " + var12.getMessage(), var12);
} finally {
if (response != null) {
response.close();
}
}
return var14;
}
Then can we inherit RestTemplate class , And rewrite doExecute Method , stay doExecute Call in method createRequest Change it before ?
Load balancing
First create our own RestTemplate, Name it MyRestTemplate.java, Examples are as follows :
/** * Custom load balancer * @Author: official account : The programmer 965 * @create 2022-06-06 **/
public class MyRestTemplate extends RestTemplate {
private DiscoveryClient discoveryClient;
public MyRestTemplate (DiscoveryClient discoveryClient) {
this.discoveryClient = discoveryClient;
}
/** * Interface call * @Author: official account : The programmer 965 * @create 2022-06-06 **/
protected <T> T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback,
@Nullable ResponseExtractor<T> responseExtractor) throws RestClientException {
Assert.notNull(url, "URI is required");
Assert.notNull(method, "HttpMethod is required");
ClientHttpResponse response = null;
try {
System.out.println(" Before replacement url :"+url.toString());
url = replaceUrl(url);
System.out.println(" After replacement url :"+url.toString());
ClientHttpRequest request = createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
response = request.execute();
handleResponse(url, method, response);
return (responseExtractor != null ? responseExtractor.extractData(response) : null);
}
catch (IOException ex) {
String resource = url.toString();
String query = url.getRawQuery();
resource = (query != null ? resource.substring(0,resource.indexOf('?')) : resource);
throw new ResourceAccessException("I/O error on " + method.name() +
" request for \"" + resource + "\": " + ex.getMessage(), ex);
} finally {
if (response != null) {
response.close();
}
}
}
/** * Replace url * @Author: official account : The programmer 965 * @create 2022-06-06 **/
private URI replaceUrl(URI url){
String sourceUrl = url.toString();
String [] httpUrl = sourceUrl.split("//");
int index = httpUrl[1].replaceFirst("/","@").indexOf("@");
String serviceName = httpUrl[1].substring(0,index);
List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances(serviceName);
// Adopt random algorithm , Get one of the service information
Random random = new Random();
Integer randomIndex = random.nextInt(serviceInstanceList.size());
String serviceIp = serviceInstanceList.get(randomIndex).getUri().toString();
String targetSource = httpUrl[1].replace(serviceName,serviceIp);
try {
return new URI(targetSource);
} catch (URISyntaxException e) {
e.printStackTrace();
}
return url;
}
}
stay doExecute In the method , call createRequest Before method , We added a line replaceUrl() Method call , In this method , We analyze Url, Get the service name , Then still get the service information list according to the service name , And through random algorithm , Return the... Of one of the services in the service information list uri And back to , Realize the load balancing of random algorithm .
Interface call
Come back to , Let's modify the call point of the interface , First restTemplate Instead, create our customized MyRestTemplate:
@Bean
RestTemplate restTemplate(DiscoveryClient discoveryClient) {
return new MyRestTemplate(discoveryClient);
}
Then modify the interface , Change the interface address directly to call with the service name :
@GetMapping("/hello2")
public String hello2(String name) {
String returnInfo = restTemplate.getForObject( "http://provider/hello?name={1}", String.class, name);
return returnInfo;
}
Start debugging

The successful running , Our results are returned correctly !
Now , There may be questions : Get one at random directly at the interface call ip Just call the port ? Why bother to pick up the source code and then inherit RestTemplate Class and override its doExecute Methods? ? Isn't that a bit of a fuss ?
friends ? think about it , Why do that ? This problem will be left to us when we use the load balancing component .
summary
In this paper , We use random algorithm to realize the function of load balancing , Of course, you can also implement polling as needed , Various load algorithms such as weight . Have you learned ?
边栏推荐
- Qt的拖动事件
- 「Redis源码系列」关于源码阅读的学习与思考
- Complete solution of servlet: inheritance relationship, life cycle, container, request forwarding and redirection, etc
- 微服务实战|声明式服务调用OpenFeign实践
- oracle删除表空间及用户
- Pdf document of distributed service architecture: principle + Design + practice, (collect and see again)
- QT -- how to set shadow effect in QWidget
- Avoid breaking changes caused by modifying constructor input parameters
- Finishing the interview essentials of secsha system!!!
- [go practical basis] how to bind and use URL parameters in gin
猜你喜欢
![[go practical basis] how to customize and use a middleware in gin](/img/fb/c0a4453b5d3fda845c207c0cb928ae.png)
[go practical basis] how to customize and use a middleware in gin

What is the future value of fluorite mine of karaqin Xinbao Mining Co., Ltd. under zhongang mining?

「Redis源码系列」关于源码阅读的学习与思考

Linux binary installation Oracle database 19C

C language - Blue Bridge Cup - 7 segment code

Complete solution of servlet: inheritance relationship, life cycle, container, request forwarding and redirection, etc

Programmers with ten years of development experience tell you, what core competitiveness do you lack?

盘点典型错误之TypeError: X() got multiple values for argument ‘Y‘

Minecraft install resource pack

Sentinel reports failed to fetch metric connection timeout and connection rejection
随机推荐
oracle删除表空间及用户
[go practical basis] how to set the route in gin
微服务实战|手把手教你开发负载均衡组件
Use of libusb
Qt的connect函数和disconnect函数
History of Web Technology
Judge whether it is Sudoku
C call system sound beep~
微服务实战|微服务网关Zuul入门与实战
机器学习之数据类型案例——基于朴素贝叶斯法,用数据辩男女
C # save web pages as pictures (using WebBrowser)
Redis zadd导致的一次线上问题排查和处理
「面试高频题」难度大 1.5/5,经典「前缀和 + 二分」运用题
远程连接IBM MQ报错AMQ4036解决方法
Programmers with ten years of development experience tell you, what core competitiveness do you lack?
Jd.com interviewer asked: what is the difference between using on or where in the left join association table and conditions
[staff] common symbols of staff (Hualian clef | treble clef | bass clef | rest | bar line)
Sentinel reports failed to fetch metric connection timeout and connection rejection
"Redis source code series" learning and thinking about source code reading
Installing Oracle database 19C RAC on Linux