Nacos 集群成员发现机制与自定义实现

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 前言:Nacos 可作为注册中心、配置中心,其组成集群对外提供一致的服务,类似于 Zookeeper;zk 的集群成员列表是通过其配置文件 zoo.cfg 维护的 ,其它类似的组件不再讨论,那么 nacos 的集群成员是通过什么机制发现的呢?Nacos 集群成员发现逻辑说明Nacos 在启动时创建 ServerMemberManager(核心的集群成员操作类),它会调用 LookupFactory

前言:Nacos 可作为注册中心、配置中心,其组成集群对外提供一致的服务,类似于 Zookeeper;zk 的集群成员列表是通过其配置文件 zoo.cfg 维护的 ,其它类似的组件不再讨论,那么 nacos 的集群成员是通过什么机制发现的呢?

Nacos 集群成员发现

逻辑说明

Nacos 在启动时创建 ServerMemberManager(核心的集群成员操作类),它会调用 LookupFactory.createLookup() 通过 nacos.core.member.lookup.type 指定的类别初始化 MemberLookup 实现类;后续的成员发现和变更由 MemberLookup.afterLookup() 通知到 ServerMemberManager,此后"配置管理模块"、"注册中心模块"所感知的集群成员都由 ServerMemberManager 取得。

源码关注

  • ServerMemberManager                集群成员的所有操作都汇聚于此类,初始化、成员变更、成员列表、集群间汇报等。 
  • LookupFactoty.createLookup()
  • AbstractMemberLookup 
  • StandaloneMemberLookup          only self
  • FileConfigMemberLookup           watch conf/cluster.conf
  • AddressServerMemberLookup     http get from address server

在 k8s 部署 Nacos 集群

nacos 官方提供 docker 镜像,并结合 nacos-k8s-yaml附录:peer-finder-cluster-demo.yaml)部署于 Kubernetes,以部署 nacos 三个节点为例。       查看 yaml 可看到其包含了一个 initContainer: peer-finder-plugin-install,用来干嘛?其实 peer-finder 插件是用于不断地监听 nacos-headless 的服务列表变更,若列表有变更则写入 conf/cluster.conf,如下:

nacos-0.nacos-headless.default.svc.cluster.local:8848 nacos-1.nacos-headless.default.svc.cluster.local:8848 nacos-2.nacos-headless.default.svc.cluster.local:8848

所以该方案还是利用了上节所述 FileConfigMemberLookup 成员发现机制,conf/cluster.conf 的维护由一个脚本不断地更新,在集群扩缩节点时通过 nacos-headless 准实时获得变更成员,从而每个节点都能维持一致的成员列表。

上述方案有什么缺陷?

  • 有状态:StatefulSet
  • 无法跨 k8s 集群部署 nacos 集群:因为依赖 nacos-headless (k8s Service) ,k8s 集群内的 CoreDNS 域名。

