去年,我曾写过一篇#架构设计与开发、运维之间关系#的文章,大体对在架构设计时如何权衡面向运维与面向开发进行过一通理论化梳理。也许是因为当时才刚刚开始写作,无论是案例还是措词,都显得极其平庸,总感觉有一肚子话无法倾囊抖出。
又是一年过去了,时间是否虚度?虽然这一年的工作场景略显单调,但是却很充实,帮助我取得了更大的长进。
今天,我以中间件为载体,再次探讨一下 “如何与中间件的各种利益相关者相互协调?他们的关注点一般又会有哪些?”的相关话题,也许你在曾经想到过,或思绪一闪而过,却没有探究其深层的根由。
就这个问题,我觉得是开发与运维对中间件需求不一致引起的,这其实没什么大不了,因为跟架构有关系的任何话题,如果权衡不好这两者之间的权重,那你的方案基本上也就告吹了。
那么,作为一名应用研发,你一般会有哪些疑问?或作为一名系统运维,你会如何理解“面向开发”与“面向运维”之间的关联呢?
设计之初的常见疑问
对于应用研发来说,即学即用,且接入成本低廉的中间件是最好的,因此在中间件设计之前,他们通常会提出一些疑问。
疑问1:当架构师提出缓存自主研发方案时,他们会问 “为什么非要自主研发?下载个Redis用起来就行了呀,集群及高可用方案官方都提供了,很成熟呀”。
其实不然,如果站在 “比数据库快,满足Request/Response就行” 的角度看当然没问题,但实际中间件需解决 “应用交互之间的技术解耦”,如某业务线因“特殊原因“”提出要使用HBase作为介质时,你只能再为他提供一个客户端,常此以往,运维侧需要投入的时间、人力及风险制衡将增大,更何况同时管理那么多SDK(或协议)也是个头痛的问题。
疑问2:当架构师提出通过添加代理层,解决客户端与服务端之间的解耦问题,他们又会问 “为什么要增加代理层?将SDK再次封装下,并把配置外移,便于维护就可以了呀。”
也不尽然,增加代理层的目的是将所有现有与将来可能出现的处理逻辑与规则(如路由控制、服务降级、协议转换)尽可能的放在代理层来实现,并在发布、维护及弹性伸缩、出现故障、冗余时,能够更快更灵活的变更,不仅达到技术解耦的效果,而且整个过程对于应用无感知。
值得一提的是,增加代理层,也方便在多机房场景中进行来回切换。
聊完了应用研发,再来说说系统运维。也许分布式或微服务架构,对于运维来说不是什么好事,不仅管理成本高,而且治理难度大,所以在设定中间件的目标过程中,他们似乎也有话要说。
疑问3:为了满足用户增长,当架构师提出利用分布式架构来提升扩展性,他们会说 “为什么要采用分布式架构?集群化架构也能扛住啊,我们的流量有那么大吗?你们有考虑过运维的感受吗?”
通过实际案例说明下,某调度中间件系统采用集群化架构,把几万个调度逻辑都放在一个WAR包里部署,然后运行在几十个同构的虚拟机上。过了不久,因为A调度出现阻塞,导致实例异常挂起,尽管几十个实例在运行,但由于资源互通,最终触发雪崩效应。
设想一下,如果这个场景使用的是分布式切片服务,每个切片服务于不同的应用,那影响的也只是有A调度和其他相关联的服务,而不会导致整个系统都不能使用。
这些疑问和见解,在许多公司的系统演变过程中或多或少都出现过,当然,纯靠 “堆人+堆机器” 打通关的也不在少数,甚至一年之间系统重构过2-3次的也屡见不鲜。在我看来,大部分原因都是前期没有调研,尤其没有在设计目标上做出权衡(如开发与运维之间的资源投入倾向),进入研发周期时才发现,对于快速发展的创业型公司来说无疑是沉重打击。
怎么理解 “面向开发” 与 “面向运维”?
我们先来看看网上热门多年的话题,在绝大多数人的印象中 “开发工程师与运维工程师的区别”。
从客观的叙述可以看到,由于岗位职责的不同与视角上的差异,无论是架构设计还是技术选型,在目标设定之初就容易引起开发与运维之间的博弈,尤其在使用者日趋大众化的今天,许多系统在设计之初并未明确技术的原则与目标,导致利益相关者(如开发和运维)之间失衡,引发复杂性向后倾斜,使得运维的工作越来越沉重,而且系统也越改越复杂,最终增大了事故发生率,甚至推倒重来、互相推诿。
简而言之,从中间件设计的原则与目标来看,我们可以基本得出以下公式:
这样得结论已很明确,这两者之间并非互斥关系,而是一种互补关系。
具体案例说明
我来通过一个案例,说明一下当遇到 “如何权衡中间件在面向运维与面向开发的设计目标” 时,该如何做出选择。
先来介绍下故事情节,假设我们公司的业务在近几年突飞猛进,从业务视角来看,从“单业务”发展为“事业部(多条业务)”;从技术视角看,传统关系型数据库已无法承受持续增长的性能需求——这个时候,我们就需要一个缓存系统来解决当前的性能痛点。
在十万火急的前置下,必须快速满足业务要求,所以没有仔细考虑,简单实现Jedis封装,并支持主动感知Master切换,匆忙上线了V1.0版本。
图1 我们的分布式缓存V1.0
又过了一段时间,随着接入的应用系统越来越多,版本混乱、维护成本等现象频发,今天这头告急,明天那头起火,对于中间件运营及运维而言,真是苦不堪言。
当遇到这些问题时,我们对原因进行了复盘整理:
从复盘整理可以看出,在无法实施轻量级Java框架的客观条件之下,为了能在面向运维与面向开发间做出权衡,我们发布了V2.0版本。
图2 我们的分布式缓存V2.0
又过了一段时间,随着接入的应用系统越来越多,版本混乱、维护成本等现象频发,今天这头告急,明天那头起火,对于中间件运营及运维而言,真是苦不堪言。
通过增加代理层、支持分片化、协议私有化等功能,基本已达到“主体面向运维,且兼顾开发”的设计目标:
通过上面的陈述,我们可以看到既面向运维,又面向开发,是中间件设计过程中始终追求的核心准则,但有时却会因为客观场景、技术债务、硬件环境等原因使其难以兼顾,而我们需要保证的,是在设计目标时做出合理的权衡,以保障系统的持续发展。
小结
现在只要一谈起架构策略,相信许多人的脑海中会浮现出中台战略、基础服务下沉,以及大平台与小团队等一系列高大上的词汇。
中间件作为企业应用级基础建设,在目标设计时的盲目往往会引发后期的故障发生与成本损失,所以我们必须思考 “如何与中间件的各种利益相关者相互协调,并合理满足他们的关注点”,希望对你有所帮助。
相信你在设计目标时,应该有遇到过开发与运维不一致的情况吧?最后你又是如何权衡的呢?欢迎你把答案写到评论区,和我一起讨论。
作者:王晔倞,18年IT从业经验,现任职好买财富平台架构部技术总监,负责好买中间件及平台化的研发及运营,团队管理和实施重大技术决策。曾任大智慧测试总监,在2年内带领团队自研了“大智慧云测试平台”,通过平台化将金融数据服务业务从瀑布式逐渐转型为DevOps。
———END———
限 时 特 惠: 本站每日持续更新海量各大内部创业教程,一年会员只需98元,全站资源免费下载 点击查看详情
站 长 微 信: wxii2p22