RestTemplate 负载均衡原理

RestTemplate负载均衡原理

RestTemplate为什么具有负载均衡的功能?

在使用了@LoadBalanced后,Spring容器在启动的时候会为被修饰过的RestTemplate添加拦截器,拦截器里会使用LoadBalanced相关的负载均衡接口来处理请求,通过这样一个间接的处理,会使原来的RestTemplate变得不是原来的RestTemplate了,就变的更NB了,因此具备了负载均衡的功能。
那么在这章的内容中呢,笔者将带大家实现一个很简单的LoadBalanced注解,为RestTemplate添加拦截器的这么一个过程,至于如何在拦截器中实现负载均衡的功能,这个还需探索。。。(如果各位道友知道如何实现,请告知一二,先感谢了)

引入web依赖:pom.xml

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.0.3.RELEASE</version>
    </dependency>
</dependencies>

自定义注解:MyLoadBalanced.java

/**
 * 修饰:域、参数、方法
 */
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
/**
 * 作用是定义被它所注解的注解保留多久,一共有三种策略,定义在RetentionPolicy枚举中
 * 1. SOURCE:被编译器忽略
 * 2. CLASS:注解将会被保留在Class文件中,但在运行时并不会被VM保留。这是默认行为,所有没有用Retention注解的注解,都会采用这种策略
 * 3. RUNTIME:保留至运行时。所以我们可以通过反射去获取注解信息。
 */
@Retention(RetentionPolicy.RUNTIME)
/**
 * 限定注解
 */
@Qualifier
public @interface MyLoadBalanced {

}

创建Controller:MyController.java

@RestController@Configuration
public class MyController {

    @Bean  // 将getRestTemplate修饰为Bean,交给spring管理
    @MyLoadBalanced  // 这里使用刚刚自定义的注解
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

创建配置类:Config.java

@Configuration
public class Config {

    @Autowired(required = false)// 非必须的,将那些被@MyLoadBalanced注解修饰过的对象,自动装配到tpls集合中
    @MyLoadBalanced
    private List<RestTemplate> tpls = Collections.emptyList();

    // 在spring容器启动之后,需要对每一个RestTemplate都要设置一个拦截器,拦截器里面会实现负载均衡的功能
    @Bean
    public SmartInitializingSingleton lbInitializing(){
        return new SmartInitializingSingleton() {
            @Override
            public void afterSingletonsInstantiated() {
                System.out.println("RestTemplate集合大小:"+tpls.size());
            }
        };
    }

}

下面我们创建一个启动类,看一看到底有没有自动装配成功:Application.java

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

如图,RestTemplate集合大小:1  说明,我们的配置生效了。。。。。。

下面我们创建一个自定义的拦截器:MyInterceptor.java  该拦截器需要实现 ClientHttpRequestInterceptor 接口

public class MyInterceptor implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        System.out.println("==================== 进入自定义拦截器");
        return null;
    }

}

现在自定义拦截器有了,那么我们就去修改一下配置类,让程序启动后,循环向每个被@MyLoadBalanced修饰过的RestTemplate添加拦截器,修改 Config.java 如下:

@Bean
public SmartInitializingSingleton lbInitializing(){
    return new SmartInitializingSingleton() {
        @Override
        public void afterSingletonsInstantiated() {
            for(RestTemplate rtl : tpls){
                // 为了防止覆盖默认拦截器,将默认拦截器取出
                List<ClientHttpRequestInterceptor> interceptors = rtl.getInterceptors();
                // 将自定义的拦截器加入到默认拦截器中
                interceptors.add(new MyInterceptor());
                // 给RestTemplate设置拦截器
                rtl.setInterceptors(interceptors);
            }
        }
    };
}

拦截器是用来拦截请求的,我们还需要在 MyController.java 中定义一个接口,用于调用测试,修改 MyController.java 如下:

@RequestMapping(value="/getPolice", method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE)
public String getPolice(){
    RestTemplate rtl = getRestTemplate();
    String result = rtl.getForObject("http://springCloud-ribbon-police/getPolice", String.class);
    return result;
}

下面,我们访问下接口,试试拦截器有没有配置成功,如图:

拦截器中输出了内容,那么就证明拦截器配置成功了。报错是因为在拦截器中返回了null,那我们现在就来解决这个问题。

在拦截器中暂时不实现负载均衡的功能,我们以跳转为例,给大家讲解。。。将旧请求进行修改,并返回一个新的请求。这样的话,就需要我们返回一个新的request对象。

创建 NewRequest.java 并实现 HttpRequest 接口:NewRequest.java

public class NewRequest implements HttpRequest{

    private HttpRequest sourceRequest;// 原请求request

    public NewRequest(HttpRequest sourceRequest){
        this.sourceRequest = sourceRequest;
    }

    @Override
    public HttpHeaders getHeaders() {
        return sourceRequest.getHeaders();
    }

    @Override
    public String getMethodValue() {
        return sourceRequest.getMethodValue();
    }

    @Override
    public URI getURI() {
        try {
            // 将拦截到的URI,修改为新的URI
            URI uri = new URI("http://localhost:9090/getPoliceById/123");
            return uri;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sourceRequest.getURI();
    }

}

下面修改一下我们自定义的拦截器:MyInterceptor.java

public class MyInterceptor implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        System.out.println("==================== 这是自定义拦截器");
        System.out.println("==================== 旧的URL:"+request.getURI());
        NewRequest newRequest = new NewRequest(request);
        System.out.println("==================== 新的URL:"+newRequest.getURI());
        return execution.execute(newRequest, body);
    }

}

