动态应用,是相对于网站静态内容而言,是指以c/c++、php、Java、perl、.net等服务器端语言开发的网络应用软件,好比论坛、网络相册、交友、BLOG等常见应用。动态应用系统一般与数据库系统、缓存系统、分布式存储系统等密不可分。php
大型动态应用系统平台主要是针对于大流量、高并发网站创建的底层系统架构。大型网站的运行须要一个可靠、安全、可扩展、易维护的应用系统平台作为支撑,以保证网站应用的平稳运行。css
大型动态应用系统又可分为几个子系统:html
1)Web前端系统前端
2)负载均衡系统java
3)数据库集群系统mysql
4)缓存系统linux
5)分布式存储系统nginx
6)分布式服务器管理系统c++
7)代码分发系统web
结构图:
为了达到不一样应用的服务器共享、避免单点故障、集中管理、统一配置等目的,不以应用划分服务器,而是将全部服务器作统一使用,每台服务器均可以对多个应用提供服务,当某些应用访问量升高时,经过增长服务器节点达到整个服务器集群的性能提升,同时使他应用也会受益。该Web前端系统基于Apache/Lighttpd/Eginx等的虚拟主机平台,提供PHP程序运行环境。服务器对开发人员是透明的,不须要开发人员介入服务器管理
负载均衡系统分为硬件和软件两种。硬件负载均衡效率高,可是价格贵,好比F5等。软件负载均衡系统价格较低或者免费,效率较硬件负载均衡系统低,不过对于流量通常或稍大些网站来说也足够使用,好比lvs, nginx。大多数网站都是硬件、软件负载均衡系统并用。
结构图:
因为Web前端采用了负载均衡集群结构提升了服务的有效性和扩展性,所以数据库必须也是高可靠的,才能保证整个服务体系的高可靠性,如何构建一个高可靠的、能够提供大规模并发处理的数据库体系?
咱们能够采用如上图所示的方案:
1) 使用 MySQL 数据库,考虑到Web应用的数据库读多写少的特色,咱们主要对读数据库作了优化,提供专用的读数据库和写数据库,在应用程序中实现读操做和写操做分别访问不一样的数据库。
2) 使用 MySQL Replication 机制实现快速将主库(写库)的数据库复制到从库(读库)。一个主库对应多个从库,主库数据实时同步到从库。
3) 写数据库有多台,每台均可以提供多个应用共同使用,这样能够解决写库的性能瓶颈问题和单点故障问题。
4) 读数据库有多台,经过负载均衡设备实现负载均衡,从而达到读数据库的高性能、高可靠和高可扩展性。
5) 数据库服务器和应用服务器分离。
6) 从数据库使用BigIP作负载均衡。
缓存分为文件缓存、内存缓存、数据库缓存。在大型Web应用中使用最多且效率最高的是内存缓存。最经常使用的内存缓存工具是Memcached。使用正确的缓存系统能够达到实现如下目标:
一、使用缓存系统能够提升访问效率,提升服务器吞吐能力,改善用户体验。
二、减轻对数据库及存储集服务器的访问压力。
三、Memcached服务器有多台,避免单点故障,提供高可靠性和可扩展性,提升性能。
结构图:
Web系统平台中的存储需求有下面两个特色:
1) 存储量很大,常常会达到单台服务器没法提供的规模,好比相册、视频等应用。所以须要专业的大规模存储系统。
2) 负载均衡cluster中的每一个节点都有可能访问任何一个数据对象,每一个节点对数据的处理也能被其余节点共享,所以这些节点要操做的数据从逻辑上看只能是一个总体,不是各自独立的数据资源。
所以高性能的分布式存储系统对于大型网站应用来讲是很是重要的一环。(这个地方须要加入对某个分布式存储系统的简单介绍。)
结构图:
随着网站访问流量的不断增长,大多的网络服务都是以负载均衡集群的方式对外提供服务,随之集群规模的扩大,原来基于单机的服务器管理模式已经不可以知足咱们的需求,新的需求必须可以集中式的、分组的、批量的、自动化的对服务器进行管理,可以批量化的执行计划任务。
在分布式服务器管理系统软件中有一些比较优秀的软件,其中比较理想的一个是Cfengine。它能够对服务器进行分组,不一样的分组能够分别定制系统配置文件、计划任务等配置。它是基于C/S 结构的,全部的服务器配置和管理脚本程序都保存在Cfengine Server上,而被管理的服务器运行着 Cfengine Client 程序,Cfengine Client经过SSL加密的链接按期的向服务器端发送请求以获取最新的配置文件和管理命令、脚本程序、补丁安装等任务。
有了Cfengine这种集中式的服务器管理工具,咱们就能够高效的实现大规模的服务器集群管理,被管理服务器和 Cfengine Server 能够分布在任何位置,只要网络能够连通就能实现快速自动化的管理。
结构图:
随着网站访问流量的不断增长,大多的网络服务都是以负载均衡集群的方式对外提供服务,随之集群规模的扩大,为了知足集群环境下程序代码的批量分发和更新,咱们还须要一个程序代码发布系统。
这个发布系统能够帮咱们实现下面的目标:
1) 生产环境的服务器以虚拟主机方式提供服务,不须要开发人员介入维护和直接操做,提供发布系统能够实现不须要登录服务器就能把程序分发到目标服务器。
2) 咱们要实现内部开发、内部测试、生产环境测试、生产环境发布的4个开发阶段的管理,发布系统能够介入各个阶段的代码发布。
3) 咱们须要实现源代码管理和版本控制,SVN能够实现该需求。
这里面可使用经常使用的工具Rsync,经过开发相应的脚本工具实现服务器集群间代码同步分发。
主体架构能够基于 Struts 1.X/2.X,固然有不少更好的控制层框架供选择,以快速敏捷为准则吧。
抽象出核心库封装 控制器和中间层的操做。
在大规模集群环境下,session复制会引发严重的性能问题。考虑用 集群缓存 + cookie验证 代替session实现权限控制吧。
二、Cache层
配置 Memcache 组成集群缓存
对 Memcache 客户端进行封装
Memcached 节点组成池,调用示意:opList (BizName, 策略 ...)
三、中间层
“中间层”能够理解为基于应用和数据之间的层次。它被设计用来为Web应用提供:数据缓存 和 对应用透明的数据访问——即应用不须要考虑数据表拆分的问题。以服务的方式提供对存储层的高性能调用以及分布式计算。可供选择的框架:ICE 、Hadoop 直接基于Memcache开发(减小复杂度,推荐)
四、存储
推荐MySQL,理由:免费,通过实践检验,有大量成熟的案例、解决方案、技术支持。
小规模:一个 data table 维护存储服务器阵列,内容 -> mount ……
大规模:Master-Slave模式+MySQL Proxy,实现数据库读写分离。在中间层的包装下,可作以下扩展,以支持更大规模的数据存取:
数据库/表水平拆分,例 User -> User33% + User33% + User34%
数据库/表垂直拆分,例 User -> UserBaseInfo + UserAddrInfo
也可考虑使用 LongStore (龙存) 解决方案,由龙存管理存储阵列……
五、部署
划分子域名,每一个子域名一个Web应用包,互不干扰
静态资源(css, js, image ...)使用专门的静态服务器
六、负载均衡
小规模:DNS轮询。
大规模:F5, 2*X 台F5服务器,F5是L4/L7层交换机,每台至少可处理200万链接(与服务器内存有关)。
Ngnix是L7层交换,LVS负载均衡也是一种方案
七、Web中间件选择
Tomcat - 最高400并发
Apache - 最高2000并发
Ngnix - 优于Apache
采用方案:Ngnix + Resin ,理由:
Resin提供更为快速的servlet引擎 - 选择Resin。
gzip问题 - Resin在单独处理gzip时存在内存溢出的隐患,所以要加一层 Ngnix。
Ngnix 能减小单独使用Resin时的内存占用 - Resin创建1000个链接使用1000个线程;加Ngnix后,透过其“异步链接”、“创建长链接”机制使Resin内存压力大大减少。
Ngnix 针对Linux系统有性能优化措施 - 0 Copy, send file ...
所以采用:1 Ngnix + 1 Resin,一对一。
静态服务器采用:Squid + Apache, why? because Squid has cache ability ...
新变化 - Nginx从0.7.48版本开始,支持了相似Squid的缓存功能。这个缓存是把URL及相关组合看成Key,用md5编码哈希后保存在硬盘上,因此它能够支持任意URL连接,同时也支持 404/301/302 这样的非200状态码。虽然目前官方的Nginx Web缓存服务只能为指定URL或状态码设置过时时间,不支持相似Squid的PURGE指令,手动清除指定缓存页面,可是,经过一个第三方的Nginx 模块,能够清除指定URL的缓存。
Nginx的Web缓存服务主要由proxy_cache相关指令集和fastcgi_cache相关指令集构成,前者用于反向代理时,对后端内容源服务器进行缓存,后者主要用于对FastCGI的动态程序进行缓存。二者的功能基本上同样。
最新的Nginx 0.8.31版本,proxy_cache和fastcgi_cache已经比较完善,加上第三方的ngx_cache_purge模块(用于清除指定 URL的缓存),已经能够彻底取代Squid。有的网站已经在生产环境使用了 Nginx 的 proxy_cache 缓存功能超过两个月,十分稳定,速度不逊于 Squid。
大型网站,好比门户网站。在面对大量用户访问、高并发请求方面,基本的解决方案集中在这样几个环节:使用高性能的服务器、高性能的数据库、高效率的编程语言、还有高性能的Web容器。可是除了这几个方面,还无法根本解决大型网站面临的高负载和高并发问题。
上面提供的几个解决思路在必定程度上也意味着更大的投入,而且这样的解决思路具有瓶颈,没有很好的扩展性,下面我从低成本、高性能和高扩张性的角度来讲说个人一些经验。
一、HTML静态化
其实你们都知道,效率最高、消耗最小的就是纯静态化的html页面,因此咱们尽量使咱们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。可是对于大量内容而且频繁更新的网站,咱们没法所有手动去挨个实现,因而出现了咱们常见的信息发布系统CMS,像咱们常访问的各个门户站点的新闻频道,甚至他们的其余频道,都是经过信息发布系统来管理和实现的,信息发布系统能够实现最简单的信息录入自动生成静态页面,还能具有频道管理、权限管理、自动抓取等功能,对于一个大型网站来讲,拥有一套高效、可管理的CMS是必不可少的。
除了门户和信息发布类型的网站,对于交互性要求很高的社区类型网站来讲,尽量的静态化也是提升性能的必要手段,将社区内的帖子、文章进行实时的静态化,有更新的时候再从新静态化也是大量使用的策略,像Mop的大杂烩就是使用了这样的策略,网易社区等也是如此。目前不少博客也都实现了静态化,我使用的这个Blog程序WordPress尚未静态化,因此若是面对高负载访问,www.toplee.com必定不能承受
同时,html静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询可是内容更新很小的应用,能够考虑使用html静态化来实现,好比论坛中论坛的公用设置信息,这些信息目前的主流论坛均可以进行后台管理而且存储再数据库中,这些信息其实大量被前台程序调用,可是更新频率很小,能够考虑将这部份内容进行后台更新的时候进行静态化,这样避免了大量的数据库访问请求。
在进行html静态化的时候可使用一种折中的方法,就是前端使用动态实现,在必定的策略下进行定时静态化和定时判断调用,这个能实现不少灵活性的操做,我开发的台球网站故人居(www.8zone.cn)就是使用了这样的方法,我经过设定一些html静态化的时间间隔来对动态网站内容进行缓存,达到分担大部分的压力到静态页面上,能够应用于中小型网站的架构上。故人居网站的地址:http://www.8zone.cn,顺便提一下,有喜欢台球的朋友多多支持我这个免费网站:)
二、图片服务器分离
你们知道,对于Web服务器来讲,无论是Apache、IIS仍是其余容器,图片是最消耗资源的,因而咱们有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略,他们都有独立的图片服务器,甚至不少台图片服务器。这样的架构能够下降提供页面访问请求的服务器系统压力,而且能够保证系统不会由于图片问题而崩溃。
在应用服务器和图片服务器上,能够进行不一样的配置优化,好比Apache在配置ContentType的时候能够尽可能少支持,尽量少的LoadModule,保证更高的系统消耗和执行效率。
个人台球网站故人居8zone.cn也使用了图片服务器架构上的分离,目前是仅仅是架构上分离,物理上没有分离,因为没有钱买更多的服务器:),你们能够看到故人居上的图片链接都是相似img.9tmd.com或者img1.9tmd.com的URL。
另外,在处理静态页面或者图片、js等访问方面,能够考虑使用lighttpd代替Apache,它提供了更轻量级和更高效的处理能力。
三、数据库集群和库表散列
大型网站都有复杂的应用,这些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓶颈很快就能显现出来,这时一台数据库将很快没法知足应用,因而咱们须要使用数据库集群或者库表散列。
在数据库集群方面,不少数据库都有本身的解决方案,Oracle、Sybase等都有很好的方案,经常使用的MySQL提供的Master/Slave也是相似的方案,您使用了什么样的DB,就参考相应的解决方案来实施便可。
上面提到的数据库集群因为在架构、成本、扩张性方面都会受到所采用DB类型的限制,因而咱们须要从应用程序的角度来考虑改善系统架构,库表散列是经常使用而且最有效的解决方案。咱们在应用程序中安装业务和应用或者功能模块将数据库进行分离,不一样的模块对应不一样的数据库或者表,再按照必定的策略对某个页面或者功能进行更小的数据库散列,好比用户表,按照用户ID进行表散列,这样就可以低成本的提高系统的性能而且有很好的扩展性。sohu的论坛就是采用了这样的架构,将论坛的用户、设置、帖子等信息进行数据库分离,而后对帖子、用户按照板块和ID进行散列数据库和表,最终能够在配置文件中进行简单的配置便能让系统随时增长一台低成本的数据库进来补充系统性能。
四、缓存
缓存一词搞技术的都接触过,不少地方用到缓存。网站架构和网站开发中的缓存也是很是重要。这里先讲述最基本的两种缓存。高级和分布式的缓存在后面讲述。
架构方面的缓存,对Apache比较熟悉的人都能知道Apache提供了本身的mod_proxy缓存模块,也可使用外加的Squid进行缓存,这两种方式都可以有效的提升Apache的访问响应能力。
网站程序开发方面的缓存,Linux上提供的Memcached是经常使用的缓存方案,很多web编程语言都提供memcache访问接口,php、perl、c和java都有,能够在web开发中使用,能够实时或者Cron的把数据、对象等内容进行缓存,策略很是灵活。一些大型社区使用了这样的架构。
另外,在使用web语言开发的时候,各类语言基本都有本身的缓存模块和方法,PHP有Pear的Cache模块和eAccelerator加速和Cache模块,还要知名的Apc、XCache(国人开发的,支持!)php缓存模块,Java就更多了,.net不是很熟悉,相信也确定有。
五、镜像
镜像是大型网站常采用的提升性能和数据安全性的方式,镜像的技术能够解决不一样网络接入商和地域带来的用户访问速度差别,好比ChinaNet和EduNet之间的差别就促使了不少网站在教育网内搭建镜像站点,数据进行定时更新或者实时更新。在镜像的细节技术方面,这里不阐述太深,有不少专业的现成的解决架构和产品可选。也有廉价的经过软件实现的思路,好比Linux上的rsync等工具。
六、负载均衡
负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。
负载均衡技术发展了多年,有不少专业的服务提供商和产品能够选择,我我的接触过一些解决方法,其中有两个架构能够给你们作参考。另外有关初级的负载均衡DNS轮循和较专业的CDN架构就很少说了。
6.1 硬件四层交换
第四层交换使用第三层和第四层信息包的报头信息,根据应用区间识别业务流,将整个区间段的业务流分配到合适的应用服务器进行处理。 第四层交换功能就象是虚IP,指向物理服务器。它传输的业务服从的协议多种多样,有HTTP、FTP、NFS、Telnet或其余协议。这些业务在物理服务器基础上,须要复杂的载量平衡算法。在IP世界,业务类型由终端TCP或UDP端口地址来决定,在第四层交换中的应用区间则由源端和终端IP地址、TCP和UDP端口共同决定。
在硬件四层交换产品领域,有一些知名的产品能够选择,好比Alteon、F5等,这些产品很昂贵,可是物有所值,可以提供很是优秀的性能和很灵活的管理能力。Yahoo中国当初接近2000台服务器使用了三四台Alteon就搞定了。
6.2 软件四层交换
你们知道了硬件四层交换机的原理后,基于OSI模型来实现的软件四层交换也就应运而生,这样的解决方案实现的原理一致,不过性能稍差。可是知足必定量的压力仍是游刃有余的,有人说软件实现方式其实更灵活,处理能力彻底看你配置的熟悉能力。
软件四层交换咱们可使用Linux上经常使用的LVS来解决,LVS就是Linux Virtual Server,他提供了基于心跳线heartbeat的实时灾难应对解决方案,提升系统的鲁棒性,同时可供了灵活的虚拟VIP配置和管理功能,能够同时知足多种应用需求,这对于分布式的系统来讲必不可少。
一个典型的使用负载均衡的策略就是,在软件或者硬件四层交换的基础上搭建squid集群,这种思路在不少大型网站包括搜索引擎上被采用,这样的架构低成本、高性能还有很强的扩张性,随时往架构里面增减节点都很是容易。这样的架构我准备空了专门详细整理一下和你们探讨。
总结:
对于大型网站来讲,前面提到的每一个方法可能都会被同时使用到,Michael这里介绍得比较浅显,具体实现过程当中不少细节还须要你们慢慢熟悉和体会,有时一个很小的squid参数或者apache参数设置,对于系统性能的影响就会很大,但愿你们一块儿讨论,达到抛砖引玉之效。
好湿好湿
SQL语句要优化
索引建立有艺术
三大范式不可废
冗余字段难维护
查询过多怎么办
缓存使用是本固
频繁访问不用怕
每秒数千扛得住
更新插入可延迟
消息队列来辅助
满天消息不乱飞
定向收集捋清楚
Java代码执行快
阻塞瓶颈是同步
下降同步锁优化
请求处理畅无阻
以上所有作到后
还需WebServer来分布
Nginx好选择
多台Server同服务