Connection Piscina e configuração pool de threads em Java

hguser:

aplicação de Primavera usando Hikari piscina.

Agora, para um único pedido do cliente eu tenho que consultar 10 mesas (negócio necessário) e, em seguida, composite o resultado juntos. E consulta para cada tabela pode custar 50ms a 200ms. Para acelerar o tempo de resposta, eu criar uma FixedThreadPoolno meu serviço para consultar cada tabela no segmento diferente (pseudocódigo):

class MyService{
    final int THREAD_POOL_SIZE = 20;
    final int CONNECTION_POOL_SIZE = 10;


    final ExecutorService pool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
    protected DataSource ds;


    MyClass(){
        Class.forName(getJdbcDriverName());
        HikariConfig config = new HikariConfig();
        config.setMaximumPoolSize(CONNECTION_POOL_SIZE);
        ds = new HikariDataSource(config);
    }



    public Items doQuery(){
        String[] tables=["a","b"......]; //10+ tables
        Items result=new Items();
        CompletionService<Items> executorService = new ExecutorCompletionService<Items>(pool);
        for (String tb : tables) {
            Callable<Item> c = () -> {
                Items items = ds.getConnection().query(tb); ......
                return Items;
            };
            executorService.submit(c);
        }


        for (String tb: tables) {
            final Future<Items> future = executorService.take();
            Items items = future.get();
            result.addAll(items);
        }
    }
}

Agora, para um único pedido, o tempo médio de resposta talvez 500ms.

digite descrição da imagem aqui

Mas para solicitações simultâneas, o tempo médio de resposta vai aumentar rapidamente, mais os pedidos, o tempo o tempo de resposta será.

digite descrição da imagem aqui

Gostaria de saber como definir o tamanho do pool de conexão e pool de threads tamanho adequado para fazer o trabalho aplicação eficaz?

BTW, the database use RDS in cloud with 4 cpu 16GB mem, 2000 max connections and 8000 max IOPS.

skott :

You might want to think about a few more parameters:
1. Max concurrent request parameter for the database. Cloud providers have different limits of concurrent requests for different tiers, you might want to check yours.

2. When you say 50-200 ms, although it is difficult to say, are there 8 requests of 50ms and 2 requests of 200ms on an average or all of them pretty much the same? Why? Your doQuery might be limited by the query taking maximum time (which is 200ms), but the threads taking 50 ms will get released after it's task is done making them available for next set of requests.

3. What is the QPS you are expecting to receive?

Some calculations: If a single request takes 10 threads, and you have provisioned 100 connections with 100 concurrent query limit, assuming 200ms for each query, you can only handle 10 requests at a time. Maybe a little better than 10 if most queries take 50ms or so (but I wouldn't be optimistic).

Of course, some of these calculations goes for a toss if any of your queries takes >200ms (network latency or anything else) , in which case I recommend you have a circuit breaker, either at the connection end (if you are allowed to abort the query after a timeout) or at the API end.

Note : max connection limit is not the same as max concurrent query limit.

Sugestão: Desde que você precisa de resposta sob 500ms, você também pode ter um connectionTimeout de cerca de 100-150ms na piscina. Pior caso: execução 150ms tempo limite de conexão + consulta 200ms + 100ms para processamento de aplicativos <500ms pela sua resposta. Trabalho.

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=312921&siteId=1
Recomendado
Clasificación