zeus00456

导航

微服务架构 | 服务注册发现中心/配置中心/消息总线 - [nacos]

@

§1 简介

Nacos = Naming Configration Service

在 SpringCloud alibaba 中,nacos 同时扮演了 服务注册发现中心、配置中心、消息总线等角色。

nacos 与其他注册中心特性对比

nacos Eureka Consul CoreDNS zookeeper
一致性协议 AP/CP AP CP / CP
健康检查 TCP/Http/Mysql/Client Beat Client Beat TCP/Http/gRPC/Cmd / Client Beat
负载均衡 权重/DSL/metadata/CMDB ribbon fabio RR /
雪崩保护 × × ×
自动注销实例 × ×
访问协议 Http/DNS/UDP Http Http/DNS DNS TCP
监听支持 ×
多数据中心 × ×
跨注册中心 × × ×
springcloud 集成 × ×
Dubbo 集成 × × ×
k8s 集成 × ×

§2 简单使用

§2.1 搭建 nacos-server

在官网下载

https://github.com/alibaba/nacos

在这里插入图片描述
在这里插入图片描述

移动到指定位置并解压安装

tar -zxvf nacos-server-2.1.0.tar.gz

启动 nacos 服务

sh startup.sh -m standalone

使用 localhost:8848/nacos 本机访问
在这里插入图片描述

非本机访问
在非本机上,使用 ip:8848/nacos 可能连接超时,按下面步骤尝试

  • 关闭防火墙

service iptables stop

  • 重试访问
  • 若访问成功,添加防火墙规则

vim /etc/sysconfig/iptables

然后在文件中按队形增加一行

-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT

重启防火墙 (不用 restart是因为不成功,分开操作就可以了,原因不明)

service iptables stop
service iptables start

§2.2 作为服务注册发现中心

注意事项:

  • nacos 可以同时成为 springcloud 的配置中心服务发现中心
  • 但两个职能对应的 依赖、配置文件、配置项均不同

provider / comsumer 均按如下配置
默认服务调用方式同 ribbon
依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

配置文件
application.yml

server:
  port: 9001

spring:
  application:
    name: provider-nacos
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.3.10:8848

服务启动后可见
在这里插入图片描述

§2.3 作为服务配置中心

依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

配置文件
bootstrap.yml

server:
  port: 3377

spring:
  application:
    name: nacos-config-client
  cloud:
    nacos:
      config:
        server-addr: 192.168.3.10:8848
        file-extension: yml
      discovery:
        server-addr: 192.168.3.10:8848

application.yml

spring:
  profiles:
    active: dev

配置文件
注意使用注解 @RefreshScope,以支持热更新
除下面示例中的 @ConfigurationProperties 外,@Value 的方式也支持

@Configuration
@ConfigurationProperties(prefix = "config")
@RefreshScope
public class ConfigTest {
    String info;

    /* *******************************
     * 以下是 setter/getter
     ******************************* */
    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}

在 nacos 控制台添加配置
在这里插入图片描述
在这里插入图片描述
Data ID
即配置文件名,完整格式如下

${prefix}-${spring.profiles.active}.${file-extension}
  • ${prefix} 默认是 ${spring.application.name} 的值,即示例中的 nacos-config-client
  • ${prefix} 也可以通过 ${spring.cloud.nacos.config.prefix} 配置
  • ${spring.profiles.active} 即示例中的 dev
  • ${spring.profiles.active} 可以省略,省略时,前面的 - 也会省略,但强烈建议保留
  • ${file-extension} 即示例中的 yml
  • ${file-extension} 的值必须与 ${spring.cloud.nacos.config.file-extension} 一致,比如混淆 yml 和 yaml 会导致问题(虽然二者其实是一回事)

Group
默认是 DEFAULT_GROUP

配置格式
配置格式要和配置文件名(Data ID)的后缀相匹配

配置内容
配置内容的格式要和配置格式相匹配

§2.4 切换 nacos 的一致性协议

curl -X ==PUT== '**$NACOS_SERVER**:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'

§3 配置的层次和分组

nacos 中,如下图所示,
在这里插入图片描述
每个配置文件依次有三级所属层次,由概念的从大到小依次为

  • namespace,命名空间,默认 public
  • Group,组,默认 DEFAULT_GROUP
  • Data Id,数据id(配置文件名),默认 ${prefix}-${spring.profiles.active}.${file-extension}

namespace、group 和 data id 的作用和实践(存疑)
说明
众多视频和帖子在讲解 nacos 时,多数会涉及上述三个配置层次,感谢各位大佬的分享。

但讲解的过程中鲜见对应用场景的套用,尤其在演示切换不同 namespace、group、data_id 的作用时,均以 通过切换上述三个层次已达到切换 DEV/TEST/PROD 环境 为例。
笔者学习时递归懵逼,无法区分三者在真实使用上的区别。

从 nacos 的官网(nacos.io)中,笔者未找到三者比较明确的配置指导,比如 namespace 是用来具体配置什么的(也可能是没找对地方[手动捂脸])。

