AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

優化SpringBoot吞吐量的七個高效策略

來源: 責編: 時間:2024-06-28 17:15:11 138觀看
導讀1、異步執行實現方式二種:使用異步注解 @aysnc、啟動類:添加 @EnableAsync 注解JDK 8 本身有一個非常好用的 Future 類——CompletableFuture@AllArgsConstructorpublic class AskThread implements Runnable{ priva

1、異步執行Lyv28資訊網——每日最新資訊28at.com

實現方式二種:Lyv28資訊網——每日最新資訊28at.com

  • 使用異步注解 @aysnc、啟動類:添加 @EnableAsync 注解
  • JDK 8 本身有一個非常好用的 Future 類——CompletableFuture
@AllArgsConstructorpublic class AskThread implements Runnable{    private CompletableFuture<Integer> re = null;    public void run() {        int myRe = 0;        try {            myRe = re.get() * re.get();        } catch (Exception e) {            e.printStackTrace();        }        System.out.println(myRe);    }    public static void main(String[] args) throws InterruptedException {        final CompletableFuture<Integer> future = new CompletableFuture<>();        new Thread(new AskThread(future)).start();        //模擬長時間的計算過程        Thread.sleep(1000);        //告知完成結果        future.complete(60);    }}

在該示例中,啟動一個線程,此時 AskThread 對象還沒有拿到它需要的數據,執行到  myRe = re.get() * re.get() 會阻塞。Lyv28資訊網——每日最新資訊28at.com

我們用休眠 1 秒來模擬一個長時間的計算過程,并將計算結果告訴 future 執行結果,AskThread 線程將會繼續執行。Lyv28資訊網——每日最新資訊28at.com

public class Calc {    public static Integer calc(Integer para) {        try {            //模擬一個長時間的執行            Thread.sleep(1000);        } catch (InterruptedException e) {            e.printStackTrace();        }        return para * para;    }    public static void main(String[] args) throws ExecutionException, InterruptedException {        final CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> calc(50))                .thenApply((i) -> Integer.toString(i))                .thenApply((str) -> "/"" + str + "/"")                .thenAccept(System.out::println);        future.get();    }}

CompletableFuture.supplyAsync 方法構造一個 CompletableFuture 實例,在 supplyAsync() 方法中,它會在一個新線程中,執行傳入的參數。Lyv28資訊網——每日最新資訊28at.com

在這里它會執行 calc() 方法,這個方法可能是比較慢的,但這并不影響 CompletableFuture 實例的構造速度,supplyAsync() 會立即返回。Lyv28資訊網——每日最新資訊28at.com

而返回的 CompletableFuture 實例就可以作為這次調用的契約,在將來任何場合,用于獲得最終的計算結果。Lyv28資訊網——每日最新資訊28at.com

supplyAsync 用于提供返回值的情況,CompletableFuture 還有一個不需要返回值的異步調用方法 runAsync(Runnable runnable),一般我們在優化 Controller 時,使用這個方法比較多。Lyv28資訊網——每日最新資訊28at.com

這兩個方法如果在不指定線程池的情況下,都是在 ForkJoinPool.common 線程池中執行,而這個線程池中的所有線程都是 Daemon(守護)線程,所以,當主線程結束時,這些線程無論執行完畢都會退出系統。Lyv28資訊網——每日最新資訊28at.com

核心代碼:Lyv28資訊網——每日最新資訊28at.com

CompletableFuture.runAsync(() ->   this.afterBetProcessor(betRequest,betDetailResult,appUser,id));

異步調用使用 Callable 來實現:Lyv28資訊網——每日最新資訊28at.com

@RestController  public class HelloController {    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);    @Autowired      private HelloService hello;    @GetMapping("/helloworld")    public String helloWorldController() {        return hello.sayHello();    }    /**     * 異步調用restful     * 當controller返回值是Callable的時候,springmvc就會啟動一個線程將Callable交給TaskExecutor去處理     * 然后DispatcherServlet還有所有的spring攔截器都退出主線程,然后把response保持打開的狀態     * 當Callable執行結束之后,springmvc就會重新啟動分配一個request請求,然后DispatcherServlet就重新     * 調用和處理Callable異步執行的返回結果, 然后返回視圖     *     * @return     */      @GetMapping("/hello")    public Callable<String> helloController() {        logger.info(Thread.currentThread().getName() + " 進入helloController方法");        Callable<String> callable = new Callable<String>() {            @Override              public String call() throws Exception {                logger.info(Thread.currentThread().getName() + " 進入call方法");                String say = hello.sayHello();                logger.info(Thread.currentThread().getName() + " 從helloService方法返回");                return say;            }        };        logger.info(Thread.currentThread().getName() + " 從helloController方法返回");        return callable;    }}

異步調用的方式 WebAsyncTask:Lyv28資訊網——每日最新資訊28at.com

@RestController  public class HelloController {    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);    @Autowired      private HelloService hello;    /**     * 帶超時時間的異步請求 通過WebAsyncTask自定義客戶端超時間     * @return     */      @GetMapping("/world")    public WebAsyncTask<String> worldController() {        logger.info(Thread.currentThread().getName() + " 進入helloController方法");        // 3s鐘沒返回,則認為超時        WebAsyncTask<String> webAsyncTask = new WebAsyncTask<>(3000, new Callable<String>() {            @Override              public String call() throws Exception {                logger.info(Thread.currentThread().getName() + " 進入call方法");                String say = hello.sayHello();                logger.info(Thread.currentThread().getName() + " 從helloService方法返回");                return say;            }        });        logger.info(Thread.currentThread().getName() + " 從helloController方法返回");        webAsyncTask.onCompletion(new Runnable() {            @Override              public void run() {                logger.info(Thread.currentThread().getName() + " 執行完畢");            }        });        webAsyncTask.onTimeout(new Callable<String>() {            @Override              public String call() throws Exception {                logger.info(Thread.currentThread().getName() + " onTimeout");                // 超時的時候,直接拋異常,讓外層統一處理超時異常                throw new TimeoutException("調用超時");            }        });        return webAsyncTask;    }    /**     * 異步調用,異常處理,詳細的處理流程見MyExceptionHandler類     * @return     */      @GetMapping("/exception")    public WebAsyncTask<String> exceptionController() {        logger.info(Thread.currentThread().getName() + " 進入helloController方法");        Callable<String> callable = new Callable<String>() {            @Override              public String call() throws Exception {                logger.info(Thread.currentThread().getName() + " 進入call方法");                throw new TimeoutException("調用超時!");            }        };        logger.info(Thread.currentThread().getName() + " 從helloController方法返回");        return new WebAsyncTask<>(20000, callable);    }}


Lyv28資訊網——每日最新資訊28at.com

2、增加內嵌 Tomcat 的最大連接數Lyv28資訊網——每日最新資訊28at.com

代碼如下:Lyv28資訊網——每日最新資訊28at.com

@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(Connector connector) {            Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();            //設置最大連接數            protocol.setMaxConnections(20000);            //設置最大線程數            protocol.setMaxThreads(2000);            protocol.setConnectionTimeout(30000);        }    }}

3、使用 @ComponentScan()Lyv28資訊網——每日最新資訊28at.com

使用 @ComponentScan() 定位掃包比 @SpringBootApplication 掃包更快。Lyv28資訊網——每日最新資訊28at.com

4、默認 Tomcat 容器改為 UndertowLyv28資訊網——每日最新資訊28at.com

默認 Tomcat 容器改為 Undertow(Jboss 下的服務器,Tomcat 吞吐量 5000,Undertow 吞吐量 8000)Lyv28資訊網——每日最新資訊28at.com

<exclusions>  <exclusion>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-tomcat</artifactId>  </exclusion></exclusions>

改為:Lyv28資訊網——每日最新資訊28at.com

<dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-undertow</artifactId></dependency>

5、使用 BufferedWriter 進行緩沖Lyv28資訊網——每日最新資訊28at.com

這里不給大家舉例,可自行嘗試。Lyv28資訊網——每日最新資訊28at.com

6、Deferred 方式實現異步調用Lyv28資訊網——每日最新資訊28at.com

代碼如下:Lyv28資訊網——每日最新資訊28at.com

@RestControllerpublic class AsyncDeferredController {    private final Logger logger = LoggerFactory.getLogger(this.getClass());    private final LongTimeTask taskService;    @Autowired    public 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(){   @Override   public void run() {    logger.info(Thread.currentThread().getName() + " onTimeout");    // 返回超時信息    deferredResult.setErrorResult("time out!");   }  });        // 處理完成的回調方法,無論是超時還是處理成功,都會進入這個回調方法        deferredResult.onCompletion(new Runnable(){   @Override   public void run() {    logger.info(Thread.currentThread().getName() + " onCompletion");   }  });        return deferredResult;    }}

7、異步調用可以使用 AsyncHandlerInterceptor 進行攔截Lyv28資訊網——每日最新資訊28at.com

代碼如下:Lyv28資訊網——每日最新資訊28at.com

@Componentpublic class MyAsyncHandlerInterceptor implements AsyncHandlerInterceptor { private static final Logger logger = LoggerFactory.getLogger(MyAsyncHandlerInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)   throws Exception {  return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,   ModelAndView modelAndView) throws Exception {// HandlerMethod handlerMethod = (HandlerMethod) handler;  logger.info(Thread.currentThread().getName()+ "服務調用完成,返回結果給客戶端"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)   throws Exception {  if(null != ex){   System.out.println("發生異常:"+ex.getMessage());  } } @Override public 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方法"); }}


Lyv28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-97290-0.html優化SpringBoot吞吐量的七個高效策略

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 列表大揭秘:一文掌握 Python 列表的高級玩法

下一篇: C#/.NET這些實用的技巧和知識點你都知道嗎?

標簽:
  • 熱門焦點
  • 帥氣純真少年!日本最帥初中生選美冠軍出爐

    日本第一帥哥初一生選美大賽冠軍現已正式出爐,冠軍是來自千葉縣的宗田悠良。日本一直熱衷于各種選美大賽,從&ldquo;最美JK&rdquo;起到&ldquo;最美女星&r
  • 線程通訊的三種方法!通俗易懂

    線程通信是指多個線程之間通過某種機制進行協調和交互,例如,線程等待和通知機制就是線程通訊的主要手段之一。 在 Java 中,線程等待和通知的實現手段有以下幾種方式:Object 類下
  • 一個注解實現接口冪等,這樣才優雅!

    場景碼猿慢病云管理系統中其實高并發的場景不是很多,沒有必要每個接口都去考慮并發高的場景,比如添加住院患者的這個接口,具體的業務代碼就不貼了,業務偽代碼如下:圖片上述代碼有
  • 一文搞定Java NIO,以及各種奇葩流

    大家好,我是哪吒。很多朋友問我,如何才能學好IO流,對各種流的概念,云里霧里的,不求甚解。用到的時候,現百度,功能雖然實現了,但是為什么用這個?不知道。更別說效率問題了~下次再遇到,
  • 小米MIX Fold 3下月亮相:今年唯一無短板的全能折疊屏

    這段時間以來,包括三星、一加、榮耀等等有不少品牌旗下的最新折疊屏旗艦都有新的進展,其中榮耀、三星都已陸續發布了最新的折疊屏旗艦,尤其號榮耀Magi
  • 8月見!小米MIX Fold 3獲得3C認證:支持67W快充

    這段時間以來,包括三星、一加、榮耀等等有不少品牌旗下的最新折疊屏旗艦都得到了不少爆料,而小米新一代折疊屏旗艦——小米MIX Fold 3此前也屢屢被傳
  • 2納米決戰2025

    集微網報道 從三強爭霸到四雄逐鹿,2nm的廝殺聲已然隱約傳來。無論是老牌勁旅臺積電、三星,還是誓言重回先進制程領先地位的英特爾,甚至初成立不久的新
  • 超閉合精工鉸鏈 徹底消滅縫隙 三星Galaxy Z Flip5與Galaxy Z Fold5發布

    2023年7月26日,三星電子正式發布了Galaxy Z Flip5與Galaxy Z Fold5。三星新一代折疊屏手機采用超閉合精工鉸鏈,讓折疊后的縫隙不再可見。同時,配合處
  • iQOO Neo8 Pro真機諜照曝光:天璣9200+和V1+旗艦雙芯加持

    去年10月,iQOO推出了iQOO Neo7系列機型,不僅搭載了天璣9000+,而且是同價位唯一一款天璣9000+直屏旗艦,一經上市便受到了用戶的廣泛關注。在時隔半年后,
Top