一、文档说明

1.1 适用环境

  • 操作系统:Windows

  • 开发工具:IDEA 2024

  • Go 版本:1.21+

  • JDK 版本:17

  • SpringBoot 版本:3.2.x

  • Protoc 版本:v26+

1.2 架构简介

本项目采用跨语言混合微服务架构,结合 SpringBoot 业务开发效率与 Go 网关高性能转发能力:

  • SpringBoot:实现核心业务,对内提供标准 gRPC 二进制服务,不暴露 HTTP 接口

  • Go grpc-gateway:统一对外 HTTP 网关,自动完成 HTTP/JSON ↔ gRPC 协议转换

  • go-proto 公共模块:统一维护 Protobuf 定义,一键生成 Go、Java 双端代码,彻底解决跨语言接口不一致问题

1.3 调用链路

前端HTTP请求 → Go Gateway 路由匹配 → 自动转 gRPC 请求 → 内网调用 SpringBoot gRPC服务 → 原路返回 JSON 数据

1.4 项目整体结构

grpc-mix-demo/

├─ go-proto/ # 公共Proto模块(核心)

│ ├─ api/google/api/ # 网关HTTP注解proto

│ ├─ api/user/user.proto # 跨语言统一业务接口

│ ├─ gen/ # Go生成代码

│ ├─ java-gen/ # Java生成代码

│ ├─ gen.bat # 一键批量生成脚本

│ └─ go.mod

├─ api-gateway/ # Go grpc-gateway网关服务

│ ├─ cmd/gateway/main.go

│ └─ go.mod

└─ spring-user/ # SpringBoot gRPC业务服务

├─ src/main/proto/

├─ src/main/java/

└─ pom.xml

二、前置环境配置

2.1 Go环境配置

配置国内代理,加速依赖下载:

go env -w GOPROXY=https://goproxy.cn,direct

安装 protoc 编译插件:

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest

go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest

go install github.com/grpc-ecosystem/protoc-gen-grpc-java@latest

2.2 IDEA必备插件

  • Go(官方)

  • Protocol Buffers

  • Spring Initializr

三、模块一:公共 Proto 模块 go-proto

3.1 创建模块

IDEA 新建 Empty Project,手动创建 Go Module 模块 go-proto,执行目录初始化:

mkdir -p api/google/api api/user gen java-gen

go get google.golang.org/grpc

go get google.golang.org/protobuf

go get github.com/grpc-ecosystem/grpc-gateway/v2

3.2 手动创建网关依赖注解文件(解决新版网关缺失问题)

新版 grpc-gateway v2 已无 runtime/googleapis,手动创建以下两个文件。

文件1:api/google/api/http.proto
syntax = "proto3";

package google.api;

// Go代码生成路径,本地项目统一改成 ./gen/google/api;googleapi
option go_package = "./gen/google/api;googleapi";

// 单个RPC方法的HTTP映射规则
message HttpRule {
  // 必填:匹配当前RPC方法名(全限定名,protoc自动填充,无需手动写)
  string selector = 1;

  // 标准HTTP方法路径(六选一,一个规则只能写一种)
  string get = 2;
  string put = 3;
  string post = 4;
  string delete = 5;
  string patch = 6;

  // 自定义HTTP方法(如OPTIONS、HEAD),搭配CustomHttpPattern使用
  CustomHttpPattern custom = 8;

  // 请求体映射规则
  // body = "*":所有POST/PUT参数全部从JSON body读取
  // body = "field":只把请求结构体里的field字段放到body,其余走URL路径参数
  string body = 7;

  // 多条绑定规则:一个RPC可以绑定多个HTTP接口(GET路径 + POST提交)
  repeated HttpRule additional_bindings = 11;
}

// 自定义非标准HTTP方法(HEAD/OPTIONS等)
message CustomHttpPattern {
  string kind = 1;  // HTTP方法名,如 "HEAD"
  string path = 2;  // 接口路径
}
文件2:api/google/api/annotations.proto
syntax = "proto3";

package google.api;

option go_package = "../../gen/google/api;googleapi";

// 导入HttpRule定义
import "google/api/http.proto";
// 导入protobuf原生描述符,用于扩展MethodOptions
import "google/protobuf/descriptor.proto";

// 扩展protobuf原生的方法选项:给每个rpc方法新增http选项
extend google.protobuf.MethodOptions {
  // 固定扩展ID 72295728,官方预留ID不可修改
  HttpRule http = 72295728;
}

3.3 业务统一 Proto 文件(跨Go/Java共用)

路径:api/user/user.proto

syntax = "proto3";

package user;
// 生成代码输出到 gen/user,包名 userpb
option go_package = "/gen/user;userpb";

// 导入网关HTTP注解
import "google/api/annotations.proto";

// 请求参数
message GetUserReq {
  int64 uid = 1;
}
// 响应参数
message GetUserResp {
  int64 uid = 1;
  string username = 2;
  int32 age = 3;
}

// 用户GRPC服务
service UserService {
  rpc GetUser(GetUserReq) returns (GetUserResp) {
    // 绑定RESTful HTTP接口
    option (google.api.http) = {
      get: "/api/v1/user/{uid}"
      additional_bindings {
        post: "/api/v1/user/get"
        body: "*"
      }
    };
  }
}

3.4 一键批量生成脚本 gen.bat

自动清理旧代码、递归扫描全部proto、同时生成 Go + Java 双端代码:

@echo off
:: 切换控制台编码为UTF-8,解决乱码
chcp 65001 >nul
setlocal enabledelayedexpansion

