7 种提升 Spring Boot 吞吐量神技( 二 )

二、增加内嵌Tomcat的最大连接数@Configurationpublic class TomcatConfig {@Beanpublic ConfigurableServletWebServerFactory webServerFactory() {TomcatServletWebServerFactory tomcatFactory = new TomcatServletWebServerFactory();tomcatFactory.addConnectorCustomizers(new MyTomcatConnectorCustomizer());tomcatFactory.setPort(8005);tomcatFactory.setContextPath("/api-g");return tomcatFactory;}class MyTomcatConnectorCustomizer implements TomcatConnectorCustomizer {public void customize(Connector connector) {Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();//设置最大连接数protocol.setMaxConnections(20000);//设置最大线程数protocol.setMaxThreads(2000);protocol.setConnectionTimeout(30000);}}} 
三、使用@ComponentScan()定位扫包比@SpringBootApplication扫包更快四、默认tomcat容器改为Undertow(Jboss下的服务器,Tomcat吞吐量5000,Undertow吞吐量8000)<exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions>改为:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId></dependency>五、使用 BufferedWriter 进行缓冲六、Deferred方式实现异步调用@RestControllerpublic class AsyncDeferredController {private final Logger logger = LoggerFactory.getLogger(this.getClass());private final LongTimeTask taskService;@Autowiredpublic AsyncDeferredController(LongTimeTask taskService) {this.taskService = taskService;}@GetMapping("/deferred")public DeferredResult<String> executeSlowTask() {logger.info(Thread.currentThread().getName() + "进入executeSlowTask方法");DeferredResult<String> deferredResult = new DeferredResult<>();// 调用长时间执行任务taskService.execute(deferredResult);// 当长时间任务中使用deferred.setResult("world");这个方法时,会从长时间任务中返回,继续controller里面的流程logger.info(Thread.currentThread().getName() + "从executeSlowTask方法返回");// 超时的回调方法deferredResult.onTimeout(new Runnable(){@Overridepublic void run() {logger.info(Thread.currentThread().getName() + " onTimeout");// 返回超时信息deferredResult.setErrorResult("time out!");}});// 处理完成的回调方法,无论是超时还是处理成功,都会进入这个回调方法deferredResult.onCompletion(new Runnable(){@Overridepublic void run() {logger.info(Thread.currentThread().getName() + " onCompletion");}});return deferredResult;}}七、异步调用可以使用AsyncHandlerInterceptor进行拦截@Componentpublic class MyAsyncHandlerInterceptor implements AsyncHandlerInterceptor {private static final Logger logger = LoggerFactory.getLogger(MyAsyncHandlerInterceptor.class);@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {// HandlerMethod handlerMethod = (HandlerMethod) handler;logger.info(Thread.currentThread().getName()+ "服务调用完成,返回结果给客户端");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {if(null != ex){System.out.println("发生异常:"+ex.getMessage());}}@Overridepublic void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {// 拦截之后,重新写回数据,将原来的hello world换成如下字符串String resp = "my name is chhliu!";response.setContentLength(resp.length());response.getOutputStream().write(resp.getBytes());logger.info(Thread.currentThread().getName() + " 进入afterConcurrentHandlingStarted方法");}}



推荐阅读