在同一个 Python 服务器中组合 gRPC 标准和异步方法
Combining gRPC standard and async methods in the same Python server
我有一个 gRPC 服务器,用 Python 3.6 编写。此服务器遵循 gRPC examples 中描述的模式,如下所示:
from concurrent import futures
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
# ...
def ReadRemoteData(self, request, context):
return fetch_some_data_io_bound()
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig()
serve()
在我的服务器应用中,方法比较多,但大体上大同小异。
这些方法中有许多目前是我的服务器的瓶颈,我想通过 运行 使用 async
来优化它们(这些方法花费大量时间等待 IO 所以他们是一个很好的候选人)。
grpc
的最新版本现在支持 async
,如 this example 中所示,通过使用 server = grpc.aio.server()
.
创建异步服务器
我的问题如下:
服务端有很多gRPC的方法,很多都非常复杂。我想避免重写任何目前不是瓶颈的方法,让它们保持原样。我只想重写那些可以从异步实现中受益的方法,这只是总数的一小部分。出于向后兼容的原因,我无法更改 .proto
定义以将服务拆分为 async/non-async。
问题是,是否可以在同一个 gRPC 服务中以某种方式组合异步和非异步方法?
是的,这是可能的。应用程序需要创建带有额外参数 migration_thread_pool
的异步服务器。这确实是迁移必不可少的功能。
请参阅 https://grpc.github.io/grpc/python/grpc_asyncio.html#grpc.aio.server
处的文档
import asyncio
from concurrent import futures
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
# ...
def ReadRemoteData(self, request, context):
return fetch_some_data_io_bound()
async def serve():
server = grpc.aio.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:50051')
await server.start()
await server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig()
asyncio.run(serve())
我有一个 gRPC 服务器,用 Python 3.6 编写。此服务器遵循 gRPC examples 中描述的模式,如下所示:
from concurrent import futures
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
# ...
def ReadRemoteData(self, request, context):
return fetch_some_data_io_bound()
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig()
serve()
在我的服务器应用中,方法比较多,但大体上大同小异。
这些方法中有许多目前是我的服务器的瓶颈,我想通过 运行 使用 async
来优化它们(这些方法花费大量时间等待 IO 所以他们是一个很好的候选人)。
grpc
的最新版本现在支持 async
,如 this example 中所示,通过使用 server = grpc.aio.server()
.
我的问题如下:
服务端有很多gRPC的方法,很多都非常复杂。我想避免重写任何目前不是瓶颈的方法,让它们保持原样。我只想重写那些可以从异步实现中受益的方法,这只是总数的一小部分。出于向后兼容的原因,我无法更改 .proto
定义以将服务拆分为 async/non-async。
问题是,是否可以在同一个 gRPC 服务中以某种方式组合异步和非异步方法?
是的,这是可能的。应用程序需要创建带有额外参数 migration_thread_pool
的异步服务器。这确实是迁移必不可少的功能。
请参阅 https://grpc.github.io/grpc/python/grpc_asyncio.html#grpc.aio.server
处的文档import asyncio
from concurrent import futures
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
# ...
def ReadRemoteData(self, request, context):
return fetch_some_data_io_bound()
async def serve():
server = grpc.aio.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:50051')
await server.start()
await server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig()
asyncio.run(serve())