高并发高流量网站架构

目录
 
1.网络层架构 
  1.1 镜像网站技术 
  1.2 CDN内容分发网络——调整服务器的域名解析来实现 
  1.3 应用层分布式设计——查询、定向 

2.交换层架构 
  2.1 第四层交换简介 
  2.2 硬件实现 
  2.3 软件实现——LVS，负载均衡 

3.应用程序层优化 
  3.1 网站服务器程序的选择 
  3.2 数据库选择——mysqL主辅、集群设计 
  3.3 服务器端脚本解析器的选择——JSP、PHP、ASP 
  3.4 可配置性 
  3.5 封装和中间层思想 

4.服务器优化（接收请求的服务器优化） 
  4.1 Socket优化——调相关内核参数，再用命令检测效果 
  4.2 硬盘级缓存——squid 
  4.3 内存级缓存——memcached 
  4.4 CPU与IO均衡 
  4.5 读写分离——文件系统改进 

5.扩容、容错处理 
  5.1 扩容 
  5.2 容错 


1.网络层架构 
  1.1  镜像网站技术 
    
    镜像网站是指将一个完全相同的站点放到几个服务器上，分别有自己的URL，这些服务器上的网站互相称为镜像网站［13］。镜像网站和主站并没有太大差别，或者可以视为主站的拷贝。镜像网站的好处是：如果不能对主站作正常访问（如服务器故障，网络故障或者网速太慢等），仍能通过镜像服务器获得服务。不便之处是：更新网站内容的时候，需要同时更新多个服务器；需要用户记忆超过一个网址，或需要用户选择访问多个镜像网站中的一个，而用户选择的，不一定是最优的。在用户选择的过程中，缺乏必要的可控性。 

          在互联网发展的初期，互联网上的网站内容很少，而且大都是静态内容，更新频率底。但因为服务器运算能力低，带宽小，网速慢，热门网站的访问压力还是很大。镜像网站技术在这种情况下作为一种有效解决方案，被广泛采用。随着互联网的发展，越来越多的网站使用服务器端脚本动态生成内容，同步更新越来越困难，对可控性要求越来越高，镜像技术因为不能满足这类网站的需要，渐渐的淡出了人们的视线。但有一些大型的软件下载站，因为符合镜像网站的条件——下载的内容是静态的，更新频率较低，对带宽，速度要求又比较高，如国外的SourceForge （http://www.SourceForge.net，著名开源软件托管网站），Fedora（http://fedoraproject.org，RedHat赞助的Linux发行版），国内的华军软件园（http://www.onlinedown.net），天空软件站（http://www.skycn.com）等，还在使用这项技术（图1）。 


  1.2  CDN内容分发网络 

          CDN的全称是Content Delivery Network，即内容分发网络。其目的是通过在现有的互联网中增加一层新的网络架构，将网站的内容发布到最接近用户的网络“边缘”，使用户可以就近取得所需的内容，分散服务器的压力，解决互联网拥挤的状况，提高用户访问网站的响应速度。从而解决由于网络带宽小、用户访问量大、网点分布不均等原因所造成的用户访问网站响应速度慢的问题［14］。 

          CDN与镜像网站技术的不同之处在于网站代替用户去选择最优的内容服务器，增强了可控制性。CDN其实是夹在网页浏览者和被访问的服务器中间的一层镜像或者说缓存，浏览者访问时点击的还是服务器原来的URL地址，但是看到的内容其实是对浏览者来说最优的一台镜像服务器上的页面缓存内容。这是通过调整服务器的域名解析来实现的。使用CDN技术的域名解析服务器需要维护一个镜像服务器列表和一份来访IP到镜像服务器的对应表。当一个用户的请求到来的时候，根据用户的IP，查询对应表，得到最优的镜像服务器的IP地址，返回给用户。这里的最优，需要综合考虑服务器的处理能力，带宽，离访问者的距离远近等因素。当某个地方的镜像网站流量过大，带宽消耗过快，或者出现服务器，网络等故障的时候，可以很方便的设置将用户的访问转到另外一个地方（图2）。这样就增强了可控制性。 

  ![11d64441-fe50-33ad-a86b-be42355a2323.jpg](https://qiita-image-store.s3.amazonaws.com/0/61381/fbeb0a8f-9baa-da3a-05dc-c68c14b55f8a.jpeg "11d64441-fe50-33ad-a86b-be42355a2323.jpg")
  
          CDN网络加速技术也有它的局限性。首先，因为内容更新的时候，需要同步更新多台镜像服务器，所以它也只适用于内容更新不太频繁，或者对实时性要求不是很高的网站；其次，DNS解析有缓存，当某一个镜像网站的访问需要转移时，主DNS服务器更改了IP解析结果，但各地的DNS服务器缓存更新会滞后一段时间，这段时间内用户的访问仍然会指向该服务器，可控制性依然有不足。 

          目前，国内访问量较高的大型网站如新浪、网易等的资讯频道，均使用CDN网络加速技术（图3），虽然网站的访问量巨大，但无论在什么地方访问，速度都会很快。但论坛，邮箱等更新频繁，实时性要求高的频道，则不适合使用这种技术。 
![93b47741-fda0-343e-9163-0f5a7387f659.jpg](https://qiita-image-store.s3.amazonaws.com/0/61381/134bc040-8140-90eb-7d72-d35f4627faf8.jpeg "93b47741-fda0-343e-9163-0f5a7387f659.jpg")

 
  1.3  应用层分布式设计 

          新浪播客为了获得CDN网络加速的优点，又必须避免CDN的不足，在应用层软件设计上，采取了一个替代的办法。新浪播客提供了一个供播放器查询视频文件地址的接口。当用户打开视频播放页面的时候，播放器首先连接查询接口，通过接口获得视频文件所在的最优的镜像服务器地址，然后再到该服务器去下载视频文件。这样，用一次额外的查询获得了全部的控制性，而这次查询的通讯流量非常小，几乎可以忽略不计。CDN中由域名解析获得的灵活性也保留了下来：由接口程序维护镜像网站列表及来访IP到镜像网站的对应表即可。镜像网站中不需要镜像所有的内容，而是只镜像更新速度较慢的视频文件。这是完全可以承受的。 

      网络层架构小结 
      
          从整个互联网络的高度来看网站架构，努力的方向是明确的：让用户就近取得内容，但又要在速度和可控制性之间作一个平衡。对于更新比较频繁内容，由于难以保持镜像网站之间的同步，则需要使用其他的辅助技术。 


2.交换层架构 
  2.1 第四层交换简介 

    第四层交换的一个简单定义是：它是一种传输功能，它决定传输不仅仅依据MAC地址(第二层网桥)或源 / 目标IP地址(第三层路由)，而且依据IP地址与 TCP/UDP (第四层) 应用端口号的组合（Socket）［17］。第四层交换功能就像是虚拟IP，指向实际的服务器。它传输的数据支持多种协议，有HTTP、FTP、NFS、 Telnet等。 

          以HTTP协议为例，在第四层交换中为每个服务器组设立一个虚拟IP（Virtue IP，VIP），每组服务器支持某一个或几个域名。在域名服务器（DNS）中存储服务器组的VIP，而不是某一台服务器的真实地址。 

          当用户请求页面时，一个带有目标服务器组的VIP连接请求发送给第四层交换机。第四层交换机使用某种选择策略，在组中选取最优的服务器，将数据包中的目标 VIP地址用实际服务器的IP地址取代，并将连接请求传给该服务器。第四层交换一般都实现了会话保持功能，即同一会话的所有的包由第四层交换机进行映射后，在用户和同一服务器间进行传输 
          
  2.2 硬件实现 
  
  2.3 软件实现 
![cb8d1e4c-246f-3448-afbc-5c0f7319dacf.jpg](https://qiita-image-store.s3.amazonaws.com/0/61381/60e82c49-8de7-dd75-40e8-484e46fd0dc8.jpeg "cb8d1e4c-246f-3448-afbc-5c0f7319dacf.jpg")


    软件四层交换常用的有 Linux上的LVS（Linux Virtual Server），它提供了基于心跳（heart beat）的实时灾难应对解决方案，提高了系统的鲁棒性，同时提供了灵活的VIP配置和管理功能，可以同时满足多种应用需求 


3.应用程序层优化 
  3.1 网站服务器程序的选择 

    经统计［40］，当前互联网上有超过50%的网站主机使用Apache［41］服务器程序。 Apache是开源界的首选Web服务器，因为它的强大和可靠，而且适用于绝大部分的应用场合。但是它的强大有时候却显得笨重，配置文件复杂得让人望而生畏，高并发情况下效率不太高。而轻量级的Web服务器Lighttpd［42］却是后起之秀，基于单进程多路复用技术，其静态文件的响应能力远高于 Apache。 Lighttpd对PHP的支持也很好，还可以通过Fastcgi方式支持其他的语言，比如Python等。虽然Lighttpd是轻量级的服务器，功能上不能跟Apache比，某些复杂应用无法胜任，但即使是大部分内容动态生成的网站，仍免不了会有一些静态元素，比如图片、JS脚本、CSS等等，可以考虑将Lighttpd放在Squid的前面，构成 Lighttpd->Squid->Apache的一条处理链，Lighttpd在最前面，专门处理静态内容的请求，把动态内容请求通过 Proxy模块转发给Squid，如果Squid中有该请求的内容且没有过期，则直接返回给Lighttpd。新请求或者过期的页面请求交由Apache 中的脚本程序来处理。经过Lighttpd和Squid的两级过滤，Apache需要处理的请求大大减少，减少了Web应用程序的压力。同时这样的构架，便于把不同的处理分散到多台计算机上进行，由Lighttpd在前面统一分发。 

          在这种架构下，每一级都是可以进行单独优化的，比如Lighttpd可以采用异步IO方式，Squid可以启用内存来缓存，Apache可以启用MPM （Multi -Processing Modules，多道处理模块）等，并且每一级都可以使用多台机器来均衡负载，伸缩性好。 

          著名视频分享网站YouTube就是选择使用Lighttpd作为网站的前台服务器程序。 

  3.2 数据库选择 
      
      MySQL提供多种后台存储引擎的选择，如MyISAM， Heap， InnoDB，Berkeley Db等。缺省格式为MyISAM。 MyISAM 存储引擎与磁盘兼容的非常好 

![31e79058-e351-3558-ba43-11056763ac55.jpg](https://qiita-image-store.s3.amazonaws.com/0/61381/92be9ac4-897c-bbfe-54de-a6c15c74e186.jpeg "31e79058-e351-3558-ba43-11056763ac55.jpg")

     主辅结构 

     MySQL也有一些它自身的缺陷，如缺乏图形界面，缺乏存储过程， 还不支持触发器，参照完整性，子查询和数据表视图等，但这些功能都在开发者的TO-DO列表当中。这就是开源的力量：你永远可以期待更好。 

          国外的Yahoo!，国内的新浪，搜狐等很多大型商业网站都使用MySQL 作为后台数据库。对于一般的网站系统，无论从成本还是性能上考虑，MySQL应该是最佳的选择。 


  3.3 服务器端脚本解析器的选择 

  3.4 可配置性 

  3.5 封装和中间层思想 


4.服务器优化 
     
     常见的影响服务器的处理速度的因素有：网络连接，硬盘读写，内存空间，CPU速度。 

  4.1 Socket优化 
    
    GNU / Linux 提供了很多可调节的内核参数，可以使用这些参数为服务器进行动态配置，包括影响 Socket 性能的一些重要的选项。这些选项包含在 / proc 虚拟文件系统中。这个文件系统中的每个文件都表示一个或多个参数，它们可以通过 cat 工具进行读取，或使用 echo 命令进行修改。这里仅列出一些影响TCP/IP 栈性能的可调节内核参数 
    如果重启了 GNU / Linux 系统，设置的内核参数都会恢复成默认值。为了将所设置的值作为这些参数的默认值，可以使用 /etc/rc.local 文件，在系统每次启动时自动将这些参数配置成所需要的值。 

  4.2 硬盘级缓存——squid 

     硬盘级别的缓存是指将需要动态生成的内容暂时缓存在硬盘上，在一个可接受的延迟时间范围内，同样的请求不再动态生成，以达到节约系统资源，提高网站承受能力的目的。Linux环境下硬盘级缓存一般使用Squid。当前的Squid可以处理HTTP， FTP， GOPHER， SSL和WAIS等协议。
     Squid默认通过检测HTTP协议头的Expires和 Cache-Control字段来决定缓存的时间。 
     Squid 运行的时候，默认会在硬盘上建两层hash目录，用来存储缓存的Object。它还会在内存中建立一个Hash Table，用来记录硬盘中Object分布的情况。如果Squid配置成为一个Squid集群中的一个的话，它还会建立一个 Digest Table(摘要表)，用来存储其它 Squid 上的Object摘要。当用户端想要的资料本地硬盘上没有时，可以很快的知道应该去集群中的哪一台机器获得。在硬盘空间快要达到配置限额的时候，可以配置使用某种策略（默认使用LRU：Least Recently Used-最近最少用）删除一些Object，从而腾出空间 

    集群中的Squid Server 之间可以有两种关系：第一种关系是：Child 和 Parent。当 Child Squid Server 没有资料时，会直接向 Parent Squid Server 要资料，然后一直等，直到 Parent 给它资料为止。第二种关系是：Sibling 和 Sibling。当 Squid Server 没有资料时，会先向 Sibling 的 Squid Server 要资料，如果 Sibling 没资料，就跳过它向 Parent 要或直接上原始网站去拿。 
    默认配置的Squid，没有经过任何优化的时候，一般可以达到 50% 的命中率［30］（图4）。如果需要，还可以通过参数优化，拆分业务，优化文件系统等办法，使得Squid达到 90% 以上的缓存命中率。 Squid处理TCP连接消耗的服务器资源比真正的HTTP服务器要小的多，当Squid分担了大部分连接，网站的承压能力就大大增强了。 


  4.3 内存级缓存——memcached 

    Memcached也有它的不足。首先它的数据是保存在内存当中的，一旦服务进程重启（进程意外被关掉，机器重启等），数据会全部丢失。其次 Memcached以root权限运行，而且Memcached本身没有任何权限管理和认证功能，安全性不足。第一条是Memcached作为内存缓存服务使用无法避免的，当然，如果内存中的数据需要保存，可以采取更改Memcached的源代码，增加定期写入硬盘的功能。对于第二条，我们可以将 Memcached服务绑定在内网IP上，通过Linux防火墙进行防护。 

  4.4 CPU与IO均衡 

    在一个网站提供的所有功能中，有的功能可能需要消耗大量的服务器端IO资源，像下载，视频播放等，而有的功能则可能需要消耗大量的服务器CPU资源，像视频格式转换，LOG统计等。在一个服务器集群中，当我们发现某些机器上CPU和IO的利用率相差很大的时候，例如CPU负载很高而IO负责很低，我们可以考虑将该服务器上的某些耗CPU资源的进程换成耗IO的进程，以达到均衡的目的。均衡每一台机器的CPU和IO消耗，不仅可以获得更充分的服务器资源利用，而且还能够支持暂时的过载，遇到突发事件，访问流量剧增的时候， 实现得体的性能下降(Graceful performance degradation)［34］，而不是立即崩溃。 

  4.5 读写分离 

  总结 
    
    对于一个高并发高流量的网站来说，任何一个环节的瓶颈都会造成网站性能的下降，影响用户体验，进而造成巨大的经济损失。在全互联网层面，应该使用分布式设计，缩短网站与用户的网络距离，减少主干网上的流量，以及防止在网络意外情况下网站无法访问的问题。在局域网层面，应该使用服务器集群，一方面可以支撑更大的访问量，另一方面也作为冗余备份，防止服务器故障导致的网站无法访问。在单服务器层面，应该配置操作系统，文件系统及应用层软件，均衡各种资源的消耗，消除系统性能瓶颈，充分发挥服务器的潜能。在应用层，可以通过各种缓存来提升程序的效率，减少服务器资源消耗（图6）。另外，还需要合理设计应用层程序，为以后的需求变更，扩容做好准备。 
![b2314e6a-6076-30bf-b3f3-b49c21f2f5c6.jpg](https://qiita-image-store.s3.amazonaws.com/0/61381/58d1b86a-c91c-1cc7-8c58-797cf8a9e3fc.jpeg "b2314e6a-6076-30bf-b3f3-b49c21f2f5c6.jpg")

    
    在每一个层次，都需要考虑容错的问题，严格消除单点故障，做到无论应用层程序错误，服务器软件错误，服务器硬件错误，还是网络错误，都不影响网站服务。