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

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方法。

解决步骤

  1. 修改Go服务监听端口:将main.go中的监听端口从:6001改为未被占用的端口(如:6002):
ln, err := net.Listen("tcp", ":6002")
  1. 调整PHP调用地址:同步修改PHP代码中的Relay地址:
$tcpRPC = new Goridge\RPC\RPC(Goridge\Relay::create('tcp://127.0.0.1:6002'));
  1. 重启服务验证:
    • 停止当前RoadRunner服务
    • 重新启动RoadRunner,确认Go服务正常启动并监听6002端口
    • 再次执行PHP命令测试调用

额外注意事项

  • 在容器内可通过netstat -tulpn命令检查端口占用情况,避免端口冲突
  • 若仅容器内部调用Go服务,无需额外配置Docker端口映射;若需外部访问,需在Docker配置中添加对应端口映射

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 09:20:13