AWS ALB配置GRPC转发Fargate Netty服务报HTTP/2序言错误咨询
问题根因
你日志中收到的字节开头160301是TLS 1.0+版本Client Hello报文的标准标识,说明ALB正在向后端服务发起TLS握手请求,但你部署的Netty gRPC服务只监听明文gRPC端口,未启用TLS,自然无法识别HTTP/2明文连接要求的前缀字符串PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n,直接抛出preface缺失的错误。
核心逻辑误区:当ALB目标组ProtocolVersion设置为GRPC时,强制要求ALB与后端之间走HTTPS(HTTP/2 over TLS)的端到端加密链路,不支持SSL卸载(即HTTPS入站解密后转明文h2c流量转发后端),因此目标组协议仅能选择HTTPS,无法切换为HTTP。你此前预期的SSL卸载模式仅适用于普通HTTP/1.1、非gRPC版本的HTTP/2目标组,gRPC场景下不支持该模式。
可运行的配置方案
方案1:后端配置自签证书走端到端TLS(AWS官方推荐配置)
该方案无需调整现有ALB的架构设计,仅需补充后端服务的TLS配置即可:
- 为Fargate运行的Netty服务生成自签SSL证书,由于ALB与Fargate任务的通信处于私有VPC内,无需使用公网信任的ACM证书,自签证书即可满足要求
- 修改Netty gRPC服务启动逻辑,加载证书开启TLS监听50051端口,注意配置TLS的ALPN扩展支持
h2协议,匹配gRPC的HTTP/2要求 - 修正原有CFN配置的错误项,调整后的目标组配置参考如下:
HubTargetGroup: Type: "AWS::ElasticLoadBalancingV2::TargetGroup" Properties: Port: 50051 Protocol: HTTPS ProtocolVersion: GRPC HealthCheckEnabled: true HealthCheckPath: "/grpc.health.v1.Health/Check" HealthCheckPort: "traffic-port" # 原配置此处为HTTP,必须改为HTTPS,否则健康检查永远失败 HealthCheckProtocol: HTTPS TargetType: ip Matcher: GrpcCode: 0 VpcId: !Ref VpcId TargetGroupAttributes: # 跳过后端证书校验,适配自签证书场景,无需给ALB上传自签证书的CA链 - Key: "validation.pattern" Value: "" - Key: "preserve_client_ip.enabled" Value: "true"
配置完成后ALB会先和客户端完成ACM证书的TLS握手,再和后端服务通过自签证书建立TLS连接转发gRPC请求,全链路符合gRPC的HTTP/2 over TLS要求。
方案2:替换为NLB实现SSL卸载(无需后端配置证书)
如果不想给后端服务维护任何证书,希望后端直接运行明文gRPC服务,ALB的gRPC目标组无法满足该需求,需要替换为网络负载均衡器(NLB):
- 为NLB配置50051端口的TLS监听器,挂载ACM公有证书完成客户端侧的SSL卸载
- 后端目标组选择TCP协议,直接转发解密后的明文流量到Fargate任务的50051端口
- 健康检查配置为TCP模式检查50051端口连通性即可,无需七层gRPC状态码校验
该模式下NLB做四层转发,不会向后端发起TLS握手,后端明文gRPC服务可以正常识别请求,不会出现preface错误。
内容的提问来源于stack exchange,提问作者Bakkenrak
相关产品推荐
相关产品推荐

