世纪证券Zabbix监控系统升级高可用架构的实践分享

Posted Zabbix_China

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了世纪证券Zabbix监控系统升级高可用架构的实践分享相关的知识,希望对你有一定的参考价值。

洪嘉铭,就职于世纪证券信息技术部,目前负责运维、监控系统的相关架构设计、开发工作。对操作系统、网络编程、服务器后台架构有丰富实践经验。

世纪证券于2022年8月初完成了Zabbix监控系统的版本(5.2->6.0)和架构升级。本次升级最重要的变更是利用Zabbix6.0官方提供的原生高可用HA特性实现了服务端架构上的高可用。主备机房所有设备的监控已平稳运行一月有余,现将整个过程做一个分享,供有需要的小伙伴参考使用。

1. 架构介绍
公司自建机房和网络,主机房和同城灾备机房通过裸光纤实现内网互联。图1为升级前的部署架构。

图1 Zabbix监控系统v5.2部署架构
该架构明显存在以下问题:

公司两个机房所有被监控设备都只连接一个Zabbix Server节点,且只有一个mysql数据库节点,造成Zabbix Server和MySQL都存在单点故障。一旦这两个服务出现异常,公司监控系统将无法工作,如发生在交易时间,将直接导致公司失去生产系统的运行状态的及时掌握,带来极大的风险隐患。
Zabbix Server和MySQL都只有单节点,造成监控时间的空缺。任何服务器的升级改造、停机操作都将导致公司整个监控服务的暂停中断;
公司业务还处于高速发展期,需监控的设备节点数量和监控维度还在不断增加,Zabbix server的承载能力受制于所在宿主主机的硬件配置,系统扩展性不够。
为解决以上问题,降低系统运行风险,我们对架构进行了升级 ,如图2。

图2 Zabbix监控系统v6.0部署架构
升级后架构带来以下改善:

升级Zabbix6.0,引入了的HA(High Availability)特性,分别在两个机房部署zabbix server主备节点;正常情况下,主节点部署于主机房,备节点部署于同城灾备机房,主节点一旦停止服务,备节点可在1分钟(可配置)内接管服务;如主机主动停止,备节点可立马接管。
增加了MySQL的双主架构下的主备模式部署,提高了监控服务可用性。
增加部署了Zabbix Proxy,用于分散Zabbix Server负载,同时也方便连接网络区域。
主备Server应急切换预案
主备Zabbix Server应急切换预案如图3所示。正常情况下,主Server处于Active状态,备Server处于Standby状态。当主Server停止服务,状态由Active变为Stop或Unavailable后,备Server通过主备状态信息同步机制感知到异常,立即启动接管服务,状态切换为Active状态;Zabbix Agent和Zabbix Proxy在连接主Server失败后,也会尝试连接备Server。整个监控服务自动接管和切换,从而保持监控持续可用。当主节点故障恢复后,状态由Stop或Unavailable切换为Standby状态。

图3 主备Zabbix Server切换预案
MySQL双主架构下的主备模式应急切换预案
MySQL数据库双主架构下的主备模式部署架构的应急切换预案如图4所示。正常情况下,主机房的MySQL数据库作为主数据库,同城灾备机房的数据库作为备数据库,同步主数据库的数据。当主机房的MySQL主数据库停止服务后,此时备数据库作为主数据库继续提供服务,由于主备Zabbix Server服务同时只能配置一个数据库地址,所以此时需要将Zabbix Server服务的数据库配置同时指向备数据库地址,并重启Zabbix Server服务保持整个系统依然可用(此过程目前采用手动切换)。当主机房数据库服务恢复后,此时作为备数据库,可自动同步灾备机房的主数据库,从而自动恢复停止服务期间丢失的数据,继续保持两个数据库可用的状态。

图4 MySQL数据库主主模式架构切换预案
数据库架构的选择
根据Zabbix HA原理,主、备Zabbix Server的状态依赖于数据库来进行同步。如数据库出现故障,整个Zabbix的服务的可用性仍然无法保障。为了保障整个服务的高可用,MySQL数据库的备份部署选择双主架构下的主从模式。

