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 ...
随机推荐
- YII框架开发一个项目的通用目录结构:
testdrive/ index. assets/ css/ images/ themes/ yiic. commands/ ...
- 计算机BIOS的简单设置(要安装Linux需关闭Security Boot选项)
计算机BIOS的简单设置(要安装Linux需关闭Security Boot选项) 发布时间:2016-12-07 22:46:19来源:linux网站作者:乐百川 BIOS是什么 BIOS全称是基本输 ...
- Win7如何查看nvidia显卡(GPU)的利用率
1.在文件夹C:\Program Files\NVIDIA Corporation\NVSMI里找到文件nvidia-smi.exe2.把该文件拖到命令提示符窗口(win+R,再输入‘CMD’进入), ...
- FFT(快速傅里叶变换) 模板
洛谷 P3803 [模板]多项式乘法(FFT)传送门 存个板子,完全弄懂之后找机会再写个详解. #include<cstdio> #include<cmath> struct ...
- Coupled model
常见的coupled models phase English paper WRF-Chem mechanism public data 一些重要的结论 干空气的状态方程 ECWMF驱动WRF 常见的 ...
- [LC] 81. Search in Rotated Sorted Array II
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...
- async包 ES6 async/await的区别
最基本的async 包 ApCollection.find({}).toArray(function (err, aps) { var num = 0; async.whilst( function ...
- Docker的部署安装(CentOS)
环境准备 操作系统需求 为兼容企业级应用,学习选用Centos7做为部署安装Docker的系统平台 # 通过以下命令可查看系统版本和内核版本等信息 cat /etc/redhat-release #- ...
- [LC] 236. Lowest Common Ancestor of a Binary Tree
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...
- PHP常用接口数据过滤的方法
<?php /** * global.func.php 公共函数库 */ /** * 返回经addslashes处理过的字符串或数组 * @param $string 需要处理的字符串或数组 * ...