Spring Boot - 限制创建连接数问题

76

我使用Spring Boot开发了一个微服务。我正在通过模拟后端调用来测试该服务的性能。当我查看线程计数时,我发现即使所做的调用数量要高得多,服务创建的最大线程数也始终为20个。对于使用Spring Boot开发的微服务是否存在关于可以调用的次数的限制?请指导我应该遵循哪些步骤来进行故障排除/增加服务接受的连接数?


2
你在使用哪种容器?Jetty、Tomcat、Nginx、Undertow......? - alexbt
1
server.tomcat.threads.max 的正确答案是 @Couper 下面的评论。 - duyetpt
5个回答

85

这个设置是从嵌入式容器(Tomcat、Jetty等)派生而来的。

Tomcat线程数

您可以在application.properties中指定此属性。

server.tomcat.threads.max=400

你说你数了20个线程,但是根据这个其他stackoverflow问题/答案,tomcat的默认线程数应该是200,因为server.tomcat.max-threads的默认值是0。请参考tomcat的文档

此连接器要创建的最大请求处理线程数,从而确定可以处理的最大并发请求数。如果未指定,则将此属性设置为200。如果将执行程序与此连接器关联,则忽略此属性,因为连接器将使用执行程序而不是内部线程池执行任务。

此外,以下是相关属性:

  • undertow: server.undertow.worker-threads

  • jetty: server.jetty.acceptors

你可以在Spring文档中找到属性列表。


非常感谢,Alex。我正在使用Tomcat。我会尝试并更新。 - Punter Vicky
不是我知道的。我的意思是,server.tomcat.max-threads的默认值肯定是0,所以归结为tomcat的值。如果我是你,我会尝试使用一个非常大的值(server.tomcat.max-threads=1000)并查看是否有所不同。 - alexbt
2
您可以注入 @Autowired private ServerProperties serverProperties;,然后查看 serverProperties.tomcat.maxThreads。但是如果您没有设置它,则默认值为0 (private int maxThreads = 0;)。 - alexbt
3
你可以将Spring Boot Actuator依赖项添加到你的项目中。这是一个非常好的工具,能够提供许多环境信息。端点“/env”将提供给你环境属性。 - bram000
14
自 Spring Boot 2.3 开始,正确的属性是 server.tomcat.threads.max - Couper
显示剩余4条评论

38

也许你可以查看Spring Boot的配置

server.tomcat.accept-count=100 # Maximum queue length for incoming connection requests when all possible request processing threads are in use.
server.tomcat.additional-tld-skip-patterns= # Comma-separated list of additional patterns that match jars to ignore for TLD scanning.
server.tomcat.background-processor-delay=10s # Delay between the invocation of backgroundProcess methods. If a duration suffix is not specified, seconds will be used.
server.tomcat.basedir= # Tomcat base directory. If not specified, a temporary directory is used.
server.tomcat.max-connections=10000 # Maximum number of connections that the server accepts and processes at any given time.
server.tomcat.max-http-header-size=0 # Maximum size in bytes of the HTTP message header.
server.tomcat.max-http-post-size=2097152 # Maximum size in bytes of the HTTP post content.
server.tomcat.max-threads=200 # Maximum amount of worker threads.
server.tomcat.min-spare-threads=10 # Minimum amount of worker threads.
server.tomcat.port-header=X-Forwarded-Port # Name of the HTTP header used to override the original port value.
server.tomcat.protocol-header= # Header that holds the incoming protocol, usually named "X-Forwarded-Proto".
server.tomcat.protocol-header-https-value=https # Value of the protocol header indicating whether the incoming request uses SSL.
server.tomcat.redirect-context-root=true # Whether requests to the context root should be redirected by appending a / to the path.
server.tomcat.remote-ip-header= # Name of the HTTP header from which the remote IP is extracted. For instance, `X-FORWARDED-FOR`.
server.tomcat.resource.cache-ttl= # Time-to-live of the static resource cache.
server.tomcat.uri-encoding=UTF-8 # Character encoding to use to decode the URI.
server.tomcat.use-relative-redirects= # Whether HTTP 1.1 and later location headers generated by a call to sendRedirect will use relative or absolute redirects.


2
“accept-count”和“max-connections”的区别是什么?“accept-count”不应该比“max-connections”大吗? - Chloe
6
accept-count 是指等待处理的连接请求队列中的请求数,这就是队列的大小。 max-connections 表示同时可以处理的最大连接数,这就是最大连接数。通常情况下,max-connections 应该大于 accept-count - Bruce
1
如果最大工作线程数量为200,则可以同时处理200个请求,那么如何做到的?@Bruce server.tomcat.max-threads=200 - Swapan Shaw

18

虽然已经有一个非常有用的答案,但我最近遇到了一个我认为与原始帖子相同的问题。这是我能找到的唯一直接相关我的经验的搜索结果,所以我想加上我的解决方案以帮助他人。

在我的情况下,20的并发限制是由org.apache.coyote.http2.Http2ProtocolmaxConcurrentStreamExecution属性的默认设置20所施加的。

如果你正在使用HTTP/2并且遇到了这个问题,增加 maxConcurrentStreamExecution 的值可能会有所帮助。

你可以在Tomcat配置参考文档中找到更多信息,该文档实际上指出这应该默认设置为200(而不是20)。不过,你肯定可以在org.apache.coyote.http2.Http2Protocol中看到默认设置为20,因此我不确定这是否是一个打字错误或者只是在Tomcat的嵌入式版本中呈现不同的东西。


1
文档已经更改,现在标明为“20”。因此观察到的行为与文档相符。 - Mirko Jahn
我本来想问如何使用它,但看起来在Spring Boot服务器中有一个标志server.http2.enabled=true。 - Kalpesh Soni
2
重要的是要注意,“maxConcurrentStreamExecution”是指在HTTP 2协议上单个连接的并发流,而不是容器可以接受的最大连接数。 - Shlomi Uziel

5
如果您拥有执行器,您可以查看指标。
/actuator/metrics/tomcat.threads.config.max
{
  "name": "tomcat.threads.config.max",
  "description": null,
  "baseUnit": null,
  "measurements": [{
    "statistic": "VALUE",
    "value": 200.0
  }],
  "availableTags": [{
    "tag": "name",
    "values": ["http-nio-8080"]
  }]
}

Tomcat决定创建的实际值是什么?

根据负载情况,可能会看到10。

Spring Boot似乎从未完全使用最大线程数,但您可以从更多线程开始。

server:
   tomcat:
     min-spare-threads: 40

1
在Spring Boot 2中增加HTTP/2的maxConcurrentStreamExecution(设置为200):
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> containerCustomizer() {
    return new WebServerFactoryCustomizer<TomcatServletWebServerFactory>() {
        @Override
        public void customize(TomcatServletWebServerFactory factory) {
            factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
                @Override
                public void customize(Connector connector) {
                    Arrays.stream(connector.getProtocolHandler().findUpgradeProtocols())
                        .filter(upgradeProtocol -> upgradeProtocol instanceof Http2Protocol)
                        .map(upgradeProtocol -> (Http2Protocol) upgradeProtocol)
                        .forEach(http2Protocol -> http2Protocol.setMaxConcurrentStreamExecution(200));
                }
            });
        }
    };
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接