springcloud之负载均衡
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springcloud之负载均衡相关的知识,希望对你有一定的参考价值。
参考技术A 在springcloud中,服务端实现负载均衡,我所知道的是通过ribbon实现的而通过ribbon实现的负载均衡目前在用的比较多的是 feign 和 restTemplate两种
feign: 已经集成了ribbon,默认是轮训算法,当然也可以通过配置更改loadbalacned算法
restTemplete: 需要配置集成ribbon 方法如下(在启动类中加入)
@Bean
@LoadBalanced
RestTemplate restTemplate()
return new RestTemplate();
两者比较
restTemplate经过上述配置后,两者其实并无差异,都可以远程调用服务,并具有负载均衡的功能,
但是就如同筷子和勺子一样,都可以吃饭,但是他们在某一方面比较出众.
先说下用法
restTemplate:
为了清楚,我再粘贴一个eureka注册列表
Feign:
结论:二者调用 都比较方便,而且feign实现方式更加优雅,不需要写任何路径,他们都可以实现服务直接的相互调用,返回预期结果
相信细心的小伙伴,看到了 fallback 这个是feign的附加功能(个人理解),经过配置它会进行一个熔断,然后走GetHelloBack类中的方法,使得当 ribbon-provider出现故障的时候,调用他的服务可以很快得到一个结果,增加客户体验,也可以防止"雪崩"发生
而我之前也说了,两者都有各自的长处,优点,这个就是feign的优点,而restTemplate则无(也许有,但是我不知道),restTemplate在另一方更加优秀,即调用第三方接口,如:微信支付等等.
为什么这么说呢?因为如果要调用第三方接口,一般是需要httpclient去调用的,但是restTemplate 可以很优雅的去调用,并很清晰的标注返回值类型.而feign 当然也可以调用第三方接口,只是没有这么简便.
这里面都是用的ribbon 实现的负载均衡,而默认都是轮询算法,当然也可以自定义ribbon去启用其他的ribbon算法.
所以说,两者都可以远程调用服务,但是我想说的是,就还是我之前举得例子,筷子勺子都可以吃饭,只是在各自的有各自的优势,长处,你非要那么用也是可以的.
云原生SpringCloud系列之客户端负载均衡Ribbon
基本概念
在微服务架构中,负载均衡是必须使用的技术,通过它来实现系统的高可用、集群扩容等功能。负载均衡可以分为两种:服务端负载均衡和客户端负载均衡。通常所说的负载均衡指服务器负载均衡,可通过硬件设备或软件来实现,硬件比如:F5、Array等,软件比如:LVS、Nginx等。
负载均衡按实现方式分类可区分为:服务端负载均衡(比如Nacos负载均衡)与客户端负载均衡。
SpringCloud Ribbon是基于客户端的负载均衡工具,它可以将面向服务的 REST 模板请求自动转换成客户端负载均衡的服务调用。执行过程如下图:
- 服务消费者与服务提供者实例在启动时向 Nacos 注册;
- 订单服务向商品服务发起通信前,Ribbon 向 Nacos 查询商品服务的可用实例列表;
- Ribbon 根据设置的负载策略从服务提供者可用实例列表中选择实例;
- 服务消费者实例向服务提供者实例发起请求,完成 RESTful 通信;
Ribbon
是由 Netflix 发布的负载均衡器,它有助于控制 HTTP 和 TCP 的客户端的行为。Ribbon 属于客户端负载均衡。
为 Ribbon 配置服务提供者地址后,Ribbon 就可基于某种负载均衡算法,自动的帮助服务消费者进行请求。同时 Ribbon 默认为我们提供了很多负载均衡算法,例如:轮询、随机算法等。
配置 Ribbon 负载均衡策略
Ribbon 内置多种负载均衡策略,常用的分为以下几种。
- RoundRobinRule:
轮询策略,Ribbon 默认策略。默认超过 10 次获取到的 server 都不可用,会返回⼀个空的 server。
- RandomRule:
随机策略,如果随机到的 server 为 null 或者不可用的话。会不停地循环选取。
- RetryRule:
重试策略,⼀定时限内循环重试。默认继承 RoundRobinRule,也⽀持自定义注⼊,RetryRule 会在每次选取之后,对选举的 server 进⾏判断,是否为 null,是否 alive,并且在 500ms 内会不停地选取判断。而 RoundRobinRule 失效的策略是超过 10 次,RandomRule 没有失效时间的概念,只要 serverList 没都挂。
- BestAvailableRule:
最小连接数策略,遍历 serverList,选取出可⽤的且连接数最小的⼀个 server。那么会调用 RoundRobinRule 重新选取。
- AvailabilityFilteringRule:
可用过滤策略。扩展了轮询策略,会先通过默认的轮询选取⼀个 server,再去判断该 server 是否超时可用、当前连接数是否超限,都成功再返回。
- ZoneAvoidanceRule:
区域权衡策略。扩展了轮询策略,除了过滤超时和链接数过多的 server,还会过滤掉不符合要求的 zone 区域⾥⾯的所有节点,始终保证在⼀个区域/机房内的服务实例进行轮询。
这里所有负载均衡策略名本质都是 com.netflix.loadbalancer 包下的类:
要更改微服务通信时采用的负载均衡策略也很简单,在 application.yml 中采用下面格式书写即可。
provider-service: #服务提供者的微服务id
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #设置对应的负载均衡类
当采用随机策略,杂乱的顺序说明随机策略已生效。
Ribbon主要组件和作用
ILoadBalancer
:定义一系列的操作接口,比如选择服务实例。IRule
:算法策略,内置算法策略来为服务实例的选择提供服务。ServerList
:负责服务实例信息的获取,可以获取配置文件中的,也可以从注册中心获取。ServerListFilter
:过滤掉某些不想要的服务实例信息。ServerListUpdater
:更新本地缓存的服务实例信息。IPing
:对已有的服务实例进行可用性检查,保证选择的服务都是可用的。
如果需要自定义相关组件,需要实现上述接口。
Ribbon使用
Ribbon 的使用方式主要分为下面这三种,
- 原生 API,Ribbon 是 Netflix 开源的,如果你没有使用 Spring Cloud,也可以在项目中单独使用 Ribbon,在这种场景下就需要使用 Ribbon 的原生 API。
- Ribbon + RestTemplate,当我们项目整合了 Spring Cloud 时,就可以用 Ribbon 为 RestTemplate 提供负载均衡的服务。
-
Ribbon + Feign,关于 Feign 的使用方式后续我会继续整理到博客中,欢迎持续关注。
原生API
配置一个服务列表,数据格式为 IP + PORT,可以固定写几个服务列表,也可以从别处读取,比如注册中心。
构建一个负载实例,将服务列表传入,再指定对应的负载均衡策略,RandomRule 是随机策略。具体的应用逻辑写在 call 方法里,call 方法的参数是 Server 对象,Server 也就是我们第一步构建的服务列表信息,得到 Server 后就可以获取到对应的 IP 和端口,然后进行接口的调用。
代码案例如下:/** * 轮询请求测试 */ @Test public void roundRobinRuleTest() // 服务列表 List<Server> serverList = Arrays.asList(new Server("localhost", 8080), new Server("localhost", 8081), new Server("localhost", 8082)); // 构建负载实例 BaseLoadBalancer loadBalancer = LoadBalancerBuilder.newBuilder().buildFixedServerListLoadBalancer(serverList); loadBalancer.setRule(new RoundRobinRule()); // 调用5次来测试效果 for (int i = 0; i < 6; i++) String result = LoadBalancerCommand.<String>builder().withLoadBalancer(loadBalancer).build() .submit(new ServerOperation<String>() @Override public Observable<String> call(Server server) try String addr = "http://" + server.getHost() + ":" + server.getPort(); System.out.println("调用地址:" + addr); return Observable.just(""); catch (Exception e) return Observable.error(e); ).toBlocking().first(); System.out.println("调用结果:" + result);
RestTemplate调用
RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程 HTTP 服务的方法,能够大大提高客户端的编写效率。
将 RestTemplate 和 Ribbon 整合起来,只需要在配置 RestTemplate 实例的时候,加一个 @LoadBalanced 的注解,这样 RestTemplate 在调用接口时,就不需要用固定的 IP 加端口的方式调用接口,而是可以用服务名称的方式进行接口的调用,自动具备客户端负载均衡的效果。// RestTemplate 配置类 @Configuration public class RestConfiguration @Bean // @LoadBalanced 注解让RestTemplate 能够直接使用服务名称调用对应的接口 @LoadBalanced public RestTemplate restTemplate() return new RestTemplate();
@Autowired
private RestTemplate restTemplate;
@GetMapping("/get")
public Object get()
User user = restTemplate.getForEntity("http://system-service/user/get?id=1", User.class).getBody();
//User user = restTemplate.getForEntity("http://localhost:8084/user/get?id=1", User.class).getBody();
return user;
> 本文内容到此结束了,
> 如有收获欢迎点赞以上是关于springcloud之负载均衡的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud之 LoadBalancer和Feign负载均衡