架构体系分层图

文章插图
在上图中我们描述了Web系统架构中的组成部分 。并且给出了每一层常用的技术组件/服务实现 。需要注意以下几点:
- 系统架构是灵活的,根据需求的不同,不一定每一层的技术都需要使用 。例如:一些简单的CRM系统可能在产品初期并不需要K-V作为缓存;一些系统访问量不大,并且可能只有一台业务服务器存在,所以不需要运用负载均衡层 。
- 业务系统间通信层并没有加入传统的HTTP请求方式 。这是因为HTTP请求-响应的延迟比较高,并且有很多次和正式请求无关的通信(这在下面的内容中会详细讲到) 。所以,传统的HTTP请求方式并不适合在两个高负载系统之间使用,其更多的应用场景是各种客户端(WEB、IOS、Android等)->服务器端的请求调用 。
- 我们把业务编码中常使用的缓存系统归入到数据存储层,是因为类似于redis这样的K-V存储系统,从本质上讲是一种键值数据库 。为什么Redis会很快以至于可以作为缓存使用,我将在随后的文章中进行详细的描述 。
- 还有一点需要注意的是,上面架构图中的每层之间实际上不存在绝对的联系(例如负载层一定会把请求转送的业务层,这样的必然性是不存在的),在通常情况下各层是可以跨越访问的 。举例说明:如果HTTP访问的是一张图片资源,负载层不会把请求送到业务层,而是直接到部署的分布式文件系统上寻找图片资源并返回 。再比如运用LVS做MySQL负载时,负载层是直接和数据存储层进行合作 。
这里我们所说的负载分配层,是单指利用软件实现的计算机系统上的狭义负载均衡 。一个大型(日PV一亿+)、中型(日PV一千万+)Web业务系统,是不可能只有一个业务处理服务,而是多台服务器同时进行某一个相同业务的服务 。所以我们需要根据业务形态设计一种架构方式,将来自外部客户端的业务请求分担到每一个可用的业务节点上 。如下图所示:

文章插图
负载层还有一个作用,是根据用户的请求规则,将不同的请求类型分派到不同的服务器上 。例如:如果某一个HTTP请求是请求一张图片,那么负载层会直接到图片存储介质上寻找相应的图片;如果某一个HTTP请求是提交的一张订单,那么负载层会根据规则将这张订单提交发送到指定的“订单服务”节点上 。
不同的业务需求,使用的负载层方案也是不同的,这就考验架构师的方案选择能力 。例如Nginx只能处理TCP/IP协议的之上应用层HTTP协议,如果要处理TCP/IP协议,则要按照第三方的TCP-Proxy-Module模 。更好的直接在TCP/IP层负载的方案,是使用HAProxy 。
常用的负载层架构方式包括:
- 独立的Nginx负载或HAProxy方案
- LVS(DR)+ Nginx方案
- DNS轮询 + LVS + Nginx方案
- 智能DNS(DNS路由) + LVS + Nginx方案
【标准Web系统的架构分层,看看没错】随后的文章中将详细介绍这些负载架构方案以及这些方案的变形 。
业务服务层和通信层概述
通俗来讲就是我们的核心业务层,订单业务、施工管理业务、诊疗业务、付款业务、日志业务等等 。如下图所示:

文章插图
很明显在中大型系统中,这些业务不可能是独立存在的,一般的设计要求都会涉及到子系统间脱耦:即X1系统除了知晓底层支撑系统的存在外(例如用户权限系统),X1系统不需要知道和它逻辑对等的X2系统的存在就可以工作 。这种情况下要完成一个较复杂业务,子系统间调用又是必不可少的:例如A业务在处理成功后,会调用B业务进行执行;A业务在处理失败后,会调用C业务进行执行;又或者A业务和D业务在某种情况下是不可分割的整体,只有同时成功才成功,其中有一个失败整个大的业务过程都失败 。如下图所示:

文章插图
这样一来业务间的通信层又是一个逃不开的话题 。在随后的文章中,我们将以Alibaba的Dubbo框架、基于AMQP协议的消息队列和Kafka消息队列技术的原理和使用方式,来讲解业务通信层技术,特别是业务通信层的技术选型注意事项 。
