日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

Spring Boot 性能太差?試試這幾招!

來源: 責(zé)編: 時間:2024-06-05 17:46:29 198觀看
導(dǎo)讀今天這篇文章介紹七種常見的Spring Boot 性能優(yōu)化方向。1. 異步執(zhí)行實(shí)現(xiàn)方式二種:使用異步注解 @Aysnc、啟動類:添加 @EnableAsync 注解。JDK 8 本身有一個非常好用的 Future 類——CompletableFuture。@AllArgsConstru

今天這篇文章介紹七種常見的Spring Boot 性能優(yōu)化方向。DeP28資訊網(wǎng)——每日最新資訊28at.com

1. 異步執(zhí)行

實(shí)現(xiàn)方式二種:DeP28資訊網(wǎng)——每日最新資訊28at.com

  • 使用異步注解 @Aysnc、啟動類:添加 @EnableAsync 注解。
  • JDK 8 本身有一個非常好用的 Future 類——CompletableFuture。
@AllArgsConstructor  public 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);          //告知完成結(jié)果          future.complete(60);      }  }

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

我們用休眠 1 秒來模擬一個長時間的計算過程,并將計算結(jié)果告訴 future 執(zhí)行結(jié)果,AskThread 線程將會繼續(xù)執(zhí)行。DeP28資訊網(wǎng)——每日最新資訊28at.com

public class Calc {      public static Integer calc(Integer para) {          try {              //模擬一個長時間的執(zhí)行              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 方法構(gòu)造一個 CompletableFuture 實(shí)例,在 supplyAsync() 方法中,它會在一個新線程中,執(zhí)行傳入的參數(shù)。DeP28資訊網(wǎng)——每日最新資訊28at.com

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

而返回的 CompletableFuture 實(shí)例就可以作為這次調(diào)用的契約,在將來任何場合,用于獲得最終的計算結(jié)果。DeP28資訊網(wǎng)——每日最新資訊28at.com

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

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

核心代碼:DeP28資訊網(wǎng)——每日最新資訊28at.com

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

異步調(diào)用使用 Callable 來實(shí)現(xiàn):DeP28資訊網(wǎng)——每日最新資訊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();      }        /**       * 異步調(diào)用restful       * 當(dāng)controller返回值是Callable的時候,springmvc就會啟動一個線程將Callable交給TaskExecutor去處理       * 然后DispatcherServlet還有所有的spring攔截器都退出主線程,然后把response保持打開的狀態(tài)       * 當(dāng)Callable執(zhí)行結(jié)束之后,springmvc就會重新啟動分配一個request請求,然后DispatcherServlet就重新       * 調(diào)用和處理Callable異步執(zhí)行的返回結(jié)果, 然后返回視圖       *       * @return       */        @GetMapping("/hello")      public Callable<String> helloController() {          logger.info(Thread.currentThread().getName() + " 進(jìn)入helloController方法");          Callable<String> callable = new Callable<String>() {                @Override                public String call() throws Exception {                  logger.info(Thread.currentThread().getName() + " 進(jìn)入call方法");                  String say = hello.sayHello();                  logger.info(Thread.currentThread().getName() + " 從helloService方法返回");                  return say;              }          };          logger.info(Thread.currentThread().getName() + " 從helloController方法返回");          return callable;      }  }

異步調(diào)用的方式 WebAsyncTask:DeP28資訊網(wǎng)——每日最新資訊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() + " 進(jìn)入helloController方法");            // 3s鐘沒返回,則認(rèn)為超時          WebAsyncTask<String> webAsyncTask = new WebAsyncTask<>(3000, new Callable<String>() {                @Override                public String call() throws Exception {                  logger.info(Thread.currentThread().getName() + " 進(jìn)入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() + " 執(zhí)行完畢");              }          });            webAsyncTask.onTimeout(new Callable<String>() {                @Override                public String call() throws Exception {                  logger.info(Thread.currentThread().getName() + " onTimeout");                  // 超時的時候,直接拋異常,讓外層統(tǒng)一處理超時異常                  throw new TimeoutException("調(diào)用超時");              }          });          return webAsyncTask;      }        /**       * 異步調(diào)用,異常處理,詳細(xì)的處理流程見MyExceptionHandler類       *       * @return       */        @GetMapping("/exception")      public WebAsyncTask<String> exceptionController() {          logger.info(Thread.currentThread().getName() + " 進(jìn)入helloController方法");          Callable<String> callable = new Callable<String>() {                @Override                public String call() throws Exception {                  logger.info(Thread.currentThread().getName() + " 進(jìn)入call方法");                  throw new TimeoutException("調(diào)用超時!");              }          };          logger.info(Thread.currentThread().getName() + " 從helloController方法返回");          return new WebAsyncTask<>(20000, callable);      }    }

2. 增加內(nèi)嵌 Tomcat 的最大連接數(shù)

