优化提升SpringBoot吞吐量的解决方案

        

程序猿羊 程序猿小杨 2023-07-11 07:30 发表于上海

收录于合集#springboot12个

                            

图片

推荐大家关注一个公众号

图片

 

程序猿小杨

分享Java相关技术、数据库、Python、职场、感悟、视频资源等干货和学习心得。 如:kettle、ES、redis\mongoDB、springboot、Zookeeper、高并发多线程、中间件、JVM、程序员攻略等。

73篇原创内容

公众号

推荐文章:

1、springBoot对接kafka,批量、并发、异步获取消息,并动态、批量插入库表;

2、SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据;

一、异步执行

  1.1、使用@aysnc(异步注解)

      参考文章:SpringBoot使用@Async实现多线程异步

  1.2、JDK8自带Future类-CompletableFuture

二、增加内嵌Tomcat的最大连接数

package com.wonders.common.config;import org.apache.coyote.http11.Http11NioProtocol;import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;
/** * @Description: TODO:增加内嵌Tomcat的最大连接数 * @Author: yyalin * @CreateDate: 2023/6/30 9:59 * @Version: V1.0 */@Configurationpublic class TomcatConfig {    @Bean    public 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(org.apache.catalina.connector.Connector connector) {            Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();            //设置最大连接数            protocol.setMaxConnections(15000);            //设置最大线程数            protocol.setMaxThreads(1000);            //设置连接超时时间            protocol.setConnectionTimeout(30000);        }    }}

三、选择Undertow代替内嵌tomcat容器

     默认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>

四、Async异步调用可用AsyncHandlerInterceptor进行拦截

package com.wonders.interceptor;
import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component;import org.springframework.web.servlet.AsyncHandlerInterceptor;import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;
/** * @Description: TODO:Async异步调用可以使用AsyncHandlerInterceptor进行拦截 * @Author: yyalin * @CreateDate: 2023/6/30 10:26 * @Version: V1.0 */@Component@Slf4jpublic class AsyncHandlerInterImpl implements AsyncHandlerInterceptor {    /**     * 功能描述:拦截于请求刚进入时,进行判断,需要boolean返回值,     * 如果返回true将继续执行,如果返回false,将不进行执行。一般用于登录校验。     * @MethodName: preHandle     * @MethodParam: [request, response, handler]     * @Return: boolean     * @Author: yyalin     * @CreateDate: 2023/6/30 10:33     */    @Override    public boolean preHandle(HttpServletRequest request,                             HttpServletResponse response,                             Object handler)            throws Exception {        return true;    }    /**     * 功能描述:拦截于方法成功返回后,视图渲染前,可以对modelAndView进行操作     * @MethodName: postHandle     * @MethodParam: [request, response, handler, modelAndView]     * @Return: void     * @Author: yyalin     * @CreateDate: 2023/6/30 10:34     */    @Override    public void postHandle(HttpServletRequest request, HttpServletResponse response,                           Object handler,ModelAndView modelAndView) throws Exception {//  HandlerMethod handlerMethod = (HandlerMethod) handler;        log.info(Thread.currentThread().getName()+ "服务调用完成,返回结果给客户端");    }    /**     * 功能描述:拦截于方法成功返回后,视图渲染前,可以进行成功返回的日志记录     * @MethodName: afterCompletion     * @MethodParam: [request, response, handler, ex]     * @Return: void     * @Author: yyalin     * @CreateDate: 2023/6/30 10:35     */    @Override    public void afterCompletion(HttpServletRequest request,                                HttpServletResponse response,                                Object handler, Exception ex)            throws Exception {        if(null != ex){            log.info("发生异常:"+ex.getMessage());        }    }    /**     * 功能描述:AsyncHandlerInterceptor中的afterConcurrentHandlingStarted()方法,     * 会在Controller方法异步执行时开始执行,     * 但是Interceptor的postHandle()方法则是需要等到Controller的异步执行完之后才能执行     * @MethodName: afterConcurrentHandlingStarted     * @MethodParam: [request, response, handler]     * @Return: void     * @Author: yyalin     * @CreateDate: 2023/6/30 10:36     */    @Override    public void afterConcurrentHandlingStarted(HttpServletRequest request,                                               HttpServletResponse response,                                               Object handler)            throws Exception {
        // 拦截之后,重新写回数据,将原来的hello world换成如下字符串        String resp = "my name is yyalin!";        response.setContentLength(resp.length());        response.getOutputStream().write(resp.getBytes());        log.info(Thread.currentThread().getName() + " 进入afterConcurrentHandlingStarted方法");    }
}

主要流程如下:

    1、拦截器是一个列表,按顺序执行所有拦截器的preHandle方法,一直遇到return false为止,比如:第二个preHandle方法是return false,则第三个以及以后所有拦截器都不会执行。若都是return true,则按顺序加载完preHandle方法。

     2、执行主方法(即controller里的接口),若中间抛出异常,则跟return false效果一致,不会继续执行postHandle,只会倒序执行afterCompletion方法。

     3、在主方法(即controller里的接口)执行完业务逻辑(页面还未渲染数据)时,按倒序执行postHandle方法。若第三个拦截器的preHandle方法return false,则会执行第二个和第一个的postHandle方法和afterCompletion(postHandle都执行完才会执行这个,也就是view页面渲染完数据后,执行after进行清理工作)方法。(注意:postHandle和afterCompletion都是倒序执行)。  

  更多详细资料,请关注个人微信公众号或搜索“程序猿小杨”添加。

部分内容借鉴网站(表示感谢):          https://blog.csdn.net/vincent_duan/article/details/100880498

  https://mp.weixin.qq.com/s/lxDr3PyVcIcEpUC16cNgMg  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值