架构模式:可复用的架构问题解决方案
现如今,互联网应用面临着高并发、高可用、大数据、安全环境恶劣等挑战,即使是传统的企业应用也需要7x24小时不间断服务,也越来越重视安全和数据的价值。因此,不管是传统企业应用还是还是互联网应用都面临着同样的挑战。而为了解决这一系列问题和挑战,大型的互联网公司在实践中提出了许多解决方案,这些解决方案又被许多企业验证,逐渐形成了软件的架构模式。
一、互联网系统架构模式
架构模式的关键在于复用,问题与场景的可重复性带来了解决方案的可重复使用。互联网架构模式就是试图去描述那些为解决互联网系统高性能、高可用、易扩展、可伸缩、安全等挑战,被很多互联网应用重复使用的一些解决方案,这些解决方案是互联网软件系统的重要组成部分,而掌握这些解决方案和设计思路,可以指导我们进行架构设计。
一般的互联网架构模式包含如下要素:
分层:将系统在横向维度上切分成几个部分,每个部分负责相对单一的职责,然后通过上层对下层依赖和调用组成一个完整的系统。
分割:将系统在纵向维度上切分,将不同功能和服务分割开来,包装成高内聚低耦合的模块单元。
分布式:大型系统通过分层和分割以后,变成独立的模块部署在不同的服务器上,通过远程调用的方式协同工作。分布式意味着解决同样的问题可以使用更多的硬件资源,也就能够支撑更多的用户数和数据量。
集群:分布式部署的服务需要构成统一的集群,通过负载均衡设备通过对外提供服务。
缓存:缓存是改善系统性能的第一手段,在复杂的软件系统中,缓存几乎无处不在。
异步:将一个业务操作分成多个阶段,每个阶段之间通过共享数据的方式异步执行进行协作。在单一服务器内部通过多线程的方式实现异步,而分布式系统中,多个服务器通过消息队列实现异步。
冗余:互联网应用需要7x24小时不间断提供服务,但服务器总会出现故障。想要在服务器故障时应用依然可以对外提供服务,且数据不丢失,就需要一定程度的服务器冗余运行,数据冗余备份。
自动化:自动化测试、自动化发布可有效减少系统故障;自动化运维可保障系统出现故障快速恢复或通知相关人员。
安全:互联网的开放性使其从诞生之初就面临巨大的安全挑战,虽然目前已有不少的措施来应对这些挑战,但新的攻击手段层出不穷,我们也只能打起精神,努力堵住系统可能存在的漏洞,预防可能的攻击。
这些要素相互组合相互作用,构成了一个典型的互联网系统架构。我们以微博架构为例,简单说明架构模式在微博的应用,下面是微博在2010年时对外分享的架构图。
从横向来看,整个系统分为3个层次,最上层是API,各种客户端与第三方应用,通过调用API集成到微博的系统中,共同组成一个生态系统。中间层是平台服务和应用服务层,是整个业务的基础。而最下层则提供数据服务和其他基础技术服务,这些服务支撑了新浪微博的海量数据和高并发访问,是整个系统的技术基础。
从纵向来看,中间的平台服务与应用服务层根据不同的业务职责,又被分割成独立的服务模块。而下层的基础服务又根据职责的不同,被分割成数据库、缓存、存储、消息队列、搜索等数据服务,它们之间相互独立,对上层提供支撑服务。
这些被分层和分割后的业务模块与基础技术模块分布式部署,每个模块都部署在一组独立的服务器集群上,通过远程调用的方式进行依赖访问。
在线用户的微博和近期微博缓存在分布式缓存集群中,对于微博操作中最常见的“刷微博”操作,几乎全部都是缓存访问操作,可以获得很好的系统性能。
为解决系统的可靠性问题,微博启用多个数据中心,用户就近访问附近数据中心,可加快用户访问速度,改善系统性能,同时也是数据冗余复制的灾备中心,所有的用户数据和微博数据通过远程消息系统在不同数据中心间同步,以防止用户数据丢失。
除此之外,微博还开发有一系列自动化工具用于改善运维水平;一些列安全策略来保障系统和用户数据安全。
二、架构模式实践
模式的作用在于解决问题,在架构设计之初一定要识别出要解决的问题是什么?而不是直接照搬大公司的解决方案。我经历过一个小系统,为了高并发和高可用,上了大量中间件和服务器,结果导致系统的复杂度直线上升,服务器成本也居高不下。到后来,由于系统确实没有多少用户,就回收了很多资源。因此,好的设计不是模仿,更不是生搬硬套某些模式,而是对问题深刻理解后的创造与创新。下面是一些在架构设计过程中可能遇到的一些问题,做一些简单的探讨。
2.1 服务如何拆分
很多公司都在考虑微服务架构,自己也做了快五年时间,大部分微服务的坑都踩过。除开组织结构、运维层面等因素,最大的坑就是服务拆分。
首先,一定要限制微服务数量。很多团队在一开始根据业务对系统进行拆分,觉得什么功能都可以被拆分成一个服务,到最后导致服务数量爆了。
我们团队最开始也这样,一个系统上了20多个微服务,开始还好,毕竟按照最初的需求,各个服务相互独立,互不影响。但随着业务的发展,单从业务层面来说,已经很难把某些业务完全独立,都是相互影响的。后面新增一个需求要同时更新好几个服务,如果这些服务是由多个团队负责,那简直就是灾难。
因此,我觉得服务拆分的第一原则,一定是要控制好服务数量,最好的情况是两个人负责一个服务,或者两个人同时负责两三个服务。即在每个服务都有人员备份的同时,让每个人负责尽量少的服务。
其次,再考虑业务因素和组织结构。业务因素,最重要的就是考虑边界问题,这个不同的团队都有自己的方法,这里就不再细说。整个系统由一个团队负责最好,如果是多个团队,最好是把系统按:公共服务、核心业务、后台管理、基础组件四个维度来拆分,分给不同的团队,然后团队内部自己再拆。公共服务类似于认证授权、邮件短信等业务;核心业务就是系统最主要的业务;后台管理就是公司内部的运营系统;基础组件则是一些中间件和基础框架的开发与维护等等。
最后,再从技术角度考虑,比如某些业务在性能、安全等方面有较高的需求,可以单独拆分出来,这样也比较好分配人力和硬件资源。
2.2 技术架构如何抓大放小
架构的目的是解决问题,但解决问题的成本有大有小,一个衡量的标准就是收益比。也就是说,我们如何用最小的人力、资源、时间成本来解决问题?下面是曹政(caoz)的几点建议,更详细的内容可直接阅读 技术架构如何抓大放小。
舍弃不必要的诉求和所需要的资源
比如,我一直搞不懂为什么系统中的所有删除都要是逻辑删除。什么是无用功,这就是。浪费资源去记录一些永远无人关心的沉默数据,还要为这些数据付出性能方面的代价。
容忍存在一些不那么高的精确度
有些数据,能不实时就不实时统计,在系统上尽量做异步更新或提前计算,特别是高并发请求下,容忍一定程度的数据丢失风险。
忙闲数据的区分处理
这个相信大家比我有经验,就不说啦
必要时响应降级
整个系统出现严重故障时,仅维持最基本和必须的功能保证用户最基本的体验。比如,以前腾讯邮箱出现严重状况时,信件可读,但无法发送和回复。在这种时候,响应降级的设计就很关键。
响应降级,你就必须明确,系统设计里,哪部分是最核心的,最基础的服务,在其他模块全部崩溃的时候,依然可以幸存的,要尽可能独立出来,做足准备。这是关键时刻救命的设计,可以在最危险的时候,减少你用户或者客户的流失。而且,也可以有效减少你紧急恢复系统时,疲于奔命的压力。
最后
牛逼的架构不是看它有多复杂多庞大,而是看它解决同样的问题有多简单。
极客大学架构师训练营第四周学习总结
参考资料
版权声明: 本文为 InfoQ 作者【NORTH】的原创文章。
原文链接:【http://xie.infoq.cn/article/82b77bddfefd328b76d31faa7】。未经作者许可,禁止转载。
评论 (6 条评论)