RestTemplate 负载均衡原理
RestTemplate 是通过拦截器改变请求的URI的方式来指定服务器的,此处将通过一个自定义LoadBalanced的方式来进行说明
1.导入jar包
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2.自定义 MyLoadBalanced 注解
import org.springframework.beans.factory.annotation.Qualifier;
import java.lang.annotation.*;
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface MyLoadBalanced {
}
3.编写配置类
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate; import java.util.Collections;
import java.util.List; @Configuration
public class MyConfig { @Autowired(required = false)
@MyLoadBalanced
private List<RestTemplate> tpls = Collections.emptyList(); @Bean
public SmartInitializingSingleton lbInitializing() {
return new SmartInitializingSingleton() {
@Override
public void afterSingletonsInstantiated() {
System.out.println("tpls 的数量:"+tpls.size());
for (RestTemplate tpl : tpls) {
List<ClientHttpRequestInterceptor> interceptors = tpl.getInterceptors();
interceptors.add(new MyInterceptor());
tpl.setInterceptors(interceptors);
} }
};
}
}
4.编写Controller测试接口 (访问 /getUser 可以发现执行的是自定义的 MyLoadBalanced 此处应该会报错,因为地址不存在,不过我们主要是为了测试是否会执行 MyLoadBalanced)
import com.idelan.ribbon.config.MyLoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; @RestController
@Configuration
public class MyController { @Bean
@MyLoadBalanced
public RestTemplate tplA() {
return new RestTemplate();
} @GetMapping(value = "/getUser")
public String getUser() {
RestTemplate restTemplate = tplA();
String json = restTemplate.getForObject("http://smart-platform-base/platform/base/getUser", String.class);
return json;
} @GetMapping(value = "/hello")
public String hello() {
return "hello world";
}
}
5.自定义拦截器来更改接口的访问地址 (@LoadBalanced 此处的逻辑会别我们复杂很多,我们只是简单模拟一下)
(1)自定义 Request 类
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest; import java.net.URI;
import java.net.URISyntaxException; public class MyRequest implements HttpRequest { HttpRequest httpRequest; public MyRequest(HttpRequest httpRequest) {
this.httpRequest = httpRequest;
} @Override
public HttpMethod getMethod() {
return httpRequest.getMethod();
} @Override
public String getMethodValue() {
return httpRequest.getMethodValue();
} @Override
public URI getURI() {
try {
URI newUri = new URI("http://localhost:8080/hello");
return newUri;
} catch (URISyntaxException e) {
e.printStackTrace();
}
return httpRequest.getURI();
} @Override
public HttpHeaders getHeaders() {
return httpRequest.getHeaders();
}
}
(2)自定义拦截器
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse; import java.io.IOException; public class MyInterceptor implements ClientHttpRequestInterceptor { @Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
System.out.println("~~~~~~~~自定义拦截器,uri:"+httpRequest.getURI());
System.out.println("旧的uri:"+httpRequest.getURI()); HttpRequest newRequest = new MyRequest(httpRequest);
System.out.println("新的uri:"+newRequest.getURI());
return clientHttpRequestExecution.execute(newRequest, bytes);
}
}
测试:可以通过访问 /getUser 接口来测试,最终会返回 /hello 接口的内容,因为我们更改了访问地址
RestTemplate 负载均衡原理的更多相关文章
- Nginx 负载均衡原理简介与负载均衡配置详解
Nginx负载均衡原理简介与负载均衡配置详解 by:授客 QQ:1033553122 测试环境 nginx-1.10.0 负载均衡原理 客户端向反向代理发送请求,接着反向代理根据某种负载机制 ...
- 六大Web负载均衡原理与实现
还有个姊妹篇也可以参考这个文章:LVS(Linus Virtual Server):三种负载均衡方式比较+另三种负载均衡方式, LVS 实现了负载均衡,NAT,DR,TUN zookeeper使用ZA ...
- 搞懂分布式技术9:Nginx负载均衡原理与实践
搞懂分布式技术9:Nginx负载均衡原理与实践 本篇摘自<亿级流量网站架构核心技术>第二章 Nginx负载均衡与反向代理 部分内容. 当我们的应用单实例不能支撑用户请求时,此时就需要扩容, ...
- (转)使用LVS实现负载均衡原理及安装配置详解
使用LVS实现负载均衡原理及安装配置详解 原文:https://www.cnblogs.com/liwei0526vip/p/6370103.html
- Zookeeper实现负载均衡原理
先玩个正常的,好玩的socket编程: 服务端: 首先公共的这个Handler: package com.toov5.zkDubbo; import java.io.BufferedReader; i ...
- LVS实现负载均衡原理及安装配置
LVS实现负载均衡原理及安装配置 负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F ...
- 使用Zookeeper实现负载均衡原理
思路 使用Zookeeper实现负载均衡原理,服务器端将启动的服务注册到,zk注册中心上,采用临时节点.客户端从zk节点上获取最新服务节点信息,本地使用负载均衡算法,随机分配服务器. 创建项目工程 M ...
- 【Zookeeper】实现负载均衡原理
一.思路 使用Zookeeper实现负载均衡原理,服务器端将启动的服务注册到,zk注册中心上,采用临时节点.客户端从zk节点上获取最新服务节点信息,本地使用负载均衡算法,随机分配服务器. 服务端启动的 ...
- LVS实现负载均衡原理及安装配置 负载均衡
LVS实现负载均衡原理及安装配置 负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F ...
随机推荐
- mysql远程导出
D:\phpStudy\PHPTutorial\MySQL\bin>mysqldump -h192.168.1.1 -u用户名 -p密码 --default-character-set=utf8 ...
- android完整资讯App、Kotlin新闻应用MVP + RxJava + Retrofit + Dagger2、优雅区间选择器等源码
Android精选源码 Android完整资讯客户端源码 android展示注册进度效果源码 Android Wifi热点数据传输Socket 通信示例源码 Android Dota的辅助信息app源 ...
- PolarDB阿里初赛问题记录 PolarDB 阿里 中间件 比赛 性能 工程手册
Contents 这篇纯碎是碎碎念记录. 每个value都是4KB,总共最多会写6400W个value,算下来就是64 * 1000 * 1000 * 4 * 1024 Bytes ≈ 256G. 每 ...
- Kafka、RabbitMQ、RocketMQ、ActiveMQ
一.资料文档 Kafka:中.有kafka作者自己写的书,网上资料也有一些.rabbitmq:多.有一些不错的书,网上资料多.zeromq:少.没有专门写zeromq的书,网上的资料多是一些代码的实现 ...
- 康耐视软件VisionPro-max-u与VisionPro-plus-u的区别
康耐视软件VisionPro-max-u与VisionPro-plus-u的区别 1.VisionPro-plus-u为基础版可以直接运用该软件包的算法,拖拽式的窗口程序 2.VisionPro-ma ...
- Null Hypotheses| Alternative Hypotheses|Hypothesis Test|Significance Level|two tailed |one tailed|
9.1 The Nature of Hypothesis Testing Over the years, however, null hypothesis has come to mean simpl ...
- mysqli存储过程
<?php$link = mysqli_connect('localhost','root','','chinatupai'); $sql = "call getEmail('000 ...
- python中sort和sorted排序的相关方法
Python list内置sort()方法用来排序,也可以用python内置的全局sorted()方法来对可迭代的序列排序生成新的序列. 1)排序基础 简单的升序排序是非常容易的.只需要调用sorte ...
- C++中字符串的表示与转换
转换总结 1.char*转string:可以直接赋值. 2.char[]转string:可以直接赋值. 3.char*转char[]:不能直接赋值,可以循环char*字符串逐个字符赋值,也可以使用st ...
- Oracle之函数中使用游标
create or replace function getcustprodinstaddr(in_CustId in number,in_area_code in number) return va ...