饿了么分布式服务治理及优化经验
光展示,我们觉得它的价值还没有利用到极致,可以把所有的调用关系和报警结合在一起.大家分析问题的时候,会发现如果某个点上发生的错误一直往上报,从而导致整条链路失败,那这个点就是 root cause,把它修复就可以问题解决了.我们做 trace 的思路是一样的,在调用链上进行着色,辅助找到问题的 root cause,也就是最初发生问题的那个点. 服务治理的经验我们最重要的经验是做好保护与自我保护. “不能被烂用的框架不是好框架”,这个是我们 CTO 经常说的一句话.原因是什么?比如我们那个监控的 SDK 曾经被业务错误的使用,每发一次报警就启一个新线程,最后整个进程因为开了太多的线程挂掉了.峰哥(CTO)说你无法预测每个开发者会怎么使用你的框架,即使框架被滥用了,最坏的情况,也需要保证能够活的下去. 所以后面写的东西都严格要求自我状态的检查,比如秒杀的时候,所有的监控系统,链路跟踪系统都是可以降级的,不能因为这些东西导致整个系统崩溃. 框架由于在底层,出了问题最容易被怀疑.比如一个 SDK,使用方说为什么占用了整个集群上 8% 的 CPU?跑过去一看,整个机器的 CPU 才 12%.某种程度做框架其实有无助的时候,容易被质疑及谴责,所以做好自我状态检查是很必要的. 定期线上扫描为了避免滥用的问题,我们会定期线上扫描.比如一些日志本来就是可以降级可以丢的,但如果开发用了写文件的同步方式,那性能就会变慢,通过扫描发现这些问题,改成异步日志服务性能就会更好. 限流、熔断、降级这个强调多少遍都不过分,因为确实很重要.服务不行的时候一定要熔断.限流是一个保护自己最大的利器,原来我们前端是用 PHP 做的,没有自我保护机制,不管有多少连接都会接收,如果后端处理不过来,前端流量又很大的时候肯定就挂了.所以我们做任何框架都会有限流措施. 有个小插曲,我们上 DAL (数据库中间件)第一版的时候,有次一个业务怎么指标突然降了 50%,然后大家去查,原来 DAL 做了限流,你不能做限流,你把它给我打开,听你们的我打开了,打开了然后数据库的 QPS 瞬间飙到两万,业务部门就慌了,赶紧邀请我们再给他限制住.这是我觉得 DAL 做的最好的一个功能. 连接复用还有连接复用,有些工程师并不能特别理解,如果不用连接池,来一个请求就发一个连接怎么样?这样就会导致后端资源连接过多.对一些基础服务来说,比如 Redis,连接是个昂贵的消耗.所以我们一些中间件的服务都实现了连接复用的功能. 代码发布上线发布是很危险的一件事情,绝大部分的事故都是由发布引起的,所以发布需要跟很多系统结合起来,所以我们做了整套流程.在每次发布的时候,一个发布事件开始,到我们这个监控系统以及调用链上,调用链就开始分析了,发布后把它的所有指标比一比,到底哪些指标发生了改变,这些指标如果有异常,就发报警,所有发布都会打到监控的主屏上面去,如果出了什么问题,这些事情优先回滚,如果可以回滚,我们肯定第一时间就把问题解决掉了. 服务治理的痛点配置复杂超时配置:超时配多少是合适的?100ms?300ms?极端情况有些业务配到 3 秒的.阈值怎么配和超时怎么配其实是同一个概念,并不是所有的程序员都知道超时设成多少合适.那怎么办?峰哥(CTO)想了一个办法,你的监控系统,你的调用链分析系统,你的日志系统,基础监控系统每天产生多少数据?这些数据到底有没有用?是否可以从这些数据里面挖掘出一些东西,比如这种超时的配置,是可以基于它历史的超时配置、所有请求的响应时间去做的. 这件事情正在进行中,但落地有点麻烦,比如说我们请求大概每天有三千万的调用量,你只有很小的一个比例它会超时,但是绝对量是很大的,你设置一个超时值,它可能有三万个请求都失败了.现在一直在优化这个东西,希望下次大家来我们这里的时候,能给大家详细介绍一下这个超时到底怎么做. 线程池配置:刚才说最重要的是限流,你不可能无限制的接受请求,不可能一百个并发你就接收一百个并发,并发到底怎么配?又是很复杂的事情.我经常看我们线程池的配置,这个东西要经过严格的性能测试,做很多调整才能调出来.在做性能测试的时候,其实有条曲线的,有个最高点的,我们在想在实时的过程中计算出这个最高点,但发现这个东西其实挺难的. 我们便用了另外一种方法,每个线程池用一个排列队列,当我发现它在涨的时候我就适当把那个线程池扩大一点,同时我们监测其他指标.如果发现在我扩大并发量的时候这些指标产生了报警,那我就把这个线程调整的操作直接拒绝掉,就保持原来那个大小.如果这些指标证明是没有问题的,那我就把它再扩大一点. Cache,DB,Queue 的手工配置问题.还有一个是服务治理,Redis、数据库等配置还都是手工的,我们也不知道我们线上有 Redis,怎么办?我们正在做基础服务的服务化,业务其实不需要关心到底连到哪个 Redis,你上线的时候你告诉我你需要多大的容量,填个工单过来,运维帮你配好了,然后通过一些自动化的方式你把这些拿到初始化 SDK 就可以了. 故障定位还有一个比较痛的问题就是排查问题很难.首先故障定位困难,每次我们出了事情之后,大家各自查各自的,比较低效.问题排查其实是有方法可以做,需要把它自动化,我们现在还缺这个东西,调用链分析是需要考虑去做. 性能退化我们现在的业务增长量非常恐怖,去年我们是以 5 倍的速度增长了,但其实这个 5 – 10 倍要看你的基数,当基数很大,扩一倍量也是非常多,评估线上到底要布多少台机器是一件很复杂的事情. 我们成立一支性能测试团队,做全链路的压测.基于全链路压测的结果来评估整个系统的容量.这个全链路只能在线上做,也不能在白天压,只能在晚上低峰期的时候做.所以性能测试也是一个比较挑战的工作,不仅仅是智力上,也是身体上的一种考验. 全链路压测试一些服务有时候出现性能下降,比如 QPS 从 500 下降到了 400,但大家并不知道最直接的原因.上次毕洪宇老师也帮我们出了主意,比如把全链路指标拉出来做一下对比,看看哪些指标有变化,可能就是罪魁祸首. 容量评估的方法容量评估方面容易出现温水煮青蛙的事情,今天流量增长一点没问题,明天再增长一点也没有问题,连续几天然后服务就挂了.这个时候怎么办?只能用最苦逼的方法,找个性能测试团队进行压测.有没有更智能化的方法?我们也正在探寻这条道路. 资源利用率低(编辑:PHP编程网 - 黄冈站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |