Spring Boot - 限制创建的连接数

Posted

技术标签:

【中文标题】Spring Boot - 限制创建的连接数【英文标题】:Spring Boot - Limit on number of connections created 【发布时间】:2016-12-24 10:24:27 【问题描述】:

我使用 Spring Boot 开发了一个微服务。我通过存根后端调用来测试服务的性能。当我查看线程数时,我发现在任何时间点为服务创建的最大线程数都是 20,即使调用的次数要高得多。对于可以对使用 Spring Boot 开发的微服务进行的调用次数是否有任何限制。请您指导我需要遵循哪些步骤来排除故障/增加服务接受的连接数?

【问题讨论】:

您使用的是哪个容器?码头、tomcat、nginx、undertow……? 【参考方案1】:

此设置源自嵌入式容器(tomcat、jetty...)。

Tomcat 的线程数

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

server.tomcat.max-threads=400

你说你统计了20个线程,但是根据other *** question/answer,tomcat的默认线程数应该是200,因为server.tomcat.max-threads的默认值为0。见tomcat's documentation:

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

另外,属性:

暗流server.undertow.worker-threads

码头server.jetty.acceptors

您将在Spring's documentation 中找到属性列表

【讨论】:

非常感谢,亚历克斯。我正在使用tomcat。我会尝试更新 嗨,Alex,有没有办法在我的应用中打印默认值? 可以注入@Autowired private ServerProperties serverProperties;,然后查看serverProperties.tomcat.maxThreads。但是如果不设置,默认值为0(private int maxThreads = 0; 您可以将 spring boot 执行器依赖添加到您的项目中。它是一个很棒的工具,可以为您提供大量环境信息。端点 /env 将为您提供环境属性。 从 Spring Boot 2.3 开始,正确的属性是 server.tomcat.threads.max【参考方案2】:

也许,你可以看看springboot's config

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.

【讨论】:

accept-countmax-connections 有什么区别? accept-count 不应该大于max-connections 吗? accept-count是队列中等待处理的连接请求,这是队列大小。max-connections是同时可以处理的最大连接数,这是最大连接数.通常,max-connections 应该大于 accept-count @Bruce server.tomcat.max-threads=200 如果最大工作线程数为 200 那么它可以随时并发处理 200 个 req 那么如何?【参考方案3】:

虽然接受的答案非常有用,但我最近遇到了我认为与原始发帖人相同的问题。这是我能找到的唯一与我的经历直接相关的搜索结果,所以我想我会添加我的解决方案以防它对某人有所帮助。

在我的例子中,观察到的并发限制 20 是由 org.apache.coyote.http2.Http2ProtocolmaxConcurrentStreamExecution 属性的默认设置 20 强加的。

如果您遇到此问题并且您正在使用 HTTP/2,那么增加 maxConcurrentStreamExecution 很有可能会有所帮助。

您可以在Tomcat Configuration Reference 中找到更多信息,它实际上指出默认情况下应将其设置为 200(而不是 20)。不过,您肯定可以在 org.apache.coyote.http2.Http2Protocol 中看到默认设置 20,所以我不确定这是一个错字还是只是在 Tomcat 的嵌入式版本中呈现不同的东西。

【讨论】:

文档在此期间发生了变化,现在状态为“20”。因此观察到的行为与文档相符。 本来想问怎么用的,但是好像spring boot server里有flag.http2.enabled=true 请注意,“maxConcurrentStreamExecution”是指通过 HTTP 2 协议的单个连接的并发流,而不是容器可以接受的最大连接数。【参考方案4】:

如果你有执行器,你可以看到指标

/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 决定创造的实际价值? /actuator/metrics/tomcat.threads.current

根据负载,您可能会看到 10 个

spring boot 似乎从来没有完全使用 max-threads 但是,您可以从更多开始

server:
   tomcat:
     min-spare-threads: 40

【讨论】:

【参考方案5】:

在 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));
                
            );
        
    ;

【讨论】:

以上是关于Spring Boot - 限制创建的连接数的主要内容,如果未能解决你的问题,请参考以下文章

Spring-Boot:如何设置 JDBC 池属性,例如最大连接数?

如何配置Spring Boot内嵌的tomcat8的最大线程数,最大连接数

Spring Boot Redis Cluster 实战干货

spring boot配置信息详解

杂谈Spring Boot 默认支持的并发量

spring boot JPA 和 数据库连接