Cloud Native 11 min read

How to Implement Nacos Service Registration & Discovery with Webman in PHP

This tutorial explains the concepts of service registration and discovery in microservice architectures, introduces Nacos as a dynamic registry, and provides step‑by‑step PHP code for registering providers and discovering services using the Webman framework, including persistence and clustering considerations.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
How to Implement Nacos Service Registration & Discovery with Webman in PHP

Introduction

Service registration and discovery are fundamental mechanisms in microservice architectures. Providers register their network location and metadata with a registry; consumers query the registry to locate providers dynamically, enabling load balancing and high availability.

Concepts

Service Registration

When a service instance starts, it sends a registration request containing its IP, port, service name, and optional metadata to the registry (e.g., Nacos). The registry stores this information in memory and the instance periodically sends heartbeats to indicate liveness.

Service Discovery

Consumers request the list of instances for a given service name from the registry. The registry returns the metadata (IP, port, etc.) and the consumer invokes the target service, optionally applying weight‑based routing, latency awareness, or other policies.

Nacos in Service Registration & Discovery

Nacos is an open‑source dynamic service discovery and configuration platform. It supports multiple protocols (HTTP, Dubbo, Spring Cloud) and provides features such as weight‑based load balancing, health checks, and real‑time instance updates.

Nacos Service Registration Process

1. Role of the Registry

The registry maintains service metadata, handles registration/deregistration, performs health checks, and supplies instance lists for discovery.

2. Provider Registration Steps

Provider starts and sends a registration request to Nacos with service name, IP, port, and optional metadata.

Nacos stores the metadata in an in‑memory database and persists it to disk for durability.

Provider sends periodic heartbeats to keep the registration alive.

Example registration code using the workbunny/webman-nacos client:
/**
 * @desc Nacos service registration
 */
public function nacosRegister()
{
    $client = \Workbunny\WebmanNacos\Client::channel();
    $response = $client->instance->register(
        '127.0.0.1',
        80,
        'http-service-8000',
        [
            'groupName'   => 'DEFAULT_GROUP',
            'namespaceId' => '',
            'enabled'    => true,
            'ephemeral'   => 'false',
            'metadata'    => [
                'version'    => '1.0.1',
                'grant_type' => 'client_credentials',
                'app_key'    => '5f5kz4s08wk4ws',
                'app_secret' => '4s08wk4c444os',
                'id'         => 10000,
            ],
        ]
    );
    if (false === $response) {
        var_dump($client->instance->getMessage());
    }
    var_dump($response);
}

3. Consumer Discovery Steps

Consumer sends a query request to Nacos specifying the desired service name.

Nacos returns a list of healthy instances (IP, port, metadata).

Consumer selects an instance (e.g., round‑robin or weight‑based) and invokes the service via HTTP/RPC.

Example discovery code:
/**
 * @desc Nacos service discovery
 */
public function nacosService()
{
    $client = \Workbunny\WebmanNacos\Client::channel();
    $instanceJson = $client->instance->list('http-service', []);
    if (false === $instanceJson) {
        echo "[x] No instance list
";
        return $client->instance->getMessage();
    }
    $instanceList = json_decode($instanceJson, true);
    foreach ($instanceList['hosts'] as $instance) {
        $metadata = $instance['metadata'];
        echo "[x] Service metadata: " . json_encode($metadata, JSON_UNESCAPED_UNICODE) . "
";
        $url = 'http://' . $instance['ip'] . ':' . $instance['port'] . '/nacos/v1/auth/users/login';
        echo "[x] Request URL: $url
";
        $result = $this->curl_get($url);
        echo "[x] Response: " . json_encode(json_decode($result, true), JSON_UNESCAPED_UNICODE) . "

";
    }
}

/**
 * Simple HTTP GET wrapper
 */
public function curl_get($url)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_URL, $url);
    return curl_exec($ch);
}

Persistence and Synchronization

Nacos keeps registry data in memory for fast queries but also writes it to disk to prevent loss. In a clustered deployment, each Nacos node replicates the data, ensuring consistency across the cluster.

Practical Implementation with Webman

Provider Implementation

Create a Webman project and add the workbunny/webman-nacos dependency via Composer.

Configure the Nacos address in plugin/workbunny/webman-nacos/app.php.

Set the listening port in config/server.php (e.g., 'listen' => 'http://0.0.0.0:8781').

Implement a RESTful controller. Example OrderController returns order details:

declare(strict_types=1);

namespace app\controller;

use support\Request;
use support\Response;

class OrderController
{
    /**
     * @desc detail
     */
    public function detail(Request $request, int $id): Response
    {
        return json(['code' => 0, 'msg' => $id . ' order detail']);
    }
}

Access the endpoint at http://127.0.0.1:8781/order/detail/10086 which returns:

{
  "code": 0,
  "msg": "10086 order detail"
}

Register the provider with the following parameters:

IP: 192.168.3.88 Port: 8781 Service name:

http-webman-8781
/**
 * @desc Nacos service registration
 */
public function nacosRegister()
{
    $client = \Workbunny\WebmanNacos\Client::channel();
    $response = $client->instance->register(
        '192.168.3.88',
        8781,
        'http-webman-8781',
        [
            'groupName'   => 'DEFAULT_GROUP',
            'namespaceId' => '',
            'enabled'    => true,
            'ephemeral'   => 'false',
        ]
    );
    if (false === $response) {
        var_dump($client->instance->getMessage());
    }
    var_dump($response);
}

Consumer Implementation

Create a Webman project and require workbunny/webman-nacos.

Configure Nacos address in plugin/workbunny/webman-nacos/app.php.

Set the consumer listening port in config/server.php (e.g., 'listen' => 'http://0.0.0.0:8782').

Use the discovery code shown earlier to obtain provider instances and invoke the /order/detail/10086 endpoint.

Metadata Format

{
    "version": "v1.0.0",
    "protocol": "http",
    "name": "http-service"
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Cloud NativeMicroservicesservice discoveryNacosPHPWebman
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.