在Google Cloud Run上运行Python gRPC服务器
我有一个基本的概念验证Python gRPC服务器.
I have a basic, proof-of-concept Python gRPC server.
当我在本地运行docker容器时,我可以向服务器发出请求,并在暴露的端口上接收响应.
When I run my docker container locally, I can make requests to the server and receive responses on the exposed port.
我可以成功地将服务器部署到Cloud Run,并且在Cloud Run UI中看到该服务正在运行.
I can successfully deploy the server to Cloud Run, and I see the service running in the Cloud Run UI.
但是,我无法从客户端访问Cloud Run版本.
However, I am unable to access the Cloud Run version from a client.
我正在寻找建议,以帮助我访问此服务器,无论是对客户端还是对服务器的更改.
I am looking for suggestions to help me access this server, whether it is changes to the clients or the server.
客户代码:
with grpc.insecure_channel('...-uc.a.run.app:80') as channel:
stub = tax_service_pb2_grpc.TaxServiceStub(channel)
response = stub.GetTaxRate(tax_service_pb2.GetTaxRateRequest(zipcode='12345'))
print("Tax client received: {}".format(response.tax_rate))
如果我尝试连接到端口80,则会收到此消息:
If I try to connect to port 80, I received this message:
raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "Trying to connect an http1.x server"
debug_error_string = "{"created":"@1575613033.176590200","description":"Error received from peer ipv4:216.239.36.53:80","file":"src/core/lib/surface/call.cc","file_line":1055,"grpc_message":"Trying to connect an http1.x server","grpc_status":14}"
如果我尝试连接到端口443,则会收到
If I try to connect to port 443, I receive
raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "Trying to connect an http1.x server"
debug_error_string = "{"created":"@1575613033.176590200","description":"Error received from peer ipv4:216.239.36.53:80","file":"src/core/lib/surface/call.cc","file_line":1055,"grpc_message":"Trying to connect an http1.x server","grpc_status":14}"
服务器代码:
import time
from concurrent import futures
import grpc
from grpc_reflection.v1alpha import reflection
import tax_service_pb2
import tax_service_pb2_grpc
class TaxServicer(tax_service_pb2_grpc.TaxServiceServicer):
def GetTaxRate(self, request, context):
return tax_service_pb2.GetTaxRateResponse(tax_rate=1.5)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
tax_service_pb2_grpc.add_TaxServiceServicer_to_server(TaxServicer(), server)
SERVICE_NAMES = (
tax_service_pb2.DESCRIPTOR.services_by_name['TaxService'].full_name,
reflection.SERVICE_NAME,
)
reflection.enable_server_reflection(SERVICE_NAMES, server)
server.add_insecure_port('0.0.0.0:{}'.format(os.environ.get('PORT', 8080)))
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
logging.basicConfig()
serve()
服务器端无需更改.
Cloud Run使用不安全的端口访问gRPC服务,然后在Google云的边缘和客户端之间添加SSL.
The insecure port is used by Cloud Run to access the gRPC service, and then the SSL is added between the edge of Google's cloud and clients.
在我的客户端上,我需要使用系统根证书才能访问服务
On my client, I needed to use the system root certificate in order to access the service
with grpc.secure_channel('<app-url>-uc.a.run.app:443', grpc.ssl_channel_credentials()) as channel:
stub = tax_service_pb2_grpc.TaxServiceStub(channel)
response = stub.GetTaxRate(tax_service_pb2.GetTaxRateRequest(zipcode='12345'))
print("Tax client received: {}".format(response.tax_rate))