构建安全可靠的微服务 | Nacos 在颜铺 SaaS 平台的应用实践
作者 | 殷铭 颜铺科技架构师
导读:颜铺科技因美业⽽⽣,“颜铺专家”是一款专为美业商家打造的 SaaS 平台,为了能够给商户提供更加安全、稳定、高效的平台,我们在技术方面做了很多尝试,经过几次演进,使系统变得更加稳定可靠。今天主要和大家分享一下颜铺科技的架构演进,以及 Nacos 在颜铺的应用实践。
单体应用时代
发布周期慢:虽然当时业务量不算大,但是代码量很大,业务迭代牵一发而动全身,每次发布需要对整个服务进行重新编译打包部署。特别是最开始在没有构建工具的时候,发布过程需要一堆的命令,总有一种 “一顿操作猛如虎,定睛一看原地杵” 的感觉;
协同效率低:合并冲突多,有时你在前面开心地写代码,而别人在解决冲突时,可能也在开心地删着你的代码,增加了很多的沟通成本;
稳定性差:当服务出现故障时,可能会导致整个系统不可用,并且系统不易扩容,当商户搞促销时,可能活动结束了,服务器还没有扩容完成;
性能差:因为在单体服务内,有些开发人员为了满足自己的业务,很多无关业务间 SQL 联表查询,并且不关注性能问题,导致线上时常出现负载警告。
业务转型:2018 年 6 月,我们公司决定从泛行业转向美业,需要打造一个专为美业商户提供技术支持的丽人 SaaS 平台;
快速占领市场:业务的转型带来了更多商户的新需求,如果不能快速迭代,则意味着被市场淘汰。因此,提升开发效率,快速占领市场成为我们急需解决的问题;
商户体验差:随着越来越多的商户入住,性能和可靠性的问题逐渐显现,出现问题,不能及时修正,商户体验变得很差,违背我们客户第一的原则。
微服务改造
1. 服务化改造 1.0 的目标
用最小的改造成本先将新、旧商户平台进行打通,做到功能上的快速迁移;
业务抽象,将新旧商户中心的公用部分进行抽象,并优化旧商户中心的代码逻辑,为后续的业务中台建设做好铺垫。
2. 服务化改造 2.0 的目标
3. 服务化改造 1.0 预期效果
我们希望老商户中心在对外提供服务的同时,还能够作为提供者,对新商户中心提供服务支持;
新商户中心仅对外提供服务,不直连数据库,业务层只对美业的特殊逻辑进行处理。
4. 服务发现选型
Consul 支持服务发现的同时,支持 kv 存储服务,因为我们想做一个配置中心的 KV 存储,所以想利用 Consul 做一个尝试;
服务健康检查相对更为详细;
在我们选型的期间,突然出现了 Eureka 2.x 开源工作宣告停止的消息,虽然后来发现,这个对我们并没有什么太大的影响,但在当时的决策让我们最终选择了 Consul 。
5. 服务化改造 1.0 架构图
功能快速完善:旧商户中心的功能快速迁移到了新的商户中心,并完成对美业的适配;
迭代速度加快:新商户中心大部分功能,能够通过旧商户中心进行修改兼容,为后续的业务中台的抽象打好基础;
性能优化:业务开发的同时,我们对旧商户中心的老代码进行优化,性能和稳定性均有所提高。
发布周期依旧不够快:大部分代码还是在就商户中心,业务迭代依然牵一发而动全身;
协同效率没有提高:在代码冲突多,沟通成本高的同时,又出现了令开发同学头痛的新老业务的兼容问题;
维护成本:Consul 是 Go 语言开发的,不易维护;Spring Cloud 在开发过程中体验不佳,在写业务的同时,还要摸索 Spring Cloud 的最佳实践,花费了一些时间去做 Spring Cloud 的基础建设。
6. 服务化改造 2.0 的预期效果
完成业务中台的初步建设,将模块重新划分,抽象为独立服务;
新、旧商户中心服务仅做自己的业务兼容,并对外暴露接口;
新增专门支持 H5、小程序 的 C 端 WEB 服务。
-
服务注册及时被发现,异常时的及时下线; -
服务管理,能够手动恢复/剔除服务; -
健康检查,检测服务是否可用; -
元数据管理; -
注册中心保证自身的高可用。
Zookeeper:
不能保证每次服务请求都是可达的,当 zk 集群 master 挂掉时,需要进行选举,在选举期间中,服务是不可用的;
不支持跨机房的路由,比如 eureka 的 zone,当前机房不可用时,可以路由到其他机房;
“惊群效应”, zk 的节点过多的时候,当 service 的节点发生变更,会同时通知到客户端,瞬时流量有可能将网卡瞬间打满,并且会有重复通知的问题。
Nacos:
注册中心部分更侧重于可用性
服务发现与服务管理
服务元数据的管理
动态配置管理
7. 服务化改造 2.0 架构图
服务器成本降低 30%:20+ 台服务器,由 4 核 16G 降配到 2 核 8G;
系统可靠性提升 80%:load 告警明显减少,线上的问题修正能够快速修复,完成部署;
代码冲突减少 75%:因为边界有了基本各自维护,冲突显著减少;
发布迭代效率提升 50%:之前 5 个人每个迭代开发评估可完成 30 个点,现在可完成 45 个点左右。
Nacos 落地实践与问题分析
部署方式:开发/测试环境单机部署,生产环境 3 台集群部署;
版本:生产环境从 0.9.0 开始使用,目前生产环境使用的版本为 1.1.4 ;
使用时间:2019 年 3 月份开始在生产环境下使用;
服务数量:线上 20+ 台服务器,提供了 600+ 个服务;
稳定性:一年的时间里没有出现大的问题,并且平滑升级;
兼容性:新老服务,在我们公司无论是 Spring 4.3+ 的工程,还是 Spring Boot 的工程均兼容良好。
1. Nacos 注册中心
服务注册:将后端服务注册到 Nacos,通过 Dubbo 进行调用。目前开发环境中我们正在测试Seata,并且也将 Seata 服务注册到 Nacos 上;
Namespace:服务统一注册到 public 中。
2. Nacos 配置管理
服务的配置文件信息:application.properties 全部配置到 Nacos,工程的配置文件仅保留 Nacos 相关配置;
业务层的 KV 配置:比如业务开关,属性默认值,定时任务配置等;
MQ Topic 的动态配置:Binlog 服务采集动态发送到在 Nacos 配置的 topic 及其需要的表信息;
Sentinel 的规则配置:Sentinel 限流规则持久化到 Nacos 。
3. 问题描述
两次出现的问题均是门店服务,但出现问题期间 JVM 和数据库的运行状态均良好;
报错信息都是 Dubbo 调用超时,且出现问题期间,门店服务没有任何流量进入;
出现问题时,注册在 Nacos 上的服务开始大量不健康。恢复正常时,这些服务又开始上线,说明出现问题时,服务被下线又重新上线。
4. 问题确认
5. 问题复盘
问题出现:下午 3 点多,突然连续出现的服务告警, Dubbo 服务出现报错;
Nacos:Nacos 服务列表里大量服务出现不健康的状态;
网络不通:可用区 B 与其它区网络不通,导致服务无法调用;
紧急部署:在 B 区部署缺失的 门店服务;
恢复正常。
6. 问题思考
服务部署:应用服务和Nacos建议多机房部署,即使在云上可用区之间也需要考虑;
容灾:问题出现时,可用区 B 并没有部署 Nacos,但可用区B内的服务之间依然能调通,且能够读到 Nacos 上的配置。因此,我们认为 Nacos 以及 Dubbo 的容灾策略都是值得信赖的。
7. 回顾与展望
未来规划
1. 提升系统高可用
Seata :目前我们公司的分布式事务主要依赖 MQ 的补偿,今年准备引入 Seata 来完善分布式事务,保证数据一致性,减少开发修数据的情况;
Sentinel :目前 Sentinel 我们只是在商户做活动时启用,因此我们要配置出适用于我们公司的最佳实践,保证系统的高可用;
全链路跟踪:我们公司现在定位问题主要靠日志和告警,做不到全链路的跟踪,所以我们要把这部分做好,做到故障快速定位,各调用环节性能分析,以及数据分析;
异地容灾:随着来自全国各省的商户越来越多,我们需要对商户的数据保障,避免数据丢失,确保服务的可靠性。
2. 社区回馈
因为我们的公司体量现在不大,我们能够做到的是尽可能地使用最新的版本,及时尝试新特性,对发现的问题提 issues,但我们也希望能够对 Nacos 开源社区尽一份我们的力量。