无法通过Postman向NestJS gRPC服务器发起请求的问题排查
NestJS gRPC服务器调试问题:Postman与grpcurl请求失败
我搭建了一台处理gRPC请求的NestJS服务器,用Postman临时调试时始终返回错误:
Received RST_STREAM with code 2 triggered by internal client error: Protocol error
服务器部署在远程机器,通过SSH隧道发送请求,未设置认证。查看服务器日志发现控制器的createLog函数完全未被触发。用grpcurl测试也失败,报错:
Failed to dial target host "localhost:6666": context deadline exceeded
相关代码
app.controller.ts
import { Metadata, ServerUnaryCall } from '@grpc/grpc-js'; import { Controller } from '@nestjs/common'; import { GrpcMethod } from '@nestjs/microservices'; import { BaseLoggingService } from './common/baseLogging.service'; import { CreateLogRequest, CreateLogResponse } from './generated/logs'; @Controller() export class AppController { constructor(private baseLoggingService: BaseLoggingService) {} @GrpcMethod('LogService', 'CreateLog') async createLog( req: CreateLogRequest, metadata: Metadata, call: ServerUnaryCall<CreateLogRequest, CreateLogResponse>, ): Promise<CreateLogResponse> { return await this.baseLoggingService.createLog(req); } }
.proto定义文件
CreateLogRequest和CreateLogResponse接口由protobuf-ts插件生成,基于以下.proto文件:
/** * Definitions of shared interfaces **/ syntax = "proto3"; package logs; enum LogLevel { INFO = 0; WARN = 1; ERROR = 2; DEBUG = 3; } message LogContext { string sessionId = 1; string requestId = 2; string hostname = 3; string podName = 4; string grpcMethodName = 5; uint32 durationMs = 6; } message ErrorData { string name = 1; string notificationCode = 2; string stack = 3; } message CreateLogRequest { LogLevel level = 1; string service = 2; int32 timestamp = 3; string message = 4; LogContext context = 5; ErrorData errorData = 6; } message CreateLogResponse { LogLevel level = 1; string service = 2; int32 code = 3; } service LogService { rpc CreateLog (CreateLogRequest) returns (CreateLogResponse) {} }
grpcurl测试命令及错误
grpcurl -plaintext -d '{ "context": { "durationMs": 4100079420, "grpcMethodName": "magna ut commodo", "hostname": "exercitation dolor", "podName": "ad Duis non", "requestId": "do", "sessionId": "nostrud" }, "errorData": { "name": "nostrud enim Lorem consectetur", "notificationCode": "in anim", "stack": "incididunt" }, "level": 0, "message": "eu qui dolore laborum eiusmod", "service": "sunt", "timestamp": -499959849 }' localhost:6666 LogService/CreateLog
报错:
Failed to dial target host "localhost:6666": context deadline exceeded
排查与解决步骤
检查SSH隧道连通性
- 用
telnet localhost 6666测试本地端口是否能连通,若不通则重新建立隧道,确保端口映射正确(示例:ssh -L 6666:localhost:50051 user@remote-server,需对应远程gRPC服务的监听端口)。
- 用
修正服务器监听配置
- 确认NestJS启动时gRPC服务绑定
0.0.0.0而非仅localhost,否则远程机器无法访问:async function bootstrap() { const app = await NestFactory.createMicroservice(AppModule, { transport: Transport.GRPC, options: { package: 'logs', protoPath: join(__dirname, './logs.proto'), url: '0.0.0.0:50051', // 绑定所有网卡 }, }); await app.listen(); } bootstrap();
- 确认NestJS启动时gRPC服务绑定
调整Postman请求参数
- 选择
gRPC协议,地址填localhost:6666并勾选Plaintext; - 确保请求参数符合proto定义:比如
durationMs是uint32类型,值不能超过4294967295,避免参数解析错误。
- 选择
优化grpcurl调用
- 通过
-proto参数指定本地proto文件路径,避免服务端反射问题:grpcurl -plaintext -proto ./logs.proto -d '{...}' localhost:6666 LogService/CreateLog
- 通过
检查服务器防火墙
- 确认远程服务器防火墙允许gRPC监听端口(如50051)的入站连接,避免端口被拦截。
内容的提问来源于stack exchange,提问作者Imperator Romanorum
相关产品推荐
相关产品推荐