由此, namespace、group 和 data id 可能不存在比较严格的使用标准,而只是配置中心划分出三个维度,用来区分各个配置文件,以方便研发人员使用。因此,在示例项目的部署场景比较简单的情况下可以十分灵活的使用它们,只要别找不到正确的配置即可(否则无法解释为啥众多教程使用“不恰当”的例子)。

但这仨层级毕竟不是按 namespace.group.data_id 的形式出现在 nacos 中的,命名空间甚至是个单独的标签页,因此肯定存在需要进行明确区分的场景。

一种在应用上可行的使用方案
下面,结合使用 apollo 的经验,尝试分享一种可行的使用方案,谬误之处请各位大佬斧正。
首先三个配置层级的关系如下 图 3-1 所示无疑
在这里插入图片描述
然后我们设想一个使用 nacos 的场景,并尽量假设的复杂一点

  • 有一个公司,叫 company,为了防止过于灵活假设它很大(废话,小公司小项目都多余上配置中心)
  • 因此,company 下有多个业务线,换句话说,好多产品,每个产品都是一个项目,P1/P2/P3
  • 每个项目都有很多子项目,或者服务,P1s1/P1s2/P2s1/P2s2……
  • 每个服务下有多个实例(instance)
  • 每个项目在部署时,为了异地容灾都会部署在多个机房,company 本部/武汉/成都……
  • 机房考虑进一步灾备,防止一套环境挂了后,所有使用此服务的业务都挂了,于是又划分了多个集群,单个个集群负责业务中的一部分
  • 现在,company 搭建了一个 nacos 平台作为配置中心

上述内容如下 图 3-2 所示:
在这里插入图片描述
对比 图 3-1图 3-2,我们可以如下使用三者:

data id
作用于 instance,它的作用是使一些实例按当前配置进行启动
一个标准的 data id 主要包含两个维度,

  • ${prefix} 用来标注属于哪个服务(service),默认值是 ${spring.application.name}
  • ${spring.profiles.active} 用来标注属于哪个环境,默认值是 ${spring.profiles.active}
  • data id 可能存在更多维度,此时可以通过 ${spring.cloud.nacos.config.prefix} 配置
    • 比如 P1s1 需要两个配置文件,可以参考 Nacos加载多个配置集 中的场景
    • 一个用来配置相关环境比如 kafka 地址
    • 另一个配置业务比如这个服务太小了所以不需要记录日志

namespace
作用于项目或者租户,以区分不同项目中的同名服务("那个瓜是孙红雷的,与我闰土何干!")
项目和租户在某些平台(比如 OpenStack)上是同一个概念,
每个项目加入配置中心,占用一块资源。对于配置中心来说,这个项目就是一个租户

group(主要是这里存疑)
作用于 data id 往上,namespace 往下的中间维度
组是对服务实例的分组,

  • 这里的服务实例不局限于同一个服务
    比如只要是部署在武汉机房的服务实例,无论属于的哪个服务只要用了 kafka 的,都配置成某个地址
  • 同时一个服务的所有实例也不一定都在同一个组里
    比如都是 P1s1 的实例,划分两个集群,一个处理客户1(这里的客户可能是指一个公司)的业务,另一个处理客户2

总结(顺便皮一下)
若有如下配置文件

namespace = coding dog ICU each-help platform
group = wuhan_oldest
data id = roast-publish-flow-prod.yml

这个配置文件用来配置 代码狗 ICU 互助平台(coding dog ICU each-help platform) 这个项目里,我也来喷一段(roast-publish-flow) 这个服务的 生产环境(prod)
服务部署在多个机房,现在这个配置文件是部署在 武汉(wuhan)机房 的实例用的
并且武汉的机房有多套环境,有的旧有的新,这个业务线的一部分还是跑在 最老性能最差的那套环境(_oldest) 里的,因为没办法,都 ICU 了,都上最新的环境太贵

§4 集群 & 持久化实战

§2 简单使用 中,完成了 单点 nacos 的搭建和使用。
但是,实际开发、生产环境中不可能按上面的姿势使用 nacos

  • standalone 的结构摆明了是等着单点故障
  • standalone 的 nacos 使用的内嵌的 derby 数据库,这意味着如果只是简单的部署多节点,会导致节点间的数据隔离

因此,实践上需要向下 图4-1 所示架构进行调整,官方文档 见此
nacos 的官方文档,有的前面的文章说过的事,后面的文章就不提了,所以只能一起看
在这里插入图片描述
下面的示例中(出 nacos 外的集群使用单点代替)

  • 使用 nginx 反向代理 nacos 集群,并对外暴露虚拟 ip
  • 持久化层使用 mysql

§4.1 变更 nacos 的持久化

准备 mysql 实例

创建 nacos 库
在 nacos 的安装目录的 config 路径下,有一个 nacos 出厂自带的建库 sql 文件,如下 图 4-1-1
在这里插入图片描述
使用它建立自己的 nacos 库(手动建库,sql 文件内容粘出来,运行即可) ,效果如下图
在这里插入图片描述

