本周掘学 2019年六月第三周

251 阅读3分钟
一个全端、全栈兼运维的打杂工程师的工作日志,20190617-0621。

线程池

事情的起因是一个服务不时会报502,首先看Nginx日志,有三类错误日志:

upstream prematurely closed connection while reading response header from upstreamconnect() failed (111: Connection refused) while connecting to upstreamno live upstreams while connecting to upstream

查看服务机器,CPU、内存、负载正常,查看tomcat实例,GC正常,请求量正常,这就很奇怪了,看了各种参数,发现唯一异常的值是进程打开的文件句柄数过多

lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr|more

使用这个命令查到的异常进程的打开文件句柄数是300w+,其他类似tomcat进程则是几十万水平,并且重启该进程后该数值也会迅速上涨至百万以上。查到这,有些怀疑是不是代码有问题导致IO流没有关闭,查了最近代码修改,并没有找到可疑的点。此时想起可以看看进程的线程数,一看才发现竟然有2000+线程了,导出一看才明白,原来是项目里误用了okhttp

jstack <pid>

项目里有一处需要调用第三方http接口,之前代码在每次请求时都创建了一个OkHttpClient实例,然而OkHttpClient实例内部其实是默认有创建线程池的,最近这个业务量上涨了很多,大量的请求并发导致创建线程数过多。正确的用法应该是维持单独一个OkHttpClient的实例,每次请求复用该实例即可。


TPAD

本周开始用tpad做团队协作工具,之前用Jira Alige,其实我觉得Alige真的很专业了,工作流完全可以自定义,任务有完整的Spring、Epic、Task体系,有很强的自定义空间,还有强大的Filter可创建自定义视图,适合进阶玩家,但就是学习成本偏高,需要花时间去理解它的设计原理,如果不按照规范去做,就容易误用。tpad腾讯也做了有几年了,真是没啥进步,到现在依然在基础设计、交互上还是那么原始,用户管理体系也超级难用,团队二十多人,我为了发邀请、分配权限这几个基本操作,硬是搞了几个小时。相比Alige、Teambition等工具,tpad能够生存,唯一的原因就是免费。


Tomcat

Java Web开发的技术栈是挺深的,每次想到自己写的代码运行在一个中间层上,而且自己对这个中间层一点都不了解,就觉得很方,本周找了资料学习下tomcat的原理。tomcat可以分为两大部分:连接器和容器。

连接器将外部的请求转化为符合servlet规范的Request,然后将servlet规范的Response转化为外部响应输出。servlet规范并没有要求一定要用http协议,只是大部分场景下是http,tomcat在设计时给协议这里预留了扩展。

容器负责实现servlet规范,容器本身采用了层级组件式设计,每一层从大到小都是包含关系,这样设计具有很强的灵活性,并且这个设计在tomcat一键启停中也发挥了很重要的作用。


end