Ribbon负载均衡
负载均衡一般分为服务器端负载均衡和客户端负载均衡
所谓服务器端负载均衡,比如Nginx、F5这些,请求到达服务器之后由这些负载均衡器根据一定的算法将请求路由到目标服务器处理
所谓客户端负载均衡,比如我们要说的Ribbon,服务消费者客户端会有一个服务器地址列表,调用方在请求前通过一定的负载均衡算法选择一个服务器进行访问,负载均衡算法的执行是在请求客户端进行
Ribbon是Netflix发布的负载均衡器。Eureka一般配合Ribbon进行使用,Ribbon利用从Eureka中读取到服务信息,在调用服务提供者提供的服务时,会根据一定的算法进行负载
在微服务中实现负载均衡
1. 新建一个微服务的项目,名称为product9001
2.将product9000项目中的内容复制一份到product9001
1)pom文件
<dependencies><dependency><groupId>com.leq</groupId><artifactId>leq-service-common</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!-- Eureka Server客户端依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency></dependencies>
2)核心配置文件,将端口号改为9001
server.port=9001 spring.application.name=leq-service-product spring.datasource.url=jdbc:mysql://localhost:3306/leq_sc?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=0216eureka.client.service-url.defaultZone= http://LEQCloudEurekaServerA:9200/eureka,http://LEQCloudEurekaServerB:9201/eureka #eureka.client.register-with-eureka= true eureka.client.fetch-register= true eureka.instance.prefer-ip-address= true eureka.instance.instance-id= ${spring.cloud.client.ipaddress}:${spring.application.name}:${server.port}:@project.version@
3)创建包目录,包目录要和生产者的目录一直,然后将produt9000目录下的文件复制一份到product9001中
4)修改启动类的类名为Product901Application,按住快捷键shit+f6就可以改名字
3. 在page的启动类中添加负载均衡的注解 @LoadBalanced :调用Ribbon负载均衡算法,实现负载均衡功能
4. 为了看我们的复制均衡是否实现,我们需要在两个product微服务中写获取端口号的方法
import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping("server") public class ServerConfigController {@Value("${server.port}")private String serverprot;@RequestMapping("getPort")public String findServerPort(){return serverprot;}}
5.在page微服务下创建一个获取端口号的方法,来看看我们的负载均衡有没有实现,并重构查询的方法
@RequestMapping("query/{id}")public Products findById(@PathVariable Integer id){String url ="http://leq-service-product/product/findById/"+id;return restTemplate.getForObject(url,Products.class);}@RequestMapping("getPort")public String getPort(){String url="http://leq-service-product/server/getPort";return restTemplate.getForObject(url,String.class);}
6.重新启动product9000,product9001和page9100的微服务,在浏览器访问获取端口的接口,可以发现每次请求时候的端口都会自动变化
http://localhost:9100/page/getPort
http://localhost:9100/page/query/1
Ribbon负载均衡策略分类
负载均衡策略 类名 描述
轮询策略 RoundRobinRule 默认超过10次获取到的server都不可用,会返回一个空的server
随机策略 RandomRule 如果随机到的server为null或者不可用的话,会while不停的循环选取
重试策略 RetryRule 一定时限内循环重试。默认继承RoundRobinRule,也支持自定义注
入,RetryRule会在每次选取之后,对选举的server进行判断,是否为
null,是否alive,并且在500ms内会不停的选取判断。而 RoundRobinRule失效的策略是超过10次,RandomRule是没有失效时 间的概念,只要serverList没都挂
最小连接数策略 BestAvailableRule 遍历serverList,选取出可用的且连接数最小的一个server。该算法里
面有一个LoadBalancerStats的成员变量,会存储所有server的运行状
况和连接数。如果选取到的server为null,那么会调用RoundRobinRule重新选取
可用过滤策略 AvailabilityFilteringRule 扩展了轮询策略,会先通过默认的轮询选取一个server,再去判断该
server是否超时可用,当前连接数是否超限,都成功再返回
区域权衡策略
(默认策略) ZoneAvoidanceRule 扩展了轮询策略,继承了两个过滤器:ZoneAvoidancePredicate和
AvailabilityPredicate,除了过滤超时和链接数过多的server,还会过
滤掉不符合要求的zone区域里面的所有节点,在一个区域/机房内的服
务实例中轮询。 先过滤再轮询
配置Ribbon负载均衡策略
语法:生产者id.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.策略名(一般都不需要我们配置,使用默认的即可)
#随机策略 #leq-service-product.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule #轮循策略 leq-service-product.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule