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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 前言: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

参考文献

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
7月前
|
存储 运维 监控
NACOS 配置中心和注册中心是分两个集群部署还是放在一个集群中
【2月更文挑战第33天】NACOS 配置中心和注册中心是分两个集群部署还是放在一个集群中
261 3
|
4月前
|
Kubernetes 关系型数据库 MySQL
k8s部署nacos集群
k8s部署nacos集群
|
4月前
|
应用服务中间件 Nacos 数据库
Nacos 1.2.1 集群搭建(三) Nginx 配置 集群
Nacos 1.2.1 集群搭建(三) Nginx 配置 集群
66 1
|
4月前
|
SQL 关系型数据库 MySQL
Nacos 1.2.1 集群搭建(二)MySQL、cluster 配置
Nacos 1.2.1 集群搭建(二)MySQL、cluster 配置
112 1
|
4月前
|
关系型数据库 MySQL Nacos
Nacos 1.2.1 集群搭建(一)环境准备
Nacos 1.2.1 集群搭建(一)环境准备
82 0
|
5月前
|
Nacos 数据中心 Docker
Docker 部署 Nacos 集群
Docker 部署 Nacos 集群
|
6月前
|
Prometheus 监控 Cloud Native
Nacos集群监控搭建
Nacos 0.8.0版本完善了监控系统,支持通过暴露metrics数据接入第三方监控系统监控Nacos运行状态。
103 1
|
6月前
|
负载均衡 算法 Nacos
SpringCloud之LoadBalancer自定义负载均衡算法,基于nacos权重
ReactorLoadBalancer接口,实现自定义负载算法需要实现该接口,并实现choose逻辑,选取对应的节点。
466 0
|
7月前
|
Linux Nacos 数据库
【微服务】生产部署nacos集群(三个节点)
【微服务】生产部署nacos集群(三个节点)
200 1
|
7月前
|
存储 应用服务中间件 Nacos
Nacos集群搭建
官方给出的Nacos集群图: 其中包含3个nacos节点,然后一个负载均衡器代理3个Nacos。这里负载均衡器可以使用nginx。
106 3