中小型研发团队对于架构的选择与思考

此篇分享分为三个部分 , 包括 框架篇 、 架构篇 和 公共应用篇。
框架篇 即中间件或工具的使用 , 如缓存、消息队列、集中式日志、度量、微服务框架等 , 工欲善其事 , 必先利其器 。
架构篇 主要是设计思想的提升 , 有企业总体架构、单个项目架构设计、统一应用分层等 。
公共应用篇 是业务与技术的结合 , 有单点登录和企业支付网关 。
框架篇——工欲善其事 , 必先利其器如果说运维是地基 , 那么框架就是承重墙 。农村建住房是一块砖一块砖地往上垒 , 而城市建大 House 则是先打地基 , 再建承重墙 , 最后才是垒砖 , 所以中间件的搭建和引进是建设高可用、高性能、易扩展可伸缩的大中型系统的前提 。
框架篇中的每篇主要由四部分组成: 它是什么 、 工作原理 、 使用场景 和 可直接调试的 Demo 。其中 Demo 及中间件历经两家公司四年时间的考验 , 涉及几百个应用 , 100 多个库 1 万多张表 , 日订单从几万张到十几万 , 年 GMV 从几十亿到几百亿 。
所有中间件及工具都是基于开源 , 早期我们也有部分自主研发如集中式日志和度量框架 。后期在第二家公司时为了快速地搭建 , 降低成本 , 易于维护和扩展 , 全部改为开源 。这样不仅利于个人的学习成长、知识重用和职业生涯 , 也利于团队的组建和人才的引进 。
集中式缓存 redis
缓存是计算机的难题之一 , 分布式缓存亦是如此 。Redis 看起来非常简单 , 但它影响着系统的效率、性能、数据一致性 。
用好它不容易 , 涉及到的问题包括:缓存时长(复杂多维度的计算)、缓存失效处理(主动更新)、缓存键(Hash 和方便人工干预)、缓存内容及数据结构的选择、缓存雪崩的处理、缓存穿透的处理等 。
Redis 除了缓存的功能 , 还有其它功能如 Lua 计算能力、Limit 与 Session 时间窗口、分布式锁等 。
消息队列 RabbitMQ
消息队列好比葛洲坝 , 有大量数据的堆积能力 , 然后再可靠地进行异步输出 。它是 EDA 事件驱动架构的核心 , 也是 CQRS 同步数据的关键 。为什么选择 RabbitMQ 而没有选择 Kafka , 因为业务系统有对消息的高可靠性要求 , 以及对复杂功能如消息确认 Ack 的要求 。
集中式日志 ELK
日志主要分为 系统日志 和 应用日志 两类 。试想一下 , 你该如何在一个具有几百台服务器的集群中定位到问题?如何追踪每天产生的几 G 甚至几 T 的数据?集中式日志就是此类问题的解决方案 。
早期我们使用自主研发的 Log4Net+MongoDB 来收集和检索日志信息 , 但随着数据量的增加 , 查询速度却变得越来越慢 。后期改为开源的 ELK , 虽然易用性有所下降 , 但它支持海量数据以及与编程语言无关的特征 。下面是 ELK 的架构图 。
中小型研发团队对于架构的选择与思考

文章插图
 
任务调度 Job
任务调度 Job 如同数据库作业或 windows 计划任务 , 是分布式系统中异步和批处理的关键 。我们的 Job 分为 WinJob 和 HttpJob:WinJob 是操作系统级别的定时任务 , 使用开源的框架 Quartz.NET 实现;而 HttpJob 则是自主研发实现 , 采用 URL 方式可定时调用微服务 。
HttpJob 借助集群巧妙地解决了 WinJob 的单点和发布问题 , 并集中管理所有的调度规则 , 调度规则有简单规则和 Cron 表达式 。HttpJob 它简单易用 , 但间隔时间不能低于 1 分钟 , 毕竟通过 URL 方式来调度并不高效 。下图是 HttpJob 的管理后台 。
中小型研发团队对于架构的选择与思考

文章插图
 
应用监控 Metrics
“没有度量就没有提升” , 度量是改进优化的基础 , 是做好一个系统的前置条件 。Zabbix 一般用于系统级别的监控 , Metrics 则用于业务应用级别的监控 。
业务应用是个黑盒子 , 通过数据埋点来收集应用的实时状态 , 然后展示在大屏或看板上 。它是报警系统和数字化管理的基础 , 还可以结合集中式日志来快速定位和查找问题 。我们的业务监控系统使用Metrics.NET+InfluxDB+Grafana 。


推荐阅读