当前位置: 首页 > 科技观察

谁更快!谁是幕后黑手(技术分析)

时间:2023-03-20 00:27:59 科技观察

本文转载自微信公众号《小姐姐的味道》,作者小姐姐养的狗。转载本文请联系味觉小姐公众号。半夜,领导:“你写的接口有问题!赶紧起来看看。”叮!提醒软件一响起,您就知道该上班了。但是想来想去,我觉得不可能。我的代码只是一个简单的redis查询。会不会是Redis挂了?我的同事把所有的证据都发给了小组。它无疑是您的界面。一个简单的Get查询平均需要2秒。jstack,promethus的监控,把所有的问题都指向你的接口!登录Redis服务器,一切正常。我应该怎么办?就这么含糊其辞的背着章丘的大铁锅?1.在这种情况下,这几乎是原罪,你必须相信你的直觉。你的界面又快又好,估计穆修雨会脱颖而出,而你就是背黑锅的。在“某些”“高并发”环境下,由于资源没有隔离,当出现问题时,一些日志和工具的表现会很混乱。问题是速度最快,请求最多的接口,但理论上是不可能的。如上所示。这种情况很常见。大多数请求,通过Tomcat线程池的调度,进行真正的业务处理。当然,线程池是不会干这种脏活累活的。它将请求交给资源处理池进行处理,例如:数据库连接池,进行耗时统计操作和快速查询操作;一个Redis连接池,执行阻塞慢查询和简单的GETSET一个Http连接池(HTTPClient,OkHTTP等),远程调用不同速度的资源...在我们平时的编码中,我们通常共享这样一个资源池。因为写代码容易,不需要动脑子。但是如果你的服务本身没有很好的拆分和隔离,问题就会很致命。比如你把报表接口和高并发的C端接口放在一个实例上。这时候,你可能会被举报界面给骗了。2.一个例子下面以数据库连接池为例来说明这个过程。先看下面的基本信息:Tomcat的连接池配置大小为200个MySQL连接池,配置大小为50个,比较大接口A需要调用一个耗时查询,耗时5秒。接口B非常快。接口B查询数据库响应时间快于200ms。请求量比接口A大很多,一般情况下是安全的。有一天,接口A突然有大量的查询,由于耗时长,很快就把数据库的50个连接池填满了(接口B响应快,保持时间短,慢慢就会连接了)被A吃掉了)。这时候无论是接口A还是接口B的请求,都需要至少等待5秒,才能拿到下一个数据库连接,业务才能正常进行。不一会儿,服务的状态就变成了这样:数据库连接池很快就塞满了50个连接,几乎都被慢查询填满了。Tomcat连接池的200个连接很快就满了,其中大部分是快速接口B,由于其请求量大,速度快,所有接口都阻塞在Tomcat线程上。进而造成:即使是查询非数据库的请求,也要等待5秒左右。一般遇到这种问题,我们倾向于使用jstack打印信息栈,或者查看一些内部监控曲线。遗憾的是,这些信息大部分都是骗人的。你看到的慢查询并不是真正的慢查询。从上面对xjjdog的分析,大家应该很容易看出问题的症结所在:不隔离的瓶颈资源导致了上游资源的连锁反应。但在平时的工作中,xjjdog不止一次看到有同学为此着急。很多证据都指向一些快速和好的接口,而这些与它们完全无关。他们欢快的截图,@相关人士等等,狂妄至极。对于这种情况,可以使用如下脚本进行初步分析:$cat10271.tdump|grep"waitingtolock"|awk'{print$5}'|sort|uniq-c|sort-k1-r26<0x0000000782e1b590>18<0x0000000787b00448>16<0x0000000787b38128>10<0x0000000787b14558>在上面的例子中,我们发现执行栈锁定了0x0000000782e1b590,可以发现都卡在了HttpClient的读操作中。实际场景中,可以查看top锁地址,寻找共性。而这些显示很少信息的堆栈是问题的根源。3、如何解决问题加大Tomcat连接池大小,或者加大连接池大小,都不能解决问题,大概率会复发。最好的解决方案当然是把耗时的服务和正常的服务分开,比如现在流行的微服务。你的服务查询慢,你自己的访问超时,和我的服务无关。但是,既然你们的服务能遇到这样的问题,就证明你们公司不具备这样的改造条件。只能在单体服务上做文章。这种方法是隔离。如上图,我们在同一个项目中创建了两个MySQL数据库连接池,指向同一个MySQL地址。这样连接池的操作就可以相对独立了。但是到目前为止,还没有结束,因为你的Tomcat连接池还是共享的。慢查询相关,需要改变从连接池获取连接的策略。与其一直等待,不如使用FailFast方法(获取连接的短暂超时也是可以的),否则症状还是一样。流行的断路器概念也在一定程度上实践了这种隔离。End我们也可以想到一个类似的场景:STW发生在JVM中,在停顿期间,受影响最大的是那些请求快,规模大的接口。而那些耗费时间的界面,因为平时就像那只鸟一样,没有人注意它的异常情况。一堆接口连接到同一个数据库。当数据库发生波动时,受影响最大的还是那些请求快、数据量大的接口。因为那些耗时的慢查询一直都是这样,所以没有人会怀疑他们。殊不知,只要这些不良接口的请求量增加,就会像老鼠屎一样,打破一锅汤,所有的请求都会被拖垮。这有点类似于我们平时的工作:效率低下的人一多,就会拖累整个项目的进度。领导一直疑惑,为什么那么多技术专家效率这么低?这是因为他们被拖累了。由于过于关注个人,最根本的问题就隐藏在表面之下。公司内部的研发永远不应受到平等对待。追求不同技术的员工也应该实现类似的隔离,而不是缺乏。由好人组成的团队,沟通顺畅,目标一致,效率极高;而那些擅长拖延项目的员工,应该被安排在一个效率低下的团队中,加班加点到最后。说了这么多,问题的症结在于:不是每个人都能理解这个规律,也很少有人关注背后的根源。你要跟领导说明你的界面没有问题,费了很大功夫。“老大,我找到原因了,是因为MySQL查询慢,把Tomcat的连接池填满,导致Redis对应的Http请求响应慢。”如此错综复杂的关系,着实让人头疼。“很好,”领头的说道,“这件事就让你带头解决吧。”你看,大多数领导都不关注问题的原因,他们只关注谁能解决问题,即使这不是你的问题。谁让你写好代码,快速满足需求的!作者简介:品味小姐姐(xjjdog),一个不允许程序员走弯路的公众号。专注于基础架构和Linux。十年架构,每天百亿流量,与你探讨高并发世界,给你不一样的滋味。我的个人微信xjjdog0,欢迎加好友进一步交流。