Docker中用Goridge实现PHP调用Go代码遇服务找不到错误
RoadRunner Go RPC服务调用报错:rpc: can't find service App.Hi
在Docker环境中使用roadrunner-php/goridge与roadrunner-server/goridge配置RoadRunner,编写了监听6001端口的Go RPC服务(注册了App服务的Hi方法)及对应PHP调用代码,启动RoadRunner后执行PHP命令时提示rpc: can't find service App.Hi,所有操作在容器内不同控制台执行,怀疑和端口转发有关。
相关配置与代码
.rr.dev.yaml配置
version: "2.7" server: command: "php bin/road-runner-console baldinof:roadrunner:worker" env: - APP_RUNTIME: Baldinof\RoadRunnerBundle\Runtime\Runtime go_worker: command: "go run main.go" env: - GOOS: linux - GOARCH: amd64
Go RPC服务代码(main.go)
package main import ( "fmt" "net" "net/rpc" goridgeRpc "github.com/roadrunner-server/goridge/v3/pkg/rpc" ) type App struct{} func (s *App) Hi(name string, r *string) error { *r = fmt.Sprintf("Hello, %s!", name) return nil } func main() { fmt.Println("Hello") ln, err := net.Listen("tcp", ":6001") if err != nil { panic(err) } _ = rpc.Register(new(App)) for { conn, err := ln.Accept() if err != nil { continue } _ = conn go rpc.ServeCodec(goridgeRpc.NewCodec(conn)) } }
PHP调用代码
$tcpRPC = new Goridge\RPC\RPC(Goridge\Relay::create('tcp://127.0.0.1:6001')); $r = $tcpRPC->call("App.Hi", "Antony"); var_dump( $r ); echo __METHOD__.':'.__LINE__;die();
启动命令与输出
启动RoadRunner命令:
bin/rr-server serve .rr.dev.yaml -d
启动后输出:
{"level":"debug","ts":1729072653.5290942,"logger":"rpc","msg":"plugin was started","address":"tcp://127.0.0.1:6001","list of the plugins with RPC methods":["informer","resetter","app"]} [INFO] RoadRunner server started; version: 2.12.3, buildtime: 2023-02-16T13:08:41+0000
错误信息
执行PHP命令时抛出异常:
"exception" => Spiral\Goridge\RPC\Exception\ServiceException^ { #message: "Error 'rpc: can't find service App.Hi' on tcp://127.0.0.1:6001"
问题原因与解决方案
核心问题
从启动日志可见,RoadRunner自身的RPC插件已占用6001端口(日志显示address":"tcp://127.0.0.1:6001"),你的Go服务也尝试监听该端口,导致Go服务未成功注册到目标端口。PHP调用时实际连接的是RoadRunner内置RPC服务,而非你的Go服务,因此找不到App.Hi方法。
解决步骤
- 修改Go服务监听端口:将
main.go中的监听端口从:6001改为未被占用的端口(如:6002):
ln, err := net.Listen("tcp", ":6002")
- 调整PHP调用地址:同步修改PHP代码中的Relay地址:
$tcpRPC = new Goridge\RPC\RPC(Goridge\Relay::create('tcp://127.0.0.1:6002'));
- 重启服务验证:
- 停止当前RoadRunner服务
- 重新启动RoadRunner,确认Go服务正常启动并监听6002端口
- 再次执行PHP命令测试调用
额外注意事项
- 在容器内可通过
netstat -tulpn命令检查端口占用情况,避免端口冲突 - 若仅容器内部调用Go服务,无需额外配置Docker端口映射;若需外部访问,需在Docker配置中添加对应端口映射
内容的提问来源于stack exchange,提问作者des1roer
相关产品推荐
相关产品推荐

