Spring Cloud Nacos&Feign负载均衡
软件方式的负载均衡一般有两种方法
1、Nginx、Haproxy分布式服务器网关的负载均衡;
2、Ribbon&Feign 结合Nacos本地消费者客户端进程内的负载均衡(即不用先去访问nginx这类的服务器网关),用于Spring Cloud;
那么先复习下Nginx负载均衡的算法和配置。
1)、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
2)、weight权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
3)、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
4)、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
5)、url_hash(第三方)
比如权重,这个weight也很好理解,权重大的被访问的概率就大,上面这个例子的话,访问2次server1,访问一次server2
upstream webname { server 192.168.0.1:8080 weight 2; server 192.168.0.2:8080 weight 1; }
IP hash,ip_hash的配置也很简单,直接加一行就可以了,这样只要是同一个ip过来的都会到同一台server上
upstream webname { ip_hash; server 192.168.0.1:8080; server 192.168.0.2:8080;
server 192.168.0.10:8090 max_fails=2 fail_timeout=1;
}
关于nginx负载均衡配置的几个状态参数讲解。
-
down,表示当前的server暂时不参与负载均衡。
-
backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。
-
max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
-
fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。
基本来说,使用nginx来进行负载均衡是非常简单的。
Ribbon&Feign 结合Nacos本地消费者进程内的负载均衡
调用方法有两种:
1、RestTemplate
2、Openfeign
restTemplate通过服务名来访问,restTemplate上要加上@LoadBalanced注解来实现负载均衡,底层使用的是ribbon。自动完成了通过服务名获取调用地址列表,并选择一个进行调用的功能。
启动类
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class NacosApplication { @LoadBalanced @Bean public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(NacosApplication.class, args); } }
RestTemplate 调用方式:
@GetMapping("/orderRibbonToMember") public Object orderRibbonToMember() { //通过服务地址加上方法名调用,String.class为方法返回值类型 String object = restTemplate.getForObject("http://member-nacos/user", String.class); return "调用返回结果"+object; }
openfeign调用方式:
SpringCloud第一代采用的是feign,第二代采用openfeign。
Openfeign客户端是一个Web声明式的Http客户端远程调用工具,底层封装了HttpClient技术。
feign是netflix研发,而openfeign是SpringCloud自己研发的,但在使用上的代码写法几乎是一致的。
在项目本地创建一个对应于要远程调用的服务的接口,然后使用@FeignClient注解。注意,要使用@EnableFeignClients开启openfeign
pom
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.0.2.RELEASE</version> </dependency>
接口声明,注册FeignClient
@FeignClient(value = "springboot2-nacos-discovery") public interface EchoService { @GetMapping(value = "/echo/{string}") String echo(@PathVariable("string") String string); }
使用客户端
@Autowired private EchoService echoService; @GetMapping(value = "/feignEcho/{str}") public String feignEcho(@PathVariable String str) { return echoService.echo(str); }
为验证负载均衡,我们需要把xin_cloud_nacos工程再复制一次,新工程为xin_cloud_nacos,多开一个端口。
工程和端口:
生产者服务xin_cloud_nacos:8080
生产者服务xin_cloud_nacos1:8081
消费者客户:8090
运行情况,Nacos发现有2个生产实例
启动消费者发现是轮询方式:
Hello Nacos Discovery 8080:abc Hello Nacos Discovery 8081:abc Hello Nacos Discovery 8080:abc Hello Nacos Discovery 8081:abc
常见负载均衡策略
负载主机可以提供很多种负载均衡方法,也就是我们常说的调度方法或算法。
1、轮循
Round Robin: 这种方法会将收到的请求循环分配到服务器集群中的每台机器,即有效服务器。如果使用这种方式,所有的标记进入虚拟服务的服务器应该有相近的资源容量 以及负载形同的应用程序。如果所有的服务器有相同或者相近的性能那么选择这种方式会使服务器负载形同。基于这个前提,轮循调度是一个简单而有效的分配请求 的方式。然而对于服务器不同的情况,选择这种方式就意味着能力比较弱的服务器也会在下一轮循环中接受轮循,即使这个服务器已经不能再处理当前这个请求了。 这可能导致能力较弱的服务器超载。
2、加权轮循
Weighted Round Robin: 这种算法解决了简单轮循调度算法的缺点:传入的请求按顺序被分配到集群中服务器,但是会考虑提前为每台服务器分配的权重。管理员只是简单的通过服务 器的处理能力来定义各台服务器的权重。例如,能力最强的服务器 A 给的权重是 100,同时能力最低的服务器给的权重是 50。这意味着在服务器 B 接收到第一个 请求之前前,服务器 A 会连续的接受到 2 个请求,以此类推。
3、最少连接数
Least Connection: 以上两种方法都没有考虑的是系统不能识别在给定的时间里保持了多少连接。因此可能发生,服务器 B 服务器收到的连接比服务器 A 少但是它已经超载,因为 服务器 B 上的用户打开连接持续的时间更长。这就是说连接数即服务器的负载是累加的。这种潜在的问题可以通过 “最少连接数” 算法来避免:传入的请求是根据每 台服务器当前所打开的连接数来分配的。即活跃连接数最少的服务器会自动接收下一个传入的请求。接本上和简单轮询的原则相同:所有拥有虚拟服务的服务器资源 容量应该相近。值得注意的是,在流量率低的配置环境中,各服务器的流量并不是相同的,会优先考虑第一台服务器。这是因为,如果所有的服务器是相同的,那么 第一个服务器优先,直到第一台服务器有连续的活跃流量,否则总是会优先选择第一台服务器。
4、最少连接数慢启动时间
Least Connection Slow Start Time: 对最少连接数和带权重的最小连接数调度方法来说,当一个服务器刚加入线上环境是,可以为其配置一个时间段,在这段时间内连接数是有限制的而且是缓慢 增加的。这为服务器提供了一个‘过渡时间’以保证这个服务器不会因为刚启动后因为分配的连接数过多而超载。这个值在 L7 配置界面设置。
5、加权最少连接
Weighted Least Connection: 如果服务器的资源容量各不相同,那么 “加权最少连接” 方法更合适:由管理员根据服务器情况定制的权重所决定的活跃连接数一般提供了一种对服务器非常 平衡的利用,因为他它借鉴了最少连接和权重两者的优势。通常,这是一个非常公平的分配方式,因为它使用了连接数和服务器权重比例;集群中比例最低的服务器 自动接收下一个请求。但是请注意,在低流量情况中使用这种方法时,请参考 “最小连接数” 方法中的注意事项。
6、基于代理的自适应负载均衡
Agent Based Adaptive Balancing: 除了上述方法之外,负载主机包含一个自适用逻辑用来定时监测服务器状态和该服务器的权重。对于非常强大的 “基于代理的自适应负载均衡” 方法来说,负 载主机以这种方式来定时检测所有服务器负载情况:每台服务器都必须提供一个包含文件,这个文件包含一个 0~99 的数字用来标明改服务器的实际负载情况 (0 = 空前,99 = 超载,101 = 失败,102 = 管理员禁用),而服务器同构 http get 方法来获取这个文件;同时对集群中服务器来说,以二进制文件形式提供自身负载情况也是该服务器工作之一,然而,并没有限制服务器如何计算自身的负载 情况。根据服务器整体负载情况,有两种策略可以选择:在常规的操作中,调度算法通过收集的服务器负载值和分配给该服务器的连接数的比例计算出一个权重比 例。因此,如果一个服务器负载过大,权重会通过系统透明的作重新调整。和加权轮循调度方法一样,不正确的分配可以被记录下来使得可以有效的为不同服务器分 配不同的权重。然而,在流量非常低的环境下,服务器报上来的负载值将不能建立一个有代表性的样本;那么基于这些值来分配负载的话将导致失控以及指令震荡。 因此,在这种情况下更合理的做法是基于静态的权重比来计算负载分配。当所有服务器的负载低于管理员定义的下限时,负载主机就会自动切换为加权轮循方式来分 配请求;如果负载大于管理员定义的下限,那么负载主机又会切换回自适应方式。
7、固定权重
Fixed Weighted: 最高权重只有在其他服务器的权重值都很低时才使用。然而,如果最高权重的服务器下降,则下一个最高优先级的服务器将为客户端服务。这种方式中每个真实服务器的权重需要基于服务器优先级来配置。
8、加权响应
Weighted Response: 流量的调度是通过加权轮循方式。加权轮循中所使用的权重是根据服务器有效性检测的响应时间来计算。每个有效性检测都会被计时,用来标记它响应成功花 了多长时间。但是需要注意的是,这种方式假定服务器心跳检测是基于机器的快慢,但是这种假设也许不总是能够成立。所有服务器在虚拟服务上的响应时间的总和 加在一起,通过这个值来计算单个服务物理服务器的权重;这个权重值大约每 15 秒计算一次。
9、 IP 哈希
Source IP Hash: 这种方式通过生成请求源 IP 的哈希值,并通过这个哈希值来找到正确的真实服务器。这意味着对于同一主机来说他对应的服务器总是相同。使用这种方式,你不需要保存任何源 IP。但是需要注意,这种方式可能导致服务器负载不平衡,但省去了Session一致性的问题。
源码:
目前维护的开源产品:https://gitee.com/475660