quarkus http调用加载测试结果1000个请求-16秒vs 65秒

时间:2019-12-11 14:42:43

标签: quarkus

测试1:

@Path("/performance")
public class PerformanceTestResource {

    @Timeout(20000)
    @GET
    @Path("/resource")
    @Produces(MediaType.APPLICATION_JSON)
    public Response performanceResource() {

        final String name = Thread.currentThread().getName();
        System.out.println(name);

        Single<Data> dataSingle = null;

                try {
                    dataSingle = Single.fromCallable(() -> {
                        final String name2 = Thread.currentThread().getName();
                        System.out.println(name2);
                        Thread.sleep(1000);
                        return new Data();
                    }).subscribeOn(Schedulers.io());

                } catch (Exception ex) {
                    int a = 1;
                }

        return Response.ok().entity(dataSingle.blockingGet()).build();
    }

}

callPeriodically定义的测试本身see also

@QuarkusTest
public class PerformanceTestResourceTest {

        @Tag("load-test")
        @Test
        public void loadTest() throws InterruptedException {

            int CALL_N_TIMES = 1000;
            final long CALL_NIT_EVERY_MILLISECONDS = 10;

            final LoadTestMetricsData loadTestMetricsData = LoadTestUtils.callPeriodically(
                                                                                    this::callHttpEndpoint,
                                                                                    CALL_N_TIMES,
                                                                                    CALL_NIT_EVERY_MILLISECONDS
                                                                            );

            assertThat(loadTestMetricsData.responseList.size(), CoreMatchers.is(equalTo(Long.valueOf(CALL_N_TIMES).intValue())));

            long executionTime = loadTestMetricsData.duration.getSeconds();

            System.out.println("executionTime: " + executionTime + " seconds");

            assertThat(executionTime , allOf(greaterThanOrEqualTo(1L),lessThan(20L)));
        }

结果测试1:

执行时间:16秒

测试2:相同,但没有@Timeout 批注:

执行时间:65秒

问:为什么?我认为即使16秒也很慢。 问:如何使其更快:比如说1000次通话要2秒。

我意识到我在资源中使用了.blockingGet(),但是我仍然希望重新使用阻塞线程。

P.S。  我尝试让更多的“反应性”返回SingleCompletionStage以从响应中返回-但这似乎还没有准备好(轻便的感觉很轻松)。因此,我使用简单的.blockingGet()`和Response。

更新:反应式/ RX Java 2方式

@path("/performance")
public class PerformanceTestResource {

//@Timeout(20000)
@GET
@Path("/resource")
@Produces(MediaType.APPLICATION_JSON)
public Single<Data> performanceResource() {

    final String name = Thread.currentThread().getName();

    System.out.println(name);
    System.out.println("name: " + name);

    return Single.fromCallable(() -> {

        final String name2 = Thread.currentThread().getName();
        System.out.println("name2: " + name2);

        Thread.sleep(1000);
        return new Data();
    });
}
}`

pom.xml

  小黑麦   smallrye上下文传播传播器-rxjava2   org.jboss.resteasy   resteasy-rxjava2

然后在运行相同的测试时:

执行时间: 64秒

输出类似于:

name: vert.x-worker-thread-5 vert.x-worker-thread-9 name: vert.x-worker-thread-9 
name2: vert.x-worker-thread-9 
name2: vert.x-worker-thread-5

因此,我们正在阻止工作线程,该工作线程用于REst / Resource端。恩然后

如果我use:Schedulers.io()在sleep-1000调用的单独执行上下文中:

return Single.fromCallable(() -> { ... }).subscribeOn(Schedulers.io());

执行时间: 16秒

输出将是这样(请参阅新手:RxCachedThreadScheduler)

name: vert.x-worker-thread-5
name2: RxCachedThreadScheduler-1683
vert.x-worker-thread-0
name: vert.x-worker-thread-0
vert.x-worker-thread-9
name: vert.x-worker-thread-9
name2: RxCachedThreadScheduler-1658
vert.x-worker-thread-8

似乎无关紧要:无论我是否显式使用blockingGet(),我都会得到相同的结果。

我认为,如果我不阻止它,则大约需要 2-3秒

问:从现在开始,我有办法解决/调整此问题吗?

在这一点上,我假设使用Schedulers.io()带来了RxCachedThreadScheduler的瓶颈,所以我以 16秒 200 io / io线程是默认限制吗?但是应该重用它们,而不是真正阻止它们。 (不要认为将该限制设置为1000是个好主意。)

Q:或无论如何:如何使应用程序像使用Quarkus一样具有响应/反应/性能。还是我想念什么?

谢谢!

1 个答案:

答案 0 :(得分:0)

好的。也许是我。 在我的callPeriodically();我通过了CALL_NIT_EVERY_MILLISECONDS = 10毫秒。 10 * 1000 = 10000-+ 10秒仅用于添加请求。

我将其设置为0。

花了我6秒钟来处理服务器1000个模拟请求。

仍然不是2-3秒。但是6。

如果我使用.getBlocking并返回Response或返回Single,似乎没有什么区别。

-

但要提一下,这个hello world应用程序需要1秒来处理1000个并行请求。 Quarkus的时间是6秒。

public class Sample2 {

    static final AtomicInteger atomicInteger = new AtomicInteger(0);

    public static void main(String[] args) {

        long start = System.currentTimeMillis();

        final List<Single<Response>> listOfSingles = Collections.synchronizedList(new ArrayList<>());

        for (int i=0; i< 1000; i++) {

//            try {
//                Thread.sleep(10);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }

            final Single<Response> responseSingle = longCallFunction();

            listOfSingles.add(responseSingle);

        }

        Single<Response> last = Single.merge(listOfSingles).lastElement().toSingle();

        final Response response = last.blockingGet();

        long end = System.currentTimeMillis();

        System.out.println("Execution time: " + (end - start) / 1000);

        System.out.println(response);

    }

    static Single<Response> longCallFunction() {
        return Single.fromCallable( () -> { // 1 sec
            System.out.println(Thread.currentThread().getName());
            Thread.sleep(1000);
            int code = atomicInteger.incrementAndGet();
            //System.out.println(code);
            return new Response(code);
        }).subscribeOn(Schedulers.io());
    }

}