引言
本文通过一次现场“血案”为引子,探讨tomcat对http的请求,由于springBoot已经被多数公司采用,本文探讨的都是基于springBoot内置的tomcat来进行分析和说明。
问题背景
服务A调用B的功能基本上都返回超时错误,直接请求服务B的http接口也是超时。
问题分析
通过jstack查看线程,发现有如下大量的日志:
分析这些Runnable的线程,发现数量等于配置的tomcat线程数,而且阻塞都发生在服务B调用服务D的过程中。如图所示:
那么即使服务B和服务D之间的调用时间很长,为什么服务A从来没有成功过,后来通过分析发现服务C调用D这个接口存在超时重试,而且是服务和服务B之间的超时时间比服务A短很多,所以服务C占用了所有的服务B的线程连接导致服务A的请求无法响应。由此我们分析一下springboot中tomcat的一部分原理。
原理分析
springboot启动tomcat流程
上图是笔者对springBoot启动过程如何启动tomcat进行代码调试绘制的顺序图,读者不必过于在乎上面的内容,只要知道像下面这种方式启动springboot,就会调用到NioEndpoint类,然后调用这个类的bind方法,绑定到特定端口进行数据监听。
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
整体流程如下:
http请求调用的顺序图为:
总结
1、tomcat中线程是有限的,切记对一些远程操作,一定要设置合理的超时时间。