Go GRPC服务迁移后Java客户端报未知未实现服务问题排查
核心结论
GRPC服务端与客户端不需要保持相同的目录结构,你遇到的报错根源在于服务全限定名不匹配,和目录结构无关。
报错原因分析
报错信息unimplemented unknown service com.example.categoryproductquery.src.CategoryProductQuery明确显示:客户端请求的服务全限定名,和Go服务端注册的服务名不一致。
关键问题点
Proto文件缺少统一Package声明
你的CategoryProductQuery.proto没有定义顶层package字段,仅通过java_package和go_package指定了各自语言的代码生成路径,这会导致不同语言生成的服务全限定名出现差异。客户端报错里的服务名带src后缀,说明客户端生成的服务全限定名和服务端实际注册的不匹配。Go服务端未完整实现所有RPC方法(次要)
你的Go服务端仅实现了GetCategoryProduct和GetCategories两个方法,但proto文件中定义的getCategoryProductWhithout、getCategoryProductSearch等其他RPC方法均未实现。虽然这不会直接导致服务未找到的错误,但后续调用这些方法时会触发未实现报错。
解决步骤
给Proto文件添加统一Package
在CategoryProductQuery.proto的syntax声明下方添加顶层package,确保客户端和服务端使用相同的服务全限定名:syntax = "proto3"; package com.example.categoryproductquery; // 添加这一行 option java_multiple_files = true; option java_package = "com.example.categoryproductquery.grpc"; option go_package = "internal/infra/grpc/pb"; // ... 其余内容不变重新生成客户端和服务端代码
- Android客户端:使用更新后的proto文件重新生成GRPC代码,确保生成的服务全限定名为
com.example.categoryproductquery.CategoryProductQuery(无src后缀)。 - Go服务端:重新生成pb代码,确保服务注册使用正确的描述符。
- Android客户端:使用更新后的proto文件重新生成GRPC代码,确保生成的服务全限定名为
确认Go服务端正确注册服务
启动GRPC服务器时,确保正确注册服务实例:import ( "github.com/rafaelsouzaribeiro/category-product-query/internal/infra/grpc/pb" "google.golang.org/grpc" ) func main() { // ... 初始化服务实例 categoryProductService := service.NewCategoryProductService(...) // 创建GRPC服务器 server := grpc.NewServer() // 注册服务 pb.RegisterCategoryProductQueryServer(server, categoryProductService) // ... 启动服务器 }补充实现所有RPC方法(可选但建议)
为避免后续调用报错,补充实现proto中定义的所有RPC方法,或者在CategoryProductService中重写未实现方法的默认逻辑。
内容的提问来源于stack exchange,提问作者Rafael Souza

