9.7.2 Go与Python客户端接入

在 Go 与 Python 接入 Nacos 时,需要同时覆盖配置管理与服务发现,并统一命名空间/分组/鉴权策略,确保跨语言一致性。以下给出原理草图、安装与示例、排错与练习。

原理草图(配置 + 服务发现)

文章图片

1) 安装与准备#

Nacos 服务端健康确认

# 假设 Nacos 在 8848 端口
curl -s "http://127.0.0.1:8848/nacos/v1/console/health" | jq .
# 预期:{"status":"UP"}

统一命名规范(示例)
- Namespace: prod
- Group: DEFAULT_GROUP
- ServiceName: order-service
- DataId: order-service.yaml

鉴权(示例环境变量)

export NACOS_SERVER="127.0.0.1:8848"
export NACOS_NAMESPACE="prod"
export NACOS_GROUP="DEFAULT_GROUP"
export NACOS_USER="nacos"
export NACOS_PASS="nacos"

2) Go 客户端接入(配置 + 注册)#

安装依赖

mkdir -p /opt/nacos-go-demo && cd /opt/nacos-go-demo
go mod init nacos-go-demo
go get github.com/nacos-group/nacos-sdk-go@v1.1.4

配置文件(/opt/nacos-go-demo/app.yaml)

server:
  port: 8081
  env: prod

Go 示例代码(/opt/nacos-go-demo/main.go)

package main

import (
    "fmt"
    "log"
    "time"

    "github.com/nacos-group/nacos-sdk-go/clients"
    "github.com/nacos-group/nacos-sdk-go/clients/config_client"
    "github.com/nacos-group/nacos-sdk-go/clients/naming_client"
    "github.com/nacos-group/nacos-sdk-go/common/constant"
    "github.com/nacos-group/nacos-sdk-go/vo"
)

func newConfigClient() (config_client.IConfigClient, error) {
    sc := []constant.ServerConfig{
        *constant.NewServerConfig("127.0.0.1", 8848),
    }
    cc := constant.ClientConfig{
        NamespaceId:         "prod",
        TimeoutMs:           5000,
        NotLoadCacheAtStart: true,
        LogDir:              "/tmp/nacos/log",
        CacheDir:            "/tmp/nacos/cache",
        Username:            "nacos",
        Password:            "nacos",
    }
    return clients.NewConfigClient(vo.NacosClientParam{ClientConfig: &cc, ServerConfigs: sc})
}

func newNamingClient() (naming_client.INamingClient, error) {
    sc := []constant.ServerConfig{
        *constant.NewServerConfig("127.0.0.1", 8848),
    }
    cc := constant.ClientConfig{
        NamespaceId:         "prod",
        TimeoutMs:           5000,
        NotLoadCacheAtStart: true,
        LogDir:              "/tmp/nacos/log",
        CacheDir:            "/tmp/nacos/cache",
        Username:            "nacos",
        Password:            "nacos",
    }
    return clients.NewNamingClient(vo.NacosClientParam{ClientConfig: &cc, ServerConfigs: sc})
}

func main() {
    // 1) 配置管理
    cfgClient, err := newConfigClient()
    if err != nil {
        log.Fatal(err)
    }

    content, err := cfgClient.GetConfig(vo.ConfigParam{
        DataId: "order-service.yaml",
        Group:  "DEFAULT_GROUP",
    })
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Config:", content)

    err = cfgClient.ListenConfig(vo.ConfigParam{
        DataId: "order-service.yaml",
        Group:  "DEFAULT_GROUP",
        OnChange: func(namespace, group, dataId, data string) {
            fmt.Printf("Config changed: %s\n", data)
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    // 2) 服务注册
    namingClient, err := newNamingClient()
    if err != nil {
        log.Fatal(err)
    }
    _, err = namingClient.RegisterInstance(vo.RegisterInstanceParam{
        Ip:          "127.0.0.1",
        Port:        8081,
        ServiceName: "order-service",
        GroupName:   "DEFAULT_GROUP",
        Weight:      1.0,
        Enable:      true,
        Healthy:     true,
        Metadata:    map[string]string{"version": "v1"},
    })
    if err != nil {
        log.Fatal(err)
    }

    // 3) 订阅服务
    err = namingClient.Subscribe(&vo.SubscribeParam{
        ServiceName: "order-service",
        GroupName:   "DEFAULT_GROUP",
        SubscribeCallback: func(services []vo.SubscribeService, err error) {
            if err != nil {
                log.Println("Subscribe error:", err)
                return
            }
            log.Printf("Instances: %+v\n", services)
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    // 阻塞运行
    for {
        time.Sleep(5 * time.Second)
    }
}

运行与预期

go run /opt/nacos-go-demo/main.go
# 预期:输出当前配置内容;服务实例可在 Nacos 控制台看到

3) Python 客户端接入(配置 + 注册)#

安装依赖

mkdir -p /opt/nacos-py-demo && cd /opt/nacos-py-demo
python3 -m venv venv
source venv/bin/activate
pip install nacos-sdk-python==0.1.7

Python 示例代码(/opt/nacos-py-demo/app.py)

import time
import nacos

SERVER_ADDR = "127.0.0.1:8848"
NAMESPACE = "prod"
GROUP = "DEFAULT_GROUP"
DATA_ID = "order-service.yaml"

client = nacos.NacosClient(
    SERVER_ADDR, namespace=NAMESPACE, username="nacos", password="nacos"
)

# 1) 获取配置
config = client.get_config(DATA_ID, GROUP)
print("Config:", config)

# 2) 监听配置
def on_change(data):
    print("Config changed:", data)

client.add_config_watcher(DATA_ID, GROUP, on_change)

# 3) 注册服务
client.add_naming_instance(
    "order-service",
    "127.0.0.1",
    8091,
    group_name=GROUP,
    cluster_name="DEFAULT",
    metadata={"version": "v1"},
    weight=1.0,
    enable=True,
    healthy=True,
)

# 4) 订阅服务
def on_subscribe(services):
    print("Instances:", services)

client.subscribe("order-service", GROUP, on_subscribe)

while True:
    time.sleep(5)

运行与预期

python /opt/nacos-py-demo/app.py
# 预期:打印配置内容,控制台显示服务实例注册成功

4) 排错清单(含命令)#

1. 无法连接 Nacos(超时/连接拒绝)

ss -lntp | grep 8848
curl -v "http://127.0.0.1:8848/nacos/v1/console/health"
  • 说明:确认端口监听、健康接口正常。

2. 鉴权失败(401/403)

# 检查用户名密码
grep -R "nacos.core.auth.enabled" /path/to/nacos/conf
  • 说明:确保客户端与服务端鉴权配置一致。

3. 配置监听不触发
- 检查 DataId/Group/Namespace 是否一致
- 查看客户端日志目录:/tmp/nacos/log

4. 注册实例不可见

curl -s "http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=order-service&groupName=DEFAULT_GROUP&namespaceId=prod" | jq .
  • 说明:确认实例注册与心跳是否正常。

5) 练习#

  1. 将 Go 与 Python 的 order-service.yaml 配置分别修改,验证监听回调是否触发,并实现热更新输出。
  2. 关闭其中一个实例进程,观察 Nacos 中实例健康状态变化,并记录订阅回调的变化日志。
  3. 自定义元数据字段(如 region=cn-bj),在订阅回调中打印并实现简单过滤逻辑。