追è¨: ãã¡ãã®è¨äºã¯å·çæç¹(2019/12/20)ã§ã® Quarkus ææ°ãã¼ã¸ã§ã³ã§ãã£ã 1.0.1.Final ã®åä½ãå
ã«è¨è¼ããã¦ãã¾ããããããããã®å¾ã«ä»¥ä¸ã®ä¿®æ£ã«ãã£ã¦ Quarkus 1.1.0.Final 以éããã¯ãQuarkus RESTEasy ã§ã¯ Vert.x ã¹ã¬ãããã¼ã«ã¯ä½¿ãããªããªããServlet ä¾åã®æç¡ã«ããã quarkus.thread-pool.max-threads
ã§è¨å®ããã main ã®ã¹ã¬ãããã¼ã«ãå©ç¨ãããããã«åä½ãå¤æ´ããã¾ããã
Red Hat 㧠JBoss ããã«ã¦ã§ã¢ã®ãµãã¼ãããã¦ããä¸æµ¦ã§ãããã®è¨äºã¯èµ¤å¸½ã¨ã³ã¸ã㢠Advent Calendar 2019ã®20æ¥ç®ã®ã¨ã³ããªã§ãã
Quarkus ã® HTTP ã¬ã¤ã¤ã¼ã®ã¹ã¬ãããã¼ã«ã«ã¤ãã¦æ¸ãããã¨æãã¾ãã
TL; DR
- Quarkus ã® HTTP ã¬ã¤ã¤ã¼ã¯ Vert.x ãã¼ã¹ã«ãªã£ã¦ãã
- Vert.x é¢é£ã¹ã¬ãããã¼ã«ã®è¨å®ã¯
quarkus.vertx.event-loops-pool-size
/quarkus.vertx.worker-pool-size
ããããã£ã§èª¿æ´å¯è½ - ä¾åé¢ä¿ã« Servlet ãããã¨ãUndertow ãå©ç¨ããå®è£
ã«ãã©ã¼ã«ããã¯ãã¦ã
quarkus.thread-pool.max-threads
ã§è¨å®ãããå¥ã¹ã¬ãããã¼ã« ãå©ç¨ããã - ããããã£ã®è¨å®ããã³ç¢ºèªã«ã¯
quarkus:generate-config
ã便å©
Quarkus ã® HTTP ã¬ã¤ã¤ã¼ã®å®è£
Quarkus ã® HTTP ã¬ã¤ã¤ã¼ã®å®è£ ã¯ã2019/12/20 ç¾æç¹ã§ææ°ã® 1.0.1 ã«ãªãã¾ã§ã«ãã¼ã¸ã§ã³ã«ãã£ã¦ä»¥ä¸ã®ãããªå¤é·ãã¨ãã¦ãã¦ãã¾ãã
- 0.22 ã¾ã§: JAX-RS/Servlet ã¢ããªã±ã¼ã·ã§ã³ãªã©ã®HTTPãªã¯ã¨ã¹ãå¦ç㯠Undertow/XNIO ãçµç±ãã¦è¡ããã¦ãã (Reactiveç³»ã®ã¢ããªã±ã¼ã·ã§ã³ã§æ示çã« Vert.x ã使ã£ãå ´åãé¤ã)
- 0.23 以é: ãã¹ã¦ã®HTTPãªã¯ã¨ã¹ãå¦ç㯠Vert.x ãçµç±ããããã«å¤æ´ããã
- ããã« 0.24 以éã§ãJAX-RS ã¢ããªã±ã¼ã·ã§ã³ã«ãã㦠Servlet API ãä¸è¦ã§ããã°ãUndertow ãçµç±ãããã¨ãªãç´æ¥ Vert.x ä¸ã§å¦çãããããã«å¤æ´ããã
JAX-RS ã¢ããªã±ã¼ã·ã§ã³ã§ Servlet API ãå©ç¨ãããå ´åã«ã¯ãä¾åã©ã¤ãã©ãªã¨ã㦠quarkus-undertow
ã追å ãããã¨ã§å¯è½ã§ããä¾åé¢ä¿ã« quarkus-undertow
ããããã¨ãæ¤ç¥ãããå ´åã«ã¯ãQuarkus ã¯èªåçã« JAX-RS å®è£
ã§ãã RESTEasy ã Servlet ä¸ã§åãããã«ãã©ã¼ã«ããã¯ããæåã«ãªã£ã¦ãã¾ãã
ãªãããã® Quarkus ã«ããã Servlet å®è£ 㯠Undertow ãã¼ã¹ã®ã¾ã¾ã§ãããå®æ 㯠Undertow 3.x ã¨ãªãäºå®ã ã£ããã®ãããã©ã¼ã¯ãã Vert.x based Undertow ã¨ãªã£ã¦ãã¾ãã
Quarkus/JAX-RSã¢ããªã±ã¼ã·ã§ã³ã§ç¢ºèªãã
ã¾ãã¯ã https://code.quarkus.io/ 㧠"RESTEasy JAX-RS" ã®ã¿ãé¸æãã¦ãµã³ãã«ã® maven ããã¸ã§ã¯ããçæãã¦åããã¦ã¿ã¾ãããã
code-with-quarkus.zip
ãçæãããã®ã§ããããå±éãã¦ä»¥ä¸ã®ã³ãã³ãã§ã³ã³ãã¤ã«ã㦠Hot Reloading ãæå¹ãª Quarkus Dev ã¢ã¼ãã§åããã¾ãã
$ ./mvnw compile quarkus:dev
ãµã³ãã«ããã¸ã§ã¯ãã® src/main/java/org/acme/ExampleResource.java
ã® hello()
ã¡ã½ããã«ã¹ã¬ããåãå¼ã³åºãã®ã¹ã¿ãã¯ãã¬ã¼ã¹ãåºåãããã°ã追å ãã¾ãã
... import org.jboss.logging.Logger; @Path("/hello") public class ExampleResource { Logger logger = Logger.getLogger(getClass()); @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { logger.infof(new Throwable(), "ExampleResource#hello() is invoked : thread name [%s], thread class name [%s]", Thread.currentThread().getName(), Thread.currentThread().getClass().getName()); return "hello"; } }
ãã㧠http://localhost:8080/hello ã«ã¢ã¯ã»ã¹ãã¦ã¿ãã¨ããã°ãã以ä¸ã®ããã« vert.x-worker-thread-N
ã¨ããããããã³ã°ãªå¦çãè¡ãããã® worker ã¹ã¬ãããã¼ã«ä¸ã§å®è¡ããã¦ãããã¨ããããã¾ãã
2019-12-01 17:39:29,744 INFO [org.acm.ExampleResource] (vert.x-worker-thread-1) ExampleResource#hello() is invoked : thread name [vert.x-worker-thread-1], thread class name [io.vertx.core.impl.VertxThread]: java.lang.Throwable at org.acme.ExampleResource.hello(ExampleResource.java:21) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:151) at org.jboss.resteasy.core.MethodInjectorImpl.lambda$invoke$3(MethodInjectorImpl.java:122) at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:616) at java.util.concurrent.CompletableFuture.uniApplyStage(CompletableFuture.java:628) at java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:1996) at java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:110) at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:122) at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:594) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:468) at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:421) at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:363) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:423) at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:391) at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invoke$1(ResourceMethodInvoker.java:365) at java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:995) at java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2137) at java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:110) at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:365) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:477) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:252) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:153) at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:363) at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:156) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:238) at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73) at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:118) at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.lambda$handle$0(VertxRequestHandler.java:74) at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$2(ContextImpl.java:316) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748)
Quarkus ã®ã½ã¼ã¹ã³ã¼ãã確èªããã¨ã io.quarkus.resteasy.runtime.standalone.VertxRequestHandler#handle() ã«ã¦ Vertx#executeBlocking() ãå¼ã³åºããã¦ãããããã³ã°ãªå¦çãè¡ãã¹ã¬ããã§ãã vert.x-worker-thread-N
ã«å¦çã渡ããã¦ãããã¨ããããã¾ãã
Vert.xé¢é£ã¹ã¬ãããã¼ã«ã¨ãã³ã°ã¹ã¬ããæ¤ç¥æ©è½
ãã®æç¹ã§ã¹ã¬ãããã³ããã¨ã£ã¦ã¿ãã¨ãVert.x é¢é£ã¹ã¬ããã¨ãã¦ä»¥ä¸ã®ãããªã¹ã¬ãããåå¨ãããã¨ããããã¾ãã
"vert.x-worker-thread-1" #50 prio=5 os_prio=0 tid=0x00007f0e20186000 nid=0x7945 waiting on condition [0x00007f0e66aed000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x000000068d73f5b0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748) "vert.x-internal-blocking-0" #49 prio=5 os_prio=0 tid=0x00007f0e20185800 nid=0x7944 waiting on condition [0x00007f0e676f9000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x000000068d73f890> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748) "vert.x-worker-thread-0" #47 prio=5 os_prio=0 tid=0x00007f0e20162800 nid=0x7942 waiting on condition [0x00007f0e671f4000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x000000068d73f5b0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748) ... "vert.x-acceptor-thread-0" #44 prio=5 os_prio=0 tid=0x00007f0e200e5800 nid=0x783e runnable [0x00007f0e679fc000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) - locked <0x000000068d63ad38> (a io.netty.channel.nio.SelectedSelectionKeySet) - locked <0x000000068d63be38> (a java.util.Collections$UnmodifiableSet) - locked <0x000000068d63bd60> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97) at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:62) at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:824) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:457) at io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1044) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748) ... "vert.x-eventloop-thread-0" #36 prio=5 os_prio=0 tid=0x00007f0e908ca800 nid=0x7836 runnable [0x00007f0e674f7000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) - locked <0x000000068d78ba98> (a io.netty.channel.nio.SelectedSelectionKeySet) - locked <0x000000068d78cba8> (a java.util.Collections$UnmodifiableSet) - locked <0x000000068d78cac0> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97) at io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:62) at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:824) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:457) at io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1044) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748)
ãããã大éæã«æ¸ãã¨ã以ä¸ã®ãããªå½¹å²ã§åãã¹ã¬ããã§ãã
vert.x-acceptor-thread
: TCPæ¥ç¶ãåãä»ããã¹ã¬ããvert.x-eventloop-thread
: ãã³ããããã³ã°IOãå¦çãã EventLoop ã¹ã¬ããvert.x-worker-thread
: ããããã³ã°ãªå¦çãè¡ã Worker ã¹ã¬ãããexecuteBlocking()
ãå¼ã³åºããã¨ã§ãã£ã¹ãããããããvert.x-internal-blocking
: é常ã®ã¢ããªã§å©ç¨ããããã®ã§ã¯ãªããå é¨ã§è¡ãããããããã³ã°ãªå¦ç(ãã¡ã¤ã«ã·ã¹ãã ããã®èªã¿è¾¼ã¿å¦çãªã©)ãè¡ãããã®ã¹ã¬ãã
vert.x-eventloop-thread
ã vert.x-worker-thread
ããã³ vert.x-internal-blocking
ã®ãã¼ã«ãµã¤ãºã¯ application.properties
ã§ä»¥ä¸ã®ãããªããããã£ã«ã¦è¨å®ã§ãã¾ãã
quarkus.vertx.event-loops-pool-size
:vert.x-eventloop-thread
ã®ãã¼ã«ãµã¤ãºè¨å®ãããã©ã«ãã§ã¯CPUã³ã¢æ° x 2
ãquarkus.vertx.worker-pool-size
:vert.x-worker-thread
ã®ãã¼ã«ãµã¤ãºè¨å®ãããã©ã«ãã§ã¯20
ãquarkus.vertx.internal-blocking-pool-size
:vert.x-internal-blocking
ã®ãã¼ã«ãµã¤ãºè¨å®ãããã©ã«ãã§ã¯20
ã
ãªããapplication.properties
ã«è¨å®ã§ãããã©ã¡ã¼ã¿ã¯Quarkus ããã¥ã¡ã³ãã® All Config ãã¼ã¸ã§ç¢ºèªã§ãã¾ãããã ãç¾æç¹ã®ããã¸ã§ã¯ãã§é¢é£ããè¨å®ãã©ã¡ã¼ã¿ã¯ quarkus:generate-config
ãå®è¡ãããã¨ã§ src/main/resources/application.properties.example
ãçæã§ãããã® application.properties.example
ã®ä¸ã«ã³ã¡ã³ãã¢ã¦ããããå½¢ã§é¢é£ããè¨å®ãã©ã¡ã¼ã¿ãå
¥ã£ã¦ãã¾ãã
ãã®ãããããã application.properties
ã«ãªãã¼ã ãã¦å©ç¨ããããé©å®å¿
è¦ãªãã®ãã³ãã¼ãã¦ä½¿ãæ¹æ³ãç°¡åã ã¨æãã¾ãã
$ ./mvnw quarkus:generate-config
çæããã application.properties.example
ã«ã¯ããã¨ãã°ä»¥ä¸ã®ããã«èª¬æä»ãã§ãªã¹ãããã¾ãã
# # The number of event loops. 2 x the number of core by default. # #quarkus.vertx.event-loops-pool-size= ... # # The size of the internal thread pool (used for the file system). # #quarkus.vertx.internal-blocking-pool-size=20 ... # # The size of the worker thread pool. # #quarkus.vertx.worker-pool-size=20
application.properties.example
ãè¦ã¦ããã¨ãquarkus.vertx.max-worker-execute-time
㨠quarkus.vertx.warning-exception-time
ã¨ãã£ããã©ã¡ã¼ã¿ããããã¨ã«æ°ã¥ãã¾ãããã㯠worker ã¹ã¬ããã§å¦çã«æå®æé以ä¸ããã£ã¦ãããã®ãWARNãã°ã§åºåããã¨ããæ©è½ã«é¢é£ãããã©ã¡ã¼ã¿ã§ãããªããquarkus.vertx.max-worker-execute-time
ã®ã³ã¡ã³ãã§ã¯ããã©ã«ã10s(=10ç§)ã¨ãªã£ã¦ãã¾ãããå®éã«ã¯60s(=60ç§)ã§ãã
# # The maximum amount of time the worker thread can be blocked. # Default is 10s. # #quarkus.vertx.max-worker-execute-time= # # The amount of time before a warning is displayed if the event loop is blocked. # #quarkus.vertx.warning-exception-time=2
ãã®æ©è½ãå®éã«è©¦ãã¦ã¿ã¾ããããapplication.properties
ã«ã¯ä»¥ä¸ã®ããã« 5s
(=5ç§) ã¨æå®ãã¦ã¿ã¾ãããªããç¾æç¹ã§ç¢ºèªããéãã¯ãquarkus.vertx.max-worker-execute-time
ãªã©ã®å¤æ´ã¯ Hot Reloading ãå¹ããªãã£ãã®ã§ãä¸åº¦åæ¢ãã¦ããèµ·åããªããå¿
è¦ãããã¾ãã
quarkus.vertx.max-worker-execute-time=5s
src/main/java/org/acme/ExampleResource.java
ã以ä¸ã®ããã«10ç§ã¹ãªã¼ãããã³ã¼ããããã¾ãã
... import java.util.concurrent.TimeUnit; import org.jboss.logging.Logger; @Path("/hello") public class ExampleResource { Logger logger = Logger.getLogger(getClass()); @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { logger.infof(new Throwable(), "ExampleResource#hello() is invoked : thread name [%s], thread class name [%s]", Thread.currentThread().getName(), Thread.currentThread().getClass().getName()); try { long duration = 10L; logger.info("sleeping " + duration + " seconds..."); TimeUnit.SECONDS.sleep(duration); logger.info("done!"); } catch (InterruptedException ignore) {} return "hello"; } }
ãã㧠http://localhost:8080/hello ã«ã¢ã¯ã»ã¹ãã¦ã¿ãã¨ãmax-worker-execute-time
è¨å®å¤ã®5ç§çµéå¾ã«ããã³ã°ãã¦ããã¹ã¬ããåãä½ç§ãã³ã°ãã¦ããããã¹ã¿ãã¯ãã¬ã¼ã¹ã¨ã¨ãã« WARN ãã°ã«åºåããããã¨ã確èªã§ãã¾ãããã®å¾ãå¼ãç¶ãã¹ã¬ããã®ãã³ã°ãç¶ç¶ãã¦ããå ´åã«ã¯ã max-worker-execute-time
ã®2ç§(ããã©ã«ãå¤ã®)ãçµéãããã¨ã«åºåããã¾ãã
2019-12-01 21:12:27,781 INFO [org.acm.ExampleResource] (vert.x-worker-thread-1) sleeping 10 seconds 2019-12-01 21:12:33,617 WARNING [io.ver.cor.imp.BlockedThreadChecker] (vertx-blocked-thread-checker) Thread Thread[vert.x-worker-thread-1,5,main]=Thread[vert.x-worker-thread-1,5,main] has been blocked for 5857 ms, time limit is 5000 ms: io.vertx.core.VertxException: Thread blocked at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386) at org.acme.ExampleResource.hello(ExampleResource.java:30) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:151) at org.jboss.resteasy.core.MethodInjectorImpl.lambda$invoke$3(MethodInjectorImpl.java:122) at org.jboss.resteasy.core.MethodInjectorImpl$$Lambda$316/1812743798.apply(Unknown Source) at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:616) at java.util.concurrent.CompletableFuture.uniApplyStage(CompletableFuture.java:628) at java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:1996) at java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:110) at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:122) at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:594) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:468) at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:421) at org.jboss.resteasy.core.ResourceMethodInvoker$$Lambda$315/408648673.get(Unknown Source) at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:363) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:423) at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:391) at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invoke$1(ResourceMethodInvoker.java:365) at org.jboss.resteasy.core.ResourceMethodInvoker$$Lambda$314/12574409.apply(Unknown Source) at java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:995) at java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2137) at java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:110) at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:365) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:477) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:252) at org.jboss.resteasy.core.SynchronousDispatcher$$Lambda$310/1423111402.run(Unknown Source) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:153) at org.jboss.resteasy.core.SynchronousDispatcher$$Lambda$311/905682736.get(Unknown Source) at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:363) at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:156) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:238) at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73) at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:118) at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.lambda$handle$0(VertxRequestHandler.java:74) at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$$Lambda$308/650568468.handle(Unknown Source) at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$2(ContextImpl.java:316) at io.vertx.core.impl.ContextImpl$$Lambda$302/216113056.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748) 2019-12-01 21:12:35,617 WARNING [io.ver.cor.imp.BlockedThreadChecker] (vertx-blocked-thread-checker) Thread Thread[vert.x-worker-thread-1,5,main]=Thread[vert.x-worker-thread-1,5,main] has been blocked for 7858 ms, time limit is 5000 ms: io.vertx.core.VertxException: Thread blocked at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386) at org.acme.ExampleResource.hello(ExampleResource.java:30) ...(ä¸ã¨åããªã®ã§çç¥)... 2019-12-01 21:12:37,617 WARNING [io.ver.cor.imp.BlockedThreadChecker] (vertx-blocked-thread-checker) Thread Thread[vert.x-worker-thread-1,5,main]=Thread[vert.x-worker-thread-1,5,main] has been blocked for 9858 ms, time limit is 5000 ms: io.vertx.core.VertxException: Thread blocked at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386) at org.acme.ExampleResource.hello(ExampleResource.java:30) ...(ä¸ã¨åããªã®ã§çç¥)... 2019-12-01 21:12:37,781 INFO [org.acm.ExampleResource] (vert.x-worker-thread-1) done!
Quarkus/JAX-RS ã¢ããªã±ã¼ã·ã§ã³ã§ Servlet ä¾åã追å ããã¨ãã«ã©ãå¤ããï¼
åè¿°ããããã«ãä¾åé¢ä¿ã« quarkus-undertow
ã追å ãããã¨ã§ãèªåçã« Servlet API ãå©ç¨ããã¨èªèãããVert.x based Undertow ä¸ã§å¦çãããããã«ãªãã¾ãããã®å ´åã®åä½ã確èªãã¦ã¿ã¾ãã
æ¢åããã¸ã§ã¯ãã¸ã® quarkus-undertow
ä¾åã®è¿½å 㯠quarkus:add-extension
ã§ä»¥ä¸ã®ããã«å®è¡ããã°ã§ãã¾ãã
$ ./mvnw quarkus:add-extension -Dextensions=quarkus-undertow
ãã㧠pom.xml
ã« quarkus-undertow
ã¸ã®ä¾åã追å ããã¾ãã
<dependencies> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <scope>test</scope> </dependency> <!-- 以ä¸ã®ä¾åã追å ããã --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-undertow</artifactId> </dependency> </dependencies>
ããã§èµ·åãã¦ã¢ã¯ã»ã¹ãã¦ã¿ã¾ããä¾åã追å ãã以å¤ãã³ã¼ããè¨å®ã¯ä¸ã§æ¸ãããã®ã®ã¾ã¾ã§ãã
2019-12-01 22:51:07,912 INFO [org.acm.ExampleResource] (executor-thread-1) ExampleResource#hello() is invoked : thread name [executor-thread-1], thread class name [org.jboss.threads.JBossThread]: java.lang.Throwable at org.acme.ExampleResource.hello(ExampleResource.java:21) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:151) at org.jboss.resteasy.core.MethodInjectorImpl.lambda$invoke$3(MethodInjectorImpl.java:122) at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:616) at java.util.concurrent.CompletableFuture.uniApplyStage(CompletableFuture.java:628) at java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:1996) at java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:110) at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:122) at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:594) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:468) at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:421) at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:363) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:423) at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:391) at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invoke$1(ResourceMethodInvoker.java:365) at java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:995) at java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2137) at java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:110) at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:365) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:477) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:252) at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:153) at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:363) at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:156) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:238) at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:249) at io.quarkus.resteasy.runtime.ResteasyFilter$ResteasyResponseWrapper.sendError(ResteasyFilter.java:65) at io.undertow.servlet.handlers.DefaultServlet.doGet(DefaultServlet.java:172) at javax.servlet.http.HttpServlet.service(HttpServlet.java:503) at javax.servlet.http.HttpServlet.service(HttpServlet.java:590) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) at io.quarkus.resteasy.runtime.ResteasyFilter.doFilter(ResteasyFilter.java:28) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:63) at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:133) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:65) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:270) at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:59) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:116) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:113) at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$9$1$1.call(UndertowDeploymentRecorder.java:475) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:250) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:59) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:82) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:290) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:669) at io.quarkus.runtime.CleanableExecutor$CleaningRunnable.run(CleanableExecutor.java:224) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2011) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1535) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1395) at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29) at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29) at java.lang.Thread.run(Thread.java:748) at org.jboss.threads.JBossThread.run(JBossThread.java:479) 2019-12-01 22:51:07,913 INFO [org.acm.ExampleResource] (executor-thread-1) sleeping 10 seconds 2019-12-01 22:51:17,913 INFO [org.acm.ExampleResource] (executor-thread-1) done!
ã¹ã¿ãã¯ãã¬ã¼ã¹ãã Undertow ä¸ã§å®è¡ãããã¾ããã¹ã¬ããåã vert.x-worker-thread-N
ã§ã¯ãªã executor-thread-N
ã¨ããå¥ãªã¹ã¬ãããã¼ã«ãå©ç¨ãããããã«å¤ãã£ã¦ãããã¨ã確èªã§ãã¾ããã¾ããVert.x ã® worker ã¹ã¬ããä¸ã§ã¯ãªããããmax-worker-execute-time
è¨å®ã«ãã WARN ãã°ãåºãªããªã£ããã¨ããããã¾ãã
ãã®ã¹ã¬ãããã¼ã«ã¯ãVert.x é¢é£ã¨ã¯ç°ãªã以ä¸ã®ããããã£ã§è¨å®ã§ãããã®ãå©ç¨ããã¦ãã¾ããä¾åé¢ä¿ã®éãã§ã¢ããªã±ã¼ã·ã§ã³å¦çã§å©ç¨ãããã¹ã¬ãããã¼ã«ãå¤ããã¨ããã®ã¯ãã¥ã¼ãã³ã°ããéã«è½ã¨ãç©´ã«ãªãããã§ããã
quarkus.thread-pool.max-threads
: ã¹ã¬ãããã¼ã«ã®æ大ãµã¤ãºãããã©ã«ãã§ã¯CPUã³ã¢æ° x 8
ãquarkus.thread-pool.core-threads
: ã¹ã¬ãããã¼ã«ã®æå°ãµã¤ãºãããã©ã«ãã§ã¯1
ãquarkus.thread-pool.keep-alive-time
: 使ç¨ããã¦ããªãã¹ã¬ãããä¿æãã¦ããæé(åä½ã¯ç§)ããã®æéãçµéããã¹ã¬ããã¯æå°ãµã¤ãºã¾ã§ç ´æ£ããããããã©ã«ãã¯30
(ç§)ã