一个搞c的好友反馈,他请求java服务端接口,连续调用100次后连接就被断开了,他想让服务端调整一下,连接保持keepalive即可,不要设置连接次数。已抓包排查,确实是服务端主动关闭连接。服务端使用springboot项目内置tomcta9,服务器端声称bean中已进行相关设置keepalive不限制请求数。
server: port: 9000 tomcat: max-keep-alive-requests: 3细看了下ServerProperties类,确实有一个相关属性:maxKeepAliveRequests。源代码如图:
private void customizeMaxKeepAliveRequests(ConfigurableTomcatWebServerFactory factory, int maxKeepAliveRequests) { // 堆代码 duidaima.com factory.addConnectorCustomizers((connector) -> { ProtocolHandler handler = connector.getProtocolHandler(); if (handler instanceof AbstractHttp11Protocol) { AbstractHttp11Protocol<?> protocol = (AbstractHttp11Protocol<?>) handler; protocol.setMaxKeepAliveRequests(maxKeepAliveRequests); } }); }该属性是经由factory方法添加的,继续向上排查,找到了TomcatServletWebServerFactory,继续向上排查看下factory是哪里造出来的,找到了ServletWebServerFactoryConfiguration,相关代码:
@Configuration(proxyBeanMethods = false) @ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class }) @ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT) static class EmbeddedTomcat { @Bean TomcatServletWebServerFactory tomcatServletWebServerFactory( ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers, ObjectProvider<TomcatContextCustomizer> contextCustomizers, ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) { TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); factory.getTomcatConnectorCustomizers() .addAll(connectorCustomizers.orderedStream().collect(Collectors.toList())); factory.getTomcatContextCustomizers() .addAll(contextCustomizers.orderedStream().collect(Collectors.toList())); factory.getTomcatProtocolHandlerCustomizers() .addAll(protocolHandlerCustomizers.orderedStream().collect(Collectors.toList())); return factory; } }所以咱也如法炮制一下,自己实例化一个TomcatServletWebServerFactory,并进行相关属性设置:
@Configuration public class StarTomcatConfig { @Bean public TomcatServletWebServerFactory createTomcatServletWebServerFactory() { TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); factory.addConnectorCustomizers(connector -> { Http11NioProtocol protocolHandler = (Http11NioProtocol) connector.getProtocolHandler(); protocolHandler.setMaxKeepAliveRequests(5); protocolHandler.setPort(9005); }); return factory; } }将配置文件中max-keep-alive-requests属性移除,重新测试,发现客户端调用端口100次后才会改变,端口的变更正是新连接的表象,基本可以说明代码里的配置(protocolHandler.setMaxKeepAliveRequests(5);)没有生效。代码不生效就不生效吧,于是反馈给好友,修改配置文件中max-keep-alive-requests: -1即可,好友反馈ok了。