我们再运行程序,得到如下结果:

再看一下页面返回的结果,完美实现拦截跳转:

OK,,,以上就是本章的全部内容了,一个简单的自定义注解、自定义拦截器,你 学会了吗!

原文地址:https://www.cnblogs.com/lpxdbk/p/9828837.html

时间: 2024-11-05 20:47:57

RestTemplate 负载均衡原理的相关文章

使用LVS实现负载均衡原理及安装配置详解

转:http://www.cnblogs.com/liwei0526vip/p/6370103.html 使用LVS实现负载均衡原理及安装配置详解 负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F5.Netscale.这里主要是学习 LVS 并对其进行了详细的总结记录. 一.负载均衡LVS基本介绍 LB集群的架构和原理很简单,就是当用户的请求过来时,会直接分发到Director

使用 LVS 实现负载均衡原理及安装配置详解

使用 LVS 实现负载均衡原理及安装配置详解 来源:肖邦linux 发布时间:2017-02-19 阅读次数:106 0 负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均衡设备F5.Netscale.这里主要是学习 LVS 并对其进行了详细的总结记录. 一.负载均衡LVS基本介绍 LB集群的架构和原理很简单,就是当用户的请求过来时,会直接分发到Director Server上,然后它把用

[转]f5负载均衡原理

f5负载均衡原理 一. 负载均衡技术 负载均衡技术在现有网络结构之上提供了一种廉价.有效.透明的方法,来扩展网络设备和服务器的带宽.增加吞吐量.加强网络数据处理能力.提高网络的灵活性和可用性. 1. 负载均衡发生的流程图: 1. 客户发出服务请求到VIP 2.BIGIP接收到请求,将数据包中目的IP地址改为选中的后台服务器IP地址,然后将数据包发出到后台选定的服务器 3. 后台服务器收到后,将应答包按照其路由发回到BIGIP 4.BIGIP收到应答包后将其中的源地址改回成VIP的地址,发回客户端

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

搞懂分布式技术9:Nginx负载均衡原理与实践 本篇摘自<亿级流量网站架构核心技术>第二章 Nginx负载均衡与反向代理 部分内容. 当我们的应用单实例不能支撑用户请求时,此时就需要扩容,从一台服务器扩容到两台.几十台.几百台.然而,用户访问时是通过如的方式访问,在请求时,浏览器首先会查询DNS服务器获取对应的IP,然后通过此IP访问对应的服务. 因此,一种方式是域名映射多个IP,但是,存在一个最简单的问题,假设某台服务器重启或者出现故障,DNS会有一定的缓存时间,故障后切换时间长,而且没有对

k8d创建资源(3)(负载均衡原理,回滚指定版本,label控制pod的位置)

Deployment介绍 Deployment是kubernetes 1.2引入的概念,用来解决Pod的编排问题.Deployment可以理解为RC的升级版(RC+Reolicat Set).特点在于可以随时知道Pod的部署进度,即对Pod的创建.调度.绑定节点.启动容器完整过程的进度展示. 使用场景 创建一个Deployment对象来生成对应的Replica Set并完成Pod副本的创建过程.检查Deployment的状态来确认部署动作是否完成(Pod副本的数量是否达到预期值).更新Deplo

06 RestTemplate负载均衡

本例将模仿拦截器机制,实现一个简单的ReatTemplate,以便更清楚地展示@LoadBalanced以及RestTemplate的原理. [email protected]注解概述 RestTemplate本是spring-web项目中的一个REST客户端,它遵循REST的设计原则,提供简单的API让我们去调用HTTP服务.RestTemplate本身并不具备负载均衡的功能,该类也与SpringCloud没有关系,但是为什么加入@LoadBalanced注解后,一个RestTemplate实

[转]Nginx负载均衡原理初解

什么是负载均衡 我们知道单台服务器的性能是有上限的,当流量很大时,就需要使用多台服务器来共同提供服务,这就是所谓的集群. 负载均衡服务器,就是用来把经过它的流量,按照某种方法,分配到集群中的各台服务器上.这样一来不仅可以承担 更大的流量.降低服务的延迟,还可以避免单点故障造成服务不可用.一般的反向代理服务器,都具备负载均衡的功能. 负载均衡功能可以由硬件来提供,比如以前的F5设备.也可以由软件来提供,LVS可以提供四层的负载均衡(利用IP和端口), Haproxy和Nginx可以提供七层的负载均

Tomcat负载均衡原理详解及配置

结构图 使用Tomcat的童鞋们注意了.为了增加tomcat的性能和稳定性,我们一般采用balance和session同步机制. 下图列出了我们常用也是最简单的解决方案. 说明 1 balance 负载均衡我们一般采用Apache proxy和Apache+mod_jk方式 所使用软件:Apache2.2.19 http://httpd.apache.org/download.cgi#apache22; Tomcat7          http://tomcat.apache.org/down

负载均衡原理

双机热备:有流量经过的设备即为主设备,为流量经过的设备即为备份设备 防火墙基于会话状态的数据同步:批量备份.实时备份批量备份:先运行的防火墙会将已有的会话表项一次性同步到加入的设备实时备份:保证表项完全一致,防火墙在产生新表项或表项变化后会及时备份到另一台设备上 双机热备:只支持数据同步.不支持配置同步 链路负载均衡:策略路由策略路由配置不方便,不够灵活,无法适应动态网络结构变化,策略路由无法根据带宽进行报文分发链路负载均衡通过动态算法,能够在多链路中进行负载均衡,算法配置简单,且具有自适应能力