You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法为gRPC服务执行HTTP/1.x请求的问题排查求助

问题分析与解决方案

问题原因

  • gRPC服务默认基于HTTP/2协议通信,直接发送HTTP/1.x请求(比如浏览器的GET请求)会被拒绝,这就是报错Unexpected HTTP/1.x request的根本原因。
  • 你在.proto中添加的google.api.http注解仅用于定义HTTP与gRPC接口的映射规则,但原生gRPC服务不会自动处理HTTP请求,必须通过gRPC网关(grpc-gateway) 实现HTTP/1.x到gRPC的协议转换。
  • 另外,你的.proto中HTTP映射存在字段不匹配:get: "/author/{id}"里的id对应不上Author消息中的author_id字段,会导致参数无法正确解析。

修复步骤与Java示例

1. 修正.proto文件

修正HTTP映射的字段名,确保和消息字段一致:

syntax = "proto3";
package com.myapp.grpc_server.proto;

option java_multiple_files = true;

import "google/api/annotations.proto";

message Book {
  int32 book_id = 1;
  string title = 2;
  float book_price = 3;
  int32 pages = 4;
  int32 author_id = 5;
}

message Author {
  int32 author_id = 1;
  string first_name = 2;
  string last_name = 3;
  string gender = 4;
  int32 book_id = 5;
}

service BookAuthorService {
  rpc getAuthor(Author) returns (Author) {
    option (google.api.http) = {
      // 修正字段为author_id,和消息中的字段对应
      get: "/author/{author_id}"
      // 可选:定义响应格式为JSON
      response_body: "*"
    };
  }
}

2. 添加依赖(Spring Boot项目)

在pom.xml中添加grpc-gateway相关依赖:

<!-- gRPC Server -->
<dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-server-spring-boot-starter</artifactId>
    <version>2.14.0.RELEASE</version>
</dependency>
<!-- gRPC Client -->
<dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-client-spring-boot-starter</artifactId>
    <version>2.14.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>3.24.4</version>
</dependency>
<dependency>
    <groupId>io.grpc</groupId>
    <artifactId>grpc-protobuf</artifactId>
    <version>1.51.0</version>
</dependency>
<dependency>
    <groupId>io.grpc</groupId>
    <artifactId>grpc-stub</artifactId>
    <version>1.51.0</version>
</dependency>

<!-- 用于生成代码的Maven插件 -->
<build>
    <extensions>
        <extension>
            <groupId>kr.motd.maven</groupId>
            <artifactId>os-maven-plugin</artifactId>
            <version>1.7.1</version>
        </extension>
    </extensions>
    <plugins>
        <plugin>
            <groupId>org.xolstice.maven.plugins</groupId>
            <artifactId>protobuf-maven-plugin</artifactId>
            <version>0.6.1</version>
            <configuration>
                <protocArtifact>com.google.protobuf:protoc:3.24.4:exe:${os.detected.classifier}</protocArtifact>
                <pluginId>grpc-java</pluginId>
                <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.51.0:exe:${os.detected.classifier}</pluginArtifact>
                <!-- 添加grpc-gateway代码生成插件 -->
                <plugins>
                    <plugin>
                        <groupId>io.grpc</groupId>
                        <artifactId>protoc-gen-grpc-gateway</artifactId>
                        <version>1.51.0</version>
                        <executable>protoc-gen-grpc-gateway-${os.detected.classifier}</executable>
                    </plugin>
                </plugins>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>compile-custom</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

3. 生成网关代码

执行mvn clean compile,会自动生成gRPC服务代码和对应的HTTP网关代码(如BookAuthorServiceGatewayGrpc.java)。

4. 配置gRPC网关路由

创建网关配置类,将HTTP请求转发到gRPC服务:

package com.myapp.grpcserver.config;

import com.myapp.grpc_server.proto.Author;
import com.myapp.grpc_server.proto.BookAuthorServiceGrpc;
import com.myapp.grpc_server.proto.BookAuthorServiceGatewayGrpc;
import io.grpc.StatusRuntimeException;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;

@Configuration
public class GrpcGatewayConfig {

    @GrpcClient("book-author-service") // 对应@GrpcService的服务名称
    private BookAuthorServiceGrpc.BookAuthorServiceBlockingStub grpcStub;

    @Bean
    public BookAuthorServiceGatewayGrpc.BookAuthorServiceGatewayImplBase bookAuthorServiceGateway() {
        return new BookAuthorServiceGatewayGrpc.BookAuthorServiceGatewayImplBase() {
            @Override
            public void getAuthor(Author request,
                                 io.grpc.stub.StreamObserver<Author> responseObserver) {
                try {
                    Author response = grpcStub.getAuthor(request);
                    responseObserver.onNext(response);
                    responseObserver.onCompleted();
                } catch (StatusRuntimeException e) {
                    responseObserver.onError(new ResponseStatusException(
                            HttpStatus.NOT_FOUND, "Author not found", e));
                }
            }
        };
    }
}

5. 配置端口

在application.properties中分别配置HTTP网关端口和gRPC服务端口:

# gRPC服务端口(默认9090)
grpc.server.port=9090
# HTTP网关端口(独立于gRPC端口,比如8080)
server.port=8080
# gRPC客户端指向本地服务
grpc.client.book-author-service.address=static://localhost:9090
grpc.client.book-author-service.enableKeepAlive=true

6. 测试HTTP请求

启动应用后,通过curl或浏览器发送请求:

curl http://localhost:8080/author/1

网关会自动将HTTP请求转换为gRPC请求,转发到后端服务后,再将响应转为JSON返回。

关键说明

  • gRPC网关作为中间层,负责处理HTTP/1.x请求与gRPC协议的双向转换。
  • 必须保证.proto中的HTTP映射字段与消息字段严格对应,否则参数无法绑定。
  • gRPC服务和HTTP网关使用不同端口,避免协议冲突。

内容的提问来源于stack exchange,提问作者Pushpak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:02:01