看一下我们的现状,中间是我们整个架构的体系,右侧是和服务化相关的一些基础,包括基础的组件或者服务。
WebAPI 主要做一些 HTTPS 卸载、限流,还有安全校验等一些通用的和业务逻辑无关的操作。
Service Orchestrator 是服务编排层,通过配置的方式实现内外网的协议转换、服务的聚合裁剪。
架构图右边是一些围绕这些服务化框架的辅助系统,比如说用于定期执行一个任务的 Job 系统。我们有将近快 1000 个服务,这些系统怎么监控?所以必须有一套监控系统。刚开始只有 30 多个人的时候,我们更擅长的是跑到机器上去搜一下 Log,那么 900 多人的时候,你不可能都到机器上去搜一遍 Log,就需要有个集中式的日志系统。其他的系统就不一一赘述了。
罗马不是一天建成的,基础架构是个演进的过程。我们精力有限,那先做什么呢?
- 每周只有两天可以发布;
- 周末是绝对不可以发布的;
- 业务的高峰期绝对不允许发布;
- 等等…
我们发现,发布的最大问题在于发布上去之后没有简单可执行的回退操作。回退操作到底是谁来执行,是发布人员就可以执行,还是需要专人来执行?如果是发布人员的话,发布人员并非 24 小时在线工作,出了问题找不到人怎么办?如果是有专人来执行回退,而又没有简单、统一的回退操作,那这个人需要熟悉发布人员的代码,这基本上不可行。
所以我们就需要有发布系统,发布系统定义了统一的回退操作,所有服务必须遵循发布系统的定义回退操作。
- 升级到一个有更多 CPU 的机器
- 把硬盘改成 SSD 的或者更高级一点的
但硬件提升终归是有一个容量的限制的。而且很多做业务的小伙伴,写代码的时候都直接操作数据库,发生过很多次服务一上线数据库就被打爆的情形。数据库被打爆掉了之后,除非等待数据库恢复,没有任何其他机会可以恢复业务。
如果数据库里面数据是正常的,业务其实都可以补偿出来的。所以我们做 DAL 服务层的时候,第一件事情是限流,其他的东西还可以放一放。然后做连接复用,我们 Python 框架用的多进程单线程加协程的模型。
多进程之间其实是不可以共享一个连接的。比如:一台机器上部署了 10 个 Python 进程,每个进程 10 个数据库连接。再扩展到 10 台机器上,就有 1000 个数据库连接。对数据库来说,连接是一个很昂贵的东西,我们 DAL 层要做一个连接复用。
这个连接复用讲的不是服务本身的连接复用,而是说 DAL 层上的连接复用,就是服务有 1000 个连接到 DAL 层,经过连接复用后对数据库可能只是保持着十几个连接。一旦发现某个数据库请求是一个事务的话,那么 DAL 就帮你保留这个连接的对应关系。当这个事务结束之后,就把数据库的连接,放回到共用池里面去,供其他人使用。
然后做冒烟和熔断。数据库也可以熔断的。当数据库发生冒烟时,我们会杀掉一些数据库的请求,保证数据库不至于崩溃。
我们的资源和时间总是有限的,作为架构师和 CTO 来说,如何在这种有限的资源下,产出更重要的东西?
我们做了很多系统,觉得自己做的很棒了,但其实不是,我感觉我们又回到了石器时代,因为问题越来越多,需求也越来越多,总感觉你的系统里还缺点什么东西,想做的功能也一大堆。
比如对于流控系统,现在我们还是需要用户去配一个并发数,那么这个并发数,是不是根本不需要用户去配?是不是可以基于我们服务本身的一个状态自动去控制并发数?
然后是升级方式,SDK 升级是个很痛苦的事情。比如说我们服务框架 2.0 发布的时候是去年 12 月份,到现在还有人用的是 1.0。是不是可以做到 SDK 的无损感升级,我们自己来控制升级的时间和节奏。
还有我们现在的监控只支持同一个服务上的汇聚,是不分集群、不分机器的,那么是不是以后的指标可以分集群的,分机器的?举一个最简单的例子,比如一个服务上有 10 台机器,那么可能只是某一个机器上出了问题。但是它所有的指标都会平均分摊到其他的 9 台机器上去。你只是看到了整个服务延时增加了,但有可能只是某一台机器拖慢了整个服务集群。但是我们现在还做不到更多维度的监控。
还有智能化的报警,这个报警,就是快、全、准,我们现在做到更快了,做到更全了,怎么才能做到更准?每天的报警量高峰时间一分钟一千多个报警发出去。所有的一千报警都是有用的吗?报警多了之后,就相当于没有报警。大家都疲劳了,就不去看了。我怎么能够把这个报警更准确地区分出来?还有更智能化的链路分析?以后是不是我们的监控不要放监控指标,而是放链路分析,这样就能够很清晰的知道,这个问题对应的是哪一个结点上出了问题。
这些问题涉及我们做事的一个原则:东西够用就好,但是要能够未雨绸缪,做一定的超前规划。
扩展阅读
SOA,即面向服务的体系结构搜索(Service-Oriented Architecture,也叫面向服务架构),是指为了解决在Internet环境下业务集成的需要,通过连接能完成特定任务的独立功能实体实现的一种软件系统架构。SOA是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。