一、文档说明1.1 适用环境操作系统Windows开发工具IDEA 2024Go 版本1.21JDK 版本17SpringBoot 版本3.2.xProtoc 版本v261.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 GOPROXYhttps://goproxy.cn,direct安装 protoc 编译插件go install google.golang.org/protobuf/cmd/protoc-gen-golatestgo install google.golang.org/grpc/cmd/protoc-gen-go-grpclatestgo install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gatewaylatestgo install github.com/grpc-ecosystem/protoc-gen-grpc-javalatest2.2 IDEA必备插件Go官方Protocol BuffersSpring Initializr三、模块一公共 Proto 模块 go-proto3.1 创建模块IDEA 新建 Empty Project手动创建 Go Module 模块go-proto执行目录初始化mkdir -p api/google/api api/user gen java-gengo get google.golang.org/grpcgo get google.golang.org/protobufgo get github.com/grpc-ecosystem/grpc-gateway/v23.2 手动创建网关依赖注解文件解决新版网关缺失问题新版 grpc-gateway v2 已无 runtime/googleapis手动创建以下两个文件。文件1api/google/api/http.protosyntax 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; // 接口路径 }文件2api/google/api/annotations.protosyntax 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.protosyntax 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语法、插件环境 ) pause3.5 IDEA 修复 proto 标红File → Settings → Languages Frameworks → Protocol Buffers 添加导入路径$PROJECT_ROOT$/go-proto/api重启IDEA生效。四、模块二SpringBoot 微服务 spring-user4.1 项目创建基于 Spring Initializr 创建JDK17依赖grpc-spring-boot-starter、Lombok4.2 pom.xml 核心配置?xml version1.0 encodingUTF-8?project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.2.5/versionrelativePath//parentgroupIdcom.example/groupIdartifactIdspring-user/artifactIdversion0.0.1-SNAPSHOT/versionpropertiesjava.version17/java.versiongrpc.version1.64.0/grpc.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter/artifactId/dependencydependencygroupIdnet.devh/groupIdartifactIdgrpc-spring-boot-starter/artifactIdversion2.15.0.RELEASE/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependency/dependenciesbuildextensionsextensiongroupIdkr.motd.maven/groupIdartifactIdos-maven-plugin/artifactIdversion1.7.1/version/extension/extensionspluginsplugingroupIdorg.xolstice.maven.plugins/groupIdartifactIdprotobuf-maven-plugin/artifactIdversion0.6.1/versionconfigurationprotocArtifactcom.google.protobuf:protoc:3.25.3:exe:${osdetector.classifier}/protocArtifactpluginIdgrpc-java/pluginIdpluginArtifactio.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${osdetector.classifier}/pluginArtifact/configurationexecutionsexecutiongoalsgoalcompile/goalgoalcompile-custom/goal/goals/execution/executions/plugin/plugins/build/project4.3 配置文件 application.ymlgrpc: erver: port:9090 spring: application: name: spring-user-service4.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, StreamObserverGetUserResp 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-gateway5.1 模块创建与依赖配置新建 Go Module 模块api-gateway修改 go.modmodule api-gatewaygo 1.22replace go-proto ../go-protorequire go-proto v0.0.0-00010101000000-000000000000require (github.com/grpc-ecogrpc-gateway/v2 v2.20.0google.golang.org/grpc v1.64.0)system/5.2 网关主程序 main.gopackage 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 严格启动顺序启动spring-user先启动gRPC业务服务启动api-gateway再启动网关6.2 接口测试GET 请求http://127.0.0.1:8080/api/v1/user/1001POST 请求地址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协议、内网业务隔离、外网流量统一收敛的企业级微服务架构可直接用于学习、开发与项目落地。