简介:
- 负载均衡框架,支持可插拔式的负载均衡规则
- 支持多种协议,如Http,UDP等
- 提供负载均衡的客户端(用在服务调用者client)
Ribbon子模块
ribbon-core
包括负载均衡,以及负载均衡规则都在这个包里
ribbon-eureka
为erurka客户端提供的负载均衡类
ribbon-httpclient
含有负载均衡功能的rest客户端
负载均衡器组件
1、一个负载均衡器,至少提供以下功能
要维护各个服务器的ip等信息
根据特定逻辑选取服务器
2、为了实现基本的负载均衡功能,Ribbon的负载均衡器有三大子模块
Rule:规则
Ping
ServerList
//ribbon的RestTemplate调用方式
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
@GetMappering("/router")
@ResponseBody
public String router(){
Restemplate tpl = getRestTemplate();
//调用方式: http://yml配置的服务id/方法名/参数
String json = tpl.getForObject("http://服务id/call/1",String.class);
}
模拟@LoadBalanced原理
@LoadBalanced注解通过拦截器来实现负载均衡
1、新建一个注解
package spring.cloud.spring_member.controller.locdbalaned;
import org.springframework.beans.factory.annotation.Qualifier;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义负载均衡的注解
*
* @param
* @return
* @date 2019-06-16 13:57
*/
@Target({ElementType.FIELD,ElementType.PARAMETER,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface MyLoadBalanced {
}
2、注册RestTemplate实例到容器中,并加上自定义的注解
package spring.cloud.spring_member.controller.locdbalaned;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.awt.*;
/**
* 类的描述 TODO
*
* @author wangwei
* @Date 2019-06-16 14:04
*/
@RestController
@Configuration
public class MyController {
@Bean
@MyLoadBalanced
RestTemplate tplA() {
return new RestTemplate();
}
@Bean
@MyLoadBalanced
RestTemplate tplB() {
return new RestTemplate();
}
@RequestMapping(value = "/call", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String call() {
RestTemplate tpl = tplA();
//被拦截器拦截,拦截器内部实现负载均衡
String json = tpl.getForObject("http://app-member-server/call", String.class);
return json;
}
}
3、自定义拦截器,可以可以写负载均衡逻辑,todo
package spring.cloud.spring_member.controller.locdbalaned;
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;
/**
* 自定义拦截器
*
* @author wangwei
* @Date 2019-06-16 14:08
*/
public class MyInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
System.out.println("=========自定义拦截器");
System.out.println("=========" + httpRequest.getURI());
//可以在这里写负载均衡逻辑代码
return null;
}
}
4、定义配置类,给tpls自动装配restTemplate,并且给restTemplate的拦截器增加自定义的拦截器
package spring.cloud.spring_member.controller.locdbalaned;
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;
import java.util.stream.Collectors;
/**
* 定义配置类,给restTemplate的拦截器增加自定义的拦截器
* @Date 2019-06-16 14:01
*/
@Configuration
public class MyConfig {
@Autowired(required = false)
@MyLoadBalanced
private List<RestTemplate> tpls = Collections.emptyList();
@Bean
public SmartInitializingSingleton Ibinitalizing() {
return new SmartInitializingSingleton() {
@Override
public void afterSingletonsInstantiated() {
System.out.println(tpls.size());
for(RestTemplate restTemplate : tpls){
List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
interceptors.add(new MyInterceptor());
restTemplate.setInterceptors(interceptors);
}
}
};
}
}