When EAS inference services scale up or down, client-side IP lists become stale, causing failed requests. By integrating Nacos service discovery, EAS automatically registers and deregisters service instances, and the client SDK routes traffic to healthy instances using weighted round-robin load balancing.
Prerequisites
Before you begin, ensure that you have:
A VPC, vSwitch, and security group. The vSwitch must have enough available IPs — EAS registers service instance IP addresses on the elastic network interface (ENI).
VPC direct connection enabled for EAS. Without it, client traffic cannot reach EAS instances over the private network. For setup instructions, see Configure network access.
A Nacos instance from Microservices Engine (MSE). The instance must be in the same VPC and vSwitch as configured for VPC direct connection. For setup instructions, see Create an MSE registry instance.
Security groups control inbound and outbound traffic between ECS instances and EAS service instances. Instances within the same basic security group can communicate over the VPC by default. If your ECS instance and EAS service use different security groups, add security group rules to allow traffic between them.
How it works
Create a Nacos instance in the same VPC and vSwitch as configured for VPC direct connection.
When deploying an EAS inference service, specify the Nacos instance to mount.
EAS registers the service pods with your Nacos instance.
The client subscribes to service change events on Nacos.
Nacos pushes service IP list updates to the client as instances scale up or down.
The client SDK selects a healthy instance using weighted round-robin load balancing.
The client calls the service using the instance IP and port.
Configure Nacos for a deployment
Include the following parameters in the JSON configuration file when deploying or updating an EAS service. The networking.nacos field accepts an array, so you can register a single service with multiple Nacos instances.
{
"cloud": {
"networking": {
"security_group_id": "sg-*****",
"vpc_id": "vpc-***",
"vswitch_id": "vsw-****"
}
},
"networking": {
"nacos": [
{
"nacos_id": "mse_regserverless_cn-****"
}
]
}
}| Parameter | Description |
|---|---|
cloud.networking.vpc_id | ID of the VPC for direct connection. Use the same VPC as your Nacos instance. |
cloud.networking.vswitch_id | ID of the vSwitch for direct connection. Make sure the vSwitch IP range has enough available IPs. |
cloud.networking.security_group_id | ID of the security group for direct connection. |
networking.nacos[].nacos_id | ID of the Nacos instance to associate with this service. |
Verify service registration
After deploying the service, EAS automatically registers it with your Nacos instance using the following properties:
| Property | Value |
|---|---|
cluster | DEFAULT |
namespace | Default public namespace |
serviceName | Your EAS service name |
groupName | pai-eas (system-generated) |
Check service registration status in the Nacos console:

Verify the instance count and health status:

