架构师训练营 - 第四周作业
罗马不是一日建成的,互联网公司的应用系统亦是如此。
研发系统的目的是为了满足业务发展的需要。因此,系统发展的外部驱动力主要包括以下几个方面:
业务规模的扩大
业务数据量增加
业务的并发增加
服务可用性挑战
业务更加复杂
公司涉及的业务更加广泛
单一业务的业务逻辑更加复杂
各业务线的数据需要打通
(业务的复杂性导致)公司组织架构更加复杂
资源的访问权限控制问题
人员沟通成本提升
(系统的复杂性导致)开发难度与开发成本提升
软件开发的难度提升
系统运维的难度提升
其中,1,2 两大问题直接决定了系统架构会演化为什么样子。而是否能够解决好 3,4 两大问题,则是公司是否有能力支撑起复杂架构的关键。
接下来,将针对可以通过技术手段来解决的问题展开讨论。
1. 业务规模扩大带来的问题
衡量业务规模的指标可以是该产品的用户量,也可以是活跃用户量,访问请求量等。这些指标一般来说都是正相关的。
1.1 业务数据量增加
该问题表现为,单机的硬盘容量无法存储全部数据。因此无论静态资源文件还是数据库中的数据,都需要被分布式地存储。也就是解决问题的核心思路是分布式,常见技术包括:
分库分表:通过拆分数据库和拆分表结构,解决单机/单表数据量瓶颈问题
NewSQL:为解决传统关系型数据库架构老旧,不适于分布式扩展和维护,NewSQL 使用分布式架构,可做到用户无感扩缩容,单库单表即可存储海量数据,减轻了研发和运维使用成本。
分布式文件存储系统
1.2 业务的并发访问量增加
由于单机的处理能力和网络带宽有限,用户访问量增加势必会导致请求响应时间增加,甚至产生连锁反应导致服务瘫痪。
解决问题的技术思路一般为增加计算资源,使用更高效的算法,异步化服务,缓存-用空间换时间,服务降级-节约计算资源。(非技术思路一般为更改产品策略,引导用户错峰使用服务)常见技术包括:
无状态服务设计:将服务设计为无状态服务,可以显著降低服务多机部署的成本。
负载均衡:分布式服务的基础
监控与报警:及时发现与分析性能问题的利器
服务弹性伸缩:以 1,2,3 为基础,服务弹性伸缩可以有效应对访问高峰
数据库读写分离:与前面提到的分库一样,通过分布式部署利用更多的计算资源。读写分离的侧重点在于偶发的较慢的读请求不会拖垮整个数据库服务
正确使用索引:虽然索引技术比较简单,但却可以带来巨大的性能提升。索引的实质是更高效的查询算法
数据异构/反范式:基于 3rd 范式设计的数据库在处理复杂逻辑时会产生大量 join 操作,根据业务的需求设计反范式的查询表,添加冗余字段,可以有效提升查询性能。
NoSQL:关系型数据库并不能满足所有业务场景,在特定场景下使用 ElasticSearch,MongoDB,图数据库,时序数据库等 NoSQL 数据库,也是解决性能问题的手段之一。
异步编程模型:epoll, nodejs 等技术对单核性能的压榨能力已经得到了证明
消息队列:夸服务/语言异步编程利器
分层缓存:缓存技术纷繁复杂,受篇幅限制,这里只聊一些通用规律
在进入业务代码前的缓存大多为资源缓存,进入业务代码后的缓存多为数据缓存
使用数据缓存就意味着服务是“有状态”的,因此数据缓存应尽可能使用分布式缓存
服务降级
2. (业务规模扩大导致)业务更加复杂
关于为什么业务规模扩大会导致业务复杂的逻辑,这里就不展开进行分析了。业务复杂带来的挑战要比业务规模带来的挑战更大,原因是解决业务复杂性问题时需要更多的考虑业务本身的属性。
2.1 单一业务的业务逻辑更加复杂
业务逻辑的复杂体现为在业务抽象流程不变的前提下,提升用户的交互体验或为不同用户提供个性化服务,而这些变化都会要求技术能力更加专业。
前后端分离:前后端的分离实质上是交互和业务逻辑的分离,前端更加专注于提升用户交互体验,后端更加专注于业务逻辑实现。
终端设备与智能硬件:随着硬件的迭代,前端可能不仅仅运行在 PC 端和移动端上,新的终端设备和新的硬件带来了新的交互需求。
开源技术/第三方服务接口调用/外部系统:更专业的业务逻辑交由更具体的技术去解决,如
开源技术:如 pdf,excel 等专业数据格式处理、音频/视频文件处理,通信协议 SDK 等
服务接口:如支付服务,身份证/银行卡校验等
外部系统:如专业的财务系统,CRM 系统,云服务等
外包服务:外包大家都懂的,坑在于大多数外包团队只对代码的运行结果负责,但不对代码质量负责,更不对业务负责。
更大的研发投入:无论是选择接入还是自研,都意味着需要投入更大的研发成本,而当问题规模增大时,买来的往往都不如自己做的好用。
2.2 公司涉及的业务更加广泛
当产品线增加,不同的产品所服务的用户角色不同,关注的交点也不同,业务代码也注定要走向分离。解决这个问题并没有特定的技术手段,但却有一些分析方法和架构方法可以作为指导思想。而针对这些思想,有一些成熟的代码分析工具,可以对代码质量进行评估
面向对象的设计原则与设计模式:通过使用这些原则和设计模式,保证代码质量和模块的高内聚低耦合,不仅可以保证代码的可维护性,还可以在业务拆分时降低重构成本
领域驱动设计与整洁架构:微服务的难点不在于微服务架构,而在于微服务拆分。而拆分的关键是做出易于拆分的设计,这就需要一些可以落地的分析方法作为指导思想。
微服务架构:服务粒度变细必然会导致管理成本的提升。随着微服务架构的成熟,微服务框架、RPC、服务发现、服务网格、分布式事务等工具几乎可以做到开箱即用,使用这些工具可以更好地对微服务进行治理
业务中台:随着业务不断地成熟,可以被复用的业务逻辑不断清晰。建设业务中台可以有效提升开发效率
2.3 各业务线的数据需要打通
随着业务的发展,业务间数据如何共享与各业务数据冗余/不一致的问题开始出现。解决问题的关键在于搭建大数据平台,将各业务数据集中管理
数据来源:业务数据定期同步,日志收集,客户端数据埋点...
数据处理:ETL,MapReduce 等大数据处理技术
数据使用:数据接口、数据报表、机器学习...
3. (业务的复杂性导致)公司组织架构更加复杂
随着业务规模的扩大,公司的成本也会随之增加。但大部分成本为线性提升,管理成本和沟通成本却是成指数上升的。
3.1 人员沟通成本提升 -> 组织架构的调整
无论 2.2 还是 2.3,技术并不是解决问题的关键,适应于业务的组织架构才是使技术发挥作用的必要条件。但由于是非技术因素,这里不展开讨论。
3.2 企业信息化建设问题
事实上,商业软件的历史比互联网产品的历史要久远的多,因此大部分问题都是有成熟的解决方案的。互联网公司更需要考虑的问题是引入这些系统之后,如何将之与业务系统进行打通,从而提升,而不是降低办公效率。
公司内部 OA
权限系统
文档/任务管理工具
企业邮箱服务
企业内部 IM
...
4. (系统的复杂性导致)开发难度与开发成本提升
当系统解决了其他人的问题之后,复杂的系统,复杂的技术栈,复杂的逻辑就成了程序员自己的问题。
4.1 如何提升研发效率
程序开发本就是一项复杂的工作。而业务越复杂,使用的技术越多,工作的难度就会显著上升。解决问题的关键是集成,配置化,自动化
开发、测试、生产环境的分离
云研发平台:为了抹平开发环境与生产环境的差异,避免"我这里是好的"之类的问题产生,统一的开发环境是必须的,同时
开发工具:除 IDE 之外,脚手架,代码生成工具,代码检查,mock 环境等都会使开发效率得到提升
CI/CD:敏捷开发的基础,
4.2 如何管理复杂的计算设备/资源与服务
技术栈的复杂,集群规模的扩大,使得无论是对集群的管理,还是服务的运维,都成为了挑战。不同的服务依赖的底层系统不同,运维的方法也不尽相同。解决的思路就是构建技术平台,用统一的 API 对集群和服务进行管理,同时将底层能力封装为统一的 API,供业务研发人员使用。这里推荐 Kubernates。
k8s 并不是一项单独的技术,而是一整套完整的生态。包括集群部署,监控,测试,安全,服务部署,CI/CD,serverless,服务网格,服务发现等各类需求,都有多种开源产品可供选择,这里不展开介绍了。
总结
互联网系统演化的驱动力是为了更好的满足用户的需求。而发展的结果则是系统不仅对外提供服务,公司内部的员工,甚至程序员本身也称为了系统的一部分。而这种关联,并不是通过某些特定技术实现的,而是通过业务,数据与通信(组织架构和互联网通信技术)实现的。而随着业务的演化,问题本身会变得越来越复杂,可以直接拿来解决问题的现成技术越来越少,解决问题更重要的是综合的分析能力和分析方法,以及全局的视角。
版权声明: 本文为 InfoQ 作者【Mark】的原创文章。
原文链接:【http://xie.infoq.cn/article/fcedfdce17648d6ee4b761eef】。
本文遵守【CC BY-NC】协议,转载请保留原文出处及本版权声明。
评论