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 负载均衡原理的更多相关文章

  1. Nginx 负载均衡原理简介与负载均衡配置详解

    Nginx负载均衡原理简介与负载均衡配置详解   by:授客  QQ:1033553122   测试环境 nginx-1.10.0 负载均衡原理 客户端向反向代理发送请求,接着反向代理根据某种负载机制 ...

  2. 六大Web负载均衡原理与实现

    还有个姊妹篇也可以参考这个文章:LVS(Linus Virtual Server):三种负载均衡方式比较+另三种负载均衡方式, LVS 实现了负载均衡,NAT,DR,TUN zookeeper使用ZA ...

  3. 搞懂分布式技术9:Nginx负载均衡原理与实践

    搞懂分布式技术9:Nginx负载均衡原理与实践 本篇摘自<亿级流量网站架构核心技术>第二章 Nginx负载均衡与反向代理 部分内容. 当我们的应用单实例不能支撑用户请求时,此时就需要扩容, ...

  4. (转)使用LVS实现负载均衡原理及安装配置详解

    使用LVS实现负载均衡原理及安装配置详解 原文:https://www.cnblogs.com/liwei0526vip/p/6370103.html

  5. Zookeeper实现负载均衡原理

    先玩个正常的,好玩的socket编程: 服务端: 首先公共的这个Handler: package com.toov5.zkDubbo; import java.io.BufferedReader; i ...

  6. LVS实现负载均衡原理及安装配置

    LVS实现负载均衡原理及安装配置 负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F ...

  7. 使用Zookeeper实现负载均衡原理

    思路 使用Zookeeper实现负载均衡原理,服务器端将启动的服务注册到,zk注册中心上,采用临时节点.客户端从zk节点上获取最新服务节点信息,本地使用负载均衡算法,随机分配服务器. 创建项目工程 M ...

  8. 【Zookeeper】实现负载均衡原理

    一.思路 使用Zookeeper实现负载均衡原理,服务器端将启动的服务注册到,zk注册中心上,采用临时节点.客户端从zk节点上获取最新服务节点信息,本地使用负载均衡算法,随机分配服务器. 服务端启动的 ...

  9. LVS实现负载均衡原理及安装配置 负载均衡

    LVS实现负载均衡原理及安装配置 负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F ...

随机推荐

  1. Image.FromStream(ms) 提示参数无效

    说明ms有问题,首先确保有读到数据,这种情况是保存到库的时候出错的. 原来你可能是这样写的: MemoryStream stream = new MemoryStream();PictureBox1. ...

  2. python3下scrapy爬虫(第十二卷:解决scrapy数据存储大量数据时阻塞问题)

    之前我们使用scrapy爬取数据,用的存储方式是直接引入PYMYSQL,或者MYSQLDB,案例中数据量并不大,这种数据存储方式属于同步过程,也就是上一条语句执行完才能执行下一条语句,当数据量变大时, ...

  3. [C#] 动态指定泛型类型

    前言 今天为了程序能写好看一点,一直在纠结怎么指定动态泛型, 但是想想实用性好像不太大,可是把这技术忘掉太可惜XD 还是记录下来,以防忘记 以下程序范例 类 cs 123456789101112131 ...

  4. [LC] 139. Word Break

    Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine ...

  5. java第二节课 java语法基础动手动脑

    动手动脑1:枚举变量   运行EnumTest.java package test2; public class EnumTest {  public static void main(String[ ...

  6. worship|spurs|drowns out|frauds|expell|spray with|deposit|moist|gave a sigh

    to have or show a strong feeling of respect and admiration for God or a god 敬奉,崇拜,信仰(上帝或神) On the is ...

  7. zoj2588-tarjan求桥/割边

    tarjan求桥,算法流程详见核心代码: void tarjan(int k){ dfn[k]=low[k]=++cnt; //fa[k]=(edge){f,0,fid}; for(int i=hea ...

  8. python学习笔记(4)数据类型-元组

    元组其实和列表一样,不一样的是,元组的值不能改变,一旦创建,就不能再改变了,比如说,要存数据库的连接信息,这个连接信息在程序运行中是不能被改变的,如果变了那数据库连不上了,就程序就完犊子了,这样的就可 ...

  9. 一致性 hash 算法( consistent hashing )及java实现

    consistent hashing 算法早在 1997 年就在论文 Consistent hashing and random trees 中被提出,目前在cache 系统中应用越来越广泛: 1 基 ...

  10. asp.net mvcview界面does not contain a definition

    在cshtml使用linq操作数据集,自动补全是可以使用Select,但是一直提示System.Collection.GenericList' does not contain a definitio ...