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 ...
随机推荐
- Prefix and Suffix
题目描述 Snuke is interested in strings that satisfy the following conditions: The length of the string ...
- android电子书App、自定义图表、仿腾讯漫画App、仿淘宝优惠券、3D选择容器等源码
Android精选源码 仿支付宝记账本功能,饼状图:数字键盘 android一款功能完善的电子书应用源码 Android自定义图标库,使用方便,扩展性强 android 3D立体无限旋转容器源码 an ...
- python后端面试第五部分:Linux操作系统--长期维护
################## Linux操作系统 ####################### 1,讲一下你常用的Linux/git命令和作用: 2,查看当前进程是用什么命 ...
- [LC] 295. Find Median from Data Stream
Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...
- jQuery中的bind(), live(), on(), delegate()
当我们试图绑定一些事件到DOM元素上的时候,我相信上面这4个方法是最常用的.而它们之间到底有什么不同呢?在什么场合下用什么方法是最有效的呢? 准备知识: 当我们在开始的时候,有些知识是必须具备的: D ...
- 分布式Web服务器架构(通俗易通)
最开始,由于某些想法,于是在互联网上搭建了一个网站,这个时候甚至有可能主机都是租借的,但由于这篇文章我们只关注架构的演变历程,因此就假设这个时候已经是托管了一台主机,并且有一定的带宽了,这个时候由于网 ...
- 2017 ACM-ICPC, Universidad Nacional de Colombia Programming Contest K - Random Numbers (dfs序 线段树+数论)
Tamref love random numbers, but he hates recurrent relations, Tamref thinks that mainstream random g ...
- Hibernate中的对象图关系转换:游离、持久、自由状态
- Linux搭建nginx+php/php-fpm+mysql环境
百度内部php框架odp有单独的nginx+php/php-fpm环境,但为了更好的实践,自己搭建一套单独的. 1.首先安装nginx 两种方式: 1)yum源安装(使用root权限)yum inst ...
- TCP大文件发送案例以及UDP介绍
基于TCP的大文件发送 #server服务端 import struct import json import os import socket server = socket.socket() # ...