Spring Cloud
知识点:
- Ribbon介绍(3点)
- 使用方法
- 开发公司开发公司负载均衡策略和自定义负载均衡策略
- Ping机制
- Ribbon配置
1、介绍
Spring Cloud Ribbon 开发公司是一套基于 Ribbon 开发公司实现的客户端负载均衡开发公司和服务调用工具。通过Spring Cloud的封装,开发公司可以让我们轻松地将面向服务的REST开发公司模版请求自动转换成客开发公司户端负载均衡的服务调用。Spring Cloud Ribbon开发公司虽然只是一个工具类框架,开发公司它不像服务注册中心、配置中心、API开发公司网关那样需要独立部署,开发公司但是它几乎存在于每一个Spring Cloud开发公司构建的微服务和基础设施中。开发公司因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的。
- Spring Cloud Ribbon 是一套基于 Netflix Ribbon 实现的客户端负载均衡工具
- spring cloud进行二次封装,让我们可以将面向服务的Rest模板(RestTemplate)请求装换成客户端负载均衡的服务调用
- 不需要单独部署
2、客户端负载均衡
在调用者服务中实现负载均衡,来分发请求至被调用者。如图所示
3、使用方法
3.1、单独使用
3.1.1、导入Ribbon使用的依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> <version>2.2.9.RELEASE</version></dependency>
- 1
- 2
- 3
- 4
- 5
3.1.2、配置文件
# 配置被调用服务集合goods-service.ribbon.listOfServers=\ http://localhost:9090/goods,http://localhost:9093/goods # httpClient 连接池最大总连接数ribbon.MaxTotalConnections=200# httpClient 每个host最大连接数ribbon.MaxConnectionsPerHost=50
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
3.1.3、LoadBalancerClient方式
@Autowiredprivate LoadBalancerClient loadbalancerClient;@GetMappingpublic String goods(){ log.info("begin do order"); ServiceInstance si=loadbalancerClient.choose("goods-service"); String url=String.format("http://%s:%s",si.getHost(),si.getPort()); log.info("ribbon-url:{}",url); String goodsInfo=restTemplate.getForObject(url,String.class); return goodsInfo;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
3.1.4、通过@LoadBalanced
注解方式
配置RestTemplate
时,添加@LoadBalanced
注解
@Configurationpublic class RestTemplateConfiguration { @LoadBalanced @Bean public RestTemplate restTemplate(){ return new RestTemplate(); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
接口调用,直接通过服务名goods-service
调用
@GetMappingpublic String goods(){ log.info("begin do order"); String url="http://goods-service/goods"; String goodsInfo=restTemplate.getForObject(url,String.class); return goodsInfo;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
3.2、基于Eureka的使用
3.2.1、添加依赖
<!--Spring Cloud Ribbon 依赖--><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> <version>2.2.9.RELEASE</version></dependency><!--Spring Cloud Eureka 客户端依赖--><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
3.2.2、注入RestTemplate
通过@LoadBalanced
注解开启
@Configurationpublic class RestTemplateConfiguration { @Bean @LoadBalanced //在客户端使用 RestTemplate 请求服务端时,开启负载均衡(Ribbon) public RestTemplate restTemplate(){ return new RestTemplate(); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
3.2.3、配置文件application.properties
server: port: 80 #端口号# eureka配置eureka: client: register-with-eureka: false # 本微服务为服务消费者,不需要将自己注册到服务注册中心 fetch-registry: true # 本微服务为服务消费者,需要到服务注册中心搜索服务 service-url: defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ #服务注册中心集群
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
3.2.4、接口调用
直接使用goods-service
,服务提供者的服务名称调用,ribbon会通过eureka获取服务列表,通过负载策略选择服务
@GetMappingpublic String goods(){ log.info("begin do order"); String url="http://goods-service/goods"; String goodsInfo=restTemplate.getForObject(url,String.class); return goodsInfo;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
4、Ribbon自定义负载均衡策略
Ribbon提供的负载均衡策略
序号 | 实现类 | 负载均衡策略 |
---|---|---|
1 | RoundRobinRule | 按照线性轮询策略,即按照一定的顺序依次选取服务实例 |
2 | RandomRule | 随机选取一个服务实例 |
3 | RetryRule | 按照 RoundRobinRule(轮询)的策略来获取服务,如果获取的服务实例为 null 或已经失效,则在指定的时间之内不断地进行重试(重试时获取服务的策略还是 RoundRobinRule 中定义的策略),如果超过指定时间依然没获取到服务实例则返回 null 。 |
4 | WeightedResponseTimeRule | WeightedResponseTimeRule 是 RoundRobinRule 的一个子类,它对 RoundRobinRule 的功能进行了扩展。 根据平均响应时间,来计算所有服务实例的权重,响应时间越短的服务实例权重越高,被选中的概率越大。刚启动时,如果统计信息不足,则使用线性轮询策略,等信息足够时,再切换到 WeightedResponseTimeRule。 |
5 | BestAvailableRule | 继承自 ClientConfigEnabledRoundRobinRule。先过滤点故障或失效的服务实例,然后再选择并发量最小的服务实例。 |
6 | AvailabilityFilteringRule | 先过滤掉故障或失效的服务实例,然后再选择并发量较小的服务实例。 |
7 | ZoneAvoidanceRule | 默认的负载均衡策略,综合判断服务在不同区域(zone)的性能和服务(server)的可用性,来选择服务实例。在没有区域的环境下,该策略与轮询(RoundRobinRule)策略类似。 |
如上图所示,Ribbon已经提供很多负载均衡策略,如果我们想定义自己的负载均衡策略可以通过如下方式,实现
4.1、集成AbstractLoadBalancerRule
,实现choose
方法
package com.gupaoedu.mall.gpmallportal;import com.netflix.client.config.IClientConfig;import com.netflix.loadbalancer.AbstractLoadBalancerRule;import com.netflix.loadbalancer.ILoadBalancer;import com.netflix.loadbalancer.Server;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import java.util.List;public class DefinieIpHashRule extends AbstractLoadBalancerRule { @Override public void initWithNiwsConfig(IClientConfig clientConfig) { //.... } public Server choose(ILoadBalancer lb, Object key) { if(lb==null){ return null; } Server server=null; while(server==null){ //表示启动的服务列表.(默认情况下单纯只用Ribbon时,不会对目标服务做心跳检测) List<Server> upList=lb.getReachableServers(); List<Server> allList=lb.getAllServers(); int serverCount=upList.size(); if(serverCount==0){ return null; } int index=ipAddressHash(serverCount); server=upList.get(index); } return server; } private int ipAddressHash(int serverCount){ ServletRequestAttributes requestAttributes= (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); String remoteAddr=requestAttributes.getRequest().getRemoteAddr(); int code=Math.abs(remoteAddr.hashCode()); return code%serverCount; } @Override public Server choose(Object key) { return choose(getLoadBalancer(),key); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
4.2、配置文件
配置服务名称是goods-service
的使用自定义负载均衡
goods-service.ribbon.NFLoadBalancerRuleClassName=com.xxxx.xxx.DefinieIpHashRule
- 1
5、Ribbon的Ping机制
在Ribbon负载均衡器中,提供了ping机制,每隔一段时间,就会去ping服务器,由 com.netflix.loadbalancer.IPing 接口去实现。
单独使用ribbon,不会激活ping机制,默认采用DummyPing(在RibbonClientConfiguration中实例化),isAlive()方法直接返回true。
Ribbon和Eureka集成,默认采用NIWSDiscoveryPing(在EurekaRibbonClientConfiguration中实例化的),只有服务器列表的实例状态为up的时候 才会为Alive。
IPing中默认内置了一些实现方法如下
- PingUrl: 使用httpClient对目标服务逐个实现Ping操作。
- DummyPing: 默认认为对方服务是正常的,直接返回true。
- NoOpPing:永远返回true。
5.1、实现com.netflix.loadbalancer.IPing
接口
public class HealthChecker implements IPing { @Override public boolean isAlive(Server server) { String url="http://"+server.getId()+"/healthCheck"; boolean isAlive=true; HttpClient httpClient=new DefaultHttpClient(); HttpUriRequest request=new HttpGet(url); try { HttpResponse response = httpClient.execute(request); isAlive = response.getStatusLine().getStatusCode() == 200; }catch (Exception e){ isAlive=false; }finally { request.abort(); } return isAlive; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
5.2、配置文件
goods-service.ribbon.NFLoadBalancerPingClassName=com.xxxxx.xxx.HealthChecker
- 1