package com.shkpr.service.aimodelpower; import com.global.base.component.SnowFlakeEx; import com.global.base.log.LogLevelFlag; import com.global.base.log.LogPrintMgr; import com.shkpr.service.aimodelpower.constants.LogFlagBusiType; import com.shkpr.service.aimodelpower.globalcache.GlobalData; import com.shkpr.service.aimodelpower.globalmgr.ThreadTaskMgr; import com.shkpr.service.aimodelpower.interfaces.sinks.LogPrintSink; import org.apache.catalina.connector.Connector; import org.apache.catalina.core.AprLifecycleListener; import org.apache.coyote.AbstractProtocol; import org.apache.coyote.http11.Http11AprProtocol; import org.apache.coyote.http11.Http11NioProtocol; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.retry.annotation.EnableRetry; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.annotation.PostConstruct; @EnableTransactionManagement //开启数据库事务 @SpringBootApplication @EnableRetry public class AimodelpowerApplication { @Value("${global.server.apr:false}") private boolean mBUseApr = false; @Value("${server.port:9001}") private int mNPort; @Value("${global.server.id:tri.adbs.v100}") private String mStrServerId; //本服务的ID @Value("${global.machine.index:0}") private int mOwnerMachineIndex; //本服务所在的部署机器的索引编号 @Value("${global.service.index:0}") private int mOwnerServiceIndex; //本服务在部署机器上的服务索引编号 @Value("${global.max.tomcat.concurrent.request:10000}") private int mNMaxConcurrentRequest; //tomcat同一时刻可接收的第三方最大并发连接数(Java NIO模式下默认是10000) @Value("${global.max.tomcat.threads:200}") private int mNMaxThreads; //tomcat可启动的最大线程数(默认值为200),调优取值[200,1000] @Value("${global.max.tomcat.accept.queue:100}") private int mNMaxAcceptCounts; //tomcat启动的线程数达到最大时,接受排队的请求个数(默认值为100),调优取值[100,400] @Value("${global.switch.trace.log:true}") private boolean mBSwitchTraceLog = true; //是否开启基于TraceId的log记录 public static void main(String[] args) { GlobalData.getInstance().setCpuCores(Runtime.getRuntime().availableProcessors()); LogPrintMgr.getInstance().initRes(2, new LogPrintSink());//io型线程池=CPU Core*2;计算型线程池=CPU Core SpringApplication.run(AimodelpowerApplication.class, args); } @PostConstruct public void init(){ ThreadTaskMgr.initThreadResource(); LogPrintMgr.getInstance().setSwitchTraceLog(mBSwitchTraceLog); GlobalData.getInstance().setServerId(mStrServerId); GlobalData.getInstance().setNOwnerMachineIndex(mOwnerMachineIndex); GlobalData.getInstance().setNOwnerServiceIndex(mOwnerServiceIndex); GlobalData.getInstance().setSwitchTraceLog(mBSwitchTraceLog); SnowFlakeEx.init(mOwnerMachineIndex, mOwnerServiceIndex); } @Component class GlobalWebServerFactoryCustomizer implements WebServerFactoryCustomizer { @Override public void customize(ConfigurableServletWebServerFactory factory) { TomcatServletWebServerFactory factoryReal = (TomcatServletWebServerFactory)factory; if (mBUseApr){ factoryReal.setProtocol("org.apache.coyote.http11.Http11AprProtocol"); factoryReal.addContextLifecycleListeners(new AprLifecycleListener()); } factoryReal.addConnectorCustomizers(new MyTomcatConnectorCustomizer()); factoryReal.setPort(mNPort); } } class MyTomcatConnectorCustomizer implements TomcatConnectorCustomizer { public void customize(Connector connector) { connector.setEnableLookups(false); if (mBUseApr){ Http11AprProtocol protocol = (Http11AprProtocol) connector.getProtocolHandler(); initTomcatParam(protocol); }else{ Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); initTomcatParam(protocol); } } private void initTomcatParam(AbstractProtocol protocol){ /* * application.properties中的参数优先级高于代码设置的参数 * 即代码设置参数后若application.properties中有同名参数,application.properties中的优先生效 * */ /** *Tomcat在MaxThreads和AcceptCount队列设置基础上,对请求连接多做了一层保护,也就是MaxConnections的大小限制。 *当Client端的大量请求过来时,首先进入MaxThreads,MaxThreads满了则进入AcceptCount队列, *若AcceptCount队列也满了则后续的连接无法进入AcceptCount队列,无法交由工作线程处理,Client将得到connection refused或者connection reset的错误。 *第二层保护就是:在acceptor线程里头进行缓冲,当连接的socket超过MaxConnections的时候,则进行阻塞等待,控制acceptor转给worker线程连接的速度,稍微缓缓,等待worker线程处理响应client。 */ protocol.setMaxConnections(mNMaxConcurrentRequest); protocol.setMaxThreads(mNMaxThreads); protocol.setAcceptCount(mNMaxAcceptCounts); protocol.setMinSpareThreads(mNMaxThreads/10);//初始化时创建的线程数 LogPrintMgr.getInstance().printLogMsg(LogLevelFlag.LOG_INFO , LogFlagBusiType.BUSI_INIT.toStrValue(), this.getClass().getSimpleName() , String.format("tomcat pramas:{mode=%s max-threads=%d max-conns=%d accept-counts=%d conn-timeout=%d minSpareThreads=%d} server-id:{%s}" , mBUseApr?"Apr":"Nio" , protocol.getMaxThreads() , protocol.getMaxConnections() , protocol.getAcceptCount() , protocol.getConnectionTimeout() , protocol.getMinSpareThreads() , mStrServerId)); } } }