大型网站架构的演进最开始都是由小及大慢慢演变过来的,任何一个好的架构都不是设计出来的,是通过业务发展迭代而来的,这个观点我是赞同的。对于网站架构技术很是有兴趣,一直持续关注学习架构技术,本次想经过大型网站技术发展历程,剖析大型网站技术架构模式,深刻分析大型互联网架构设计。这篇文章咱们只关注架构的演变历程。
经过电商业务为例,该系统的功能有用户模块【用户注册和管理】、商品模块【商品展现和管理】、交易模块【建立交易和管理】。经过图例分析一个最初从单台LAMP怎么发展到庞大的分布架构体系。css
线上系统高可用参考指标:html
网站程序用到的开源框架如maven+spring+struct+hibernate、maven+spring+springmvc+mybatis;网站初期,咱们常常会用单机跑全部的程序和软件。一般由app server 和DB server组成,如tomcat和mysq;最后经过JDBC进行数据库的链接和操做。前端
通常5万pv到30万pv访问量,结合内核参数调优、web应用性能参数调优、数据库调优,基本上可以稳定的运行。mysql
随着网站的发展当访问量逐渐增大,服务器的负载慢慢提升,系统的压力愈来愈大,响应速度愈来愈慢,这个时候比较明显的是数据库和应用互相影响,应用出问题了,数据库也很容易出现问题,而数据库出问题的时候,应用也容易出问题。在服务器尚未超载的时候,咱们应该提早作好准备,提高网站的负载能力。假如咱们代码层面已难以优化,在不提升单台机器的性能的状况下,将应用和数据库从物理上分离,增长机器是一个不错的方式,不只能够有效地提升系统的负载能力,并且性价比高。此时咱们能够把数据库、web服务器拆分开来,这样不只提升了单台机器的负载能力,也提升了容灾能力。nginx
随着用户量的增大、对带宽需求的增大、对CPU处理能力的增大;不足以融合全部用户的需求了,或者网站业务量的需求了。此处不多也不该该直接就对它作负载均衡式的扩展,由于数据同步很麻。因此咱们架构扩展,不会上来就直接作负载均衡式的每一组组件当作一个总体来进行扩展,而是功能上切割 。这个时候技术上没有什么新的要求,但你发现确实起到效果了,系统又恢复到之前的响应速度了,而且支撑住了更高的流量,而且不会由于数据库和应用造成互相的影响。web
随着访问量继续增长,单台应用服务器已经没法知足需求了。假设数据库服务器没有压力,咱们能够把应用服务器从一台变成了两台甚至多台,把用户的请求分散到不一样的服务器中,从而提升负载能力。此时咱们应该选择一款合适的负载均衡产品,通常来说keepalived配合上ipvsadm作负载均衡,可谓是神器。这一阶段是须要掌握更多基础知识的关键节点。如下可使用DNS解析对用户请求作负载均衡:redis
须要注意:负载均衡产品的选择、负载均衡算法的选择、用户session保持的问题、应用占用资源的角度选择合理的服务器配置。
解决方案:根据如下技术特性选择适合业务的产品、技术。例如nginx+keepalived一台服务器、apache+tomcat一台服务器、mysql一台服务器。算法
三种负载均衡器的优缺点说明以下:摘自(互联网)
LVS的优势:
一、抗负载能力强、工做在第4层仅做分发之用,没有流量的产生,这个特色也决定了它在负载均衡软件里的性能最强的;无流量,同时保证了均衡器IO的性能不会受到大流量的影响;
二、工做稳定,自身有完整的双机热备方案,如LVS+Keepalived和LVS+Heartbeat;
三、应用范围比较广,能够对全部应用作负载均衡;
四、配置性比较低,这是一个缺点也是一个优势,由于没有可太多配置的东西,因此并不须要太多接触,大大减小了人为出错的概率;
LVS的缺点:
一、软件自己不支持正则处理,不能作动静分离,这就凸显了Nginx/HAProxy+Keepalived的优点。
二、若是网站应用比较庞大,LVS/DR+Keepalived就比较复杂了,特别是后面有Windows Server应用的机器,实施及配置还有维护过程就比较麻烦,相对而言,Nginx/HAProxy+Keepalived就简单多了。spring
Nginx的优势:
一、工做在OSI第7层,能够针对http应用作一些分流的策略。好比针对域名、目录结构。它的正则比HAProxy更为强大和灵活;
二、Nginx对网络的依赖很是小,理论上能ping通就就能进行负载功能,这个也是它的优点所在;
三、Nginx安装和配置比较简单,测试起来比较方便;
四、能够承担高的负载压力且稳定,通常能支撑超过几万次的并发量;
五、Nginx能够经过端口检测到服务器内部的故障,好比根据服务器处理网页返回的状态码、超时等等,而且会把返回错误的请求从新提交到另外一个节点;
六、Nginx不只仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP如今也是很是流行的web环境,大有和LAMP环境平起平坐之势,Nginx在处理静态页面、特别是抗高并发方面相对apache有优点;
七、Nginx如今做为Web反向加速缓存愈来愈成熟了,速度比传统的Squid服务器更快,有需求的朋友能够考虑用其做为反向代理加速器;
Nginx的缺点:
一、Nginx不支持url来检测。
二、Nginx仅能支持http和Email,这个它的弱势。
三、Nginx的Session的保持,Cookie的引导能力相对欠缺。sql
HAProxy的优势:
一、HAProxy是支持虚拟主机的,能够工做在四、7层(支持多网段);
二、可以补充Nginx的一些缺点好比Session的保持,Cookie的引导等工做;
三、支持url检测后端的服务器;
四、它跟LVS同样,自己仅仅就只是一款负载均衡软件;单纯从效率上来说HAProxy更会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的;
五、HAProxy能够对Mysql读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,不过在后端的MySQL slaves数量超过10台时性能不如LVS;
六、HAProxy的算法较多,达到8种;
负载均衡的基础技术:
一、http重定向。HTTP重定向就是应用层的请求转发,用户的请求到了HTTP重定向负载均衡服务器,根据算法要求用户重定向,浏览器自动从新请求实际服务器的IP地址。
优势:简单
缺点:性能较差
二、DNS域名解析负载均衡。DNS域名解析负载均衡就是在用户请求DNS服务器,获取域名对应的IP地址时,DNS服务器直接解析到负载均衡后的服务器IP。
优势:使用DNS省心,不用咱们去维护。
缺点:使用DNS,它不具有故障检测功能,DNS解析结果会被缓存所以效果通常,DNS负载均衡多数为商业产品,其功能、管理权限有限。
三、反向代理服务器。反向代理服务器转发的请求在HTTP协议层面,所以也叫应用层负载均衡。用户的请求到达反向代理服务器,由反向代理服务器根据算法转发到具体的服务器。反向代理软件经常使用的有apache、nginx。
优势:部署简单。
缺点:反向代理服务器是全部请求和响应的分发服务器,其性能可能会成为瓶颈。特别是上传大文件。
四、IP层负载均衡。用户的请求到达负载均衡器后,经过修改请求的目的IP地址,实现负载均衡。表明实现LVS的NAT模式
优势:性能更好。
缺点:负载均衡器的宽带成为瓶颈。
五、数据链路层负载均衡。用户的请求到达负载均衡器后,经过修改请求的mac地址,实现负载均衡。与IP负载均衡不一样当请求访问完服务器以后,直接返回客户而无需再通过负载均衡器。表明实现LVS的DR模式
常见的调度算法:摘自(互联网)
一、rr 轮询调度算法。顾名思义,轮询分发请求。
优势:实现简单
缺点:不考虑每台服务器的处理能力
二、wrr 加权调度算法。咱们给每一个服务器设置权值weight,负载均衡调度器根据权值调度服务器,服务器被调用的次数跟权值成正比。
优势:考虑了服务器处理能力的不一样
三、sh 原地址散列:提取用户IP,根据散列函数得出一个key,再根据静态映射表,查处对应的value,即目标服务器IP。过目标机器超负荷,则返回空。
四、dh 目标地址散列:同上,只是如今提取的是目标地址的IP来作哈希。
优势:以上两种算法的都能实现同一个用户访问同一个服务器。
五、lc 最少链接。优先把请求转发给链接数少的服务器。
优势:使得集群中各个服务器的负载更加均匀。
六、wlc 加权最少链接。在lc的基础上,为每台服务器加上权值。算法为:(活动链接数*256+非活动链接数)÷权重 ,计算出来的值小的服务器优先被选择。
优势:能够根据服务器的能力分配请求。
七、sed 最短时间望延迟。其实sed跟wlc相似,区别是不考虑非活动链接数。算法为:(活动链接数+1)*256÷权重,一样计算出来的值小的服务器优先被选择。
八、nq 永不排队。改进的sed算法。咱们想一下什么状况下才能“永不排队”,那就是服务器的链接数为0的时候,那么假若有服务器链接数为0,均衡器直接把请求转发给它,无需通过sed的计算。
九、LBLC 基于局部性的最少链接。均衡器根据请求的目的IP地址,找出该IP地址最近被使用的服务器,把请求转发之,若该服务器超载,最采用最少链接数算法。
十、LBLCR 带复制的基于局部性的最少链接。均衡器根据请求的目的IP地址,找出该IP地址最近使用的“服务器组”,注意,并非具体某个服务器,而后采用最少链接数从该组中挑出具体的某台服务器出来,把请求转发之。若该服务器超载,那么根据最少链接数算法,在集群的非本服务器组的服务器中,找出一台服务器出来,加入本服务器组,而后把请求转发之。
session会话保持:
session sticky
ip based
cookie based
session replication
session server
一、Session Sticky。始终将同一个请求者的链接定向至同一个RS(第一次请求时仍由调度方法选择);没有容错能力,有损均衡效果。常见的算法有ip_hash法,即上面提到的两种散列算法。
优势:实现简单。
缺点:无高可用,反均衡。
二、Session Replication。在RS之间同步session,所以每一个RS持集群中全部的session;对于大规模集群环境不适用。
优势:减轻负载均衡服务器的压力,能够随意调度。
缺点:带宽、内存占用量大,并发能力有限。
三、Session Server:利用单独部署的服务器来统一管理session; 实现了session和应用服务器的解耦。
优势:相比session replication的方案,集群间对于宽带和内存的压力减小了不少。
缺点:须要维护存储session的数据库。
四、Cookie Base:cookie base就是把session存在cookie中,由浏览器来告诉应用服务器用户的session是什么,一样实现了session和应用服务器的解耦。
优势:实现简单,基本免维护。
缺点:cookie长度限制,安全性低,宽带消耗。
应用从资源占用的角度分类:
一、CPU Bound 【CPU密集型】通常指aap server
二、IO Bound 【IO密集型】通常指db server
有了以上理论经验,根据业务咱们能够从新对架构演进为如下方案:
前面几个阶段咱们都是假设后端数据库负载没问题,但随着访问量的增大,数据库的负载也在慢慢增高。那么可能有人立刻想到跟应用服务器同样,把数据库一分为二再负载均衡便可。但对于数据库来讲,并无那么简单。假如咱们简单的把数据库一分为二,而后对于数据库的请求,分别负载到A机器和B机器,那么显然会形成两台数据库数据不一致的问题。那么对于这种状况,咱们能够先考虑使用读写分离的方式。
须要注意:引用MySQL主从势必会面临的问题,数据复制的问题、应用选择数据源的问题
解决方案:使用MySQL自带的master+slave的方式实现主从复制。采用第三方数据库中间件,例如mycat。mycat是从cobar发展而来的。mycat目前是国内比较好的mysql开源数据库分库分表中间件。
MySQL对于全局搜索能力支持不强,MySQL只对MyISAM引擎作全文索引但不支持事务,而MySQL对InnoDB引擎不支持全文索引。当一个站点到了这一个阶段其用户搜索量是很是大的。作为一个电商站点的交易达成有70%是经过搜索进行的,由此像这种愈来愈多的搜索需求使得咱们数据库根本就没办法应付这种须要,由于每一次搜索都是一次全面查询,经常对模糊查找力不从心,即便作了读写分离,这个问题还未能解决。咱们要想应付这种需求,通常只能本身构建搜索引擎来缓解读库的压力。
搜索引擎并不能替代数据库,他解决了某些场景下的“读”的问题,是否引入搜索引擎,须要综合考虑整个系统的需求。引入搜索引擎后的系统结构:
一、页面缓存
web服务器压力较大时,若是让站点的一部份内容能缓存,一部份内容不能缓存,咱们可使用ESI动态缓存技术。web缓存服务器还能够对jpg、jpeg、gif、png、html、css、js格式的页面作缓存。例如:varnish, squid
二、数据缓存
随着访问量的增长,逐渐出现了许多用户访问同一部份内容的状况,对于这些比较热门的内容,不必每次都从数据库读取,咱们可使用缓存技术。例如:memcached, redis
优势:减轻数据库的压力、大幅度提升访问速度
缺点:须要维护缓存服务器、提升了编码的复杂性
缓存服务器集群的调度算法不一样与上面提到的应用服务器和数据库,最好采用“一致性哈希算法”。
当访问量逐渐增大,单一应用增长机器带来的效果不明显,须要考结合业务考虑数据库拆分,来提高系统运行效率。咱们的网站演进到如今,交易、商品、用户的数据都还在同一个数据库中。尽管采起了增长缓存,读写分离的方式,但随着数据库的压力继续增长,数据库的瓶颈愈来愈突出,此时主库写操做压力只能作数据库拆分,咱们能够有垂直拆分和水平拆分两种选择。
一、垂直拆分:把数据库中不一样的业务的数据拆分到不一样的数据库服务器中。
二、水平拆分:把一个单独的表中的数据拆分到多个不一样的数据库服务器上。
随着业务的发展,业务愈来愈多,应用愈来愈大。咱们须要考虑如何避免让应用愈来愈臃肿。这就须要把应用拆开,从一个应用变为俩个甚至更多。仍是以咱们上面的例子,咱们能够把用户、商品、交易拆分开。变成“用户、商品”和“用户,交易”两个子系统。
须要注意:这样拆分后,可能会有一些相同的代码,如用户相关的代码,商品和交易都须要用户信息,因此在两个系统中都保留差很少的操做用户信息的代码。如何保证这些代码能够复用是一个须要解决的问题。
解决方案:经过走服务化的路线来解决,把公共的服务拆分出来,造成一种服务化的模式,简称SOA。
服务化以后的系统结构:
须要注意:如何进行远程的服务调用
解决方案:咱们能够经过引入消息中间件来解决
随着网站的继续发展,咱们的系统中可能出现不一样语言开发的子模块和部署在不一样平台的子系统。此时咱们须要一个平台来传递可靠的,与平台和语言无关的数据,而且可以把负载均衡透明化,能在调用过程当中收集调用数据并分析之,推测出网站的访问增加率等等一系列需求,对于网站应该如何成长作出预测。开源消息中间件有阿里的dubbo,能够搭配Google开源的分布式程序协调服务zookeeper实现服务器的注册与发现。
引入消息中间件后的结构:
三层架构(3-tier architecture) 一般意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。区分层次的目的即为了“高内聚低耦合”的思想。在软件体系架构设计中,分层式结构是最多见,也是最重要的一种结构。微软推荐的分层式结构通常分为三层,从下至上分别为:数据访问层、业务逻辑层(又或称为领域层)、表示层。(百度百科)
微服务的特色:
单一职责:微服务中每个服务都对应惟一的业务能力,作到单一职责。
微:微服务的服务拆分粒度很小,例如一个用户管理就能够做为一个服务。每一个服务虽小,但“五脏俱全”。
面向服务:面向服务是说每一个服务都要对外暴露服务接口API。并不关心服务的技术实现,作到与平台和语言无关,也不限定用什么技术实现,只要提供Rest的接口便可。
自治:自治是说服务间互相独立,互不干扰
团队独立:每一个服务都是一个独立的开发团队,人数不能过多。
技术独立:由于是面向服务,提供Rest接口,使用什么技术没有别人干涉
先后端分离:采用先后端分离开发,提供统一Rest接口,后端不用再为PC、移动段开发不一样接口
数据库分离:每一个服务都使用本身的数据源
部署独立,服务间虽然有调用,但要作到服务重启不影响其它服务。有利于持续集成和持续交付。每一个服务都是独立的组件,可复用,可替换,下降耦合,易维护。
架构优化:• 以用户为中心,提供快速的网页访问体验。主要参数有较短的响应时间,较大的并发处理能力,较高的吞吐量,稳定的性能参数;• 可分为前端优化,应用层优化,代码层优化,存储层优化;• 前端优化:网站业务逻辑以前的部分;• 浏览器优化:减小Http请求数,使用浏览器缓存,启用压缩,Css Js位置,Js异步,减小Cookie传输;• CDN加速,反向代理;• 应用层优化:处理网站业务的服务器。使用缓存,异步,集群;• 代码优化:合理的架构,多线程,资源复用(对象池,线程池等),良好的数据结构,JVM调优,单例,Cache等;• 存储优化:缓存,固态硬盘,光纤传输,优化读写,磁盘冗余,分布式存储(HDFS),NOSQL等。