すべてのプロダクト
Search
ドキュメントセンター

Platform For AI:Nacosを使用してサービスを呼び出す

最終更新日:Jan 20, 2025

イメージサービスなど、1秒あたりのクエリ数 (QPS) が高いサービスの場合、VPC直接接続を有効にすると、アクセスパフォーマンスが大幅に向上し、レイテンシが削減されます。 ただし、複数のインスタンス間で負荷分散機能は付与されません。 Nacosを使用するマイクロサービスが既にある場合は、Nacosを使用してアクセス制御を実装できます。 このトピックでは、NacosインスタンスをマウントしてElastic Algorithm Service (EAS) サービスを呼び出す方法について説明します。

前提条件

  • 仮想プライベートクラウド (VPC) 、vSwitch、およびセキュリティグループが作成されています。 vSwitchには十分な数の使用可能なIPが必要です。 EASは、elastic network interface (ENI) にサービスインスタンスのIPアドレスを登録します。 詳細については、「VPCの作成と管理」および「セキュリティグループの管理」をご参照ください。

    重要

    セキュリティグループは、ECSインスタンスのインバウンドトラフィックとアウトバウンドトラフィックの両方、およびEASサービスインスタンスとのネットワーク相互作用を管理します。 デフォルトでは、同じ基本セキュリティグループ内のインスタンスはVPCを介して対話できます。 VPCダイレクト接続を設定する場合、インスタンス間通信を容易にするために、EASサービスへのアクセスを必要とするECSインスタンスに適切なセキュリティグループを選択します。 異なるセキュリティグループ間の通信を有効にするには、セキュリティグループルールを適切に設定する必要があります。

  • EASのVPC直接接続が有効になっています。 詳細については、「ネットワーク接続の設定」をご参照ください。

  • Nacosインスタンスが利用可能です。「インスタンスの作成」をご参照ください。

  • NacosインスタンスがデプロイされているVPCおよびvSwitchは、VPC直接接続用に設定されているものと同じです。

仕組み

image
  1. VPCおよびvSwitch内にNacosインスタンスを作成します。これらはVPC直接接続用に設定されたものと同じです。

  2. EAS推論サービスをデプロイするときは、マウントするNacosを指定してください。

  3. EASは、推論サービスに関連付けられたポッドをNacosインスタンスに登録します。

  4. クライアントはNacosサービス登録リスナーを開始します。

  5. Nacosは、EASサービスのIPリストの更新をクライアントにプッシュします。

  6. クライアントはSDKを使用してインスタンスを選択します (SDKには負荷分散アルゴリズム: 加重ラウンドロビンが含まれています) 。

  7. クライアントは、SDKによって提供されるサービスインスタンスのIPとポートを使用してサービスにアクセスし、呼び出しを開始します。

ナコス山

Nacosインスタンスを関連付けるには、サービスをデプロイまたは更新するときに、JSON設定ファイルに次の重要なパラメーターを含めます。 この構成はアレイをサポートし、ディザスタリカバリなどのシナリオで複数のNacosインスタンスに同時に登録できます。 サンプル:

{
    "cloud": {
        "networking": {
            "security_group_id": "sg-*****",
            "vpc_id": "vpc-***",
            "vswitch_id": "vsw-****"
        }
    },
    "networking": {
        "nacos": [
            {
                "nacos_id": "mse_regserverless_cn-****"
            }
        ]
    }
}

項目

説明

cloud

始め方

vpc_id

VPC、vSwitch、およびセキュリティグループを設定して、VPC直接接続を有効にします。

重要
  • Nacosインスタンスと同じVPCを使用します。

  • vSwitchのIPアドレスセグメントに十分なIPがあることを確認します。

vswitch_id

security_group_id

始め方

ナコス

id

作成されたNacosインスタンスのID。

チェックNacosサービス登録

サービスのデプロイが成功すると、EASはNacosインスタンスに登録します。 登録の詳細:

  • cluster: DEFAULTクラスター

  • namespace: デフォルトのパブリック名前空間

  • serviceName: サービス名

  • groupName: システム生成の静的フィールド、pai-eas

作成されたサービス情報の正確性を確認します。

挂载Nacos

サービス内のインスタンスの数とステータスを確認します。

Nacos实例状态

クライアント呼び出し

Go

 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) {

	nacosClient, err := NewAndGetNacosClient("yourAliyunUid", "yourNacosEndpoint")
	if err != nil {
		panic(err)
	}

	nacosClient.Subscribe("your_service", "pai-eas")

	params := vo.SelectOneHealthInstanceParam{
		ServiceName: "your_service",
		GroupName:   "pai-eas",
	}
	
	instance, err := nacosClient.SelectOneHealthyInstance(params)
	fmt.Println(instance)

    // check your own invoke info on console and replace host by ip:port
	url := fmt.Sprintf("http://%s:%s/api/predict/xxxxxxx", instance.Ip, strconv.FormatUint(instance.Port, 10))
	fmt.Println(url)

    //todo invoke service by url
}    

Python

説明

Nacos用の公式Python SDKには、負荷分散アルゴリズムは含まれていません。 あなたはあなた自身によって加重ラウンドロビンを実装する必要があります。

依存関係のインストール

pip install nacos-sdk-python

呼び出しの開始

# -*- coding: utf8 -*-
import nacos

# Nacos server configuration
SERVER_ADDRESSES = "yourNacosEndpoint"
NAMESPACE = ""  # Use default namespace if empty
SERVICE_NAME = "your_service"
GROUP_NAME = "pai-eas"

# Create Nacos client
client = nacos.NacosClient(SERVER_ADDRESSES, namespace=NAMESPACE)


def callback(args):
    print(args)


if __name__ == '__main__':
    # Correctly pass the callback function as a list
    client.add_config_watchers(SERVICE_NAME, "pai-eas", [callback])

    # Fetch and print naming instance details
    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"]
        # check your own invoke info on console and replace host by ip:port
        url = f"http://{ip}:{port}/api/predict/xxxxxxx"
        print(url)
     #todo invoke service by url        

Java

Maven依存関係の追加

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>2.3.2</version>
</dependency>

呼び出しの開始

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 {
            String serverAddr = "yourNacosEndpoint:8848";
            NamingService namingService = NacosFactory.createNamingService(serverAddr);

            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);
            Instance instance = namingService.selectOneHealthyInstance("your_service", "pai-eas");
            System.out.println(instance.getIp());
            System.out.println(instance.getPort());
            // check your own invoke info on console and replace host by ip:port
            String url = String.format("http://%s:%d/api/predict/xxxxxxx", instance.getIp(), instance.getPort());
            System.out.println(url);
            
            //todo invoke service by url
            
        } catch (NacosException e) {
            e.printStackTrace();
        }
    }
}