10倍性能!主动服务降级带来更好的性能

雪崩效应

当一个服务已经负载不了当前的请求压力的时候,应该主动暂停或者拒绝新到来的服务请求,以保证自身存活,以及防止雪崩效应。

我们举一个例子来说明雪崩效应。

比如说有一个erlang的进程:

  1. 突然收到大量请求,请求数远大于该进程的处理能力。
  2. 如果这个时候这个进程决定服务所有请求,就需要将所有请求buffer在内存中,然后一个个处理(或者好几个并行处理)。
  3. 这个时候,由于大量请求占用了大量的内存,erlang的gc开始显得吃力。
  4. 为了服务其中的某个请求,需要申请新的内存。
  5. 但是由于buffer住了大量请求,不够内存分配给请求处理。

这个时候erlang就陷入了一个GC与内存申请的死循环:要处理完这个请求就得申请内存,要申请内存就得GC,要GC就得处理完这个请求(否则都是有用的内存),loop forever,然后因为oom crash。


以前我对服务降级的认识停留在该节点压力过大不可用,需要减少请求以保证服务不会出现crash,而没有想过这个降级会给集群提供一个更加优越的性能表现。这里分享下我遇到的一个涉及服务降级的坑。 


先简单介绍下公司的集群架构。我们的集群大概就是一个接入集群,后接一个rabbitmq集群,通过rabbitmq,与后端的逻辑服务器实现异步请求。大概如下所示: 


front < ——— > rabbit mq < ———> logic cluster < ———> storage 


为了方便测试性能瓶颈,我们测试的时候,每个点都是只有一个进程,并且在同一台机器上运行。照说在一个机器上,cpu分配如果均匀的话,逻辑服务器应该是可以hold住所有从front过来的请求,哪怕再多也没关系。另外逻辑服务器由于从mq拿消息来处理,理论来说应该是有多少处理多少,不存在压力过大的问题,但是实际测试发现,逻辑处理服务器不断oom。


仔细分析了代码后,我们发现逻辑服务处理mq过来的数据有问题,逻辑服务器拿mq数据并且分发的逻辑如下


mq -> mq client -> mq proxy -> mq receiver -> [workers]


通过erlang的线上分析工具,我们最后定位到大量内存被使用到了mq proxy 和 mq receiver上,他们的的erlang msgq堆积大量数据,而上层又处理不过来,出现雪崩,于是导致了oom。

进一步检查,发现是 mq proxy上对内存检测的速度过慢,检测之后还要上传消息给mq client,告知其停止订阅,这个过程过于缓慢,导致了消息堆积。


主动服务降级

知道了oom的问题出在这里,就有思路了,我们主动将过多的请求直接丢弃,然后停止消费mq,主动降级服务,并且降低proxy发现消息堆积的阀值,oom就不再出现了。当然这个不是最好的办法,但是是最快处理的办法。最好的方法是通过服务发现,将服务器压力实时广播出去。

1 月25日更新:

事实上,在我们做了服务降级之后,我们的服务不再oom了,愉快做了大量的性能优化。直到前两天,又一次性能测试,发现由于服务降级的压力阀值设置过低,导致突然有压力的时候,集群又进入了另一个死循环:

压力突增 -> 一个节点服务降级,拒绝服务 -> 其他节点也因为压力增加,而拒绝服务 ->消息堆积到mq -> 服务恢复,重新订阅mq -> 积压的消息一下涌入新启动的服务 -> 服务又一次进入降级处理

这里的问题就是,服务降级的阀值过低,导致本来可以服务的节点,以为自己应该拒绝服务了,最后导致了后续的雪崩。

所以,服务降级具体应该以一个什么阀值来降,并不是一个随便定的事情,需要一个经验值,也需要结合具体环境进行适配。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值