gRPC Python thread_pool против max_concurrent_rpcs - PullRequest
0 голосов
/ 28 июня 2018

При запуске Python grpc.server, в чем разница между maximum_concurrent_rpcs и max_workers, используемыми в пуле потоков. Если я хочу maximum_concurrent_rpcs=1, я все еще должен предоставить больше чем один поток в пул потоков?

Другими словами, должен ли я сопоставить maximum_concurrent_rpcs с моим max_workers, или я должен предоставить больше рабочих, чем максимальное число одновременных RPC?

server = grpc.server(
    thread_pool=futures.ThreadPoolExecutor(max_workers=1),
    maximum_concurrent_rpcs=1,
)

1 Ответ

0 голосов
/ 31 июля 2018

Если ваш сервер уже обрабатывает maximum_concurrent_rpcs количество запросов одновременно, и еще один запрос получен, запрос будет отклонен немедленно.

Если max_workers ThreadPoolExecutor меньше maximum_concurrent_rpcs, то после того, как все потоки будут заняты обработкой запросов, следующий запрос будет поставлен в очередь и будет обработан, когда поток завершит свою обработку.

У меня был тот же вопрос. Чтобы ответить на этот вопрос, я немного отладил, что происходит с maximum_concurrent_rpcs. Отладка пошла на py36/lib/python3.6/site-packages/grpc/_server.py в моем virtualenv. Поиск concurrency_exceeded. Суть в том, что если сервер уже обрабатывает maximum_concurrent_rpcs и приходит другой запрос, он будет отклонен:

# ...
elif concurrency_exceeded:
    return _reject_rpc(rpc_event, cygrpc.StatusCode.resource_exhausted,
                        b'Concurrent RPC limit exceeded!'), None
# ...

Я попробовал это на примере gRPC Python Quickstart:

В greeter_server.py я изменил SayHello() метод:

# ...
def SayHello(self, request, context):
    print("Request arrived, sleeping a bit...")
    time.sleep(10)
    return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
# ...

и serve() метод:

def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), maximum_concurrent_rpcs=2)
    # ...

Затем я открыл 3 терминала и запустил в них клиент вручную (так быстро, как мог, используя python greeter_client.py:

Как и ожидалось, для первых двух клиентов обработка запроса началась немедленно (можно увидеть на выходе сервера), потому что было доступно много потоков, но 3-й клиент был отклонен немедленно (как и ожидалось) с StatusCode.RESOURCE_EXHAUSTED, Concurrent RPC limit exceeded!.

Теперь, чтобы проверить, что происходит, когда недостаточно потоков, переданных ThreadPoolExecutor Я изменил max_workers, чтобы он стал 1:

server = grpc.server(futures.ThreadPoolExecutor(max_workers=1), maximum_concurrent_rpcs=2)

Я снова запустил 3 своих клиентов примерно в то же время, что и раньше.

Результат - , что первый получил немедленно. Второму нужно было подождать 10 секунд (пока первый был подан), а затем он был подан. Третий был немедленно отклонен.

...