❝
在微服务架构中,配置管理是一个至关重要的环节。Nacos(Naming and Configuration Service)作为一款优秀的配置中心和服务管理平台,为微服务提供了动态配置服务。本文将介绍如何使用 Nacos 作为 Python 微服务的配置中心,以及如何实现配置的实时监听与自动重启功能。
NACOS
一、Nacos 集群搭建
在微服务架构中,Nacos 作为核心的服务发现和配置管理组件,其稳定性和可用性至关重要。
NACOS集群
为什么需要搭建 Nacos 集群?
- 单点故障风险:单节点的 Nacos 部署存在单点故障的风险。如果该节点发生故障,所有依赖 Nacos 的微服务将无法进行配置拉取、服务注册与发现,导致整个系统不可用。
- 性能瓶颈:在单节点模式下,Nacos 无法有效处理大量请求。在高并发或大数据量的场景中,容易导致响应延迟或系统崩溃。
- 扩展性差:单节点无法根据流量需求进行水平扩展,当流量激增时,系统难以应对。
通过集群部署,Nacos 可以实现高可用性和负载均衡,提高系统的稳定性、扩展性和容错能力。
在 NACOS 集群架构中加入 NGINX 是出于什么考虑?
- 负载均衡:Nginx 作为反向代理服务器,可以均匀地分发客户端请求到多个 Nacos Server 实例上,从而实现负载均衡,提高系统的处理能力和响应速度。
- 高可用性:通过 Nginx 可以实现故障转移和高可用性。如果一个 Nacos Server 节点发生故障,Nginx 可以将流量自动转移到其他可用的 Server 节点上,确保服务的不间断运行。
- 安全性增强:Nginx 可以作为第一道防线,对进入 Nacos 集群的所有请求进行过滤和处理,如 SSL/TLS 加密、IP 限制等,增加系统的安全性。
- 性能优化:Nginx 具有高性能的网络模型和缓存机制,能够有效提升系统整体性能,减少延迟。
- 简化部署和管理:通过集中管理 Nginx 配置,可以更方便地对整个 Nacos 集群进行管理和维护。
- 动态路由:Nginx 支持根据不同的条件(如 URL、HTTP 头信息)来决定如何转发请求,这为灵活的路由策略提供了可能。
- 访问控制:可以通过 Nginx 设置访问控制策略,比如限制某些 IP 地址或域名的访问权限。
- 日志记录和分析:Nginx 可以记录详细的访问日志,便于监控和分析网络活动。
加入 Nginx 不仅提升了 Nacos 集群的性能和可靠性,还增强了其安全性和管理的灵活性。
使用 docker-compose 来搭建 NACOS 集群
使用Docker Compose来搭建 Nacos 集群是可行的。Docker Compose 允许通过定义一个 yaml 文件来配置应用程序的服务,从而简化了 Nacos 集群的部署过程。使用 Docker Compose,可以方便地管理多个 Nacos 实例,实现集群的快速部署和扩展。
version: "3.8"
services:
nacos1:
hostname: nacos1
container_name: nacos1
image: nacos/nacos-server:latest
volumes:
- ./cluster-logs/nacos1:/home/nacos/logs
ports:
- "7848:7848"
- "18848:8848"
- "9868:9848"
- "9850:9849"
env_file:
PREFER_HOST_MODE=hostname
NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
SPRING_DATASOURCE_PLATFORM=mysql
MYSQL_SERVICE_HOST=nacos-mysql
MYSQL_SERVICE_DB_NAME=nacos_devtest
MYSQL_SERVICE_PORT=3306
MYSQL_SERVICE_USER=nacos
MYSQL_SERVICE_PASSWORD=nacos
MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
NACOS_AUTH_IDENTITY_KEY=2222
NACOS_AUTH_IDENTITY_VALUE=2xxx
NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
NACOS_AUTH_ENABLE=true
NACOS_AUTH_USER_AGENT_AUTH_WHITE_ENABLE=true
restart: always
depends_on:
nacos-mysql:
condition: service_healthy
nacos2:
hostname: nacos2
image: nacos/nacos-server:latest
container_name: nacos2
volumes:
- ./cluster-logs/nacos2:/home/nacos/logs
ports:
- "7849:7848"
- "18849:8848"
- "9869:9848"
- "9851:9849"
env_file:
PREFER_HOST_MODE=hostname
NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
SPRING_DATASOURCE_PLATFORM=mysql
MYSQL_SERVICE_HOST=nacos-mysql
MYSQL_SERVICE_DB_NAME=nacos_devtest
MYSQL_SERVICE_PORT=3306
MYSQL_SERVICE_USER=nacos
MYSQL_SERVICE_PASSWORD=nacos
MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
NACOS_AUTH_IDENTITY_KEY=2222
NACOS_AUTH_IDENTITY_VALUE=2xxx
NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
NACOS_AUTH_ENABLE=true
NACOS_AUTH_USER_AGENT_AUTH_WHITE_ENABLE=true
restart: always
depends_on:
nacos-mysql:
condition: service_healthy
nacos3:
hostname: nacos3
image: nacos/nacos-server:latest
container_name: nacos3
volumes:
- ./cluster-logs/nacos3:/home/nacos/logs
ports:
- "7850:7848"
- "18850:8848"
- "9870:9848"
- "9852:9849"
env_file:
PREFER_HOST_MODE=hostname
NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
SPRING_DATASOURCE_PLATFORM=mysql
MYSQL_SERVICE_HOST=nacos-mysql
MYSQL_SERVICE_DB_NAME=nacos_devtest
MYSQL_SERVICE_PORT=3306
MYSQL_SERVICE_USER=nacos
MYSQL_SERVICE_PASSWORD=nacos
MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
NACOS_AUTH_IDENTITY_KEY=2222
NACOS_AUTH_IDENTITY_VALUE=2xxx
NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
NACOS_AUTH_ENABLE=true
NACOS_AUTH_USER_AGENT_AUTH_WHITE_ENABLE=true
restart: always
depends_on:
nacos-mysql:
condition: service_healthy
nacos-mysql:
container_name: nacos-mysql
build:
context: .
dockerfile: ./image/mysql/5.7/Dockerfile
image: example/mysql:5.7
env_file:
MYSQL_ROOT_PASSWORD=root
MYSQL_DATABASE=nacos_devtest
MYSQL_USER=nacos
MYSQL_PASSWORD=nacos
LANG=C.UTF-8
volumes:
- ./nacos-mysql:/var/lib/mysql
ports:
- "13306:3306"
healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
interval: 5s
timeout: 10s
retries: 10
使用 compose 模式搭建 Nacos 集群,除了数据持久化之外,还需要关注
- 集群架构设计:合理规划集群的节点数量和拓扑结构,确保集群的高可用性和负载均衡
- 数据库准备:Nacos 集群需要使用数据库进行数据共享。选择合适的数据库(如 MySQL)并正确配置,确保集群中的 Nacos 实例可以访问和同步数据
- 配置文件修改:对于每个 Nacos 节点,需要修改配置文件以指定数据库信息和集群节点信息
- 网络配置:确保集群中的所有 Nacos 节点可以相互通信,网络配置是关键
- 集群管理:包括集群的启动、监控和维护,确保集群的稳定运行
搭建 Nacos 集群是提高微服务架构性能和可靠性的重要步骤,用 Docker Compose 可以简化集群部署过程,但在部署时还需要注意多个方面,以确保集群的稳定性和效率
二、配置中心搭建
微服务架构对配置中心的需求极为关键,它要求配置中心能够提供集中管理、动态更新、配置隔离、版本控制、高可用性、安全性、容错性、可扩展性、实时监控和环境区分等功能。这些特性确保了微服务配置的一致性、灵活性和系统稳定性,是微服务高效运行的重要保障。
录入配置到 Nacos
在 Nacos 配置列表中,开发人员需手动录入各个微服务的配置内容。配置以 JSON 格式存储,便于后端程序解析。
微服务拉取配置
def load_config_func(self, group="default", tenant="public"):
project_name = self.project_name
if not all([self.username, self.nacos_password, self.nacos_host, self.nacos_port]):
config_logger.error("Nacos credentials are not set in .env file.")
config_logger.info(f"正在获取配置: dataId={project_name}; group={group}; tenant={tenant}")
client = nacos.NacosClient(
server_addresses=f"{self.nacos_host}:{self.nacos_port}",
username=self.username,
password=self.nacos_password
)
nacos_config = client.get_config(project_name, 'default')
config_dict = json.loads(nacos_config)
# 将内容写入到CONFIG_FILENAME中
try:
with open(CONFIG_FILENAME, 'w', encoding='utf-8') as f:
json.dump(config_dict, f, indent=4, ensure_ascii=False)
config_logger.info(f"配置中心自动LOAD配置:写入文件成功")
except Exception as e:
config_logger.error(f"配置中心自动LOAD配置:写入文件失败{str(e)}")
return config_dict
实时监听配置变更
- 启动配置监听器,该函数创建一个守护线程,用于监听配置变更。
def start_config_watcher(self):
if not hasattr(self, '_watcher_thread'):
self._watcher_thread = threading.Thread(
target=self._start_config_watcher,
daemon=True
)
self._watcher_thread.start()
# 监听器
def _start_config_watcher(self):
project_name = self.project_name
client = nacos.NacosClient(
server_addresses=f"{self.nacos_host}:{self.nacos_port}",
username=self.username,
password=self.nacos_password
)
client.add_config_watcher(project_name, 'default', self.config_change_callback)
config_logger.info("配置监听器已启动")
2. 配置变更回调函数,当配置发生变化时,以下回调函数将被触发,该函数将新的变更配置内容写入本地文件,并调用重启后端的函数 3. 自动重启后端
def restart_django_runserver(self):
config_logger.info(f"监听到{self.project_name}的配置发生变化,准备自动重载后端")
try:
if os.name == 'nt': # 如果是Windows系统
config_logger.info("请手动重启服务")
else:
subprocess.run(
['supervisorctl', '-c', '/app/supervisord_prd.conf', 'restart', 'uwsgi'],
check=True
)
config_logger.info("后端自动重启成功")
except subprocess.CalledProcessError as e:
config_logger.error(f"后端重启失败: {e}")
通过整合python与nacos-python-sdk,我们初步构建了一个基于Nacos的微服务配置中心,实现了配置的集中管控、实时监控以及服务的自动重启机制。这一方案显著提升了微服务的稳定性和可维护性,为微服务架构的持续迭代和扩展奠定了坚实的基础。在项目实践中,开发团队可根据具体场景和需求,对配置管理策略进行细化和优化。虽然当前实现的是一个基础版本,但留有广阔的改进空间,未来我们将持续对其进行精雕细琢。