Call the service
All examples use the Nacos SDK to subscribe to service changes, select a healthy instance, and build the request URL from the instance IP and port. The group name is always pai-eas.
Python
The official Python SDK for Nacos does not include built-in load balancing. Implement weighted round-robin manually if you need to distribute traffic across multiple instances.
Install the SDK:
pip install nacos-sdk-pythonInitialize the Nacos client, then subscribe to service changes and select a healthy instance:
# -*- coding: utf8 -*-
import nacos
# Nacos server configuration
SERVER_ADDRESSES = "yourNacosEndpoint"
NAMESPACE = "" # Use default namespace
SERVICE_NAME = "your_service"
GROUP_NAME = "pai-eas"
# Initialize the Nacos client with your server address and namespace
client = nacos.NacosClient(SERVER_ADDRESSES, namespace=NAMESPACE)
def callback(args):
print(args)
if __name__ == '__main__':
# Subscribe to service changes to receive real-time IP list updates
client.add_config_watchers(SERVICE_NAME, "pai-eas", [callback])
# Get all healthy service instances
b = client.list_naming_instance(SERVICE_NAME, None, None, GROUP_NAME, True)
print(b)
if b["hosts"]:
print("ip", b["hosts"][0]["ip"])
ip = b["hosts"][0]["ip"]
port = b["hosts"][0]["port"]
# Build the service URL from the instance IP and port
url = f"http://{ip}:{port}/api/predict/xxxxxxx"
print(url)
# Call the service using the URLReplace yourNacosEndpoint with the endpoint address of your Nacos instance and your_service with your EAS service name.
Java
Add the Maven dependency:
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.3.2</version>
</dependency>Initialize the naming service, subscribe to changes, and select a healthy instance:
package test;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.listener.AbstractEventListener;
import com.alibaba.nacos.api.naming.listener.Event;
import com.alibaba.nacos.api.naming.listener.EventListener;
import com.alibaba.nacos.api.naming.listener.NamingEvent;
import com.alibaba.nacos.api.naming.pojo.Instance;
public class NacosTest {
public static void main(String[] args) {
try {
// Initialize the Nacos naming service with your server address and port
String serverAddr = "yourNacosEndpoint:8848";
NamingService namingService = NacosFactory.createNamingService(serverAddr);
// Subscribe to service changes to receive real-time IP list updates
ExecutorService executorService = Executors.newFixedThreadPool(1);
EventListener serviceListener = new AbstractEventListener() {
@Override
public void onEvent(Event event) {
if (event instanceof NamingEvent) {
System.out.println(((NamingEvent) event).getServiceName());
System.out.println(((NamingEvent) event).getGroupName());
}
}
@Override
public Executor getExecutor() {
return executorService;
}
};
namingService.subscribe("your_service", "pai-eas", serviceListener);
// Select a healthy instance using weighted round-robin load balancing
Instance instance = namingService.selectOneHealthyInstance("your_service", "pai-eas");
System.out.println(instance.getIp());
System.out.println(instance.getPort());
// Build the service URL from the instance IP and port
String url = String.format("http://%s:%d/api/predict/xxxxxxx", instance.getIp(), instance.getPort());
System.out.println(url);
// Call the service using the URL
} catch (NacosException e) {
e.printStackTrace();
}
}
}Replace yourNacosEndpoint with the endpoint address of your Nacos instance and your_service with your EAS service name.
Go
The Go SDK handles weighted round-robin load balancing through SelectOneHealthyInstance.
package main
import (
"fmt"
"github.com/nacos-group/nacos-sdk-go/v2/clients"
"github.com/nacos-group/nacos-sdk-go/v2/clients/naming_client"
"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
"github.com/nacos-group/nacos-sdk-go/v2/model"
"github.com/nacos-group/nacos-sdk-go/v2/util"
"github.com/nacos-group/nacos-sdk-go/v2/vo"
"strconv"
"testing"
"time"
)
var Clients = make(map[string]NacosClientManager)
type NacosClientManager struct {
userId string
endPoint string
client naming_client.INamingClient
}
func NewAndGetNacosClient(userId string, endPoint string) (*NacosClientManager, error) {
key := generateKey(userId, endPoint)
client, exists := Clients[key]
if exists {
return &client, nil
}
client, exists = Clients[key]
if exists {
return &client, nil
}
newClient, err := clients.NewNamingClient(
vo.NacosClientParam{
ClientConfig: constant.NewClientConfig(
constant.WithNamespaceId(""),
constant.WithTimeoutMs(5000),
constant.WithNotLoadCacheAtStart(true),
constant.WithLogDir("/tmp/nacos/log"),
constant.WithCacheDir("/tmp/nacos/cache"),
constant.WithLogLevel("debug"),
),
ServerConfigs: []constant.ServerConfig{
*constant.NewServerConfig(endPoint, 8848, constant.WithContextPath("/nacos")),
},
},
)
if err != nil {
return nil, err
}
nacosClient := NacosClientManager{
userId: userId,
endPoint: endPoint,
client: newClient,
}
Clients[key] = nacosClient
return &nacosClient, nil
}
func (p *NacosClientManager) SelectOneHealthyInstance(param vo.SelectOneHealthInstanceParam) (*model.Instance, error) {
instance, err := p.client.SelectOneHealthyInstance(param)
if err != nil {
return nil, fmt.Errorf("SelectOneHealthyInstance failed: %v", err)
}
fmt.Printf("SelectOneHealthyInstance success, param: %+v\n", param)
return instance, nil
}
func (p *NacosClientManager) Subscribe(service string, group string) error {
subscribeParam := &vo.SubscribeParam{
ServiceName: service,
GroupName: group,
SubscribeCallback: func(services []model.Instance, err error) {
fmt.Printf("callback return services:%s \n\n", util.ToJsonString(services))
},
}
return p.client.Subscribe(subscribeParam)
}
func generateKey(userId string, endPoint string) string {
return userId + fmt.Sprintf("-%s", endPoint)
}
func Test(t *testing.T) {
// Initialize the Nacos client with your Alibaba Cloud UID and Nacos endpoint
nacosClient, err := NewAndGetNacosClient("yourAliyunUid", "yourNacosEndpoint")
if err != nil {
panic(err)
}
// Subscribe to service changes to receive real-time IP list updates
nacosClient.Subscribe("your_service", "pai-eas")
// Select a healthy instance using weighted round-robin load balancing
params := vo.SelectOneHealthInstanceParam{
ServiceName: "your_service",
GroupName: "pai-eas",
}
instance, err := nacosClient.SelectOneHealthyInstance(params)
fmt.Println(instance)
// Build the service URL from the instance IP and port
url := fmt.Sprintf("http://%s:%s/api/predict/xxxxxxx", instance.Ip, strconv.FormatUint(instance.Port, 10))
fmt.Println(url)
// Call the service using the URL
}Replace the following placeholders:
| Placeholder | Description |
|---|---|
yourAliyunUid | Your Alibaba Cloud account UID |
yourNacosEndpoint | Endpoint address of your Nacos instance |
your_service | Your EAS service name |
What's next
Configure network access — Set up VPC direct connection for EAS
Create and manage a VPC — Configure the VPC and vSwitch
Manage security groups — Configure security group rules for cross-group access