- Spring Cloud Ribbon是一个基于http和tcp的客户端负载均衡器,是基于Netflix Ribbon实现的。在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http Restful的。Spring Cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign。
- Ribbon是一个服务调用组件,并且是一个客户端实现负载均衡的处理的组件。
一、客户单负载均衡和服务端负载均衡
1、服务端负载均衡
-
通常我们说的负载均衡是指服务端负载均衡,包括软件负载均衡和硬件负载均衡。常用服务端负载均衡架构:
服务端服务均衡架构图 - 在服务端负载均衡中,会通过某种手段维护一份可用的服务端清单,然后通过心跳检查的机制来剔除失效不可用的服务端节点。当客户端发送请求到负载均衡器时候,负载均衡器会按某种负载均衡算法从维护的可用服务器清单中取出一台服务器的地址,进行转发。
2、客户端负载均衡
-
客户端负载均衡和服务端负载均衡最大的区别在于服务清单所存储的位置。在客户端负载均衡中,所有的客户端节点都有一份自己要访问的服务端清单,这些清单统统都是从服务注册中心(比如eureka)获取的。
Ribbon客户端负载均衡架构图 - 在微服务架构中使用Ribbon作为客户端负载均衡调用步骤
1、服务提供者,启动多个应用实例并注册到 注册中心
2、服务消费者直接通过调用被@LoaderBalance注解修饰过的RestTemplate来实现服务接口的调用。
二、RestTemplate详解
- RestTemplate是一个http请求的客户端工具,它不是类似HttpClient的东东,也不是类似Jackson,jaxb等工具,但它封装了这些工具.RestTemplate是Spring 调用http的client端核心类.顾名思义,与其它template类如JdbcTemplate一样,它封装了与http server的通信的细节,使调用端无须关心http接口响应的消息是什么格式,统统使用Java pojo来接收请求结果.它主要做了以下事情:
封装并屏蔽了http通信细节
组装Http请求参数
抽取结果并转成调用端指定的Java pojo对象
屏蔽了不同消息格式的差异化处理
- 在http通信的底层,它默认采用的是Jdk的标准设施,当然你也可以切换成其它的http类库 例如ApacheHttpComponents,Netty, andOkHttp等.,RestTemplate这个类是用在同步调用上的,异步调用请移步AsyncRestTemplate
1、Restful API
(1)get
api:
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType)
//返回String对象
ResponseEntity<String> strResults = restTemplate.getForEntity("domain/user?name={1}",
String.class, "qiu");
// Map<String,Object> params=new HashMap<>();
// params.put("name","qiu" );
// ResponseEntity<String> strResults = restTemplate.getForEntity("domain/user?name={name}",
// String.class, params);
String body=strResults.getBody();
//返回user对象
ResponseEntity<User> userResult = restTemplate.getForEntity("domain/user?name={1}",
User.class, "qiu");
User user=userResult.getBody();
(2)post
- 和get不同的是,方法中多了一个request对象,该参数是一个普通对象,也可以是一个httpentity对象。如果是一个普通对象,resttemplate会将请求转为httpentity对象处理,request的内容会被视作为完成的body来处理;如果是httpentity对象,就会当做一个完整的http请求来处理,不仅包括body还包括header等内容。
api:
public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request,Class<T> responseType, Object... uriVariables)
public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request,Class<T> responseType, Map<String, ?> uriVariables)
public <T> ResponseEntity<T> postForEntity(URI url, @Nullable Object request, Class<T> responseType)
2、restTemplate简单使用配置
@Configuration
public class RestConfiguration {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate(simpleClientHttpRequestFactory());
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
//设置超时时间
factory.setReadTimeout(5000);//ms
factory.setConnectTimeout(15000);//ms
return factory;
}
}
3、restTemplate一些高级应用(替换底层连接、配置转换器、配置拦截器等等)
https://www.jianshu.com/p/b4e479a6f5a8
https://www.xncoding.com/2017/07/06/spring/sb-restclient.html
https://blog.csdn.net/w05980598/article/details/79166507
三、Ribbon负载均衡策略
- 在Ribbon中使用AbastractBalanceRule作为负载均衡的抽象类。在该类中,定义了ILoaderBalancer对象,该对象能够在具体实现服务策略时候,获取一些负载均衡中维护的信息作为分配依据,并以此设计一些算法来实现针对特定场景的 高效策略。
策略名 | 策略声明 | 策略描述 | 实现说明 |
---|---|---|---|
BestAvailableRule | public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule | 选择一个最小的并发请求的server | 逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server |
ZoneAvoidanceRule | public class ZoneAvoidanceRule extends PredicateBasedRule | 复合判断server所在区域的性能和server的可用性选择server | 使 用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个 zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的 Server。 |
RandomRule | public class RandomRule extends AbstractLoadBalancerRule | 随机选择一个server | 该策略实现了从服务实例清单中随机选择一个服务实例的功能。 |
RoundRobinRule | public class RoundRobinRule extends AbstractLoadBalancerRule | roundRobin方式轮询选择server | 该策略实现了按照线性轮询的方式依次选择每个服务实例的功能。 |
WeightedResponseTimeRule | public class WeightedResponseTimeRule extends RoundRobinRule | 根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。 | 一 个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成statas时,使用roubine策略选择 server。 |
RetryRule | public class RetryRule extends AbstractLoadBalancerRule | 对选定的负载均衡策略机上重试机制。 | 在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server |
四、Ribbon配置使用
1、默认实现
- 由于Ribbon中定义的每 一个接口都有多种不同的策略实现,同时这些接口之间又有 一定的 依赖关系,这使得第 一次使用rbbion的开发者很难上手,不知道如何选择具体的实现策略以及如何组织它们 的关系。 Spring Cloud ribbon中的自动化配置恰恰 能够解决这样的痛点,在引入Spring Cloud Ribbon的 依赖之后, 就能够自动化构建下面这些接口的实现。
com.netflix.client.config.IClientConfig:Ribbon的客户端配置,默认采用com.netflix.client.config.DefaultClientConfigImpl实现。
com.netflix.loadbalancer.IRule:Ribbon的负载均衡策略,默认采用com.netflix.loadbalancer.ZoneAvoidanceRule实现,该策略能够在多区域环境下选出最佳区域的实例进行访问。
com.netflix.loadbalancer.IPing:Ribbon的实例检查策略,默认采用com.netflix.loadbalancer.NoOpPing实现,该检查策略是一个特殊的实现,实际上它并不会检查实例是否可用,而是始终返回true,默认认为所有服务实例都是可用的。
com.netflix.loadbalancer.ServerList:服务实例清单的维护机制,默认采用com.netflix.loadbalancer.ConfigurationBasedServerList实现。
com.netflix.loadbalancer.ServerListFilter:服务实例清单过滤机制,默认采org.springframework.cloud.netflix.ribbon.ZonePreferenceServerListFilter,该策略能够优先过滤出与请求方处于同区域的服务实例。
com.netflix.loadbalancer.ILoadBalancer:负载均衡器,默认采用com.netflix.loadbalancer.ZoneAwareLoadBalancer实现,它具备了区域感知的能力。
2、自定义配置文件(全局)
@Configuration
public class ConfigBeans {
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
/**自定义配置ribbon负载均衡算法
* @return
*/
@Bean
public IRule myRule(){
//return new RoundRobinRule();//轮询
//return new RetryRule();//重试
return new BestAvailableRule();
}
}
3、针对某一个服务调用私人定制
- 如果要自定义Ribbon配置, 则需要把这个配置类放在@SpringBootApplication扫不到的包中(@ComponentScan),因为如果可以扫到自定义的Ribbon配置类的话,那么会对所有的Riboon都生效,也就是说这种情况下所有的微服务的负载均衡算法都是相同的。
https://blog.csdn.net/u010816545/article/details/80461957
4、脱离eureka使用
#取消Ribbon使用Eureka
ribbon.eureka.enabled=false
#配置Ribbon能访问 的微服务节点,多个节点用逗号隔开
microservice-provider-user.ribbon.listOfServers=localhost:8001,localhost:8002
网友评论