为何不是单主从?在MySQL数据库单主从模式下,当主数据库实例故障后,Zabbix Server服务数据库请求切换到备数据库,如需恢复主数据库停止服务期间丢失的数据,则需要手工同步故障期间的数据,而双主同步则可自动恢复故障期间数据。

为何不用keepalived?考虑到keepalived存在发生“脑裂”的可能,当出现“脑裂”时,主备Zabbix Server基于数据库的状态同步可能会出现数据不一致的情况,从而导致极端情况下,主备Zabbix Server切换不成功。

2. 环境准备

主机ip操作系统软件
主Zabbix server/Zabbix web192.168.8.111CentOS 7.7.1908docker 20.10.2
备Zabbix server/Zabbix web192.168.24.111CentOS 7.7.1908docker 20.10.2
主Mysql192.168.8.222CentOS 7.7.1908mysql 8.0.28
备Mysql192.168.24.222CentOS 7.7.1908mysql 8.0.28

· 为了阐述后续的配置步骤,此处列出IP地址,但均已做了处理,和真实环境IP地址无任何实际关联。
· zabbix agent版本不高于zabbix server
· zabbix server、zabbix web通过docker镜像的方式安装
· mysql通过原生方式安装。
3. 备份zabbix server文件
· /etc/zabbix/* 中的配置文件
· /usr/lib/zabbix/externalscripts/ 中的外部脚本
· /usr/lib/zabbix/alertscripts 中的告警通知脚本
4. 备份数据库
进入zabbix web,配置zabbix维护期间
停止zabbix server、zabbix web服务(都以docker方式运行)。

docker stop zabbix-web-nginx-mysql
docker stop zabbix-server-mysql

备份整个数据库

mysqldump -uroot -p --single-transaction  zabbix | gzip > zabbix_backup.sql.gz

官方文档介绍history相关表结构有相关变化,很多人的做法是不备份history相关表,通过额外脚本导入原数据库的history相关表数据。我们的做法有所不同,备份的是整个数据库,原因是zabbix server在启动时会自动检测数据库版本,并完成数据库的自动升级操作

5. 安装mysql 8
为了避免安装mysql冲突,需先移除已安装的mariadb。

rpm –qa|grep maria
> mariadb-libs-5.5.64-1.el7.x86_64
rpm –e --nodeps mariadb-libs-5.5.64-1.el7.x86_64

官网下载rpm安装包,解压到一个空目录中。

mysql8下载地址
3.rpm安装。

rpm –ivh *.rpm --force

4.关闭selinux。

setenforce 0

编辑 /etc/selinux/config使永久生效

SELINUXTYPE=disabled

启动mysql服务

systemctl start mysqld
systemctl status mysqld
systemctl enable mysqld

查看、修改初始默认密码

cat /var/log/mysqld.log|grep "temporary password"
mysql -uroot -p
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password by 'xxxxx@password';

6. 还原数据库
1.创建zabbix数据库和用户

mysql> create database zabbix character set utf8mb4 collate utf8mb4_bin;
mysql> create user zabbix@localhost identified by 'xxxxxx@password';
mysql> grant all privileges on zabbix.* to zabbix@localhost;
mysql> FLUSH PRIVILEGES;

2.创建root和zabbix用户远程访问权限

mysql> CREATE USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'admin@1234'
mysql> GRANT ALL privileges  ON *.* TO 'root'@'%' WITH GRANT OPTION ;
mysql> CREATE USER 'zabbix'@'%' IDENTIFIED WITH mysql_native_password BY 'admin@1234' ;
mysql> GRANT ALL ON zabbix.* TO 'zabbix'@'%' ;
mysql> FLUSH PRIVILEGES;

3.还原zabbix数据库

gunzip < zabbix_backup.sql.gz | mysql -uzabbix -p zabbix
  1. 配置数据库主主同步
    修改配置文件
    修改主数据库配置文件/etc/my.cnf,重启服务
#server-id MySQL实例中全局唯一
server-id=1
#relay-log命名,binlog采用默认命名
relay-log=zabbix-relay-bin
#增加最大连接数
#防止当zabbix server进程过多无法连接数据库
max_connections=1500
skip-name-resolve
systemctl restart mysqld

修改从数据库配置文件/etc/my.cnf,重启服务

#server-id MySQL实例中全局唯一
server-id=2
#relay-log命名,binlog采用默认命名
relay-log=zabbix-relay-bin
#增加最大连接数
#防止当zabbix server进程过多无法连接数据库
max_connections=1500
skip-name-resolve
systemctl restart mysqld

2.主从数据库分别创建用户备份的账户

CREATE USER 'repl'@'%' identified with mysql_native_password by 'xxxxxx@password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

3.设置互为主从
主从数据库分别设置如下

#加锁,阻止所有的写入操作
FLUSH TABLES WITH READ LOCK;
change master to master_host='192.168.xxx.222', \\
master_user='repl', \\
master_password='xxxxxx@password', \\
master_port=3306, \\
master_log_file='binlog.0000xx',\\
master_log_pos=xxxx;
#master host:同步的数据库的地址
#master_user:备份的用户名
#master_password:备份的用户密码
#master_log_file:bin-log的文件名
#master_log_pos:bin-log的位置
#bin-log文件名和位置通过
#show master status命令查看
#对应File, Position字段
START SLAVE;#开启同步
#解锁
UNLOCK TABLES;

分别检查主从数据库同步状态

show slave status\\G;

如下则证明正常

8. 启动zabbix server
1.自定义docker镜像,编写dockerfile

FROM zabbix/zabbix-server-mysql:6.0-centos-latest
USER root
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo \\
&& yum makecache \\
&& yum -y install epel-release \\
&& yum -y install python38 \\
&& python3.8 -m pip install pymssql 
USER 1997

在官方镜像的基础上构建了一个python环境

2.构建镜像

docker build -t zabbix/zabbix-server-mysql:6.0-centos-py38 .

3.启动容器
主server

docker run --name zabbix-server-mysql -t \\
  -e DB_SERVER_HOST="192.168.8.222" \\
  -e MYSQL_DATABASE="zabbix" \\
  -e MYSQL_USER="zabbix" \\
  -e MYSQL_PASSWORD="xxxxxx@password" \\
  -e MYSQL_ROOT_PASSWORD="xxxxxx@password" \\
  -e ZBX_HANODENAME="zabbix-server-pbs" \\
  -e ZBX_NODEADDRESS="192.168.8.111:10051" \\
  -v /etc/localtime:/etc/localtime:ro \\
  --privileged=true \\
  --restart unless-stopped \\
  --net=host \\
  -d zabbix/zabbix-server-mysql:6.0-centos-py38

备server

docker run --name zabbix-server-mysql -t \\
  -e DB_SERVER_HOST="192.168.8.222" \\
  -e MYSQL_DATABASE="zabbix" \\
  -e MYSQL_USER="zabbix" \\
  -e MYSQL_PASSWORD="xxxxxx@password" \\
  -e MYSQL_ROOT_PASSWORD="xxxxxx@password" \\
  -e ZBX_HANODENAME="zabbix-server-nfzx" \\
  -e ZBX_NODEADDRESS="192.168.24.111:10051" \\
  -v /etc/localtime:/etc/localtime:ro \\
  --privileged=true \\
  --restart unless-stopped \\
  --net=host \\
  -d zabbix/zabbix-server-mysql:6.0-centos-py38

8. 启动zabbix web
1.自定义docker镜像,编写dockerfile

#用stkaiti.ttf文件替换DejaVuSans文件
#解决中文乱码问题
mv stkaiti.ttf DejaVuSans.ttf
FROM zabbix/zabbix-web-nginx-mysql:6.0-centos-latest
USER root
COPY DejaVuSans.ttf /usr/share/zabbix/assets/fonts/DejaVuSans.ttf
USER 1997

2.构建镜像

docker build -t zabbix/zabbix-web-nginx-mysql:6.0-centos-ch .

3.启动容器
主/备web

docker run --name zabbix-web-nginx-mysql -t \\
 -e DB_SERVER_HOST="192.168.8.222" \\
 -e MYSQL_DATABASE="zabbix" \\
 -e MYSQL_USER="zabbix" \\
 -e MYSQL_PASSWORD="xxxxxx@password" \\
 -e MYSQL_ROOT_PASSWORD="xxxxxx@password" \\
 -e php_TZ="Asia/Shanghai" \\
 -p 80:8080 \\
 --restart unless-stopped \\
 -d zabbix/zabbix-web-nginx-mysql:6.0-centos-ch

9. zabbix agent配置
1.agent 5.2
根据公司的实际情况,agent端尽量保持5.2版不变,但如何保证服务的高可用性,我们的解决方案是:配置文件Server和ServerActive项多配一个ip,用逗号分隔

Server=192.168.8.111,192.168.24.111
ServerActive=192.168.8.111,192.168.24.111

2.agent 6.0
ServerActive项用分号分隔

Server=192.168.8.111,192.168.24.111
ServerActive=192.168.8.111;192.168.24.111

10. 总结
本次升级重点可归纳为三个部分。

· Zabbix Server的主备架构的升级
· MySQL数据库双主架构下的主从模式架构升级
· 为实现高可用,Zabbix Agent在版本v5.2和v6.0共存的情形下进行的升级。
升级后完善了公司的监控服务架构,但仍有可以继续改善的地方。如Zabbix Proxy服务还没有做到高可用,后期可考虑引入keepalived做高可用;Zabbix Server切换MySQL数据库时,目前采用的是人为判定切换时机,后期可考虑设定数据库故障检测的规则,通过脚本实现自动化切换。

更多案例分享将在12月2日Zabbix中国峰会分享!

扫码报名!

扫一扫|加入技术交流群

微信号|17502189550

备注“使用Zabbix年限+企业+姓名”

5000+用户已加入!

一个人走得快,一群人走得远!

鲸品堂|复杂业务系统高扩展架构设计与实践

如果问架构师什么是架构,可能会得到很多不同的答案,每个架构师对“架构”都有不一样的理解,当然这不分对错。数据架构、应用架构、部署架构、高性能架构、高可用架构、高扩展架构等都是架构,每一种架构都有应用场景,有不同的技术方法、特征及要求,但我觉得有一个核心的概念是共同的:架构必定是在长期的生产过程中,经过架构师深刻的总结和思考,积累下来的最佳实践和可复用的合理抽象。能够应对复杂挑战的架构在过去、现在及未来都是架构师所向往和追求的理想目标。

鲸品堂|复杂业务系统高扩展架构设计与实践
鲸品堂|复杂业务系统高扩展架构设计与实践

为什么我们要研究思考这个问题



此前无意中在阿里巴巴泰山版Java开发手册里面看到关于系统设计可扩展性的一段话,谈到设计可扩展性的本质是找到系统的变化点,并隔离变化点;极致扩展性的标志,就是需求新增时,无需在原有代码交付物上进行任何形式的修改。这段话是阿里技术架构师的经验总结,他们用实际案例告诉我们, 想要实现业务的快速支撑,系统的可扩展能力不可忽视

对于大多数架构师而言,可扩展的系统架构设计有一个朴素的认识,就是解决服务横向扩展、容量、可用性及性能瓶颈问题,虽简单粗暴,却也是最有效的方式,就是我们俗称的“加机器”。这一认识,在实际生产运作中,变成了一种很普遍的做法。对于一个规模和数据量都迅速增长的系统而言,高性能和高可用问题自然是我们要优先考虑的。但是随着时间的推移,业务 的不断发展,面临的业务场景越来越复杂,为了解决这些复杂的业务问题,我们的实现方案也越来越复杂,理解、维护、迭代的难度随之增加,加速了系统腐化速度。

最终摆在我们面前的问题,除了要解决性能慢与体验差的问题,还需要面对功能与代码指数级增长带来的系统扩展性问题以及业务变化带来的差异化服务问题。而很多系统,在架构设计时并未充分考虑到这些问题,存在平台代码和业务代码耦合严重难以分离、业务和业务之间代码交织缺少拆解的现象,导致系统的重构、代码推倒重来成为常态,从而影响业务交付能力,还浪费人力财力。

同样在实际开发过程中,可扩展性问题也经常被开发人员忽略掉,满足业务需求最简单的处理,就是在代码中用“if else”分支来处理自己的逻辑思维,“if else”是开发人员写代码时,使用频率最高的关键词之一,然而有时过多的“if else”会让我们感到脑壳疼。当我们去review代码时,都会发现类似一个业务处理类上万行代码,一个函数方法上千行代码的场景。缺少组件化、代码隔离,通常都是直接在核心代码中逐块增加业务代码,这种写法在很短时间内会让核心服务“太胖”,复用性较差甚至无法复用,核心代码的频繁变动,需要全量部署发布,容易导致版本不稳定、代价高、风险大。

根据实际经验总结,不论从代码质量、可读性、可扩展性还是从可维护性、开发效率方面看,缺少代码抽象、扩展性考虑,采取简便直接上线的方法所需的额外返工,从长远来看都会很糟糕。

在聊架构的时候,我们一定需要聊一聊架构设计的目的,在我看来,为什么要实现架构设计,用一句话来概括就是"架构设计的真正目的是为了解决系统的复杂度带来的问题,控制好复杂度,就可快速实现业务创新。"我们往往有“为了高性能、高可用、高扩展,所以要做架构设计”这样的想法并在实际当中这么做,不管什么系统,不管什么业务场景,上来就要去“三高”,那么将非常有可能会让架构设计过于复杂,项目落地遥遥无期。历尽千辛万苦,最终客户不满意,老板不高兴,那也是白搭了。

至此,我们简单的对为什么要研究思考高扩展架构进行了说明,可扩展性是衡量架构设计好与坏的一个重要因素,但是一个系统要在一开始就设计出比较好的可扩展性是有一定难度的,可扩展性体现在不同层次、不同维度上,有大有小,它不是个体行为,需要依靠团队共同完成。任何系统最开始相对都是简单的,随着业务增加,慢慢开始变的复杂起来。我们需要在这个循序渐进的过程中,在极其不确定的业务变化中,寻找到真正的可扩展点,让架构具备高扩展性。

实现高扩展架构的目标、原则和方法是什么?



扩展性涉及面非常广,突破系统架构的扩展性约束是构建复杂业务系统必须解决的难题之一。一份良好可扩展的架构方案绝对是无价的,我们定义高扩展架构的目标是让系统架构简单清晰、应用系统间耦合低、容易水平扩展、业务功能增改方便快捷,实现服务/模块/代码级动态化、热插拔管理机制,提高研发效率,快速响应业务需求,提升客户感知。

在系统扩展性设计方面我们定义了几个关键原则:
鲸品堂|复杂业务系统高扩展架构设计与实践

1、解耦拆分原则:稳定部分与易变部分分离;核心业务与非核心业务分离;主流程与辅流程分离;应用与数据分离;服务与实现细节分离。

鲸品堂|复杂业务系统高扩展架构设计与实践

2、松耦合原则:跨域调用异步化,不同业务域之间尽量异步解耦。非核心业务尽量异步化,核心和非核心业务之间,尽量异步解耦。

鲸品堂|复杂业务系统高扩展架构设计与实践

3、服务依赖原则:核心服务不依赖非核心服务;非核心服务可依赖核心服务;稳定部分不依赖易变的部分、容易变的部分可以依赖稳定的部分。

鲸品堂|复杂业务系统高扩展架构设计与实践

4、服务自治原则:服务能彼此独立修改、部署、发布和管理。避免引发连锁反应。

对于实施可扩展架构,一些简单而有效的方法:
鲸品堂|复杂业务系统高扩展架构设计与实践

1、要定义规范:明确代码扩展性规范与约束,给出示例,引导开发人员在实现业务逻辑时,能够进行结构化、抽象化思考,保障代码的可维护性和可读性。

鲸品堂|复杂业务系统高扩展架构设计与实践

2、要搭好基础框架:高扩展架构有很多成功的案例,但实施起来没有标准,不能复制,也难以衡量,所以我们需要结合我们自身规范,自身需求,搭建基础框架,降低技术门槛,让开发人员关注业务逻辑编码。

鲸品堂|复杂业务系统高扩展架构设计与实践

3、要引入设计模式:应用面向对象思想,原则,使用常见设计模式,进行代码层面的设计。

鲸品堂|复杂业务系统高扩展架构设计与实践

4、要找到扩展点:结合业务需求,识别易变化的点,梳理扩展点清单,对于存在业务变动的代码,利用扩展点重构原有代码,抽象稳定基础能力。

鲸品堂|复杂业务系统高扩展架构设计与实践

5、要做好代码审查:对代码的审查内容很多,在关注代码的编写是否规范、技术处理规范、业务逻辑实现等的同时,考虑扩展设计来阻止代码腐化。


为了实现高扩展的架构,我们做了哪些实践?



基于上述考虑,我们今年在一些新产品、新项目建设过程中,做了一些关于可扩展性架构的实践,尝试对传统架构模式进行变革,为后续打造新一代产品架构做好准备。

高扩展实践一:通过领域分层设计,将业务规则分离出来,抽象在领域层,提升系统的可读性、复用性和扩展性。

传统三层架构,非常简单,基本没有太多开发门槛,在它带来便捷的同时,也带来了一些不利因素,其中之一就是开发人员缺乏对业务场景的深度理解以及对该类问题的抽象思考,当再次遇到同类功能时,都需要重复做一遍。长此以往,相似的代码模块也会很多,十分不利于系统的升级维护。

在我们已有的微服务架构中,我们尝试着以一种更轻量级的领域设计来融合到微服务系统设计中。通过领域模式的核心思想,来管理业务域的核心逻辑,在概念上保留领域对象、基础设施、领域服务、领域事件,同时领域对象采用贫血模型,通过领域方法来描述领域能力,逻辑功能高度内聚。同时,在领域服务层,我们分离读和写,只有写服务依赖领域能力来实现核心的状态变更,读服务直接基于基础设施层来提供能力。分层架构示意图如下:

鲸品堂|复杂业务系统高扩展架构设计与实践

通过这样的分层,我们在层次间的依赖上面,保持了足够的灵活性;而在核心的业务逻辑上,也具备领域能力的高度内聚,保证了一定的复用性和扩展性。同时,也降低了对开发人员的要求,让对领域模型理解不深的人员也能保证一定的完成质量。系统实际分层架构如下图所示:
鲸品堂|复杂业务系统高扩展架构设计与实践
鲸品堂|复杂业务系统高扩展架构设计与实践

基于领域模式实现功能时,经常遇到的问题之一,是哪些逻辑应该放在领域内?如果把所有业务逻辑都放到领域内,那过度膨胀的领域就失去了自身表达的意义。我们在实践中,通常会先将业务逻辑拆分为原子的功能点和控制流程,将明确属于领域内的逻辑合并,将不明确的功能点放在应用层,在后续迭代中再根据业务沉淀模型能力。

在分层设计实现中,我们需要将领域逻辑与业务场景流程控制分离。在领域层实现核心业务功能;在应用层通过流程控制聚合各个领域,实现特定业务场景,同时在应用层实现不属于领域内的业务场景细节逻辑。流程控制方面需要结合业务,原则上以简洁实用为主,保证既能满足业务功能,又能保持扩展性和可读性。在我们业务中,大部分业务场景是基于领域能力组合实现,少部分业务场景我们引入了轻量流程引擎、状态机、规则引擎、策略控制模式等。

DDD虽然有很多优点,但是我们在实践和持续迭代过程中也遇到一些问题。最明显的问题是DDD对设计人员要求较高,需要设计人员对领域模型和业务知识有较深入的思考与理解,才能设计出符合领域规范的实现方案。在理解不充分时,会出现生搬硬套现象,代码最终的实现往往会变成“四不像”,不仅不能合理表达领域的能力,而且还会因为未正确实现约束导致代码混乱。

高扩展实践二:面向功能拆分,产生微内核架构,实现业务和平台分离、业务和业务分离。

以最近我们新上线的促销中心为例讲解高扩展性系统设计与实现。促销中心是一个平台型的业务系统,要做到业务与业务的隔离、业务与平台的隔离。

为了达成这个目标,我们自研了一套插件框架,促销中心基于这个框架构建了促销业务调度框架及业务插件库。接入这个框架后,平台逻辑和业务逻辑得到了分离,各种促销类型(满减、优惠等)之间的逻辑也不再耦合,而是变成jar包级别隔离,同时支持了基于促销类型(策略)的动态路由模式。

促销平台核心程序负责促销计算初始化、促销规则执行、促销记录生成、促销分析等,实现了由主流程框架统一进行调度。我们把各种类型促销业务从核心程序中单独抽取出来,做成一个个业务插件。通过这种方式,也将核心程序和应用程序彻底进行了分离。核心程序和应用程序是通过接口联系起来,这层接口都是“声明”,包括接口定义、数据对象的定义和扩展点的默认执行策略定义等。促销平台架构如下图所示:

鲸品堂|复杂业务系统高扩展架构设计与实践
鲸品堂|复杂业务系统高扩展架构设计与实践
此外,插件框架支持在应用不停的情况下新增、更新、卸载业务插件,无感知进行升级,满足业务快速上线要求,系统更加稳定性、业务接入更加容易。各业务系统统一使用插件框架提供的插件包发布页面,完成业务插件包的装载。流程如下图所示:
鲸品堂|复杂业务系统高扩展架构设计与实践
鲸品堂|复杂业务系统高扩展架构设计与实践

高扩展实践三:搭建业务能力运营平台,实现管理域和运行域分离架构,让业务快速接入、快速扩展。

管理域指的是系统业务管理员配置业务流程、参数、规则或业务扩展点的实现工具的代码运行空间。运行域指的是系统业务逻辑处理程序的代码运行空间,为了支撑实际业务运行而存在的,而管理域则是为了对运行域的动态调整控制而存在的。

在应用的分层架构中,我们可以从用户能够接触的层次往系统抽象层次依次分为:页面、功能、能力、数据模型。在不同的业务场景下,有大量的业务模块是可以在这四个维度中的某几个进行共用的,那我们就可以在架构上做一项考虑:把每一个应用中的页面、功能、能力和数据模型都打散,分别沉淀到对应的页面、功能、能力、数据模型的共性库中,这样以后每次来一个新的业务只要通过从共性库中选择自己所需要的页面、功能、能力、数据模型就可以快速搭建匹配特定业务逻辑的应用。

按管理和运行域划分,页面、功能、能力、数据模型都是属于运行域的内容,而由于这些内容在业务不断的演化过程中会越来越丰富,所以我们需要提供一个平台来对这些内容进行管理,随之管理域就出现了。如图基于管理域和运行域分离的应用架构示意:

在管理域中有如下三个基础功能模块: 元数据管理、能力管理、组件管理。

首先, 元数据管理 主要完成对数据模型的管理,包括对内置对象的数据结构进行扩展、部分字段的定义,也包括对应用中的业务对象进行定义、字段设置等功能,在整个业务逻辑中元数据只是作为配置参数存在。

其次, 能力管理 主要是实现能力运营及功能扩充的管理,主要包括两部分,第一是对如业务系统透出的能力进行注册和发现,第二是给业务系统预留接口,可让应用自己进行定制化开发实现业务逻辑,再通过机制进行注册和发现并提供给应用使用。具体的实现机制可参考 Java 中的 SPI 机制,简单来说步骤如下:首先在代码中使用统一注解,通过扫描可以自动把注解部分的代码上报到能力管理实现注册;在能力对应的代码进行修改了之后,扫描机制也能在一定的时机进行更新;然后通过统一的编码规范,对某些类预留抽象类,可暴露给应用方自己进行实现;应用方对抽象类进行实现后,可通过扫描机制发现,并让应用进行调用。

最后, 组件管理 主要可以分为页面组件和服务组件的管理。

前端的组件最终是以页面编辑器的方式进行实现,在此不做详细表述,而管理后台的页面组件库则需要与全局管理中的资源、菜单、角色管理配合满足业务的需求。其核心业务逻辑在于,所有系统中的页面、菜单、页签、按钮以及其它页面元素都可以由统一的提供方提供,放到公共库中,使用方只需要按照标准进行调用即可,能够实现最大限度的资源复用。

功能服务组件则是把业务和平台分离的关键,大量具有业务特性的聚合服务从核心业务逻辑中抽离,形成一个一个的服务组件,以插件的方式装配到主干业务流程中,由于使用统一的标准进行开发,在业务组件中预设大量的配置项,通过自动注册和发现机制实现配置项自动化上报,而组件一被生产方生产出来后就会进入统一的服务组件库中,能够被任一业务方进行调用。

通过以上三个能力,能够实现对数据模型、能力、功能以及页面的统一管理的需求,只是对这些内容管理还是不够的,不能实现最终目的,在能够对其进行管理之后,我们需要能够按业务需求通过配置化、低代码的方式把这些内容组装拼接起来,以满足业务的实际需求。

为了解决不同业务动态化配置的问题我们需要引入业务身份这一概念,业务身份主要是把前后台的应用放在同一个空间下进行管理,我们通过管理域可在相应业务身份下进行业务逻辑的配置,这些配置可以让系统中包含的各个应用在运行域时能够识别所需要使用的页面、功能、能力和数据模型,能很好地运用业务身份进行业务逻辑的扩展。

总结展望



高扩展性”作为今年我们团队的三大架构研究方向之一,结合实际项目已经有了应用落地,目前业务系统已上线运行,我们正在积极将实践框架和经验复制到更多的产品上。基于框架能够实现增量式开发、增量式发布,解决了一直以来业务系统代码交织耦合、难以拆解的困扰。在代码质量和开发效率上也取得了显著提升,业务支撑更加敏捷、快速迭代。

“没有最好,只有最合适!回到最开始说的那句话,架构设计的真正目的是为了解决系统的复杂度带来的问题,不是为了追求所谓的高大上。就像任何一种复杂的架构一样,解决扩展性问题都不存在什么银弹。以业务需求作为指引,做出权衡和妥协对于实现高扩展性来说至关重要。高扩展性设计不仅仅是一个技术问题,它更像是一种模式,可以是思维模式,也可以是运行模式。高扩展架构是我们继续努力的方向,我们将持续进行探索。

以上是关于世纪证券Zabbix监控系统升级高可用架构的实践分享的主要内容,如果未能解决你的问题,请参考以下文章

跨园区容灾,升级不停服——高可用负载均衡集群实践

跨园区容灾,升级不停服:高可用负载均衡集群实践

鲸品堂|复杂业务系统高扩展架构设计与实践

zabbix高可用搭建--基础

高可用系统在点评的实践与经验--讲座思考

zabbix集群使用keepalived的高可用方案