diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/ServletConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/ServletConfig.java
index 6bcbe50b609..d87938c5507 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/ServletConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/ServletConfig.java
@@ -28,6 +28,14 @@ public class ServletConfig implements Serializable {
*/
private Boolean enabled;
+ /**
+ * Maximum concurrent streams.
+ *
For HTTP/2
+ *
Note that the default value for tomcat is 20. Highly recommended to change it to {@link Integer#MAX_VALUE}
+ *
If set to zero or a negative number, the actual value will be set to {@link Integer#MAX_VALUE}.
+ */
+ private Integer maxConcurrentStreams;
+
/**
* The URL patterns that the servlet filter will be registered for.
*
The default value is '/*'.
@@ -48,6 +56,14 @@ public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
+ public Integer getMaxConcurrentStreams() {
+ return maxConcurrentStreams;
+ }
+
+ public void setMaxConcurrentStreams(Integer maxConcurrentStreams) {
+ this.maxConcurrentStreams = maxConcurrentStreams;
+ }
+
public String[] getFilterUrlPatterns() {
return filterUrlPatterns;
}
diff --git a/dubbo-spring-boot/dubbo-spring-boot-3-autoconfigure/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-3-autoconfigure/pom.xml
index e65cf6bf5fd..07ec5b92a4a 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-3-autoconfigure/pom.xml
+++ b/dubbo-spring-boot/dubbo-spring-boot-3-autoconfigure/pom.xml
@@ -70,7 +70,12 @@
jakarta.servlet
jakarta.servlet-api
- true
+ provided
+
+
+ org.apache.tomcat.embed
+ tomcat-embed-core
+ provided
diff --git a/dubbo-spring-boot/dubbo-spring-boot-3-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTriple3AutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-3-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTriple3AutoConfiguration.java
index 6b03e6be7d0..8caac7a29a7 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-3-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTriple3AutoConfiguration.java
+++ b/dubbo-spring-boot/dubbo-spring-boot-3-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTriple3AutoConfiguration.java
@@ -20,11 +20,16 @@
import org.apache.dubbo.rpc.protocol.tri.servlet.jakarta.TripleFilter;
import jakarta.servlet.Filter;
+import org.apache.coyote.ProtocolHandler;
+import org.apache.coyote.UpgradeProtocol;
+import org.apache.coyote.http2.Http2Protocol;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
+import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory;
+import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
@@ -39,7 +44,7 @@ public class DubboTriple3AutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Filter.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
- @ConditionalOnProperty(prefix = PREFIX, name = "enabled")
+ @ConditionalOnProperty(prefix = PREFIX, name = "enabled", havingValue = "true")
public static class TripleServletConfiguration {
@Bean
@@ -54,5 +59,23 @@ public FilterRegistrationBean tripleProtocolFilter(
registrationBean.setOrder(order);
return registrationBean;
}
+
+ @Bean
+ @ConditionalOnClass(Http2Protocol.class)
+ @ConditionalOnProperty(prefix = PREFIX, name = "max-concurrent-streams")
+ public WebServerFactoryCustomizer tripleTomcatHttp2Customizer(
+ @Value("${" + PREFIX + ".max-concurrent-streams}") int maxConcurrentStreams) {
+ return factory -> factory.addConnectorCustomizers(connector -> {
+ ProtocolHandler handler = connector.getProtocolHandler();
+ for (UpgradeProtocol upgradeProtocol : handler.findUpgradeProtocols()) {
+ if (upgradeProtocol instanceof Http2Protocol) {
+ Http2Protocol protocol = (Http2Protocol) upgradeProtocol;
+ int value = maxConcurrentStreams <= 0 ? Integer.MAX_VALUE : maxConcurrentStreams;
+ protocol.setMaxConcurrentStreams(value);
+ protocol.setMaxConcurrentStreamExecution(value);
+ }
+ }
+ });
+ }
}
}
diff --git a/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/pom.xml
index 7e3b19cb4e0..5f9ebd3daf1 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/pom.xml
+++ b/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/pom.xml
@@ -83,6 +83,11 @@
javax.servlet-api
provided
+
+ org.apache.tomcat.embed
+ tomcat-embed-core
+ provided
+
diff --git a/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTripleAutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTripleAutoConfiguration.java
index 16f21dfef8d..3dfecdb9529 100644
--- a/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTripleAutoConfiguration.java
+++ b/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboTripleAutoConfiguration.java
@@ -21,11 +21,16 @@
import javax.servlet.Filter;
+import org.apache.coyote.ProtocolHandler;
+import org.apache.coyote.UpgradeProtocol;
+import org.apache.coyote.http2.Http2Protocol;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
+import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory;
+import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
@@ -40,7 +45,7 @@ public class DubboTripleAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Filter.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
- @ConditionalOnProperty(prefix = PREFIX, name = "enabled")
+ @ConditionalOnProperty(prefix = PREFIX, name = "enabled", havingValue = "true")
public static class TripleServletConfiguration {
@Bean
@@ -55,5 +60,23 @@ public FilterRegistrationBean tripleProtocolFilter(
registrationBean.setOrder(order);
return registrationBean;
}
+
+ @Bean
+ @ConditionalOnClass(Http2Protocol.class)
+ @ConditionalOnProperty(prefix = PREFIX, name = "max-concurrent-streams")
+ public WebServerFactoryCustomizer tripleTomcatHttp2Customizer(
+ @Value("${" + PREFIX + ".max-concurrent-streams}") int maxConcurrentStreams) {
+ return factory -> factory.addConnectorCustomizers(connector -> {
+ ProtocolHandler handler = connector.getProtocolHandler();
+ for (UpgradeProtocol upgradeProtocol : handler.findUpgradeProtocols()) {
+ if (upgradeProtocol instanceof Http2Protocol) {
+ Http2Protocol protocol = (Http2Protocol) upgradeProtocol;
+ int value = maxConcurrentStreams <= 0 ? Integer.MAX_VALUE : maxConcurrentStreams;
+ protocol.setMaxConcurrentStreams(value);
+ protocol.setMaxConcurrentStreamExecution(value);
+ }
+ }
+ });
+ }
}
}