架构师之路系列文章整理

前言

从工程项目的角度,大概很少有像后端开发这样技术概念浩繁,技术栈庞杂的支系。即便是最顶级的架构师,也未必能对整个技术栈上的所有细节都了如指掌,而而对刚入门的工程师来说,单单是搞清楚一些技术概念已经很不容易,更不用说面临具体业务时在众多方案中进行取舍。

正好有个机会需要全面的梳理下有关后端架构的知识,有幸看到沈剑大神的公众号“架构师之路”(微信号:road5858)的系列文章,深入浅出,堪称神作,如果按照一定的顺序读下来,就会对整套后端架构有个概念性的理解。索性就做一把搬运工,以相关文章为骨架,将整个后端架构的知识梳理串编,再补充一些其他的神作使之更加完整。

本文旨在理清后端开发技术栈中的知识骨架,间或对某层技术栈中的一些关键点做些介绍和比对,但不会涉及更加具体的细节。读者如果对某个知识点感兴趣,还需要自行查找相关资料做更深入的研究。

架构概览

先看一张整体架构图,这张图多次出现在架构师之路的系列文章当中:

这是一整套后端系统的逻辑架构,实际应用中根据具体业务而大同小异。最简单的业务也许只需要单机部署WebServer,最复杂的需要大规模并发的业务可能会在每一层上部署集群,但整个后端的技术栈已经基本都体现在图里了。

衡量一个系统架构的重要指标,是高可用(High Availability)、高并发度(High Concurrency),而一个架构师的全部职责就是根据业务目标设计、实现、维护一个可用度,并发度都能满足需求的服务系统。

很多时候,为实现高可用和高并发所采用的手段是类似的,其本质上都是采用适当的“冗余”来增加服务的性能及稳定性。因此,在实际的应用中,很多时候系统架构看起来更像下图:

然而冗余又引入了其他一些问题,如何将请求路由到多个节点?如何在各节点之间同步信息?为了应对这些问题开发出了很多不同的方法,这些方法通常有各自的应用场景及优缺点,而能否根据实际的业务场景,设计选择适当的解决方案就成为考验一名架构师技术能力的重要标尺。

在进入到更详细的讨论之前,先寄出沈剑的几篇神作,这些文章从概化的角度介绍了上述架构中的一些关键点,先通读这几篇文章,有助于理解架构问题的精髓,进而也成为后面知识的有效铺垫。

第一篇:沈剑:究竟啥才是互联网架构“高可用”

第二篇:沈剑:究竟啥才是互联网架构“高并发”

第三篇:沈剑:一分钟了解负载均衡的一切


补充知识:

  1. 知乎:分布式与集群的区别是什么?
  2. 转载:看看腾讯和百度等这样的大型网站系统架构是如何演化的

在请求到达之前

因为我们讨论的是后端架构,所以一切的起始从客户端请求出发的那一刻开始。通常认为,请求的第一站是到达前端服务器,但事实上在这之前还有非常重要的一步“域名解析”。

补充知识中有关于域名解析过程更详细的介绍。但我们更感兴趣的部分,就像前面文章中所提到的,是借助DNS的解析的轮询机制,可以做到有效的水平扩展从而增加系统的并发度(思考:为什么不是可用度?)。

如何使用DNS实现负载均衡?通常域名提供商会提供将同一个域名解析到不同IP地址的服务,更高级一点,服务商还提供将域名解析授权到你自己的DNS服务器的服务。而有关如何自建DNS服务,也可以参考补充知识。

关于使用DNS做负载均衡的场景和价值,沈剑有篇更详细的讨论:

第四篇:沈剑:lvs为何不能完全替代DNS轮询


补充知识:

  1. 转载:DNS解析过程详解
  2. 转载:DNS and Bind详解
  3. 转载:利用dns解析来实现网站的负载均衡

反向代理层

当然,并不是所有业务都需要反向代理,反向代理是为了解决高可用和负载均衡的问题,并且它还有个前提——你得有个集群先。而有关反向代理的方案,除了Nginx,还有LVS、F5等。

从第四篇文章可以看到,F5是硬件方案,性能优于LVS,LVS是四层负载均衡,性能要优于Nginx,但Nginx更贴近业务层,容易实现更多的功能。

有关它们之间的联系,还可以参考以下这篇文章:

第五篇:CSDN: 关于LVS+Nginx为什么会被同时使用的思考


应用层(站点层)