代碼如下:DeP28資訊網(wǎng)——每日最新資訊28at.com

@Configuration  public 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();              //設(shè)置最大連接數(shù)              protocol.setMaxConnections(20000);              //設(shè)置最大線程數(shù)              protocol.setMaxThreads(2000);              protocol.setConnectionTimeout(30000);          }      }    }

3. 使用 @ComponentScan()

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

4. 默認(rèn) Tomcat 容器改為 Undertow

默認(rèn) Tomcat 容器改為 Undertow(Jboss 下的服務(wù)器,Tomcat 吞吐量 5000,Undertow 吞吐量 8000)DeP28資訊網(wǎng)——每日最新資訊28at.com

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

改為:DeP28資訊網(wǎng)——每日最新資訊28at.com

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

5. 使用 BufferedWriter 進(jìn)行緩沖

這里不給大家舉例,可自行嘗試。DeP28資訊網(wǎng)——每日最新資訊28at.com

6. Deferred 方式實(shí)現(xiàn)異步調(diào)用

代碼如下:DeP28資訊網(wǎng)——每日最新資訊28at.com

@RestController  public 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() + "進(jìn)入executeSlowTask方法");          DeferredResult<String> deferredResult = new DeferredResult<>();          // 調(diào)用長時間執(zhí)行任務(wù)          taskService.execute(deferredResult);          // 當(dāng)長時間任務(wù)中使用deferred.setResult("world");這個方法時,會從長時間任務(wù)中返回,繼續(xù)controller里面的流程          logger.info(Thread.currentThread().getName() + "從executeSlowTask方法返回");          // 超時的回調(diào)方法          deferredResult.onTimeout(new Runnable(){       @Override     public void run() {      logger.info(Thread.currentThread().getName() + " onTimeout");      // 返回超時信息      deferredResult.setErrorResult("time out!");     }    });            // 處理完成的回調(diào)方法,無論是超時還是處理成功,都會進(jìn)入這個回調(diào)方法          deferredResult.onCompletion(new Runnable(){       @Override     public void run() {      logger.info(Thread.currentThread().getName() + " onCompletion");     }    });            return deferredResult;      }  }

7. 異步調(diào)用可以使用 AsyncHandlerInterceptor 進(jìn)行攔截

代碼如下:DeP28資訊網(wǎng)——每日最新資訊28at.com

