软件开发实际上跟英语比较相似,都是一项工具,服务于各行各业。从程序员的我的修养上来说,一是要研习好软件开发这门技艺,二是要深刻到所服务的行业。说到底,软件的终极目标是模拟业务,在此期间经常会有一个认知层面的小误会,即软件开发人员在入行之初所学习的都是与计算机、编程语言相关的知识,因而就造成“只须要把代码写完”事情就算完成的观念,显然这远远不及对软件架构师所要求的业务主导意识。程序员
最近在看王概凯(Kevin)的《聊聊架构》,其中特别强调软件架构师应深刻到业务中,并以业务的问题是否解决做为工做优良的判断标准,比较受启发,接下来我也根据过往工做经历说说本身的感知和体会。数据库
软件所模拟的业务行为,其核心也在于数据,它们共同表达的都是行为背后的状态和结果,先看看下图:编程
在明确了业务主体后,业务目标天然就能够获得聚焦,有了清晰的业务目标,就值得花精力来探知业务的生命周期,接下来就能够像外科手术医生同样细致地实行架构拆分。安全
因而可知,软件架构师在实行架构拆分行为时,基本上都把业务从头至尾捋了一遍,不然势必陷入设计不足或过分设计的漩涡。服务器
好的架构拆分是基于对业务的正确认识,但业务这个东西每每总使人心生畏惧。网络
在众多的传统企业中,信息技术部肩负起了全集团、全公司的以业务为导向的信息化重担。依靠全部成员去解构业务是不现实的,这时候软件架构师或者项目负责人就须要迎难而上,积极参与到需求分析中。能够确定的是,只有直面业务的人,才能真正体会到按时、按需解决业务问题所面临的时间压力,这种压力的源头恰是职业人的天性,由于人们总倾向于认为本身从事一个行业而后精通该行业就能够,却不知,软件行业其本质就是服务业,那么做为软件架构师,则必须超越对时间、对业务的恐惧,认识到须要解决问题的主体是业务人员而非本身,即须要解决的问题是“非软件行业”的问题,本身是在协助业务人员解决问题,从这个层面来说,工做是否完成实际上是由业务人员决定的,而不是软件架构师本身。架构
假若选择拈轻怕重,尽管在短期内部署上线了,但问题并未真正获得解决,业务部门的催促又会加剧后续任务的时间压力。何况,仅仅以作好本身的编程工做为主要目标,并试图用本身的软件知识去理解另外一个行业,又很容易陷入沟通困境。负载均衡
在 2016 年,才加入申通快递不久就接到客服部关于开发备案系统的诉求,这个系统是涉及到全国网点,在备案请求提交后会由上级机构审核。我在接到这个任务的时候,首先按常规把会议记要过了几遍,而后对其中的审核功能作了重点铺开想像。个人脑补过程是这样的,首先它涉及到多机构递交审核,那么这期间有没有可能出现并行会审的情形?当流程出现退回时又该如何处理?要不干脆上一套流程框架吧,但发现 .NET 平台下开源的框架并很少,那就考虑 Java 平台的 Activiti 吧,可转而发现更换平台的成本又过高,并且照这样作下去,在预约的时间内恐怕很难交付。何况这个审核功能还只是全部问题之一,困惑之余,以为仍是要主动跟业务表明(客服部)作二次沟通。框架
经过主动出击,了解到审核的节点只有三步左右,只需采用最多见的串行单审便可,并不须要太多的复杂步骤。获得这样的答复后可谓喜出望外,回来的路上就想好了基于状态模式的实施方案,这样减去了引入各类工做流框架的麻烦,重要的是对时间压力和对交付 deadline 的焦虑减轻了许多。运维
虽然这个例子可能相比较于不少大型系统来讲有点偏小,或者说是带有运气成份,但至少能够说明积极地与需求方沟通,能在很大程度上减少实现与需求的偏差,以及自身对业务和时间的恐惧。
这里包含了一个隐形的要求,即软件架构师须要把对编程上的职业成就感,适当的转移到解决业务工做中,把完成业务工做做为本身的最大利益。如此,随着对业务的熟悉,那么对时间的恐惧便会慢慢消失。
人的生命周期无非是出生、成长、衰老直至死亡,而软件亦同,根据核心生命周期和非核心生命周期之分,一般能够把非核心的部分分工出去,让新进人员来承接,锻炼并促成其快速地融入大团队的协做。不妨思考一个问题,软件开发生命周期和软件运行生命周期哪个更偏向于核心生命周期呢?一般企业开发一款软件的目的就是拿来使用的,其效益的持续提高依靠的正是软件的稳定运行,因此我以为软件运行生命周期或者说运维才是核心。
能够稍微再提一提关于对非核心生命周期的分工问题,这是软件架构师须要平常考虑的问题。分工即拆分,而架构的拆分从本质上来说也是一种利益的从新分配,毕竟每一个人处理问题的承受力老是有限的,这就须要把一些非核心的业务分拆出去,无形中也是让本身走出时间困境的有效办法。然而在甄别一项业务是否为核心业务的时候就须要特别仔细,假若对相关人的利益分析不透彻,便极易致使架构没法落地。
理解到了业务的主体及其生命周期后,就能够安心的作架构方面的拆分,从而造成不一样的软件生命周期,从大的方面一般包括有开发和运行周期。
开发的生命周期其实就是代码的累积过程,它以项目启动为始,而后和业务人员学习业务并造成需求文档,进而编码、测试以达到正确模拟现实业务的效果,最终得以部署上线,这时开发生命周期就终止了。最值得注重的实际上是在开发以前就须要为软件的运行来考虑一系列的资源,好比机器、子域名申请以及监控等等,因此软件架构师在统筹方面须要更多的前瞻。
2017 年下半年,我参与到了申通快递的自动分拣项目中,这又是一个涉及全国各地的系统,并且是专为各大型转运中心所使用,为提高数据分发和故障排查等方面的效率,咱们寻思着先从消息队列和监控两方面来改进。全新启用的开源消息队列 RabbitMQ 很好的帮咱们桥连起各个子系统,它自身所带的监控页面,也帮咱们在平常运维上省了很多心。趁此机会,又梳理了自动分拣项目所涉及的所有服务器,以指望并入统一的监控体系中,这时我想起了孙宇聪在高可用架构里提到的《SRE: Google运维解密》,大体解决办法仍是在每台机器上运行一个代理程序,那我姑且就叫“埋点”吧,经过这样简单又颇有效的方式对各子系统的运行情况作了监控,初步就以发短信的形式通知到组内人员,这样第一时间便能知晓线上运行情况。
其实,软件开发的过程可谓是八仙过海,各显神通。每一位软件架构师或者项目负责人能依据不一样企业环境将软件构建出来就是最大的成功,到底是采用传统的瀑布式(Waterfall),或是新兴的敏捷(Agile)迭代,甚至是两相结合都无可厚非,我最想强调的是对外沟通,即上面提到的对获取各项资源的前瞻性。毕竟“外行人”并不知道开发中的细节,不清楚咱们一天到晚坐在那儿究竟在干什么,因此咱们要对外保持 Open 状态并显现出沟通的意愿。
软件运行生命周期才是一个软件真正的开始,一个有价值的软件从它启动的那一刻开始就已经为企业带来了效益,因此运行生命周期,即运维才是真正的核心竞争力。
运维的业务目标很简单,即保证软件稳定地被用户访问,那么风险控制工做即是重中之重。
首先是隔离措施。软件的开发生命周期一般是平常办公环境,而软件运行周期则是服务于用户的,所以要区分出办公环境(或测试环境)和生产环境。以我目前熟悉的快递行业,上规模的企业基本都有自建机房和运维团队,其电源、网络、空调、排风都是一体化的独立管控。
其次是控制变动。这里面还划分有被动变动和主动变动,被动变动包括机器主板或硬盘的损坏,以及用户访问量的突增等等,这时候做为软件架构师就须要警醒一下,必要时提醒运维人员针对上线的子系统作好负载均衡,小型应用一般保持两台机器,面向全国全网的应用就须要考虑四台以上机器了。主动变动多半状况下指的是频繁的发布更新,为了最大程度的下降影响面,要确保在指定地点、指点时间进行变动,并让全部的运维人员知情。从安全和便利角度考量每每还会用到运维堡垒机,若是要求更为严苛,还能够从账号、公钥等方面进一步来增强。
在软件运行这样一个最为核心的生命周期中,发布更新的质量直接影响到企业信息部门的运维表现,结合孙宇聪的诸多建议我也列举一些值得注意的要点:
线下测试(Offline Test)。重点检查线下测试环境是否完善,除此以外还须要产品人员和开发人员的督促。除了通常的代码逻辑测试,尽可能再兼顾到压力测试。
灰度发布(Gray Released)。指的是根据业务特色、数据特色来选择一批有极强表明性的线上服务器实例进行发布,其发布的比例能够考虑按 1%、10%,最后 100% 这一指数型方式来增加。这样有利于把新上线功能可能的不良影响降到最低,固然也能够做为小范围收集用户的反馈意见以待完善产品功能。灰度发布能够视做是上线前的最后一道安全防御机制。
回滚机制(Rollback)。通常来讲用上一个版本的相关程序集进行覆盖便可,但有时还会出现数据格式的兼容性问题。好比数据库表字段的类型此前发生了变化,那这时候还须要有配套的回滚 SQL 脚本。另外一种情形是新的变动内容把数据删掉了,回滚后数据也回不来了,这种状况是没有补救措施的,建议的作法是将程序代码分红两块逻辑,先发布第一段逻辑并记录好日志,等发现没有问题后再将删除的代码做为第二次发布。
在实际工做中,开发生命周期和运行生命周期每每是并行存在的。在软件部署上线后,总会不断地进行修改,好比出现了 Bug,或者是要增长新的需求,这时软件的开发、测试以及部署流程就须要再迭代一遍。不管新需求的开发多么重要,都要摆正软件运行生命周期的核心位置。
无论是软件架构师仍是软件开发人员,一般都很专一于技术,以至于不过重视各类技术背后的业务,使得技术与应用老是没法较好的相融。计算机相关的技术,围绕的核心点始终是如何让用户可以更好的使用软件,这背后千丝万缕的业务关系无不是源于现实生活,因此认真工做之余还能够多读一些人文历史,并走进生活以获取灵感。