Tomcat请求线程池默认线程数量为10,最大为200
min-spare-threads: 10
max-threads: 200
当超过最大值时,对进入到等待对列,队列长度默认为100
accept-count: 100
springboot1.×
@Autowired ServletWebServerApplicationContext applicationContext; TomcatServletWebServerFactory tomcatServletWebServerFactory=applicationContext.getBean(TomcatServletWebServerFactory.class); String tomcatLog = (((TomcatWebServer)(tomcatServletWebServerFactory.getWebServer())).getTomcat().getConnector()).getProtocolHandler().getExecutor().toString();
springboot2.×
@Autowired ServletWebServerApplicationContext applicationContext; String tomcatLog = ((TomcatWebServer) applicationContext.getWebServer()).getTomcat().getConnector().getProtocolHandler().getExecutor().toString();
接下来如何融入到springboot项目中呢?
第一反应是写个定时任务,结果失败,因为要拿到Tomcat的连接。如果只是项目里的cron,并没涉及到Tomcat层面的连接,也就拿不到相关信息
第二反应是写个拦截器吧,拦截actuator/prometheus,并注入自定义的Prometheus参数。结果失败,拦截器默认是拦截不到这个接口,只能拦截到我们的业务接口。具体原理需回头探究。
第三反应是写个过滤器吧,过滤器是可以拿到接口的。但新的问题又来了。过滤器由于生命周期的原因,一些注入的bean是拿不到的。只得在配置类上加上component注解,不过付出的代价是,需要在内部处理url过滤的问题
最终代码如下
拦截器:
@Slf4j
@Component
public class PrometheusFilter implements Filter {
@Autowired
ServletWebServerApplicationContext applicationContext;
@Autowired
private PrometheusApacheThreadMonitor monitor;
private static final String URL = "/actuator/prometheus";
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
String path = ((HttpServletRequest) servletRequest).getServletPath();
if(URL.equals(path)) {
log.info("进入统计");
Executor executor = ((TomcatWebServer) applicationContext.getWebServer()).getTomcat().getConnector().getProtocolHandler().getExecutor();
String tomcatLog = executor.toString();
String regex = "queued tasks = (\d+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(tomcatLog);
matcher.find();
Integer size = Integer.valueOf(matcher.group(1));
monitor.getQueuedTasks().set(size);
}
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
@Component
@Slf4j
public class PrometheusApacheThreadMonitor {
private final CollectorRegistry registry;
private Gauge register;
@Autowired
public PrometheusApacheThreadMonitor(CollectorRegistry registry) {
this.registry = registry;
}
@PostConstruct
private void init() {
register = Gauge.build("queued_tasks", "help").register(registry);
}
public Gauge getQueuedTasks() {
return register;
}
}