修改配置文件
配置文件即 图4-1-1application.properties
按官网教程配置
在这里插入图片描述
效果如下,注意红框处于实际建库使用的数据库名一致
在这里插入图片描述

重启 nacos 验证
先单点重启 nacos,查看持久化层切换效果

sh startup.sh -m standalone

看到一个空白的 nacos
在这里插入图片描述
创建一个配置,在数据库中查看数据
在这里插入图片描述
在这里插入图片描述

§4.2 准备 nacos 实例

PS: 现在停止上一节启动的 nacos,如果没有,后面实践时会出现莫名其妙的问题

cluster.conf
cluster.conf 用于配置集群内各节点的 ip:port,因为是纵向集群模拟,所以示例中使用端口号区分
同时参考 §2.1 搭建 nacos-server#非本机访问 的方式配置防火墙(注意重启)
在这里插入图片描述

startup.sh(在这个示例中很重要)
nacos 是基于 JVM 运行的,默认的 nacos 集群模式配置 JVM 的参数为

-Xms2g -Xmx2g -Xmn1g  -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m

若机器性能有限,需要调整启动脚本以降低硬件需求(实际开发生产环境 务必不要这样搞

startup.sh 的摘要和修改点如下:

#!/bin/bash
#
# 这里有一大坨代码
#

# 指令参数对应的变量
export SERVER="nacos-server"
export MODE="cluster"
export FUNCTION_MODE="all"
export MEMBER_LIST=""
export EMBEDDED_STORAGE=""
# 接受指令参数
while getopts ":m:f:s:c:p:" opt
do
    case $opt in
        m)
            MODE=$OPTARG;;
		# 依次用接受的参数给上面变量复制
        ?)
        echo "Unknown parameter"
        exit 1;;
    esac
done

#===========================================================================================
# JVM Configuration,
# nacos 是基于 java 的,这里是针对 -m 参数给 jvm 配置启动参数 
#===========================================================================================
if [[ "${MODE}" == "standalone" ]]; then
    JAVA_OPT="${JAVA_OPT} -Xms512m -Xmx512m -Xmn256m" # 抄这里
    JAVA_OPT="${JAVA_OPT} -Dnacos.standalone=true"
else
    if [[ "${EMBEDDED_STORAGE}" == "embedded" ]]; then
        JAVA_OPT="${JAVA_OPT} -DembeddedStorage=true"
    fi
    # 抄到这里,原始的值是 -Xms2g -Xmx2g -Xmn1g  -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m
    JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn256m  -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m"
    JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${BASE_DIR}/logs/java_heapdump.hprof"
    JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages"

fi

#
# 这里是一大坨代码,处理其他参数和日志目录
#

# start
# 下面是实际启动 nacos 的命令,启动时用了上面的 JVM Configuration
if [[ "$JAVA_OPT_EXT_FIX" == "" ]]; then
  nohup "$JAVA" ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
else
  nohup "$JAVA" "$JAVA_OPT_EXT_FIX" ${JAVA_OPT} nacos.nacos >> ${BASE_DIR}/logs/start.out 2>&1 &
fi

准备多个nacos
将上面改好的 nacos 准备三份
在这里插入图片描述

application.properties
application.properties 里需要配置两个地方

  • 如上节演示的变更持久化层
  • 本示例需要修改默认端口,按 cluster.conf 的值变更,本示例中上面准备的三份 nacos 依次改为 8838/8848/8858

在这里插入图片描述

启动和验证
使用启动指令依次启动三个 nacos 实例

./shartup.sh

而后,可以再管理端看到效果
在这里插入图片描述

§4.3 加入 nginx 支持

上面已经实现了 nacos 的集群部署,引入 nginx 的目的是对 nacos 集群进行代理和负载均衡,实现统一的集群访问

准备 nginx
下载解压 nginx,因环境限制略,有需要的可参考 Linux安装nginx
在这里插入图片描述

配置 nginx.conf

vim opt/nginx-1.22.0/conf/nginx.conf
    #gzip  on;
	# 配置上游服务器,用 nginx 进行代理和负载均衡
    upstream cluster{
    server 192.168.3.10:8838;
    server 192.168.3.10:8848;
    server 192.168.3.10:8858;
    }
    # 配置 nginx 的访问地址
    server {
        listen       8888;
        server_name  localhost;
        ...... 略

启动并验证

因环境限制,直接用 windows 版的    

在这里插入图片描述
在这里插入图片描述

§4.4 项目应用

修改项目配置
调整对应项目的 application.yml

server:
  port: 9001

logging:
  config: classpath:logback.cfg.dev.xml

spring:
  application:
    name: provider-nacos
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.3.7:8888 #换成 nginx 的访问地址,这里现在已经是个 nacos 集群了

management:
  endpoints:
    web:
      exposure:
        include: '*'

启动验证
在这里插入图片描述


本文部分内容参考自
Nacos加载多个配置集
Linux安装nginx


传送门:
微服务架构 | 组件目录

posted on 2022-07-28 15:43  问仙长何方蓬莱  阅读(161)  评论(0编辑  收藏  举报