对这一层来说,通常是最容易引起概念混乱的地方(包括本节标题使用了两种描述,以及在架构概览图中使用的 Web-Server 一词都是令许多人理解不一致的根源)。之所以这样,是因为从编程角度,这一层有更细致的功能划分,而不同的解决方案通常只涵盖这些功能中的某个子集,它们时而可以相互配合,时而在功能上又有交叉。

为了对这一层先有个大概的认识,先寄出这篇文章:

第六篇:转载:【译】什么是Web框架?

典型的应用层输入输出,input是客户端发起的GET或POST请求,output是一段HTML内容,这中间的复杂过程,因业务类型的不同而有很多差别,进而衍生出不同的解决方案。但既然input和output是一致的,当然就会有很多技术工具可以为这些业务中相同的部分提供通用的服务。Apache 和 Nginx 就是通用技术工具中最典型的两个,它们帮助开发者解决HTTP层面(即IO的两端)的问题,使开发者能够加关注业务相关的部分,而这些部分中的绝大部分问题都因所谓“动态页面”(参见补充知识2)而起。

在动态网页这件事上,迄今为止已经涌现出N多种解决方案,各种语言,各种框架,各种流派交替盛行,大致盘点下:

CGI

CGI是一种框架接口。HTTP层有Apache,Ngxin这些WebServer搞定,那么业务层应用程序如果想用其他语言或技术来编写怎么办?那么就设定某种接口,WebServer把HTTP解析后的请求发给应用程序,处理后,应用程序把结果通过接口返回WebServer,再由WebServer通过HTTP返回给客户。理论上,只要符合CGI接口规范,应用程序可以用任何语言来实现,事实上早期大量的CGI程序都是 C 或者 Perl 语言编写的。

ASP

早期微软的产品,与Windows+IIS 配套,使用VBScript,Javascript语言,现在已经不像以前那么流行了。微软后来又推出了ASP.NET,算是作为ASP的更新替代产品。

JSP

Sun搞出来的解决方案,用Java编写的服务器程序叫做servlet,并且为了能在服务端提供能运行Java servlet的环境,同时能够与WebServer进行交互,还需要提供一个容器环境,叫做Servlet Container,而当下比较流行的Tomcat在本质上就是一种Servlet Container(可参考补充知识3)。需要说一下,Java系产品在后端开发技术图谱中独树一帜,作为商业产品在技术栈的几乎每一层都有自己的独特实现(可参考补充知识4、5、6),与其他开源系产品形成明显的界限。因此,在后面的章节里,很多时候也会把Java系技术跟其他技术区别开阐述。

PHP

PHP语言天生就是为了Web应用而服务的,因此它通常都能通过CGI(或者 FastCGI)与WebServer结合得很好,各主流WebServer通常也都会内置对PHP的支持。曾经的LAMP(Linux+Apache+MySQL+PHP)几乎成为开发网站的主流首选(一个很重要的原因是免费),目前PHP也是当红的Web开发语言之一。PHP门下的各类框架和组件繁多,可以说应有尽有,顺手列举一些耳熟能详的PHP框架:Lavavel, CodeIgniter, Yii, THinkPHP, Zend, Phalcon, Symfony ...

Python

PHP不同,Python在设计之初并不是专门为了开发Web应用,而是作为一种教学语言被设计出来的,因此它在语言层面上很具美感且功能强大,被称为胶水语言。Web开发也正在越来越多成为Python的使用场景之一,目前比较流行的Python框架有:Django, Tornado, Flask ...

Node.js

Javascript 语言可以说是一种神奇的存在。早年大学里计算机系的课程表里从不会出现这门语言,但这一点也没有妨碍JS在业界扮演越来越重要的角色。在在绝对垄断前端开发领域之后,一些狂热者开始发现JS的语言特性使得它在后端开发领域也具有独特的价值,Node.js就在这种背景下诞生了。


补充知识:

  1. 知乎:tomcat 与 nginx,apache的区别是什么?
  2. 转载:静态页面和动态页面的区别
  3. 知道:servlet与Tomcat的关系
  4. 知乎:如何系统地学习java web技术?
  5. 转载:几张图让你彻底了解JAVASE、JAVAEE、JAVAWEB整个的知识体系
  6. 简书:从懵逼到再入门——JavaEE完整体系架构
  7. 知乎:Java新手如何学习Spring、Struts、Hibernate三大框架?(主要看David的回答)

Service层

先来看一篇高屋建瓴的概要文:

第七篇:沈剑:互联网架构为什么要做服务化?