:: 脚本所在根目录
set "ROOT=%~dp0"

protoc ^
--proto_path=%ROOT%api ^
--go_out=%ROOT% ^
--go-grpc_out=%ROOT% ^
--grpc-gateway_out=%ROOT% ^
%ROOT%api\user\user.proto ^
%ROOT%api\google\api\http.proto ^
%ROOT%api\google\api\annotations.proto

if %errorlevel% equ 0 (
    echo 【成功】proto文件编译完成!
) else (
    echo 【失败】protoc编译出错,检查proto语法、插件环境!
)
pause

3.5 IDEA 修复 proto 标红

File → Settings → Languages & Frameworks → Protocol Buffers 添加导入路径:$PROJECT_ROOT$/go-proto/api,重启IDEA生效。

四、模块二:SpringBoot 微服务 spring-user

4.1 项目创建

基于 Spring Initializr 创建,JDK17,依赖:grpc-spring-boot-starter、Lombok

4.2 pom.xml 核心配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version>
        <relativePath/>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>spring-user</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
        <java.version>17</java.version>
        <grpc.version>1.64.0</grpc.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-spring-boot-starter</artifactId>
            <version>2.15.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    <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.25.3:exe:${osdetector.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${osdetector.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

4.3 配置文件 application.yml

grpc:
  erver:
    port:9090
spring:
  application:
    name: spring-user-service

4.4 gRPC 业务实现类

package com.example.springuser.service;

import com.example.springuser.grpc.GetUserReq;
import com.example.springuser.grpc.GetUserResp;
import com.example.springuser.grpc.UserServiceGrpc;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;

@GrpcService
public class UserGrpcServiceImpl extends UserServiceGrpc.UserServiceImplBase {

    @Override
    public void getUser(GetUserReq request, StreamObserver<GetUserResp> responseObserver) {
        long uid = request.getUid();
        GetUserResp resp = GetUserResp.newBuilder()
                .setUid(uid)
                .setUsername("业务用户_" + uid)
                .setAge(26)
                .build();
        responseObserver.onNext(resp);
        responseObserver.onCompleted();
    }
}

4.5 启动类

package com.example.springuser;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringUserApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringUserApplication.class, args);
    }
}

五、模块三:Go 网关 api-gateway

5.1 模块创建与依赖配置

新建 Go Module 模块 api-gateway,修改 go.mod:

module api-gateway
go 1.22

replace go-proto => ../go-proto
require go-proto v0.0.0-00010101000000-000000000000

require (
        github.com/grpc-ecogrpc-gateway/v2 v2.20.0
        google.golang.org/grpc v1.64.0
)system/

5.2 网关主程序 main.go

package main

import (
    "context"
    "log"
    "net/http"
    "go-proto/gen/user"

    "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
        "google.golang.org/grpc"
 .golang.org/grpc/credentials/insecure"
)

const (
        springGRPCAd27.0.0.1:9090"
        httpListenAddr = ":8080"
)

func main() {
        .Background()
        ctx, cancel := context.WithCancel(ctx)
        defconn, err := grpc.DialContext(
                ctx,
                springGR                grpc.WithTransportCredentials(insecure.NewCredentials()), nil {
                log.Fatalf("连接Spring gRPC服务失败        defer conn.Close()

        mux := runtime.NewServeMux()
        err = userpb.RegisterU, mux, conn)
        if err != nil {
                lv", err)
        }

        log.Printf("网关启动成功,监听端口 %s", h
        _ = http.ListenAndServe(httpListenAddr, mux)
}ttpListenAddr)og.Fatalf("注册网关路由失败:%serServiceHandler(ctx:%v", err)
        }

        )
        if err !=PCAddr,
                grpc.WithBlock(),
er cancel()

        ctx := contextdr = "1       "google

六、项目启动与测试

6.1 严格启动顺序

  1. 启动 spring-user(先启动gRPC业务服务)

  2. 启动 api-gateway(再启动网关)

6.2 接口测试

GET 请求

http://127.0.0.1:8080/api/v1/user/1001

POST 请求

地址:http://127.0.0.1:8080/api/v1/user/get Body:{"uid":2002}

七、常见报错与解决方案

7.1 google/api/annotations.proto 找不到

新版网关无内置 googleapis,手动创建 api/google/api 下两个注解文件即可。

7.2 Output filenames must never have a relative path

禁止 go_package 使用 ../../,改为模块内路径 ./gen/user;userpb

7.3 找不到 google.golang.org/genproto

修改 google 注解 proto 的 go_package,生成本地代码,不依赖远程官方包。

7.4 网关连接超时

确保 Spring 服务9090端口正常启动、使用明文连接、关闭防火墙拦截。

7.5 修改proto后接口404

重新执行 gen.bat 生成代码,重启网关。

八、生产优化方案

  • 接入 Nacos/Etcd 实现服务发现与负载均衡,替换硬编码地址

  • 网关增加跨域、鉴权、限流、统一返回体、链路追踪中间件

  • Docker 容器化部署,内网只暴露 gRPC 端口,公网仅开放网关

  • 自动生成 OpenAPI 接口文档

九、总结

本文基于IDEA完整搭建Go网关 + SpringBoot gRPC业务 + 统一Proto混合微服务架构,解决了新版protoc、grpc-gateway所有兼容性报错,实现一套Proto跨双语言统一接口、HTTP自动转gRPC协议、内网业务隔离、外网流量统一收敛的企业级微服务架构,可直接用于学习、开发与项目落地。

更多推荐