那有什么方法解决呢?可以清楚地知道,上述的 nacos 集群有状态就是与 cluster.conf 文件的维护有关,那么在不引入额外依赖的情况下能想到的唯一解决方案就是使用“配置管理模块”依赖的数据库。(注:注册中心模块不依赖数据库

在 k8s 部署无状态的 Nacos 集群 - Customize DatabaseMemberLookup

集群间成员的感知就是一个成员列表,各节点只要知道一致的成员列表就行;数据库是中心化的依赖,借鉴 AddressServerMemberLookup 实现类似的成员列表发现逻辑,实现基于数据库的集群成员发现:DatabaseMemberLookup

  • 节点启动 
  • 清理超时的过期成员节点
  • (不断心跳)将自己维护到数据库
  • 从数据库获取所有成员列表(有变更则通知 ServerMemberManager)
  • 节点下线 
  • 清理自己在数据库的记录
  • 将自己下线的事件实时告知其他成员(实时性很重要)

以此,Nacos 仅依赖数据库,不断维护自身心跳且节点下线时主动通知其他成员,各个节点均能准实时地获取一致的(在线)成员列表。

附录

peer-finder-cluster-demo.yaml

### Nacos ###
#### https://hub.docker.com/r/nacos/nacos-server
#### https://github.com/nacos-group/nacos-k8s
#### https://github.com/nacos-group/nacos-docker

---
apiVersion: v1
kind: Service
metadata:
  name: nacos-headless
  labels:
    app: nacos-headless
spec:
  selector:
    app: nacos
  type: ClusterIP
  clusterIP: None
  ports:
    - port: 8848
      name: server
      targetPort: 8848
    - port: 7848
      name: rpc
      targetPort: 7848

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nacos
spec:
  serviceName: nacos-headless
  selector:
      matchLabels:
        app: nacos
  replicas: 3
  template:
    metadata:
      labels:
        app: nacos
      annotations:
        pod.alpha.kubernetes.io/initialized: "true"
        prometheus.io/path: /nacos/actuator/prometheus
        prometheus.io/port: '8848'
        prometheus.io/scrape: 'true'
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: "app"
                    operator: In
                    values:
                      - nacos
              topologyKey: "kubernetes.io/hostname"
      initContainers:
        - name: peer-finder-plugin-install
          image: nacos/nacos-peer-finder-plugin:1.1
          imagePullPolicy: Always
          volumeMounts:
            - name: plugin-dir
              mountPath: /home/nacos/plugins/peer-finder
      containers:
        - name: k8snacos
          imagePullPolicy: Always
          image: nacos/nacos-server:1.4.2
          resources:
            requests:
              memory: "8Gi"
              cpu: "4"
          ports:
            - containerPort: 8848
              name: client
            - containerPort: 7848
              name: rpc
          env:
            - name: JVM_XMS
              value: 6g
            - name: JVM_XMX
              value: 6g
            - name: JVM_XMN
              value: 3g
            - name: JVM_MS
              value: 128m
            - name: JVM_MMS
              value: 320m
            - name: SERVICE_NAME
              value: "nacos-headless"
            - name: DOMAIN_NAME
              value: "cluster.local"
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.namespace
            - name: NACOS_REPLICAS
              value: "3"
            - name: MYSQL_SERVICE_HOST
              valueFrom:
                configMapKeyRef:
                  name: nacos-cm
                  key: mysql.host
            - name: MYSQL_SERVICE_DB_NAME
              valueFrom:
                configMapKeyRef:
                  name: nacos-cm
                  key: mysql.db.name
            - name: MYSQL_SERVICE_PORT
              valueFrom:
                configMapKeyRef:
                  name: nacos-cm
                  key: mysql.port
            - name: MYSQL_SERVICE_USER
              valueFrom:
                configMapKeyRef:
                  name: nacos-cm
                  key: mysql.user
            - name: MYSQL_SERVICE_PASSWORD
              valueFrom:
                configMapKeyRef:
                  name: nacos-cm
                  key: mysql.password
            - name: MODE
              value: "cluster"
            - name: NACOS_SERVER_PORT
              value: "8848"
            - name: PREFER_HOST_MODE
              value: "hostname"
            - name: NACOS_SERVERS
              value: "nacos-0.nacos-headless.default.svc.cluster.local:8848 nacos-1.nacos-headless.default.svc.cluster.local:8848 nacos-2.nacos-headless.default.svc.cluster.local:8848"
            - name: NACOS_AUTH_ENABLE
              value: "true"
            - name: NACOS_AUTH_TOKEN
              value: "SecretKey012345678901234567890123456789012345678901234567890123456789TODO"
            - name: NACOS_AUTH_CACHE_ENABLE
              value: "true"
            - name: NACOS_AUTH_USER_AGENT_AUTH_WHITE_ENABLE
              value: "false"
            - name: NACOS_AUTH_IDENTITY_KEY
              value: serverIdentityTODO
            - name: NACOS_AUTH_IDENTITY_VALUE
              value: securityTODO
          volumeMounts:
            - name: plugin-dir
              mountPath: /home/nacos/plugins/peer-finder
      volumes:
        - name: plugin-dir
          emptyDir: {}


---
apiVersion: v1
kind: ConfigMap
metadata:
  name: nacos-cm
data:
  mysql.host: "TODO"
  mysql.db.name: "TODO"
  mysql.port: "3306"
  mysql.user: "TODO"
  mysql.password: "TODO"


# ---
# ------------------- App Ingress ------------------- #
# apiVersion: extensions/v1beta1
# kind: Ingress
# metadata:
#   name: nacos-headless
# #  namespace: default
# spec:
#   rules:
#   - host: TODO
#     http:
#       paths:
#       - path: /
#         backend:
#           serviceName: nacos-headless
#           servicePort: server

参考文献

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
2月前
|
存储 运维 监控
NACOS 配置中心和注册中心是分两个集群部署还是放在一个集群中
【2月更文挑战第33天】NACOS 配置中心和注册中心是分两个集群部署还是放在一个集群中
84 2
|
2月前
|
弹性计算 网络协议 IDE
Nacos报错问题之集群开启鉴权无法注册如何解决
Nacos是一个开源的、易于部署的动态服务发现、配置管理和服务管理平台,旨在帮助微服务架构下的应用进行快速配置更新和服务治理;在实际运用中,用户可能会遇到各种报错,本合集将常见的Nacos报错问题进行归纳和解答,以便使用者能够快速定位和解决这些问题。
|
2月前
|
Java 数据库连接 Nacos
nacos常见问题之Nacos2.0.3集群模式启动报错如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
|
3月前
|
关系型数据库 MySQL 应用服务中间件
从零开始,掌握Nacos搭建的艺术(单点、集群、docker-compose)
从零开始,掌握Nacos搭建的艺术(单点、集群、docker-compose)
58 0
|
13天前
|
Linux Nacos 数据库
【微服务】生产部署nacos集群(三个节点)
【微服务】生产部署nacos集群(三个节点)
26 1
|
1月前
|
存储 应用服务中间件 Nacos
Nacos集群搭建
官方给出的Nacos集群图: 其中包含3个nacos节点,然后一个负载均衡器代理3个Nacos。这里负载均衡器可以使用nginx。
37 3
|
2月前
|
SpringCloudAlibaba Nacos 数据中心
SpringCloudAlibaba Nacos集群改为单机版启动
SpringCloudAlibaba Nacos集群改为单机版启动
21 0
|
2月前
|
Java 数据库连接 网络安全
Nacos报错问题之集群节点间的健康检查超时异常如何解决
Nacos是一个开源的、易于部署的动态服务发现、配置管理和服务管理平台,旨在帮助微服务架构下的应用进行快速配置更新和服务治理;在实际运用中,用户可能会遇到各种报错,本合集将常见的Nacos报错问题进行归纳和解答,以便使用者能够快速定位和解决这些问题。
|
2月前
|
关系型数据库 Nacos 数据库
nacos常见问题之集群异常如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
53 5
|
3月前
|
域名解析 Kubernetes 网络协议
dns问题之nacos集群dns解析不了如何解决
DNS解析是指将人类可读的域名转换成机器可读的IP地址的过程,它是互联网访问中不可或缺的一环;本合集将介绍DNS解析的机制、类型和相关问题的解决策略,以确保域名解析的准确性和高效性。
70 6