分布式系统应对雪崩及如何防范数据被非法篡改

最近遇到这两个问题,整理思路如下。

应对雪崩

通过流控,然后对每秒请求数量的限制,或者线程并发的限制。让系统不雪崩。或者说通过实时的监控平台,发现雪崩的正在形成。然后实时调整参数,避免雪崩。

某个业务大概有多少的量其实一般都是比较清楚的,不会超过太多,设置时增加一点的量,给一个数值给它,如果超了,或者达到的报警值,那么就可以查下原因,是真的业务增长了还是的系统出了问题。另外,及时识别和处理无效或者超时请求,避免雪球的堆积。也很重要(开启单独进程,利用时间戳,在业务开始前,对比该请求时间戳是否早于当前与timeout的差值)。

【备注】线程并发限制方案:To be continued...


参考:1.java流控方案  2.轻量级系统监控方案  3. 小心雪崩效应 

3. dubbo流控

就算是不敏感的服务,也不是能任意调用,比如某服务突然多了一个消费者,这个消费者的请求量直接把服务给拖跨了,其它消费者跟着一起故障。

首先服务提供方需要流控,当流程超标时,能拒绝部分请求,进行自我保护。

其次,消费者上线前和提供者约定《服务质量等级协定(SLA)》,SLA包括消费者承诺每天调用量,请求数据量,提供方承诺响应时间,出错率等,将SLA记录在监控中心,定时与监控数据对比,超标则报警。

虽然有SLA约定,如果不能控制,就只是君子协定,如何确保服务质量?

比如:一个应用很重要,一个不那么重要,它们调用同一个服务,这个服务就应该向重要应用倾斜,而不是一视同仁,当支撑不住时,应限制不重要应用的访问,保障重要应用的可用,如何做到这一点呢。这时,就需要服务路由,控制不同应用访问不同机器,比如:
应用分离:
consumer.application = foo => provider.host = 1,2,3
consumer.application != foo => provider.host = 5,6
读写分离:
method.name = find*,get* => provider.host = 1,2,3
method.name != find*,get* => provider.host = 5,6

总结:就是首先让系统不雪崩,然后通过监控发现请求正在接近或者超过阀值,然后再根据具体情况处理。这个接近或者超过阀值的过程,可以称为  “提前发现雪崩”。

流控相关方案,参考:java应用的并发与流量控制

关键数据:金额或者支付数据被非法修改。

将最后操作余额的操作号,加上余额做个唯一算法(md5),得出一个值,然后存储。在需要检测这个余额的时候就算一次,如果两个是一致的,那么这个余额就是系统业务改的,反之是非法修改。

此过程通过后台的Job执行,认为是被改了的,就不能提钱或者将这个钱用掉,并将这个东西记录到一个运维用的监控里面,让人工核查,不过首先要保证系统中的关键流程每一步都是可以追溯的。

展开阅读全文

没有更多推荐了,返回首页