一、application.properties 配置文件
server.port: 端口号
server.address: IP 地址
server.tomcat.accept-count: 等待队列长度,默认100
server.tomcat.max-connections: 最大可被连接数,默认10000
server.tomcat.max-threads: 最大工作线程数,默认200
server.tomcat.min-spare-threads: 最小工作线程数,默认10
# 开启 tomcat 日志
server.tomcat.accesslog.enabled=true: 开启日志
server.tomcat.accesslog.directory: 设置日志路径
# 日志格式
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D
二、容器定制
- 实现 EmbeddedServletContainerCustomizer 接口,并把实现的类纳入到 Spring 容器中管理
@Component public class MyEmbeddedServletContainerCustomizer implements EmbeddedServletContainerCustomizer { public void customize(ConfigurableEmbeddedServletContainer arg0) { TomcatEmbeddedServletContainerFactory factory= (TomcatEmbeddedServletContainerFactory)arg0; factory.setPort(10003); factory.setBaseDirectory(new File("E:\\WorkSpace\\WS_Eclipse\\springboot\\tomcat")); factory.addContextValves(getAccessLogValve()); //设置日志 factory.addInitializers((servletContext)->{ //初始化 System.out.println("=========servletContext startup============"); // servletContext.addListener(className); //添加 监听器 // servletContext.addFilter(filterName, filter); //添加 过滤器 servletContext.setAttribute("startup", "true"); //可以设置 全局变量 }); factory.addConnectorCustomizers(new MyTomcatConnectorCustomizer()); //设置连接器 } //日志设置 private AccessLogValve getAccessLogValve() { AccessLogValve log=new AccessLogValve(); log.setDirectory("E:\\WorkSpace\\WS_Eclipse\\springboot\\tomcat\\logs"); log.setEnabled(true); log.setPattern("common"); log.setPrefix("springboot-access-log"); log.setSuffix(".txt"); return log; } //连接器 class MyTomcatConnectorCustomizer implements TomcatConnectorCustomizer{ public void customize(Connector arg0) { Http11NioProtocol protocol=(Http11NioProtocol)arg0.getProtocolHandler(); protocol.setMaxConnections(2000); //最大连接数 protocol.setMaxThreads(500); //最大线程数 //设置 30s 内没有请求则服务端自动断开 keepalive 连接 protocol.setKeepAliveTimeout(30000); //当客户端发送超过 10000 个请求,则自动断开 keepalive 连接 protocol.setMaxKeepAliveRequests(10000); } }
- 在 spring 容器中装配一个 EmbeddedServletContainerFactory 对象
@SpringBootConfiguration public class WebServerConfiguration { @Bean public EmbeddedServletContainerFactory createEmbeddedServletContainerFactory() { TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); factory.setPort(10003); factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404.html")); factory.addInitializers((servletContext) -> { System.out.println("=========servletContext startup============"); servletContext.setAttribute("startup", "true"); // 可以设置 全局变量 }); factory.addContextValves(getAccessLogValve()); return factory; } // 日志设置 private AccessLogValve getAccessLogValve() { AccessLogValve log = new AccessLogValve(); log.setDirectory("E:\\WorkSpace\\WS_Eclipse\\springboot\\tomcat\\logs"); log.setEnabled(true); log.setPattern("common"); log.setPrefix("springboot-access-log"); log.setSuffix(".txt"); return log; } }
- spring 容器中如果没有 EmbeddedServletContainerFactory ,则根据使用的Web容器,创建不同的EmbeddedServletContainerFactory实现类
@Configuration @ConditionalOnClass({ Servlet.class, Tomcat.class }) @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT) public static class EmbeddedTomcat { @Bean public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() { return new TomcatEmbeddedServletContainerFactory(); } } /** * Nested configuration if Jetty is being used. */ @Configuration @ConditionalOnClass({ Servlet.class, Server.class, Loader.class,WebAppContext.class }) @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT) public static class EmbeddedJetty { @Bean public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() { return new JettyEmbeddedServletContainerFactory(); } } /** * Nested configuration if Undertow is being used. */ @Configuration @ConditionalOnClass({ Servlet.class, Undertow.class, SslClientAuthMode.class }) @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT) public static class EmbeddedUndertow { @Bean public UndertowEmbeddedServletContainerFactory undertowEmbeddedServletContainerFactory() { return new UndertowEmbeddedServletContainerFactory(); } }
备注:
MySQL 数据库 QPS 容量问题:
- 主键查询: 千万级别数据 == 1-10 ms
- 唯一索引查询: 千万级别数据 == 10-100 ms
- 非唯一索引查询: 千万级别数据 == 100-1000ms
- 无索引数据: 百万级别数据 == 1000ms+
MySQL 数据库 TPS 容量问题:
- 非插入的更新删除操作: 同查询
- 插入操作: 1w~10w tps(依赖配置优化)