@Component  public 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()+ "服務(wù)調(diào)用完成,返回結(jié)果給客戶端");   }     @Override   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)     throws Exception {    if(null != ex){     System.out.println("發(fā)生異常:"+ex.getMessage());    }   }     @Override   public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)     throws Exception {      // 攔截之后,重新寫回數(shù)據(jù),將原來的hello world換成如下字符串    String resp = "my name is chhliu!";    response.setContentLength(resp.length());    response.getOutputStream().write(resp.getBytes());      logger.info(Thread.currentThread().getName() + " 進(jìn)入afterConcurrentHandlingStarted方法");   }    }

DeP28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-92174-0.htmlSpring Boot 性能太差?試試這幾招!

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

上一篇: 團(tuán)隊代碼風(fēng)格混亂?Spotless 幫你搞定!

下一篇: 現(xiàn)在停止濫用useMemo吧!

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
韩国成人福利片在线播放| 欧美国产视频一区二区| 亚洲愉拍自拍另类高清精品| 亚洲一级在线观看| 欧美在线视频观看| 久久综合电影一区| 欧美精品一区二区视频 | 午夜精品福利电影| 欧美在线二区| 欧美激情91| 国产精品免费福利| 在线观看日韩欧美| 一本久道综合久久精品| 久久er99精品| 欧美日产国产成人免费图片| 国产视频在线一区二区| 99国产精品视频免费观看| 欧美伊人久久| 欧美精品一区二区高清在线观看| 国产精品自在在线| 亚洲精品在线观看视频| 欧美在线播放一区二区| 欧美日韩免费观看一区=区三区| 国产日韩欧美亚洲| 99国产精品视频免费观看| 久久久人成影片一区二区三区观看| 欧美日韩国语| 影音国产精品| 欧美有码在线观看视频| 欧美精品一区二区久久婷婷| 国内精品写真在线观看| 亚洲天堂网在线观看| 免费不卡亚洲欧美| 国产麻豆日韩欧美久久| 日韩视频在线免费| 久久综合九色九九| 国产日韩精品一区二区三区在线| 日韩视频免费| 免费观看日韩av| 国产亚洲福利| 亚洲欧美国产不卡| 欧美日韩爆操| 亚洲国产一区二区三区青草影视| 欧美一区二区三区免费视| 欧美日韩一区视频| 亚洲精品免费在线播放| 老司机一区二区| 国产在线成人| 午夜精品福利在线观看| 欧美日韩在线精品| 亚洲欧洲另类国产综合| 久久免费视频观看| 国产欧美视频在线观看| 亚洲图片你懂的| 欧美日韩国产一区二区| 亚洲国产精品美女| 久久免费黄色| 精品福利电影| 久久久人人人| 在线播放亚洲| 久久躁日日躁aaaaxxxx| 红桃视频成人| 久久嫩草精品久久久精品| 国产亚洲精品久| 欧美在线播放一区二区| 国产精品一页| 午夜精品影院在线观看| 国产麻豆日韩欧美久久| 亚洲一区二区三区成人在线视频精品| 欧美精品一区二区三区一线天视频 | 国产精品美女久久久久久2018| 亚洲看片一区| 欧美激情国产日韩| 亚洲日本中文字幕免费在线不卡| 裸体一区二区| 亚洲成人在线网| 免费观看亚洲视频大全| 亚洲国产精品v| 欧美成人嫩草网站| 亚洲人成网在线播放| 欧美激情二区三区| 亚洲老司机av| 欧美日韩中文字幕综合视频| 一区二区三区**美女毛片| 欧美日韩精品一区二区在线播放| 99re热这里只有精品免费视频| 欧美日韩国产小视频在线观看| 夜夜嗨av一区二区三区中文字幕 | 国产日韩欧美二区| 久久精品三级| 在线成人av网站| 蜜臀久久99精品久久久久久9| 亚洲电影自拍| 欧美女主播在线| 亚洲调教视频在线观看| 国产精品自在在线| 久久高清一区| 亚洲第一精品久久忘忧草社区| 嫩草影视亚洲| 99精品视频免费观看| 欧美午夜精品久久久久久人妖 | 亚洲一区二区三区高清不卡| 国产精品欧美一区喷水| 欧美一区二区免费视频| 狠狠色综合播放一区二区| 免费久久99精品国产自| 亚洲精品小视频| 国产精品成人aaaaa网站| 午夜久久99| 1024成人网色www| 欧美日韩国产专区| 亚洲欧洲99久久| 一区在线视频| 欧美日韩国产综合网| 亚洲欧美第一页| 伊人春色精品| 欧美日韩国产综合视频在线观看中文 | 国产伦精品一区二区三| 久久人人爽人人爽爽久久| 亚洲国产欧美日韩另类综合| 欧美三级视频在线| 久久久91精品国产一区二区精品| 亚洲国产专区| 国产精品九九久久久久久久| 久久久精品2019中文字幕神马| 亚洲黄色一区| 国产精品草莓在线免费观看| 久久爱www久久做| 亚洲日本电影| 国产女人18毛片水18精品| 麻豆精品精华液| 亚洲一区bb| 亚洲第一页在线| 国产精品久久久久久久久免费| 久久久视频精品| 夜夜嗨一区二区三区| 国产亚洲成av人在线观看导航| 欧美激情综合五月色丁香小说| 午夜一级久久| 亚洲精品一区在线观看香蕉| 国产麻豆日韩| 欧美日韩久久| 久久亚洲精品伦理| 亚洲影院色在线观看免费| 亚洲高清在线播放| 国产欧美日韩三级| 欧美日韩视频免费播放| 欧美综合二区| 这里只有精品电影| 亚洲高清av在线| 国产欧美日韩三区| 欧美日韩黄色大片| 久久久久中文| 亚洲欧美日韩天堂一区二区| 亚洲人成亚洲人成在线观看图片| 国产欧美一区二区三区久久| 欧美国产日韩视频| 久久久久综合| 亚洲欧美影音先锋| 99热免费精品在线观看| 亚洲第一毛片| 国产日韩欧美综合精品| 欧美三日本三级少妇三2023 | 久久久久久91香蕉国产| 亚洲一区二区三区精品动漫| 亚洲激情视频在线| 黑丝一区二区三区| 国产精品自拍视频| 欧美视频官网| 欧美黑人多人双交| 老司机久久99久久精品播放免费| 亚欧成人精品| 亚洲一区精品视频| av不卡在线观看| 91久久精品一区二区三区| 狠狠色狠狠色综合日日tαg| 国产日韩欧美亚洲| 国产精品婷婷| 国产精品家庭影院| 欧美三区美女| 欧美三区美女| 欧美日韩亚洲精品内裤| 欧美国产日韩亚洲一区| 久久亚洲国产精品日日av夜夜| 欧美一区日韩一区| 欧美一级午夜免费电影| 亚洲永久视频| 亚洲网站在线看| 国产精品99久久久久久久vr| 99视频在线精品国自产拍免费观看 | 国产欧美在线| 国产酒店精品激情| 欧美视频中文字幕| 欧美日韩一区二区三区免费看| 欧美不卡视频一区| 免费在线看一区| 免费看av成人| 欧美fxxxxxx另类| 欧美电影免费观看高清| 欧美福利视频一区| 欧美国产极速在线| 欧美精品一区三区在线观看| 欧美精品久久一区| 欧美日韩精品综合在线|