WebService在本质上起源于远程调用技术,有关这类技术的发展背景可以参看补充知识1。有关WebService和其接口相关的概念,诸如RPC、SOAP、CORBA、RMI、REST等等,很容易让人产生混淆,网上查到的很多东西也都是人云亦云,估计作者自己都没搞明白。所以这里有必要花一些篇幅来对这些概念做些概要的说明。

在WebService的概念出现以前,业界早就有了跨主机远程调用来解决分布式通信的需求,这也是RPC概念的起源(补充知识2)。为了解决RPC的问题,业界涌现出一些解决方案:OMG组织推出的CORBA,Java阵营的RMI,微软阵营的DCOM,等。随着业务需求的不断发展,这些技术也在不断的演变。Java阵营在RMI的基础之上使用EJB规范来解决分布式开发的问题;微软在DCOM失利之后推出了SOAP,而此时SOAP的着眼点已经从分布式系统转入了更广泛的Web服务;CORBA则渐渐衰落。

在Java阵营之外,基于XML的RPC(XML-RPC)曾作为RPC概念的有效实践,但还不够强大,而SOAP正是作为XML-RPC的扩展而发展起来的,有关SOAP更详细的介绍可以自行网搜。随着WebService概念的兴起,SOAP作为WebService中的重要技术得以进一步发展,但这也使得它变得更加臃肿,进而有人开始寻找其他更轻量级的RPC实现方式(如:JSON-RPC)。于此同时,REST的思想开始得到越来越多的关注和追捧。跟SOAP相比,REST更充分地利用HTTP协议本身,因而更加简洁高效。有关两者的对比,可以参考补充知识5.

了解基础概念之后,来一篇跟Service层架构有关的文章:

第八篇:沈剑:微服务架构多“微”才合适?

另外一个需要提及的技术是有关MQ(消息队列),它也是分布式系统中的重要组件,但与RPC有着不同的使用场景。请看下文:

第九篇:沈剑:到底什么时候该使用MQ?


补充知识:

  1. 转载:CORBA的兴衰
  2. 转载:深入浅出 RPC - 浅出篇
  3. 转载:远程通信(RPC,Webservice,RMI,JMS、EJB、JNDI的区别)对比
  4. 转载:corba,ejb ,webservice,rest分布式 区别
  5. 转载:WebService的两种方式SOAP和REST比较

数据层

按照惯例,先来两篇概要文:

第十篇:沈剑:数据库软件架构设计些什么

第十一篇:沈剑:缓存架构设计细节二三事

就重要性而言,数据库在整个后端开发技术栈中几乎可以占半壁江山。就性能而言,数据层往往是整个技术栈中最容易成为瓶颈的一环,因此如何建立高可用,高并发,大容量的数据层是所有技术公司需要解决的重要问题。

主流的经典数据库基本都是采用关系模型,微软系的SQLServer,甲骨文的ORACLE,开源阵营的MySQL是这类产品的三大代表。并且对一般的互联网公司来说,MySQL绝对是首选(因为便宜)。

解决数据层的性能问题,一种典型的方法是通过缓存。最常被用来做缓存工具的是 Memcached 和 Redis,有关两者的对比可以参考补充知识3.

解决数据层高可用的问题,基本思路是通过分布式数据库,而最简单也是最常用的分布式架构就是所谓“主从复制、读写分离”方案,有关其具体介绍可以参看补充知识4. 事实上,分布式数据库的架构可以根据具体业务进行非常灵活的设计,沈剑的文章中也提到58根据自身业务所选择的架构模型。补充知识5中列举了一些可能的架构思路,可以参考。

对简单的分布式数据库模型而言,应用程序完全可以在代码层控制对其的访问方式,但是当面对大型分布式集群的时候,引入中间件来管理访问策略是必要的。有关分布式数据库中间件的介绍,可以参考补充知识1、2.

与此同时,另一种针对传统关系型数据库的特点进行改进的方案被提出来,这就是所谓NoSQL,其代表产品就是MongoDB。有关NoSQL的更多细节,可以参考补充知识6、7.


补充知识:

  1. 转载:MyCat分布式数据库中间件
  2. 转载:开源数据库中间件对比
  3. 转载:Redis与Memcached的区别
  4. 转载:MySQL 主从复制与读写分离概念及架构分析
  5. 转载:数据库高可用架构(MySQL、Oracle、MongoDB、Redis)
  6. 转载:关于NoSQL与SQL的区别
  7. 转载:数据库深度解析 | 从NoSQL历史看未来