在Google Cloud Run上运行Python gRPC服务器



我有一个基本的、概念验证的Python gRPC服务器。

当我在本地运行 docker 容器时,我可以向服务器发出请求并在公开的端口上接收响应。

我可以成功地将服务器部署到云运行,并且我看到该服务在云运行 UI 中运行。

但是,我无法从客户端访问云运行版本。

我正在寻找帮助我访问此服务器的建议,无论是对客户端还是服务器的更改。

客户端代码:

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,则收到以下消息:

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,我会收到

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服务,然后在谷歌的云和客户端的边缘之间添加SSL。

在我的客户端上,我需要使用系统根证书才能访问服务

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))

我认为您的问题是您尝试在SSL点上创建一个不安全的通道。我使用这部分代码来创建我的客户端通道:

with open('certificate.pem', 'rb') as f:
creds = grpc.ssl_channel_credentials(f.read())
channel = grpc.secure_channel('predict-<PROJECTHASH>-uc.a.run.app:443',creds)
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
...

您可以从 Web 浏览器下载证书。

您是否按照 Cloud Run 提供的$PORT运行服务器?也许尝试设置一个简单的端点,只返回 200,看看你是否可以点击它并获得响应?

最新更新