nacos_client.py 2.5 KB
"""
Nacos 服务注册客户端
使用 nacos-sdk-python v2,内置自动心跳
"""

import logging
import socket

import nacos

from .settings import get_settings

logger = logging.getLogger(__name__)

_client: nacos.NacosClient | None = None


def _get_local_ip() -> str:
    """获取本机内网 IP"""
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        ip = s.getsockname()[0]
        s.close()
        return ip
    except Exception:
        return "127.0.0.1"


def register_service() -> None:
    """注册服务到 Nacos(v2 内置自动心跳)"""
    global _client
    settings = get_settings()

    if not settings.nacos_enabled:
        logger.info("Nacos 注册已禁用,跳过")
        return

    server_addr = settings.nacos_server_addr
    namespace = settings.nacos_namespace or ""

    _client = nacos.NacosClient(
        server_addr,
        namespace=namespace,
    )

    ip = _get_local_ip()
    port = settings.nacos_service_port
    service_name = settings.nacos_service_name
    group = settings.nacos_group

    metadata = {
        "group": settings.nacos_metadata_group,
        "region": settings.nacos_metadata_region,
        "version": settings.nacos_metadata_version,
        "preserved.register.source": "python",
    }

    try:
        _client.add_naming_instance(
            service_name,
            ip,
            port,
            group_name=group,
            metadata=metadata,
            enable=True,
            healthy=True,
            ephemeral=True,
            heartbeat_interval=5,
        )
        logger.info(
            f"Nacos 注册成功: {service_name} -> {ip}:{port} "
            f"(namespace={namespace}, group={group}, 心跳间隔=5s)"
        )
    except Exception as e:
        logger.error(f"Nacos 注册失败: {e}", exc_info=True)


def deregister_service() -> None:
    """从 Nacos 注销服务"""
    global _client
    settings = get_settings()

    if not settings.nacos_enabled or _client is None:
        return

    ip = _get_local_ip()
    port = settings.nacos_service_port
    service_name = settings.nacos_service_name
    group = settings.nacos_group

    try:
        _client.remove_naming_instance(
            service_name,
            ip,
            port,
            group_name=group,
        )
        logger.info(f"Nacos 注销成功: {service_name} -> {ip}:{port}")
    except Exception as e:
        logger.error(f"Nacos 注销失败: {e}", exc_info=True)
    finally:
        _client = None