负载均衡、服务熔断、服务降级、服务限流(主要是Dubbo)
1. 负载均衡负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。1.1. dubboString loadbalance() default "";dubbo的四种负载分别是:随机(权重)、轮询(权重)、最少活跃调用数、一致性Hash。
1. 负载均衡
负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。
1.1. dubbo
String loadbalance() default "";
dubbo的四种负载分别是:随机(权重)、轮询(权重)、最少活跃调用数、一致性Hash。
1.2. gateway
通过服务注册中心的服务名/接口实现负载均衡。实际上gateway的负载均衡基于的是ribbon
server:
port: 8080
spring:
application:
name: gateway_server
cloud:
gateway:
default-filters:
routes:
- id: my_route
uri: lb://my-load-balanced-service
predicates:
- Path=/gateway/**
filters:
- StripPrefix=1
my-load-balanced-service:
ribbon:
listOfServers: localhost:1001, localhost:1002
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule**
# 使用了轮询的负载均衡策略。
# https://www.jianshu.com/p/cdf63185b0c3
1.3. Ribbon
- 负载规则:从服务器列表中决定用哪个服务器
- ping任务:后台运行的任务,用来验证服务器是否可用
- 服务器列表:以是静态也可以是动态,如果是动态,那么就要有一个后台线程定时去刷新和过滤列表。我们微服务基于服务发现的情况,服务器列表肯定都是动态增减的
- 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重新选取。
- WeightedResponseTimeRule:最小响应时间。这个策略整合了随机算法和响应时间加权算法。会开启定时任务,每30秒计算一次所有Provider的响应时间,以响应时间作为权重,响应时间越短的服务器被选中的概率越大。比如Node1:node2:node3的平均响应时间为100ms:200ms:300ms,那么nodes的的权重值是300:500:600,每次以600为基础*随机值,那么落在 0–300的概率为50%,300–500的概率33%,100–600的概率为17%,也就是平均响应时间越短的节点,被选中的概率越大。
1.4. Nignx
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FDMK8kFz-1596725381127)(https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1596721489063&di=66641b845f5efbd56566eff256dccf3e&imgtype=0&src=http%3A%2F%2Fstatic.jointforce.com%2Fjfperiodical%2Fattached%2Fimage%2F20160420%2F-1451750843.png)]
nginx负载均衡基本配置
http {
upstream myapp1 {
server ip:port;
server ip:port;
server ip:port;
}
server {
listen 80;
location / {
proxy_pass http://xxx;
}
}
}
目前Nginx的upstream模块支持6种方式的负载均衡策略(算法):轮询(默认方式)、weight(权重方式)、ip_hash(依据ip分配方式)、least_conn(最少连接方式)、fair(第三方提供的响应时间方式)、url_hash(第三方通过的依据URL分配方式)。
推荐文章:
2. 服务熔断
服务熔断的作用类似于我们家用的保险丝,当某服务出现不可用或响应超时的情况时,为了防止整个系统出现雪崩,暂时停止对该服务的调用。
2.1. dubbo
String mock() default ""; //true(自动寻找mork实现类) fail(允许请求) default(和true一样) force(屏蔽请求)
2.2. Hystrix
circuitBreaker.enabled 是否开启熔断
circuitBreaker.requestVolumeThreshold 熔断最低触发请求数阈值
circuitBreaker.sleepWindowInMilliseconds 产生熔断后恢复窗口
circuitBreaker.errorThresholdPercentage 错误率阈值
circuitBreaker.forceOpen 强制打开熔断
circuitBreaker.forceClosed 强制关闭熔断
@Configuration
public class GatewayFallbackConfig {
@Autowired
private HystrixFallbackHandler hystrixFallbackHandler;
@Bean
public RouterFunction routerFunction() {
return RouterFunctions.route(
RequestPredicates.GET("/defaultfallback")
.and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), hystrixFallbackHandler);
}
}
@Component
public class HystrixFallbackHandler implements HandlerFunction<ServerResponse> {
@Override
public Mono<ServerResponse> handle(ServerRequest serverRequest) {
serverRequest.attribute(ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR)
.ifPresent(originalUrls -> log.error("--------", originalUrls));
return ServerResponse
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(ResultData.fail("HystrixFallbackHandler")));
}
}
可以采用简单的注解配置
3. 服务降级
当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。
服务降级这个问题,如果从整体来操作,
-
一定是先降级优先级地的接口,两权相害取其轻
-
如果服务链路整体没有性能特别差的点,比如就是外部流量突然激增,那么就从外到内开始降级
-
如果某个服务能检测到自身负载上升,那么可以从这个服务自身做降级
3.1. dubbo
-
第一种方式:通过dubbo-admin实现
mock=force:return+null 表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。
还可以改为 mock=fail:return+null 表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。
-
第二种方式:@Reference实现
@Reference(timeout = 1000) //设置超时时间
-
第三种方式:mork
String mock() default ""; //true(自动寻找mork实现类) fail(允许请求) default(和true一样) force(屏蔽请求) //xxxServiceMork要和接口在一个项目中,为的是方便找到Mork类
3.2. Hystrix
4. 服务限流
为了防止某个消费者的QPS或是所有消费者的QPS总和突然飙升而导致的重要服务的失效,系统可以对访问流量进行控制,这种对集群的保护措施称为服务限流。
4.1. dubbo
Dubbo中能够实现服务限流的方式较多,可以划分为两类:直接限流与间接限流
- 直接限流:通过对连接数量直接进行限制来达到限流的目的。
- 间接限流:通过一些非连接数量设置来达到限制流量的目的。
dubbo限流的方式:
-
第一种方式:executes直接限流(提供者端使用)
<dubbo:service interface="com.xxx.xxx" executes="10" /> <!--服务端并发:限制10个并发-->
<dubbo:service interface="com.xxx.xxx"> <dubbo:method name="xxxx" executes="10" /> <!--方法级别:限制10个并发--> </dubbo:service>
-
第二种方式:accepts限流(提供者端使用)
<dubbo:provider protocol="dubbo" accepts="10" /> <!--用于对指定协议的连接数量进行限制-->
<dubbo:protocol name="dubbo" port="20880" accepts="10" /> <!--用于对指定协议的连接数量进行限制-->
-
第三种方式:actives限流(两端)
根据消费者与提供者间建立的连接类型的不同,其意义也不同
- 长连接:表示当前长连接最多可以处理的请求个数。与长连接的数量没有关系
- 短连接:表示当前服务可以同时处理的短连接数量
<dubbo:service interface="com.xxx.xxx" actives="10" /> <dubbo:reference interface="com.xxx.xxx"> <dubbo:method name="xxxx" actives="10" /> </dubbo:service>
<dubbo:reference interface="com.xxx.xxx" actives="10" /> <dubbo:reference interface="com.xxx.xxx"> <dubbo:method name="xxxx" actives="10" /> </dubbo:service>
-
第四种方式:connections限流(两端)
限定连接的个数。对于短连接,该属性效果与actives相同。但对于长连接,其限制的是长连接的个数。
一般情况下,会使connectons与actives联用,让connections限制长连接个数,让actives限制一个长连接中可以处理的请求个数。联用前提:使用默认的Dubbo服务暴露协议
<dubbo:service interface="com.xxx.xxx" ref="xxx" connections="10"></dubbo:service> <dubbo:service interface="com.xxx.xxx" ref="xxx"> <dubbo:method name="xxxx" connections="10"></dubbo:method> </dubbo:service>
<dubbo:reference interface="com.xxx.xxx" id="xxx" connections="10"></dubbo:reference> <dubbo:reference interface="com.xxx.xxx" id="xxx"> <dubbo:method name="xxxx" connections="10"></dubbo:method> </dubbo:reference>
-
第五种方式:延迟连接(间接限流)
仅可设置在消费者端,且不能设置为方法级别。仅作用于Dubbo服务暴露协议。
将长连接的建立推迟到消费者真正调用提供者时。可以减少长连接的数量。<!--设置当前消费者对接口中的每个方法发出链接采用延迟加载--> <dubbo:reference id="xxx" lazy="true" interface="com.xxx.xxx.xxx"/>
-
第六种方式:粘连连接(间接限流)
仅能设置在消费者端,其可以设置为接口级别,也可以设置为方法级别。仅作用于Dubbo服务暴露协议,其会使客户端尽量向同一个提供者发起调用,除非该提供者挂了,其会连接另一台。只要启用了粘连连接,其就会自动启用延迟连接,其限制的是流向,而非流量。
<dubbo:reference id="xxxx" sticky="true" interface="com.xxx.xxx.xxx"></dubbo:reference> <dubbo:reference id="xxxx" interface="com.xxx.xxx.xxx"> <dubbo:method name="xxxx" sticky="true"></dubbo:method> </dubbo:reference>
-
第七种方式:负载均衡(间接限流)
参考负载均衡中的dubbo
4.2. Hystrix
public class CommandReject extends HystrixCommand<String> {
private String tag;
public CommandReject(String tag) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("CommandReject"))
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
.withCoreSize(5)
.withMaxQueueSize(2))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds(3000)));
this.tag = tag;
}
@Override
protected String run() throws Exception {
Thread.sleep(3000);
return tag;
}
@Override
protected String getFallback() {
return "服务降级处理";
}
}
5. 参考
Hystrix写的很少,往后学习会补充进去
更多推荐
所有评论(0)