我在 docker 容器中运行 python grpc 服务器时遇到问题,我的服务器已启动并正在运行,但没有显示日志。
这就是我的原型文件的样子
syntax = "proto3";
// The health check service definition.
service HealthCheckService {
rpc HealthCheck (HealthCheckRequest) returns (HealthCheckResponse) {}
}
// The request message containing the client's name.
message HealthCheckRequest {
string client_name = 1;
}
// The response message containing the return message
message HealthCheckResponse {
string message = 1;
}
Python 服务器
Server.py
:
import grpc
from concurrent import futures
from generated.health_check_service_pb2 import HealthCheckRequest, HealthCheckResponse
import generated.health_check_service_pb2_grpc as health_check_service_grpc
class HealthCheckServicer(health_check_service_grpc.HealthCheckService):
def HealthCheck(self, request: HealthCheckRequest, context):
return HealthCheckResponse(message="Hello, %s!" % request.client_name)
def serve_grpc():
port = "50051"
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
health_check_service_grpc.add_HealthCheckServiceServicer_to_server(HealthCheckServicer(), server)
server.add_insecure_port("[::]:" + port)
server.start()
print("GRPC Server started, listening on port " + port)
server.wait_for_termination()
if __name__ == '__main__':
serve_grpc()
NodeJS 客户端,
client.js
:
var parseArgs = require('minimist');
var messages = require('./generated/health_check_service_pb');
var services = require('./generated/health_check_service_grpc_pb');
var grpc = require('@grpc/grpc-js');
function main() {
var argv = parseArgs(process.argv.slice(2), {
string: 'target'
});
var target;
if (argv.target) {
target = argv.target;
} else {
target = 'localhost:50051';
}
var client = new services.HealthCheckServiceClient(target,
grpc.credentials.createInsecure());
var request = new messages.HealthCheckRequest();
var user;
if (argv._.length > 0) {
user = argv._[0];
} else {
clientName = 'world';
}
request.setClientName(clientName);
client.healthCheck(request, function(err, response) {
if (err) {
console.log("ERROR:", err);
}
console.log('Health Check Response:', response.getMessage());
});
}
main();
为了进行设置,我这样做了。运行
./gen-protos.sh
执行以下操作:
cd ../server
mkdir -p generated
rm -rf generated/*pb2.pyi
rm -rf generated/*pb2_grpc.py
rm -rf generated/*pb2.py
python -m grpc_tools.protoc --proto_path=../protos --python_out=generated --grpc_python_out=generated --pyi_out=generated ../protos/*.proto
cd ../client
mkdir -p generated
rm -rf generated/*.js
grpc_tools_node_protoc --proto_path=../protos --js_out=import_style=commonjs,binary:generated --grpc_out=grpc_js:generated ../protos/*.proto
然后我构建 docker 服务器并运行它
docker build . -t grpc-test-server
docker run -d -p 50051:50051 grpc-test-server
但是,当我执行
docker container logs ..
时,打印语句绝对没有任何日志,尽管我可以通过运行 node Client.js
使用节点客户端访问服务器
考虑到 Python 日志记录会刷新每个日志,您可以尝试一下,适合您的
server.py
:
import grpc
import logging
from concurrent import futures
from generated.health_check_service_pb2 import HealthCheckRequest, HealthCheckResponse
import generated.health_check_service_pb2_grpc as health_check_service_grpc
class HealthCheckServicer(health_check_service_grpc.HealthCheckService):
def HealthCheck(self, request: HealthCheckRequest, context):
logging.info(f"Received HealthCheck request from {request.client_name}")
return HealthCheckResponse(message=f"Hello, {request.client_name}!")
def serve_grpc():
port = "50051"
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
health_check_service_grpc.add_HealthCheckServiceServicer_to_server(HealthCheckServicer(), server)
server.add_insecure_port(f"[::]:{port}")
server.start()
logging.info(f"GRPC Server started, listening on port {port}")
server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[logging.StreamHandler()])
serve_grpc()
CMD
或 ENTRYPOINT
结合使用:
# Assuming the Dockerfile sets up the environment and copies the server script into the container
# Change the CMD or ENTRYPOINT line to include the -u flag
CMD ["python", "-u", "Server.py"]