9.7.3 Node.js与PHP客户端接入

本节聚焦 Node.js 与 PHP 接入 Nacos 的实战流程,覆盖安装、配置管理、服务注册发现、健康检查、鉴权与排错,配套示例与练习。

一、原理与架构草图(配置管理+服务发现)

flowchart LR
  subgraph App[业务应用]
    NJS[Node.js 服务]
    PHP[PHP 服务]
  end
  NJS -->|HTTP/SDK| Nacos[Nacos Server]
  PHP -->|HTTP API| Nacos
  Nacos -->|推送/长轮询| NJS
  Nacos -->|实例列表| NJS
  Nacos -->|实例列表| PHP
  NJS -->|心跳| Nacos
  PHP -->|心跳| Nacos

二、Node.js 客户端接入(安装、配置、命令解释)
1. 安装依赖与准备

mkdir -p /opt/nacos-node-app && cd /opt/nacos-node-app
npm init -y
npm i nacos --save
  • npm i nacos:安装 Nacos SDK(支持配置管理与服务发现)。
  • 目录建议与日志、缓存文件独立,便于排错与回滚。
  1. 配置管理示例(拉取+监听)
    文件:/opt/nacos-node-app/config.js
const NacosConfigClient = require('nacos').NacosConfigClient;

const client = new NacosConfigClient({
  serverAddr: '127.0.0.1:8848',
  namespace: 'public',
  username: 'nacos',
  password: 'nacos',
  requestTimeout: 5000
});

async function main() {
  await client.ready();
  const dataId = 'app.yaml';
  const group = 'DEFAULT_GROUP';

  const content = await client.getConfig(dataId, group);
  console.log('[init-config]', content);

  client.subscribe({ dataId, group }, (content) => {
    console.log('[config-changed]', content);
  });
}

main().catch(err => console.error(err));
  • serverAddr:Nacos 地址。
  • namespace:环境隔离。
  • subscribe:监听配置变化,避免手动轮询。
  1. 服务注册与发现示例
    文件:/opt/nacos-node-app/registry.js
const { NacosNamingClient } = require('nacos');

const client = new NacosNamingClient({
  serverList: '127.0.0.1:8848',
  namespace: 'public',
  username: 'nacos',
  password: 'nacos'
});

async function main() {
  await client.ready();

  await client.registerInstance('orders-service', {
    ip: '127.0.0.1',
    port: 3000,
    weight: 1.0,
    enabled: true,
    healthy: true,
    metadata: { zone: 'az1', version: 'v1' }
  });

  const instances = await client.getAllInstances('orders-service');
  console.log('[instances]', instances);
}

main().catch(console.error);
  • registerInstance:注册服务实例。
  • getAllInstances:服务发现,用于客户端负载均衡。
  1. 运行与预期效果
node config.js
node registry.js

预期输出包含 [init-config][config-changed] 与实例列表。

三、PHP 客户端接入(HTTP API 方式)
1. 安装与环境

apt -y install php-cli php-curl
mkdir -p /opt/nacos-php-app && cd /opt/nacos-php-app
  1. 配置获取与监听(长轮询模拟)
    文件:/opt/nacos-php-app/config_poll.php
<?php
$server = 'http://127.0.0.1:8848';
$dataId = 'app.yaml';
$group = 'DEFAULT_GROUP';
$tenant = 'public';
$user = 'nacos';
$pass = 'nacos';

function get_config($server, $dataId, $group, $tenant, $user, $pass) {
    $url = "$server/nacos/v1/cs/configs?dataId=$dataId&group=$group&tenant=$tenant";
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERPWD, "$user:$pass");
    $resp = curl_exec($ch);
    curl_close($ch);
    return $resp;
}

$last = '';
while (true) {
    $cfg = get_config($server, $dataId, $group, $tenant, $user, $pass);
    if ($cfg !== $last) {
        echo "[config-changed]\n$cfg\n";
        $last = $cfg;
    }
    sleep(5);
}
  • sleep(5):模拟定时拉取,可替换为长轮询实现。
  1. 服务注册、心跳与发现
    文件:/opt/nacos-php-app/registry.php
<?php
$server = 'http://127.0.0.1:8848';
$service = 'orders-service';
$ip = '127.0.0.1';
$port = 9000;
$user = 'nacos';
$pass = 'nacos';

function nacos_post($url, $user, $pass) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_USERPWD, "$user:$pass");
    $resp = curl_exec($ch);
    curl_close($ch);
    return $resp;
}

$register_url = "$server/nacos/v1/ns/instance?serviceName=$service&ip=$ip&port=$port";
echo "[register] " . nacos_post($register_url, $user, $pass) . PHP_EOL;

$list_url = "$server/nacos/v1/ns/instance/list?serviceName=$service";
echo "[instances] " . file_get_contents($list_url) . PHP_EOL;

$beat_url = "$server/nacos/v1/ns/instance/beat?serviceName=$service&ip=$ip&port=$port";
echo "[beat] " . nacos_post($beat_url, $user, $pass) . PHP_EOL;
  • /ns/instance:注册实例。
  • /ns/instance/beat:心跳上报。
  • /ns/instance/list:服务发现。

四、常见排错(含命令)
1. 配置不生效

curl -u nacos:nacos "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=app.yaml&group=DEFAULT_GROUP&tenant=public"
  • 若返回空:检查 dataId/group/tenant 是否一致。
  • 若报 403:检查鉴权配置或用户名密码。
  1. 实例不显示
curl "http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=orders-service"
  • 若列表为空:检查注册成功输出、Nacos 是否可达、端口防火墙。
  1. 频繁下线
    - 检查心跳间隔与 Nacos health-check 相关配置。
    - 查看 Nacos 端日志:/path/to/nacos/logs/nacos.log

五、练习
1. 练习1:Node.js 配置热更新
- 修改 Nacos 控制台 app.yaml 内容。
- 观察 config.js 是否打印 [config-changed]
- 解释:监听器触发说明推送或轮询生效。

  1. 练习2:PHP 注册与心跳
    - 运行 registry.php,确认服务出现在实例列表中。
    - 停止脚本后观察实例状态变化(可能变为不健康)。

  2. 练习3:多语言一致性
    - Node 与 PHP 使用相同 serviceName,验证实例聚合。
    - 解释:服务名一致即可跨语言集群发现。