网站性能检测评分
注:本网站页面html检测工具扫描网站中存在的基本问题,仅供参考。
大型网站的服务器
网站用户访问逐渐变大,如何增加服务器承载能力? 行业视频课程
对于用户数较多、负载较大的网站,通常都会使用负载均衡(LB:Load Balance)来增加服务器的承载能力。负载均衡是云计算的一个基本服务组件,通常都会搭配云主机来构建云服务,比如阿里云的SLB(Server Load Balancer)、腾讯云的CLB(Cloud Load Balancer)。
负载均衡可以将客户端请求分摊到多个操作单元上进行处理
负载均衡有很多种不同的实现方式,从实现方式看,可以分为硬件负载均衡与软件负载均衡两大类。
硬件负载均衡有大名鼎鼎的F5之类,这种不差钱的企业会采用。但是现在互联网公司用的越来越少。现在硬件使用较多的是使用支持OSPF协议的交换机(基本都支持了),通过ECMP做的负载均衡集群。这个查查云计算厂商的负载均衡文档,大部分都是用这个作为分发集群的。性能非常好(随便几十G器),稳定性也很高。但硬件负载均衡解决方案也有缺点,比如设备和服务费用昂贵,灵活性差,功能和容量都难以扩展。软件负载均衡相对来说,灵活性强,扩展起来更容易,所以软件负载均衡解决方案越来越受到青睐。
那么小诺说到软件负载均衡,最早通过DNS来实现,即一个域名对应多个IP地址。在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的。
DNS负载均衡的解决方案原理比较简单,不过缺点也比较明显:
第一,不能够按照Web服务器的处理能力分配负载;
第二,DNS负载均衡技术没有考虑容错,即使某个服务器不可用,DNS仍然会把请求转发过去;
第三,一旦发现某个服务器出现故障,即使及时修改了DNS设置,但还是要等DNS刷新时间到了才能生效。
开源软件解决方案
后来出现了开源软件负载均衡的解决方案,最主流的就是LVS和Nginx。基于开源软件的负载均衡打破了硬件LB的垄断,降低了负载均衡的实施成本。
(1)LVS = Linux Virtual Server(IP隧道)
LVS虚拟服务器,在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。
LVS是把负载均衡的功能做到了Linux内核里面。LVS集群采用IP负载均衡技术和基于内容请求分发技术,将一组服务器构成一个高性能的、高可用的虚拟服务器。
整个服务器集群的结构对客户是透明的,客户访问集群系统提供的网络服务就像访问一台高性能、高可用的服务器一样,而且无需修改客户端和服务器端的程序。
(2)Nginx
Nginx是一个轻量级的Web服务器,同时也是一个反向代理服务器,可以利用其反向代理的功能做负载均衡。Nginx与LVS相比主要有以下几点不同:
与LVS在层四进行负载均衡不同,Nginx是在层7进行,可以针对Http应用进行分流;
转发策略也更灵活,比如可以针对域名或目录结构进行转发;
Nginx对网络的依赖比较小,理论上只要Ping得通,网页访问正常就能连通,而LVS比较依赖网络环境。
总的来说,Nginx的应用场合要更多一些,LVS则更适合节点比较多的大型系统。
基于云的负载均衡(Cloud Load Balance)
除了在云主机上自己利用LVS或Nginx搭建负载均衡服务器,阿里云、腾讯云等云计算服务商,均提供了专门的负载均衡服务,配置容易。这些服务商的负载均衡解决方案,往往是结合了层7与层4的综合负载均衡方案,而且还需要考虑VPC网络与物理网络的不同情况。
以上是小诺所分享的负载均衡知识,相关的还有HTTP重定向、反向代理负载均衡、IP负载均衡等等,欢迎大家讨论!
手把手教你构建一个高性能、高可用的大型分布式网站 企业视频课程
本文是学习大型分布式网站架构的技术总结,对构建一个高性能、高可用、可伸缩及可扩展的分布式网站进行了概要性描述,并给出一个架构参考。
文中一部分为读书笔记,一部分是个人经验总结,对大型分布式网站架构有较好的参考价值。
大型分布式网站架构技术
大型网站的特点
大型网站一般有如下特点:用户多,分布广泛大流量,高并发海量数据,服务高可用安全环境恶劣,易受网络攻击功能多,变更快,频繁发布从小到大,渐进发展以用户为中心免费服务,付费体验大型网站架构目标
大型网站的架构目标有如下几个:
高性能:提供快速的访问体验。高可用:网站服务一直可以正常访问。可伸缩:通过硬件增加/减少,提高/降低处理能力。扩展性:方便地通过新增/移除方式,增加/减少新的功能/模块。安全性:提供网站安全访问和数据加密、安全存储等策略。敏捷性:随需应变,快速响应。大型网站架构模式
如上图是大型网站的架构模式:
分层:一般可分为应用层、服务层、数据层、管理层与分析层。分割:一般按照业务/模块/功能特点进行划分,比如应用层分为首页、用户中心。分布式:将应用分开部署(比如多台物理机),通过远程调用协同工作。集群:一个应用/模块/功能部署多份(如:多台物理机),通过负载均衡共同提供对外访问。缓存:将数据放在距离应用或用户最近的位置,加快访问速度。异步:将同步的操作异步化。客户端发出请求,不等待服务端响应,等服务端处理完毕后,使用通知或轮询的方式告知请求方。一般指:请求——响应——通知模式。冗余:增加副本,提高可用性、安全性与性能。安全:对已知问题有有效的解决方案,对未知/潜在问题建立发现和防御机制。自动化:将重复的、不需要人工参与的事情,通过工具的方式,使用机器完成。敏捷性:积极接受需求变更,快速响应业务发展需求。高性能架构
高性能的架构是以用户为中心,提供快速的网页访问体验,主要参数有较短的响应时间、较大的并发处理能力、较高的吞吐量与稳定的性能参数。
可分为前端优化、浏览器优化、应用层优化、代码层优化与存储层优化:
前端优化:网站业务逻辑之前的部分。浏览器优化:减少 HTTP 请求数,使用浏览器缓存,启用压缩,CSS JS 位置,JS 异步,减少 Cookie 传输;CDN 加速,反向代理。应用层优化:处理网站业务的服务器。使用缓存,异步,集群。代码优化:合理的架构,多线程,资源复用(对象池,线程池等),良好的数据结构,JVM调优,单例,Cache 等。存储优化:缓存、固态硬盘、光纤传输、优化读写、磁盘冗余、分布式存储(HDFS)、NoSQL 等。高可用架构
大型网站应该在任何时候都可以正常访问,正常提供对外服务。因为大型网站的复杂性,分布式,廉价服务器,开源数据库,操作系统等特点,要保证高可用是很困难的,也就是说网站的故障是不可避免的。
如何提高可用性,就是需要迫切解决的问题。首先,需要从架构级别考虑,在规划的时候,就考虑可用性。
行业内一般用几个 9 表示可用性指标,比如四个 9(99.99),一年内允许的不可用时间是 53 分钟。
不同层级使用的策略不同,一般采用冗余备份和失效转移解决高可用问题:
应用层:一般设计为无状态的,对于每次请求,使用哪一台服务器处理是没有影响的。一般使用负载均衡技术(需要解决 Session 同步问题)实现高可用。服务层:负载均衡,分级管理,快速失败(超时设置),异步调用,服务降级,幂等设计等。数据层:冗余备份(冷,热备[同步,异步],温备),失效转移(确认,转移,恢复)。数据高可用方面著名的理论基础是 CAP 理论。(持久性,可用性,数据一致性[强一致,用户一致,最终一致])可伸缩架构
伸缩性是指在不改变原有架构设计的基础上,通过添加/减少硬件(服务器)的方式,提高/降低系统的处理能力:
应用层:对应用进行垂直或水平切分。然后针对单一功能进行负载均衡(DNS、HTTP[反向代理]、IP、链路层)。服务层:与应用层类似。数据层:分库、分表、NoSQL 等;常用算法 Hash,一致性 Hash。可扩展架构
可以方便地进行功能模块的新增/移除,提供代码/模块级别良好的可扩展性:
模块化,组件化:高内聚,低耦合,提高复用性,扩展性。稳定接口:定义稳定的接口,在接口不变的情况下,内部结构可以“随意”变化。设计模式:应用面向对象思想,原则,使用设计模式,进行代码层面的设计。消息队列:模块化的系统,通过消息队列进行交互,使模块之间的依赖解耦。分布式服务:公用模块服务化,提供其他系统使用,提高可重用性,扩展性。安全架构
对已知问题有有效的解决方案,对未知/潜在问题建立发现和防御机制。对于安全问题,首先要提高安全意识,建立一个安全的有效机制,从政策层面,组织层面进行保障。
比如服务器密码不能泄露,密码每月更新,并且三次内不能重复;每周安全扫描等。
以制度化的方式,加强安全体系的建设。同时,需要注意与安全有关的各个环节。
安全问题不容忽视,包括基础设施安全,应用系统安全,数据保密安全等:
基础设施安全:硬件采购,操作系统,网络环境方面的安全。一般采用正规渠道购买高质量的产品,选择安全的操作系统,及时修补漏洞,安装杀毒软件防火墙。防范病毒,后门。设置防火墙策略,建立 DDOS 防御系统,使用攻击检测系统,进行子网隔离等手段。
应用系统安全:在程序开发时,对已知常用问题,使用正确的方式,在代码层面解决掉。防止跨站脚本攻击(XSS),注入攻击,跨站请求伪造(CSRF),错误信息,HTML 注释,文件上传,路径遍历等。
还可以使用 Web 应用防火墙(比如:ModSecurity),进行安全漏洞扫描等措施,加强应用级别的安全。
数据保密安全:存储安全(存储在可靠的设备,实时,定时备份),保存安全(重要的信息加密保存,选择合适的人员复杂保存和检测等),传输安全(防止数据窃取和数据篡改)。常用的加解密算法(单项散列加密[MD5、SHA],对称加密[DES、3DES、RC]),非对称加密[RSA]等。
敏捷性
网站的架构设计,运维管理要适应变化,提供高伸缩性,高扩展性。方便的应对快速的业务发展,突增高流量访问等要求。
除上面介绍的架构要素外,还需要引入敏捷管理,敏捷开发的思想。使业务,产品,技术,运维统一起来,随需应变,快速响应。
大型架构举例
以上采用七层逻辑架构:
第一层客户层:支持 PC 浏览器和手机 App。差别是手机 App 可以直接通过IP访问,反向代理服务器。第二层前端层:使用 DNS 负载均衡,CDN 本地加速以及反向代理服务。第三层应用层:网站应用集群;按照业务进行垂直拆分,比如商品应用,会员中心等。第四层服务层:提供公用服务,比如用户服务,订单服务,支付服务等。第五层数据层:支持关系型数据库集群(支持读写分离),NOSQL 集群,分布式文件系统集群;以及分布式 Cache。第六层大数据存储层:支持应用层和服务层的日志数据收集,关系数据库和 NOSQL 数据库的结构化和半结构化数据收集。第七层大数据处理层:通过 Mapreduce 进行离线数据分析或 Storm 实时数据分析,并将处理后的数据存入关系型数据库。(实际使用中,离线数据和实时数据会按照业务要求进行分类处理,并存入不同的数据库中,供应用层或服务层使用)
大型电商网站系统架构演变过程
一个成熟的大型网站(如淘宝、天猫、腾讯等)的系统架构并不是一开始设计时就具备完整的高性能、高可用、高伸缩等特性的,它是随着用户量的增加,业务功能的扩展逐渐演变完善的。
在这个过程中,开发模式、技术架构、设计思想也发生了很大的变化,就连技术人员也从几个人发展到一个部门甚至一条产品线。
所以成熟的系统架构是随着业务的扩展而逐步完善的,并不是一蹴而就;不同业务特征的系统,会有各自的侧重点。
例如淘宝,要解决海量的商品信息的搜索、下单、支付;例如腾讯,要解决数亿用户的实时消息传输;百度要处理海量的搜索请求。
他们都有各自的业务特性,系统架构也有所不同。尽管如此,我们也可以从这些不同的网站背景中,找出其中共用的技术。
这些技术和手段广泛运用在大型网站系统的架构中,下面就通过介绍大型网站系统的演化过程,来认识这些技术和手段。
最开始的网站架构
最初的架构,应用程序、数据库、文件都部署在一台服务器上,如下图:
应用、数据、文件分离
随着业务的扩展,一台服务器已经不能满足性能需求,所以将应用程序、数据库、文件各自部署在独立的服务器上,并且根据服务器的用途配置不同的硬件,达到最佳的性能效果。
利用缓存改善网站性能
在硬件优化性能的同时,也通过软件进行性能优化,在大部分的网站系统中,都会利用缓存技术改善系统的性能。
使用缓存主要源于热点数据的存在,大部分网站访问都遵循 28 原则(即 80% 的访问请求,最终落在 20% 的数据上),所以我们可以对热点数据进行缓存,减少这些数据的访问路径,提高用户体验。
缓存实现常见的方式是本地缓存、分布式缓存。当然还有 CDN、反向代理等。
本地缓存,顾名思义是将数据缓存在应用服务器本地,可以存在内存中,也可以存在文件,OSCache 就是常用的本地缓存组件。
本地缓存的特点是速度快,但因为本地空间有限所以缓存数据量也有限。
分布式缓存的特点是,可以缓存海量的数据,并且扩展非常容易,在门户类网站中常常被使用,速度按道理没有本地缓存快,常用的分布式缓存是 Memcached、Redis。
使用集群改善应用服务器性能
应用服务器作为网站的入口,会承担大量的请求,我们往往通过应用服务器集群来分担请求数。
应用服务器前面部署负载均衡服务器调度用户请求,根据分发策略将请求分发到多个应用服务器节点。
常用的负载均衡技术硬件的有 F5,价格比较贵,软件的有 LVS、Nginx、HAProxy。
LVS 是四层负载均衡,根据目标地址和端口选择内部服务器,Nginx 和 HAProxy 是七层负载均衡,可以根据报文内容选择内部服务器。
因此 LVS 分发路径优于 Nginx 和 HAProxy,性能要高些;而 Nginx 和 HAProxy 则更具配置性,如可以用来做动静分离(根据请求报文特征,选择静态资源服务器还是应用服务器)。
数据库读写分离和分库分表
随着用户量的增加,数据库成为最大的瓶颈。改善数据库性能常用的手段是进行读写分离以及分库分表,读写分离顾名思义就是将数据库分为读库和写库,通过主备功能实现数据同步。
分库分表则分为水平切分和垂直切分,水平切分是对一个数据库特大的表进行拆分,例如用户表。
垂直切分则是根据业务的不同来切分,如用户业务、商品业务相关的表放在不同的数据库中。
使用 CDN 和反向代理提高网站性能
假如我们的服务器都部署在成都的机房,对于四川的用户来说访问是较快的,而对于北京的用户访问是较慢的。
这是由于四川和北京分别属于电信和联通的不同发达地区,北京用户访问需要通过互联路由器经过较长的路径才能访问到成都的服务器,返回路径也一样,所以数据传输时间比较长。
对于这种情况,常常使用 CDN 解决,CDN 将数据内容缓存到运营商的机房,用户访问时先从最近的运营商获取数据,这样大大减少了网络访问的路径。比较专业的 CDN 运营商有蓝汛、网宿。
而反向代理,则是部署在网站的机房,当用户请求达到时首先访问反向代理服务器,反向代理服务器将缓存的数据返回给用户。
如果没有缓存数据才会继续访问应用服务器获取,这样做减少了获取数据的成本。反向代理有 Squid、Nginx。
使用分布式文件系统
用户一天天增加,业务量越来越大,产生的文件越来越多,单台的文件服务器已经不能满足需求,这时就需要分布式文件系统的支撑。常用的分布式文件系统有 GFS、HDFS、TFS。
使用 NoSQL 和搜索引擎
对于海量数据的查询和分析,我们使用 NoSQL 数据库加上搜索引擎可以达到更好的性能。并不是所有的数据都要放在关系型数据中。
常用的 NoSQL 有 MongoDB、HBase、Redis,搜索引擎有 Lucene、Solr、Elasticsearch。
将应用服务器进行业务拆分
随着业务进一步扩展,应用程序变得非常臃肿,这时我们需要将应用程序进行业务拆分,如百度分为新闻、网页、图片等业务。
每个业务应用负责相对独立的业务运作。业务之间通过消息进行通信或者共享数据库来实现。
搭建分布式服务
这时我们发现各个业务应用都会使用到一些基本的业务服务,例如用户服务、订单服务、支付服务、安全服务,这些服务是支撑各业务应用的基本要素。
我们将这些服务抽取出来åˆ...
阿里P8十年架构经验,两千字一张图,透析大型网站技术架构 互联网视频课程
1 架构演化
大型网站的关注指标
高可用
高性能
易扩展
可伸缩
安全
大型网站的特点
高并发,大流量
高可用
海量数据
用户分布广泛,网络情况复杂
安全环境恶劣
需求快速变更,发布频繁
渐进式发展
大型网站架构演化发展过程
初始阶段,多使用LAMP来搭建,All In One即所有资源存放在一台服务器上
应用服务和数据服务分离,有独立的数据库服务器
使用缓存改善网站性能(依据是二八定律:80%的业务访问集中在20%的数据上)
这里需要考虑哪些数据适合缓存
缓存可以是本地缓存,也可以是远程分布式缓存
需要考虑使用合理的缓存策略,防止透传
使用应用服务器集群改善网站的并发处理能力
如果能通过增加一台服务器的方式来改善负载压力,就可以以同样的方式持续增加服务器来不断改善系统性能,从而实现系统的可伸缩性
这里需要考虑使用哪些负载均衡的策略
数据库读写分离
可以利用主流数据库提供的主从热备功能,通过配置两台数据库的主从关系,同时业内也有很多优秀的开源中间件如Atlas
缓存中的数据,如果更新过快,那么会持续刷新缓存,从而降低性能
使用反向代理和CDN加速网络响应
CDN和反向代理的基本原理都是缓存
CDN部署在网络提供商的机房,用户在请求网络服务时,可以从距离自己最近的网络提供商机房获取数据
反向代理部署在网站的中心机房,当用户的请求到达中心机房后,首先访问的服务器是反向代理服务器,如果反向代理服务器中缓存着用户请求的资源,那么就将其直接返回给用户
CDN的重点:——《大型网站系统与Java中间件实践》
全局调度
缓存技术
内容分发
带宽优化
使用分布式文件系统和分布式数据库系统
网站常用的数据库拆分手段是业务分库,即将不同业务的数据库部署到不同的物理服务器上
使用NoSQL和搜索引擎
ES
MongoDB
业务拆分,使用分而治之的手段将整个网站业务分成不同的产品线
SOA、服务化
中心化的 gataway方式
消息队列
不同服务访问同一个DB等
这部分十分重要,道理很简单,但是执行起来的效果千差万别。
当下火热的微服务,也是基于这种思想。
技术实现方式也有很多
分布式服务
大型网站架构演化的价值观
网站的价值在于它能为用户提供什么价值,在于网站能做什么,而不在于它是怎么做的。因此对于小型网站来说,最需要做的是位用户提供好的服务来创造价值,得到用户的认可,从而活下去,野蛮生长。
大型网站架构技术的核心价值是随网站所需灵活应对, 它是一个演化的过程
驱动大型网站技术发展的主要力量是网站的业务发展,是业务成就了技术,而不是相反。因此要摒弃为了技术而技术的套路
网站架构设计误区
一味追求大公司的解决方案
为了技术而技术
企图用技术解决所有问题
2 架构模式
分层,这是在横向方向对系统进行切分
分层的挑战在于必须合理规划层次边界和接口
分层包括物理分层和逻辑分层两种
分割,这是在纵向方向对系统进行切分
将不同的功能和服务分割开来,包装秤高内聚低耦合的模块单元
分布式
1) 分布式应用和服务;
2) 分布式静态资源;
3) 分布式数据和存储;
4) 分布式计算;
5) 分布式配置、分布式锁、分布式文件系统。。。
1) 分布式意味着服务调用必须通过网络,需要考虑带宽的影响;
2) 服务器越多,宕机的概率越大
分层和分割的目的在于小模块便于分布式部署
带来的问题:
常用的分布式方案:
集群,即多台服务器部署相同的应用,从而构成一个集群,通过负载均衡设备共同对外提供服务
即使访问量很小的分布式应用和服务,也至少要部署到两台服务器来构成一个小集群,这样可以提高系统的可用性
缓存,即将数据放在距离计算最近的位置以加快处理速度
CDN
反向代理
本地缓存
分布式缓存
异步,业务之间的消息传递不是同步调用,而是将一个业务操作分成多个阶段,每个阶段之间通过共享数据的方法异步进行协作
1) 提高系统可用性;
2) 加快网站响应速度;
3) 消除并发访问高峰
通常需要使用消息队列
带来的好处:
冗余
集群带来的必然结果
安全需求的必然结果
自动化,DevOps思维,尽量减少人工干预
自动化发布
自动化代码管理
自动化测试
自动化安全监测
自动化部署
自动化监控
自动化报警
自动化失效转移、恢复
自动化分配资源
......
安全
3 大型网站核心架构要素
性能
一个性能问题可能会导致网站用户严重流失
衡量性能的指标:响应时间、TPS、系统性能计数器等
可用性
没有网站可以完美的7*24运行
网站高可用结构的前提是必然会出现服务器宕机,儿高可用设计的目标是当服务器宕机时,服务或者应用依然可用
必要的手段是集群,即冗余
伸缩性,即通过不断向集群中加入服务器的手段来环节不断上升的用户并发访问压力和不断增长的数据存储需求
衡量标准:是否可以构建集群;是否可以方便的向集群中添加新的服务器
扩展性,直接关注网站的功能,保证可以快速响应需求变更
衡量标准: 网站增加新的业务产品时,是否对现有业务透明无影响
安全性
衡量标准: 针对现存和潜在的各种攻击和窃密手段,是否可以有效的应对
4 瞬时响应 - 网站的高性能架构
不同视角下的网站性能
用户视角
主要是端到端的感觉
主要通过前段优化的手段来提升用户体验
开发人员视角
主要关注应用程序本身以及相关子系统的性能,包括响应延迟、系统吞吐量、并发处理能力、系统稳定性等
主要优化手段: 使用缓存加速数据读取、使用集群提高吞吐能力、使用异步消息加快请求响应、使用代码优化提升程序性能
运维人员视角
主要关注基础设施性能和资源利用率
主要优化手段: 建设优化骨干网、使用高性价比定制服务器、利用虚拟化技术优化资源利用率
性能测试指标
响应时间,即应用执行一个操作需要的时间,包括从发出请求开始到收到最后响应数据所需要的时间
并发数,即系统能够同时处理的请求的数目,也反映了系统的负载特性
吞吐量,即单位时间内系统处理的请求数量,体现系统的整理处理能力
性能计数器, 描述服务器或者操作系统性能的一些数据指标
性能测试方法
性能测试,以系统设计初期规划的性能指标为预期目标,对系统不断增压,验证系统在资源可接受范围内,是否能达到性能预期
负载测试,对系统不断的增加并发请求,知道系统的某项或者多项性能指标达到安全临界值
压力测试,超过安全负载的情况下,继续对系统增压,直到系统崩溃或者不能再处理任何请求
稳定性测试,在特定硬件、软件、网络情况下,给系统加载一定压力,是系统运行较长一段时间,来观察系统是否稳定
Web前端优化
浏览器访问优化
减少http请求
使用浏览器缓存
启用压缩
CSS放在页面最上面,JavaScript放在页面最下面
减少Cookie传输
CDN加速
反向代理
应用服务器性能优化
分布式缓存
一般会使用消息队列,带来的额外好处是会削平峰值
1)不同的缓存服务器之间进行通信,例如JBoss Cache;
2)不同缓存服务器之间不进行通信,例如Memcached
缓存从本质上来说,就是一个内存hash表
缓存需要缓存那些读写比很高、很少变化的数据,一般来说读写比在2:1以上时,缓存才有意义
应用程序读取数据时,首先到缓存中读取,如果缓存不存在或者已失效,再访问数据库,同时将新的数据放入缓存
缓存也需要注意缓存热点数据
缓存预热,在新启动的缓存系统中,在启动时就加载热点数据,这样启动后就可以直接使用
缓存穿透, 应用持续大量访问不存在的数据,因为这类数据不存在于缓存中,因此会大量访问数据库,从而降低性能
对于分布式缓存来说,目前有两类:
异步操作
使用集群
代码优化
多线程
1) 将对象设计成无状态对象;
2) 使用局部对象;
3) 并发访问资源时使用锁
需要注意线程安全问题,方法:
资源复用
主要是单例和资源池(对象池)
数据结构,选择合适的算法
垃圾回收
合理设置垃圾回收策略
存储性能优化
机械硬盘 vs 固态硬盘
B+树 vs LSM树
RAID vs HDFS
5 万无一失 - 网站的高可用架构
网站可用性度量
网站不可用时间 = 故障修复时间点 - 故障发现时间点
网站年度可用性指标 = (1 - 网站不可用时间/年度总时间)* 100%
一般以几个9来表示,2个9是基本可用,网站年度不可用时间小于88小时;3个9是较高可用,网站年度不可用时间小于9小时;4个9是具有自动恢复能力的高可用,网站年度不可用时间小于53分钟;5个9是极高可用性,网站年度不可用时间小于5分钟
网站高可用架构的设计目标是保证服务器硬件故障时服务依然可用、数据依然保存并能够被访问
网站高可用架构的主要手段:数据和服务的冗余备份以及失效转移,一旦服务器宕机,就将服务切换至其他可用的服务器上。
高可用的应用
无状态应用: 应用服务器不保存业务的上下文信息,而仅根据每次请求提交的数据进行相应的业务逻辑处理,多个服务实例之间完全对等,请求提交到任何一个服务器上,处理的结构都是相同的。
通过负载均衡进行无状态服务的失效转移
负载均衡: 主要使用在业务量和数据量较高的情况下,当单台服务器不足以承担所有的负载压力时,通过负载均衡手段,将流量和数据分摊到一个集群组成的多台服务器上, 以提升整体的负载处理能力
应用服务器集群的Session管理
Session复制
Session绑定
利用Cookie记录Session
Session服务器
高可用的服务
分级管理
核心服务与非核心服务隔离
核心服务优先使用高性能服务器
超时设置
异步调用
必须满足可以使用异步调用方式
服务降级
幂等性设计
服务高可用(高可靠)一直是美团外卖的第一要求,为了提高可用性,做了很多策略,包括并不限于上文提出的各种架构设计方案。
其实造成线上问题的很大一部分原因是由于发版造成的,也体现出了SOP的重要性。
关于降级与依赖隔离,可以考虑采用Hystrix实现自动降级与依赖隔离 。
高可用的数据
数据一旦出现问题,对于网站往往是毁灭性的打击,因此保护网站的数据就是保护企业的命脉。
主要手段:数据备份和失效转移
缓存服务高可用
观点一:缓存服务已经承担了业务中绝大多数的数据读取访问,因此需要同样保证高可用
观点二:缓存服务并不是数据存储服务,出现服务不可用导致数据丢失应从别的手段解决,而不是提高缓存服务本身高可用
缓存服务器集群中单机故障,集群规模较大时,数据丢失比例和数据负载压力影响很小。
CAP原理: 一个提供数据服务的存储系统无法同时满足数据一致性(Consistency)、数据可用性(Availibility)、分区耐受性(Parition Tolerance)这三个条件
数据高可用含义:
副本间数据一致
多个副本可读
同时写入数据副本
1)数据持久性
2)数据可访问性
3)数据一致性
数据一致性分类:
1) 数据强一致;
2) 数据用户一致;
3) 数据最终一致
数据备份
1) 异步热备;
2) 同步热备
冷备的优点是简单和廉价,成本和技术难度较低,缺点是不能保证数据最终一致
热备分为两种:
失效转移
1) 心跳检测(Keepalived、Heartbeat);
2) 应用程序访问失败报告
失效确认:
访问转移
数据恢复
高可用网站的软件质量保证
网站发布,它的过程和服务器宕机效果箱单,其对系统可用性的影响也 类似
一般采取批量更新的方式进行,不会一次关掉集群中的全部服务器
自动化测试
一般使用Selenium来进行测试
预发布验证
预发布服务器是一种特殊用途的服务器,它和线上的正式服务器唯一的区别是没有配置在负载均衡服务器上,外部用户无法访问
代码控制
主干开发,分支发布
分支开发,主干发布,这是目前使用的主流方式
自动化发布
火车模型:将每个应用的发布过程看做一次火车旅程,火车定点运行,期间有若干站点,每一站都进行例行检查,不通过的项目下车,通过的项目继续坐着火车旅行,直到火车到达终点。
实际中,可能所有项目在途中都下车了,这样火车不得不回到原点,等待é—...
大型网站图片服务器架构的演进 企业视频课程
作者:丁浪链接:cnblogs/dinglang/p/4608915.html
知音专栏
程序员的出路
写程序时该追求什么,什么是次要的?
如何准备Java初级和高级的技术面试
公众号注:更多架构技术文章,点击文末阅读原文直达
在主流的Web站点中,图片往往是不可或缺的页面元素,尤其在大型网站中,几乎都将面临“海量图片资源”的存储、访问等相关技术问题。在针对图片服务器的架构扩展中,也会历经很多曲折甚至是血泪教训(尤其是早期规划不足,造成后期架构上很难兼容和扩展)。
本文将以一个真实垂直门户网站的发展历程,向大家娓娓道来。
构建在Windows平台之上的网站,往往会被业内众多技术认为很“保守”,甚至会有点。很大部分原因,是由于微软技术体系的封闭和部分技术人员的短视造成的(当然,主要还是人的问题)。
由于长期缺乏开源支持,所以很多人只能“闭门造车”,这样很容易形成思维局限性和短板。以图片服务器为例子,如果前期没有容量规划和可扩展的设计,那么随着图片文件的不断增多和访问量的上升,由于在性能、容错/容灾、扩展性等方面的设计不足,后续将会给开发、运维工作带来很多问题,严重时甚至会影响到网站业务正常运作和互联网公司的发展(这绝不是在危言耸听)。
很多公司之所以选择Windows(.NET)平台来构建网站和图片服务器,很大部分由创始团队的技术背景决定的,早期的技术人员可能更熟悉.NET,或者团队的负责人认为Windows/.NET的易用性、“短平快”的开发模式、人才成本等方面都比较符合创业初期的团队,自然就选择了Windows。
后期业务发展到一定规模,也很难轻易将整体架构迁移到其它开源平台上了。当然,对于构建大规模互联网,更建议首选开源架构,因为有很多成熟的案例和开源生态的支持(也会有很多坑,就看是你自己最先去踩坑,还是在别人踩了修复之后你再用),避免重复造轮子和支出高额授权费用。对于迁移难度较大的应用,个人比较推荐Linux、Mono、Jexus、Mysql、Memcahed、Redis……混搭的架构,同样能支撑具有高并发访问和大数据量等特点的互联网应用。
单机时代的图片服务器架构(集中式)
初创时期由于时间紧迫,开发人员水平也很有限等原因。所以通常就直接在website文件所在的目录下,建立1个upload子目录,用于保存用户上传的图片文件。如果按业务再细分,可以在upload目录下再建立不同的子目录来区分。例如:upload\QA,upload\Face等。
在数据库表中保存的也是”upload/qa/test.jpg”这类相对路径。
用户的访问方式如下:
http://yourdomain/upload/qa/test.jpg
程序上传和写入方式:
程序员A通过在web.config中配置物理目录D:\Web\yourdomain\upload 然后通过stream的方式写入文件;程序员B通过Server.MapPath等方式,根据相对路径获取物理目录 然后也通过stream的方式写入文件。
优点:实现起来最简单,无需任何复杂技术,就能成功将用户上传的文件写入指定目录。保存数据库记录和访问起来倒是也很方便。
缺点:上传方式混乱,严重不利于网站的扩展。
针对上述最原始的架构,主要面临着如下问题:
随着upload目录中文件越来越多,所在分区(例如D盘)如果出现容量不足,则很难扩容。只能停机后更换更大容量的存储设备,再将旧数据导入。在部署新版本(部署新版本前通过需要备份)和日常备份website文件的时候,需要同时操作upload目录中的文件,如果考虑到访问量上升,后边部署由多台Web服务器组成的负载均衡集群,集群节点之间如果做好文件实时同步将是个难题。集群时代的图片服务器架构(实时同步)
在website站点下面,新建一个名为upload的虚拟目录,由于虚拟目录的灵活性,能在一定程度上取代物理目录,并兼容原有的图片上传和访问方式。
用户的访问方式依然是:
http://yourdomain/upload/qa/test.jpg
优点:配置更加灵活,也能兼容老版本的上传和访问方式。
因为虚拟目录,可以指向本地任意盘符下的任意目录。这样一来,还可以通过接入外置存储,来进行单机的容量扩展。
缺点:部署成由多台Web服务器组成的集群,各个Web服务器(集群节点)之间(虚拟目录下的)需要实时的去同步文件,由于同步效率和实时性的限制,很难保证某一时刻各节点上文件是完全一致的。
基本架构如下图所示:
从上图可看出,整个Web服务器架构已经具备“可扩展、高可用”了,主要问题和瓶颈都集中在多台服务器之间的文件同步上。
上述架构中只能在这几台Web服务器上互相“增量同步”,这样一来,就不支持文件的“删除、更新”操作的同步了。
早期的想法是,在应用程序层面做控制,当用户请求在web1服务器进行上传写入的同时,也同步去调用其它web服务器上的上传接口,这显然是得不偿失的。所以我们选择使用Rsync类的软件来做定时文件同步的,从而省去了“重复造轮子”的成本,也降低了风险性。
同步操作里面,一般有比较经典的两种模型,即推拉模型:所谓“拉”,就是指轮询地去获取更新,所谓推,就是发生更改后主动的“推”给其它机器。当然,也可以采用加高级的事件通知机制来完成此类动作。
在高并发写入的场景中,同步都会出现效率和实时性问题,而且大量文件同步也是很消耗系统和带宽资源的(跨网段则更明显)。
集群时代的图片服务器架构改进(共享存储)
沿用虚拟目录的方式,通过UNC(网络路径)的方式实现共享存储(将upload虚拟目录指向UNC)
用户的访问方式1:
http://yourdomain/upload/qa/test.jpg
用户的访问方式2(可以配置独立域名):
http://img.yourdomain/upload/qa/test.jpg
支持UNC所在server上配置独立域名指向,并配置轻量级的web服务器,来实现独立图片服务器。
优点:通过UNC(网络路径)的方式来进行读写操作,可以避免多服务器之间同步相关的问题。相对来讲很灵活,也支持扩容/扩展。支持配置成独立图片服务器和域名访问,也完整兼容旧版本的访问规则。
缺点 :但是UNC配置有些繁琐,而且会造成一定的(读写和安全)性能损失。可能会出现“单点故障”。如果存储级别没有raid或者更高级的灾备措施,还会造成数据丢失。
基本架构如下图所示:
在早期的很多基于Linux开源架构的网站中,如果不想同步图片,可能会利用NFS来实现。事实证明,NFS在高并发读写和海量存储方面,效率上存在一定问题,并非最佳的选择,所以大部分互联网公司都不会使用NFS来实现此类应用。
当然,也可以通过Windows自带的DFS来实现,缺点是“配置复杂,效率未知,而且缺乏资料大量的实际案例”。另外,也有一些公司采用FTP或Samba来实现。
上面提到的几种架构,在上传/下载操作时,都经过了Web服务器(虽然共享存储的这种架构,也可以配置独立域名和站点来提供图片访问,但上传写入仍然得经过Web服务器上的应用程序来处理),这对Web服务器来讲无疑是造成巨大的压力。所以,更建议使用独立的图片服务器和独立的域名,来提供用户图片的上传和访问。
独立图片服务器/独立域名的好处
图片访问是很消耗服务器资源的(因为会涉及到操作系统的上下文切换和磁盘I/O操作)。分离出来后,Web/App服务器可以更专注发挥动态处理的能力。独立存储,更方便做扩容、容灾和数据迁移。浏览器(相同域名下的)并发策略限制,性能损失。访问图片时,请求信息中总带cookie信息,也会造成性能损失。方便做图片访问请求的负载均衡,方便应用各种缓存策略(HTTP Header、Proxy Cache等),也更加方便迁移到CDN。......
我们可以使用Lighttpd或者Nginx等轻量级的web服务器来架构独立图片服务器。
当前的图片服务器架构(分布式文件系统+CDN)
在构建当前的图片服务器架构之前,可以先彻底撇开web服务器,直接配置单独的图片服务器/域名。但面临如下的问题:
旧图片数据怎么办?能否继续兼容旧图片路径访问规则?独立的图片服务器上需要提供单独的上传写入的接口(服务API对外发布),安全问题如何保证?同理,假如有多台独立图片服务器,是使用可扩展的共享存储方案,还是采用实时同步机制?直到应用级别的(非系统级) DFS(例如FastDFS HDFS MogileFs MooseFS、TFS)的流行,简化了这个问题:执行冗余备份、支持自动同步、支持线性扩展、支持主流语言的客户端api上传/下载/删除等操作,部分支持文件索引,部分支持提供Web的方式来访问。
考虑到各DFS的特点,客户端API语言支持情况(需要支持C#),文档和案例,以及社区的支持度,我们最终选择了FastDFS来部署。
唯一的问题是:可能会不兼容旧版本的访问规则。如果将旧图片一次性导入FastDFS,但由于旧图片访问路径分布存储在不同业务数据库的各个表中,整体更新起来也十分困难,所以必须得兼容旧版本的访问规则。架构升级往往比做全新架构更有难度,就是因为还要兼容之前版本的问题。(给飞机在空中换引擎可比造架飞机难得多)
解决方案如下:
首先,关闭旧版本上传入口(避免继续使用导致数据不一致)。将旧图片数据通过rsync工具一次性迁移到独立的图片服务器上(即下图中描述的Old Image Server)。
在最前端(七层代理,如Haproxy、Nginx)用ACL(访问规则控制),将旧图片对应URL规则的请求(正则)匹配到,然后将请求直接转发指定的web 服务器列表,在该列表中的服务器上配置好提供图片(以Web方式)访问的站点,并加入缓存策略。
这样实现旧图片服务器的分离和缓存,兼容了旧图片的访问规则并提升旧图片访问效率,也避免了实时同步所带来的问题。
整体架构如图:
基于FastDFS的独立图片服务器集群架构,虽然已经非常的成熟,但是由于国内“南北互联”和IDC带宽成本等问题(图片是非常消耗流量的),我们最终还是选择了商用的CDN技术,实现起来也非常容易,原理其实也很简单。
我这里只做个简单的介绍:
将img域名cname到CDN厂商指定的域名上,用户请求访问图片时,则由CDN厂商提供智能DNS解析,将最近的(当然也可能有其它更复杂的策略,例如负载情况、健康状态等)服务节点地址返回给用户。
用户请求到达指定的服务器节点上,该节点上提供了类似Squid/Vanish的代理缓存服务,如果是第一次请求该路径,则会从源站获取图片资源返回客户端浏览器,如果缓存中存在,则直接从缓存中获取并返回给客户端浏览器,完成请求/响应过程。
由于采用了商用CDN服务,所以我们并没有考虑用Squid/Vanish来自行构建前置代理缓存。
上面的整个集群架构,可以很方便的做横向扩展,能满足一般垂直领域中大型网站的图片服务需求(当然,像taobao这样超大规模的可能另当别论)。
经测试,提供图片访问的单台Nginx服务器(至强E5四核CPU、16G内存、SSD),对小静态页面(压缩后大概只有10kb左右的)可以扛住几千个并发且毫无压力。
当然,由于图片本身体积比纯文本的静态页面大很多,提供图片访问的服务器的抗并发能力,往往会受限于磁盘的I/O处理能力和IDC提供的带宽。Nginx的抗并发能力还是非常强的,而且对资源占用很低,尤其是处理静态资源,似乎都不需要有过多担心了。
可以根据实际访问量的需求,通过调整Nginx的参数,对Linux内核做调优,加入分级缓存策略等手段能够做更大程度的优化,也可以通过增加服务器或者升级服务器配置来做扩展,最直接的是通过购买更高级的存储设备和更大的带宽,以满足更大访问量的需求。
值得一提的是,在“云计算”流行的当下,也推荐高速发展期间的网站,使用“云存储”这样的方案,既能帮你解决各类存储、扩展、备灾的问题,又能做好CDN加速。最重要的是,价格也不贵。
总结,有关图片服务器架构扩展,大致围绕这些问题展开:
容量规划和扩展问题。数据的同步、冗余和容灾。硬件设备的成本和可靠性(是普通机械硬盘,还是SSD,或者更高端的存储设备和方案)。文件系统的选择。根据文件特性(例如文件大小、读写比例等)选择是用ext3/4或者NFS/GFS/TFS这些开源的(分布式)文件系统。图片的加速访问。采用商用CDN或者自建的代理缓存、web静态缓存架构。旧图片路径和访问规则的兼容性,应用程序层面的可扩展,上传和访问的性能和安全性等
看完本文有收获?请转发分享给更多人
大型网站服务器架构需要哪些服务器? 企业视频课程
网络是生活在互联网世界的我们形影不离的存在,新浪微博、今日头条、搜狐新闻、腾讯视频、微信QQ等我们常常访问的大型网站的网站服务器架构需要哪些服务器呢?
1、Web服务器
Web服务器主要是为访客提供http访问或是加密https访问的服务器,所接触到的网页就是直接从Web服务器中发送出来的,处于网站服务器的最前端。在windows服务器系统上常使用的是IIS,在unix和Linux服务器系统上常使用的是Apache、Nginx。
2、应用程序服务器
应用程序服务器是作为服务器执行共享业务应用程序的底层的系统软件服务器,所访问的app请求就是在应用服务器中处理的。在应用程序服务器上运行着各式的业务逻辑,主要是是EJB、 JNDI和JMX API等J2EE API方面的,还包含事务处理、业务逻辑管理、数据库连接等功能。
3、数据库服务器
运行在局域网中的一台或多台计算机和数据库管理系统软件共同构成了数据库服务器,数据库服务器为客户应用提供服务,这些服务是查询、更新、事务管理、索引、高速缓存、查询优化、安全及多用户存取控制等。
4、代理服务器
代理服务器通常是客户端访问的一种行为。它虽然不属于网站部署中的环境,但在整体的客户端访问中,它却是一个重要环节的服务器。
5、反向代理服务器
与代理服务器相对,还有一个反向代理服务器,其功能是Web服务器的功能。但是从它这里拿到的网页不是最原始产生页面的"产生地",而是由它从页面的"产生地"取回页面后的一个缓存。代理服务器中缓存的内容通常是由某些用户访问某个页面而产生访问请求后,在客户端代理服务器上留下的缓存;而反向代理服务器上缓存的页面,不是由于某些用户访问某个页面后留下的缓存,却是根据网站运维的策略定期、定时地生成一些后台服务器的页面缓存。
代理服务器与反向代理服务器的区别:代理服务器是工作在客户端,反向代理服务器时工作在服务器端,Nginx服务器常被用作于反向代理服务器。
6、 后台服务器
后台服务器只是一个说法而已,这是根据它的工作特点来说的,换句话说是没有直接提供给客户访问。例如众多的FastCGI服务器,它们都工作在后台,HTTP协议却无法访问到它们,另一种情况,如果我们从前是通过使用Apache作为Web服务器提供HTTP访问的,现在被Nginx反向代理了,是说由Nginx直接面对客户访问,而将请求再转到Apache服务器,那么这里的Apache服务器已经成为后台服务器了。
7、CDN缓存服务器
正如其名字,它是缓存服务器的角色,而且是反向代理的应用,在网站部署中,它算是一种部署策略,即对于远距离访问的解决方案,为了解决时间产生距离、时间缩短距离而产生的,它是反向代理的另一种应用。
8、负载均衡服务器
负载均衡服务器主要作用是实现某些类型服务器的规模扩展。比如对于系统前端的web服务器和后端的数据库服务器,想通过加服务器实现N+1横向扩展,通过多台服务器负载分担压力,负载均衡必不可少。
9、消息队列服务器
队列是系统解耦利器,也是大中型分布式系统标配,没有队列,业务系统很容易高度耦合,系统吞吐量也会很快遭遇瓶颈。
10、文件服务器
分布式文件系统,专门用于存储业务系统需要的各种文件如图片、多媒体文件等。
11、索引服务器
用于网站全文索引,搜索必备。对内存和CPU要求较高,大型网站,通常还需要支持主从备份和容错,甚至多实例索引集群。
12、搜索服务器
通常需要部署多台,否则查询多了性能撑不住,对内存要求不高。有的中小型站点,索引和搜索服务器在物理和逻辑上都是同一台服务器。
13、作业服务器
主要用于后端应用程序大批量大数据量复杂业务逻辑的定时作业,大多数互联网公司标配,某些企业的定时调度框架是直接部署在web服务器上的,可以减少这里的所谓作业服务器。
14、nosql服务器
海量数据处理的兴起,各种nosql产品层出不穷,nosql服务器主要用于处理海量数据,支持存储、查询、分片等。
web应用中,有两个一直是不好实现横向扩展或者由于历史遗留问题实现代价非常大的东西,如你所知,就是:A、数据库 B、网络带宽。
而某些nosql的出现很可能解决这个历史遗留难题,现在已经有nosql产品弥补了关系型数据库天生不支持横向扩展的缺点,在特定场景下正在替代关系型数据库。
15、其他
需求不断变化和应用需要,某些互联网企业还可能衍生出基于安全的授权/证书服务器,全局唯一的流水号服务器,会话服务器等等。
大型网站面对着高负载、高并发的要求,对网站服务器的架构更为苛刻,天下数据建议架构Web服务器、应用程序服务器、代理服务器、反向代理服务器、后台服务器、CDN缓存服务器等类型的服务器来应对需求。
手把手教你构建一个高性能、高可用的大型分布式网站 企业视频课程
本文是学习大型分布式网站架构的技术总结,对构建一个高性能、高可用、可伸缩及可扩展的分布式网站进行了概要性描述,并给出一个架构参考。
文中一部分为读书笔记,一部分是个人经验总结,对大型分布式网站架构有较好的参考价值。
大型分布式网站架构技术
大型网站的特点
大型网站一般有如下特点:用户多,分布广泛大流量,高并发海量数据,服务高可用安全环境恶劣,易受网络攻击功能多,变更快,频繁发布从小到大,渐进发展以用户为中心免费服务,付费体验大型网站架构目标
大型网站的架构目标有如下几个:
高性能:提供快速的访问体验。高可用:网站服务一直可以正常访问。可伸缩:通过硬件增加/减少,提高/降低处理能力。扩展性:方便地通过新增/移除方式,增加/减少新的功能/模块。安全性:提供网站安全访问和数据加密、安全存储等策略。敏捷性:随需应变,快速响应。大型网站架构模式
如上图是大型网站的架构模式:
分层:一般可分为应用层、服务层、数据层、管理层与分析层。分割:一般按照业务/模块/功能特点进行划分,比如应用层分为首页、用户中心。分布式:将应用分开部署(比如多台物理机),通过远程调用协同工作。集群:一个应用/模块/功能部署多份(如:多台物理机),通过负载均衡共同提供对外访问。缓存:将数据放在距离应用或用户最近的位置,加快访问速度。异步:将同步的操作异步化。客户端发出请求,不等待服务端响应,等服务端处理完毕后,使用通知或轮询的方式告知请求方。一般指:请求——响应——通知模式。冗余:增加副本,提高可用性、安全性与性能。安全:对已知问题有有效的解决方案,对未知/潜在问题建立发现和防御机制。自动化:将重复的、不需要人工参与的事情,通过工具的方式,使用机器完成。敏捷性:积极接受需求变更,快速响应业务发展需求。高性能架构
高性能的架构是以用户为中心,提供快速的网页访问体验,主要参数有较短的响应时间、较大的并发处理能力、较高的吞吐量与稳定的性能参数。
可分为前端优化、浏览器优化、应用层优化、代码层优化与存储层优化:
前端优化:网站业务逻辑之前的部分。浏览器优化:减少 HTTP 请求数,使用浏览器缓存,启用压缩,CSS JS 位置,JS 异步,减少 Cookie 传输;CDN 加速,反向代理。应用层优化:处理网站业务的服务器。使用缓存,异步,集群。代码优化:合理的架构,多线程,资源复用(对象池,线程池等),良好的数据结构,JVM调优,单例,Cache 等。存储优化:缓存、固态硬盘、光纤传输、优化读写、磁盘冗余、分布式存储(HDFS)、NoSQL 等。高可用架构
大型网站应该在任何时候都可以正常访问,正常提供对外服务。因为大型网站的复杂性,分布式,廉价服务器,开源数据库,操作系统等特点,要保证高可用是很困难的,也就是说网站的故障是不可避免的。
如何提高可用性,就是需要迫切解决的问题。首先,需要从架构级别考虑,在规划的时候,就考虑可用性。
行业内一般用几个 9 表示可用性指标,比如四个 9(99.99),一年内允许的不可用时间是 53 分钟。
不同层级使用的策略不同,一般采用冗余备份和失效转移解决高可用问题:
应用层:一般设计为无状态的,对于每次请求,使用哪一台服务器处理是没有影响的。一般使用负载均衡技术(需要解决 Session 同步问题)实现高可用。服务层:负载均衡,分级管理,快速失败(超时设置),异步调用,服务降级,幂等设计等。数据层:冗余备份(冷,热备[同步,异步],温备),失效转移(确认,转移,恢复)。数据高可用方面著名的理论基础是 CAP 理论。(持久性,可用性,数据一致性[强一致,用户一致,最终一致])可伸缩架构
伸缩性是指在不改变原有架构设计的基础上,通过添加/减少硬件(服务器)的方式,提高/降低系统的处理能力:
应用层:对应用进行垂直或水平切分。然后针对单一功能进行负载均衡(DNS、HTTP[反向代理]、IP、链路层)。服务层:与应用层类似。数据层:分库、分表、NoSQL 等;常用算法 Hash,一致性 Hash。可扩展架构
可以方便地进行功能模块的新增/移除,提供代码/模块级别良好的可扩展性:
模块化,组件化:高内聚,低耦合,提高复用性,扩展性。稳定接口:定义稳定的接口,在接口不变的情况下,内部结构可以“随意”变化。设计模式:应用面向对象思想,原则,使用设计模式,进行代码层面的设计。消息队列:模块化的系统,通过消息队列进行交互,使模块之间的依赖解耦。分布式服务:公用模块服务化,提供其他系统使用,提高可重用性,扩展性。安全架构
对已知问题有有效的解决方案,对未知/潜在问题建立发现和防御机制。对于安全问题,首先要提高安全意识,建立一个安全的有效机制,从政策层面,组织层面进行保障。
比如服务器密码不能泄露,密码每月更新,并且三次内不能重复;每周安全扫描等。
以制度化的方式,加强安全体系的建设。同时,需要注意与安全有关的各个环节。
安全问题不容忽视,包括基础设施安全,应用系统安全,数据保密安全等:
基础设施安全:硬件采购,操作系统,网络环境方面的安全。一般采用正规渠道购买高质量的产品,选择安全的操作系统,及时修补漏洞,安装杀毒软件防火墙。防范病毒,后门。设置防火墙策略,建立 DDOS 防御系统,使用攻击检测系统,进行子网隔离等手段。
应用系统安全:在程序开发时,对已知常用问题,使用正确的方式,在代码层面解决掉。防止跨站脚本攻击(XSS),注入攻击,跨站请求伪造(CSRF),错误信息,HTML 注释,文件上传,路径遍历等。
还可以使用 Web 应用防火墙(比如:ModSecurity),进行安全漏洞扫描等措施,加强应用级别的安全。
数据保密安全:存储安全(存储在可靠的设备,实时,定时备份),保存安全(重要的信息加密保存,选择合适的人员复杂保存和检测等),传输安全(防止数据窃取和数据篡改)。常用的加解密算法(单项散列加密[MD5、SHA],对称加密[DES、3DES、RC]),非对称加密[RSA]等。
敏捷性
网站的架构设计,运维管理要适应变化,提供高伸缩性,高扩展性。方便的应对快速的业务发展,突增高流量访问等要求。
除上面介绍的架构要素外,还需要引入敏捷管理,敏捷开发的思想。使业务,产品,技术,运维统一起来,随需应变,快速响应。
大型架构举例
以上采用七层逻辑架构:
第一层客户层:支持 PC 浏览器和手机 App。差别是手机 App 可以直接通过IP访问,反向代理服务器。第二层前端层:使用 DNS 负载均衡,CDN 本地加速以及反向代理服务。第三层应用层:网站应用集群;按照业务进行垂直拆分,比如商品应用,会员中心等。第四层服务层:提供公用服务,比如用户服务,订单服务,支付服务等。第五层数据层:支持关系型数据库集群(支持读写分离),NOSQL 集群,分布式文件系统集群;以及分布式 Cache。第六层大数据存储层:支持应用层和服务层的日志数据收集,关系数据库和 NOSQL 数据库的结构化和半结构化数据收集。第七层大数据处理层:通过 Mapreduce 进行离线数据分析或 Storm 实时数据分析,并将处理后的数据存入关系型数据库。(实际使用中,离线数据和实时数据会按照业务要求进行分类处理,并存入不同的数据库中,供应用层或服务层使用)
大型电商网站系统架构演变过程
一个成熟的大型网站(如淘宝、天猫、腾讯等)的系统架构并不是一开始设计时就具备完整的高性能、高可用、高伸缩等特性的,它是随着用户量的增加,业务功能的扩展逐渐演变完善的。
在这个过程中,开发模式、技术架构、设计思想也发生了很大的变化,就连技术人员也从几个人发展到一个部门甚至一条产品线。
所以成熟的系统架构是随着业务的扩展而逐步完善的,并不是一蹴而就;不同业务特征的系统,会有各自的侧重点。
例如淘宝,要解决海量的商品信息的搜索、下单、支付;例如腾讯,要解决数亿用户的实时消息传输;百度要处理海量的搜索请求。
他们都有各自的业务特性,系统架构也有所不同。尽管如此,我们也可以从这些不同的网站背景中,找出其中共用的技术。
这些技术和手段广泛运用在大型网站系统的架构中,下面就通过介绍大型网站系统的演化过程,来认识这些技术和手段。
最开始的网站架构
最初的架构,应用程序、数据库、文件都部署在一台服务器上,如下图:
应用、数据、文件分离
随着业务的扩展,一台服务器已经不能满足性能需求,所以将应用程序、数据库、文件各自部署在独立的服务器上,并且根据服务器的用途配置不同的硬件,达到最佳的性能效果。
利用缓存改善网站性能
在硬件优化性能的同时,也通过软件进行性能优化,在大部分的网站系统中,都会利用缓存技术改善系统的性能。
使用缓存主要源于热点数据的存在,大部分网站访问都遵循 28 原则(即 80% 的访问请求,最终落在 20% 的数据上),所以我们可以对热点数据进行缓存,减少这些数据的访问路径,提高用户体验。
缓存实现常见的方式是本地缓存、分布式缓存。当然还有 CDN、反向代理等。
本地缓存,顾名思义是将数据缓存在应用服务器本地,可以存在内存中,也可以存在文件,OSCache 就是常用的本地缓存组件。
本地缓存的特点是速度快,但因为本地空间有限所以缓存数据量也有限。
分布式缓存的特点是,可以缓存海量的数据,并且扩展非常容易,在门户类网站中常常被使用,速度按道理没有本地缓存快,常用的分布式缓存是 Memcached、Redis。
使用集群改善应用服务器性能
应用服务器作为网站的入口,会承担大量的请求,我们往往通过应用服务器集群来分担请求数。
应用服务器前面部署负载均衡服务器调度用户请求,根据分发策略将请求分发到多个应用服务器节点。
常用的负载均衡技术硬件的有 F5,价格比较贵,软件的有 LVS、Nginx、HAProxy。
LVS 是四层负载均衡,根据目标地址和端口选择内部服务器,Nginx 和 HAProxy 是七层负载均衡,可以根据报文内容选择内部服务器。
因此 LVS 分发路径优于 Nginx 和 HAProxy,性能要高些;而 Nginx 和 HAProxy 则更具配置性,如可以用来做动静分离(根据请求报文特征,选择静态资源服务器还是应用服务器)。
数据库读写分离和分库分表
随着用户量的增加,数据库成为最大的瓶颈。改善数据库性能常用的手段是进行读写分离以及分库分表,读写分离顾名思义就是将数据库分为读库和写库,通过主备功能实现数据同步。
分库分表则分为水平切分和垂直切分,水平切分是对一个数据库特大的表进行拆分,例如用户表。
垂直切分则是根据业务的不同来切分,如用户业务、商品业务相关的表放在不同的数据库中。
使用 CDN 和反向代理提高网站性能
假如我们的服务器都部署在成都的机房,对于四川的用户来说访问是较快的,而对于北京的用户访问是较慢的。
这是由于四川和北京分别属于电信和联通的不同发达地区,北京用户访问需要通过互联路由器经过较长的路径才能访问到成都的服务器,返回路径也一样,所以数据传输时间比较长。
对于这种情况,常常使用 CDN 解决,CDN 将数据内容缓存到运营商的机房,用户访问时先从最近的运营商获取数据,这样大大减少了网络访问的路径。比较专业的 CDN 运营商有蓝汛、网宿。
而反向代理,则是部署在网站的机房,当用户请求达到时首先访问反向代理服务器,反向代理服务器将缓存的数据返回给用户。
如果没有缓存数据才会继续访问应用服务器获取,这样做减少了获取数据的成本。反向代理有 Squid、Nginx。
使用分布式文件系统
用户一天天增加,业务量越来越大,产生的文件越来越多,单台的文件服务器已经不能满足需求,这时就需要分布式文件系统的支撑。常用的分布式文件系统有 GFS、HDFS、TFS。
使用 NoSQL 和搜索引擎
对于海量数据的查询和分析,我们使用 NoSQL 数据库加上搜索引擎可以达到更好的性能。并不是所有的数据都要放在关系型数据中。
常用的 NoSQL 有 MongoDB、HBase、Redis,搜索引擎有 Lucene、Solr、Elasticsearch。
将应用服务器进行业务拆分
随着业务进一步扩展,应用程序变得非常臃肿,这时我们需要将应用程序进行业务拆分,如百度分为新闻、网页、图片等业务。
每个业务应用负责相对独立的业务运作。业务之间通过消息进行通信或者共享数据库来实现。
搭建分布式服务
这时我们发现各个业务应用都会使用到一些基本的业务服务,例如用户服务、订单服务、支付服务、安全服务,这些服务是支撑各业务应用的基本要素。
我们将这些服务抽取出来åˆ...
阿里P8十年架构经验,两千字一张图,透析大型网站技术架构 流量视频课程
1 架构演化
大型网站的关注指标
高可用
高性能
易扩展
可伸缩
安全
大型网站的特点
高并发,大流量
高可用
海量数据
用户分布广泛,网络情况复杂
安全环境恶劣
需求快速变更,发布频繁
渐进式发展
大型网站架构演化发展过程
初始阶段,多使用LAMP来搭建,All In One即所有资源存放在一台服务器上
应用服务和数据服务分离,有独立的数据库服务器
使用缓存改善网站性能(依据是二八定律:80%的业务访问集中在20%的数据上)
这里需要考虑哪些数据适合缓存
缓存可以是本地缓存,也可以是远程分布式缓存
需要考虑使用合理的缓存策略,防止透传
使用应用服务器集群改善网站的并发处理能力
如果能通过增加一台服务器的方式来改善负载压力,就可以以同样的方式持续增加服务器来不断改善系统性能,从而实现系统的可伸缩性
这里需要考虑使用哪些负载均衡的策略
数据库读写分离
可以利用主流数据库提供的主从热备功能,通过配置两台数据库的主从关系,同时业内也有很多优秀的开源中间件如Atlas
缓存中的数据,如果更新过快,那么会持续刷新缓存,从而降低性能
使用反向代理和CDN加速网络响应
CDN和反向代理的基本原理都是缓存
CDN部署在网络提供商的机房,用户在请求网络服务时,可以从距离自己最近的网络提供商机房获取数据
反向代理部署在网站的中心机房,当用户的请求到达中心机房后,首先访问的服务器是反向代理服务器,如果反向代理服务器中缓存着用户请求的资源,那么就将其直接返回给用户
CDN的重点:——《大型网站系统与Java中间件实践》
全局调度
缓存技术
内容分发
带宽优化
使用分布式文件系统和分布式数据库系统
网站常用的数据库拆分手段是业务分库,即将不同业务的数据库部署到不同的物理服务器上
使用NoSQL和搜索引擎
ES
MongoDB
业务拆分,使用分而治之的手段将整个网站业务分成不同的产品线
SOA、服务化
中心化的 gataway方式
消息队列
不同服务访问同一个DB等
这部分十分重要,道理很简单,但是执行起来的效果千差万别。
当下火热的微服务,也是基于这种思想。
技术实现方式也有很多
分布式服务
大型网站架构演化的价值观
网站的价值在于它能为用户提供什么价值,在于网站能做什么,而不在于它是怎么做的。因此对于小型网站来说,最需要做的是位用户提供好的服务来创造价值,得到用户的认可,从而活下去,野蛮生长。
大型网站架构技术的核心价值是随网站所需灵活应对, 它是一个演化的过程
驱动大型网站技术发展的主要力量是网站的业务发展,是业务成就了技术,而不是相反。因此要摒弃为了技术而技术的套路
网站架构设计误区
一味追求大公司的解决方案
为了技术而技术
企图用技术解决所有问题
2 架构模式
分层,这是在横向方向对系统进行切分
分层的挑战在于必须合理规划层次边界和接口
分层包括物理分层和逻辑分层两种
分割,这是在纵向方向对系统进行切分
将不同的功能和服务分割开来,包装秤高内聚低耦合的模块单元
分布式
1) 分布式应用和服务;
2) 分布式静态资源;
3) 分布式数据和存储;
4) 分布式计算;
5) 分布式配置、分布式锁、分布式文件系统。。。
1) 分布式意味着服务调用必须通过网络,需要考虑带宽的影响;
2) 服务器越多,宕机的概率越大
分层和分割的目的在于小模块便于分布式部署
带来的问题:
常用的分布式方案:
集群,即多台服务器部署相同的应用,从而构成一个集群,通过负载均衡设备共同对外提供服务
即使访问量很小的分布式应用和服务,也至少要部署到两台服务器来构成一个小集群,这样可以提高系统的可用性
缓存,即将数据放在距离计算最近的位置以加快处理速度
CDN
反向代理
本地缓存
分布式缓存
异步,业务之间的消息传递不是同步调用,而是将一个业务操作分成多个阶段,每个阶段之间通过共享数据的方法异步进行协作
1) 提高系统可用性;
2) 加快网站响应速度;
3) 消除并发访问高峰
通常需要使用消息队列
带来的好处:
冗余
集群带来的必然结果
安全需求的必然结果
自动化,DevOps思维,尽量减少人工干预
自动化发布
自动化代码管理
自动化测试
自动化安全监测
自动化部署
自动化监控
自动化报警
自动化失效转移、恢复
自动化分配资源
......
安全
3 大型网站核心架构要素
性能
一个性能问题可能会导致网站用户严重流失
衡量性能的指标:响应时间、TPS、系统性能计数器等
可用性
没有网站可以完美的7*24运行
网站高可用结构的前提是必然会出现服务器宕机,儿高可用设计的目标是当服务器宕机时,服务或者应用依然可用
必要的手段是集群,即冗余
伸缩性,即通过不断向集群中加入服务器的手段来环节不断上升的用户并发访问压力和不断增长的数据存储需求
衡量标准:是否可以构建集群;是否可以方便的向集群中添加新的服务器
扩展性,直接关注网站的功能,保证可以快速响应需求变更
衡量标准: 网站增加新的业务产品时,是否对现有业务透明无影响
安全性
衡量标准: 针对现存和潜在的各种攻击和窃密手段,是否可以有效的应对
4 瞬时响应 - 网站的高性能架构
不同视角下的网站性能
用户视角
主要是端到端的感觉
主要通过前段优化的手段来提升用户体验
开发人员视角
主要关注应用程序本身以及相关子系统的性能,包括响应延迟、系统吞吐量、并发处理能力、系统稳定性等
主要优化手段: 使用缓存加速数据读取、使用集群提高吞吐能力、使用异步消息加快请求响应、使用代码优化提升程序性能
运维人员视角
主要关注基础设施性能和资源利用率
主要优化手段: 建设优化骨干网、使用高性价比定制服务器、利用虚拟化技术优化资源利用率
性能测试指标
响应时间,即应用执行一个操作需要的时间,包括从发出请求开始到收到最后响应数据所需要的时间
并发数,即系统能够同时处理的请求的数目,也反映了系统的负载特性
吞吐量,即单位时间内系统处理的请求数量,体现系统的整理处理能力
性能计数器, 描述服务器或者操作系统性能的一些数据指标
性能测试方法
性能测试,以系统设计初期规划的性能指标为预期目标,对系统不断增压,验证系统在资源可接受范围内,是否能达到性能预期
负载测试,对系统不断的增加并发请求,知道系统的某项或者多项性能指标达到安全临界值
压力测试,超过安全负载的情况下,继续对系统增压,直到系统崩溃或者不能再处理任何请求
稳定性测试,在特定硬件、软件、网络情况下,给系统加载一定压力,是系统运行较长一段时间,来观察系统是否稳定
Web前端优化
浏览器访问优化
减少http请求
使用浏览器缓存
启用压缩
CSS放在页面最上面,JavaScript放在页面最下面
减少Cookie传输
CDN加速
反向代理
应用服务器性能优化
分布式缓存
一般会使用消息队列,带来的额外好处是会削平峰值
1)不同的缓存服务器之间进行通信,例如JBoss Cache;
2)不同缓存服务器之间不进行通信,例如Memcached
缓存从本质上来说,就是一个内存hash表
缓存需要缓存那些读写比很高、很少变化的数据,一般来说读写比在2:1以上时,缓存才有意义
应用程序读取数据时,首先到缓存中读取,如果缓存不存在或者已失效,再访问数据库,同时将新的数据放入缓存
缓存也需要注意缓存热点数据
缓存预热,在新启动的缓存系统中,在启动时就加载热点数据,这样启动后就可以直接使用
缓存穿透, 应用持续大量访问不存在的数据,因为这类数据不存在于缓存中,因此会大量访问数据库,从而降低性能
对于分布式缓存来说,目前有两类:
异步操作
使用集群
代码优化
多线程
1) 将对象设计成无状态对象;
2) 使用局部对象;
3) 并发访问资源时使用锁
需要注意线程安全问题,方法:
资源复用
主要是单例和资源池(对象池)
数据结构,选择合适的算法
垃圾回收
合理设置垃圾回收策略
存储性能优化
机械硬盘 vs 固态硬盘
B+树 vs LSM树
RAID vs HDFS
5 万无一失 - 网站的高可用架构
网站可用性度量
网站不可用时间 = 故障修复时间点 - 故障发现时间点
网站年度可用性指标 = (1 - 网站不可用时间/年度总时间)* 100%
一般以几个9来表示,2个9是基本可用,网站年度不可用时间小于88小时;3个9是较高可用,网站年度不可用时间小于9小时;4个9是具有自动恢复能力的高可用,网站年度不可用时间小于53分钟;5个9是极高可用性,网站年度不可用时间小于5分钟
网站高可用架构的设计目标是保证服务器硬件故障时服务依然可用、数据依然保存并能够被访问
网站高可用架构的主要手段:数据和服务的冗余备份以及失效转移,一旦服务器宕机,就将服务切换至其他可用的服务器上。
高可用的应用
无状态应用: 应用服务器不保存业务的上下文信息,而仅根据每次请求提交的数据进行相应的业务逻辑处理,多个服务实例之间完全对等,请求提交到任何一个服务器上,处理的结构都是相同的。
通过负载均衡进行无状态服务的失效转移
负载均衡: 主要使用在业务量和数据量较高的情况下,当单台服务器不足以承担所有的负载压力时,通过负载均衡手段,将流量和数据分摊到一个集群组成的多台服务器上, 以提升整体的负载处理能力
应用服务器集群的Session管理
Session复制
Session绑定
利用Cookie记录Session
Session服务器
高可用的服务
分级管理
核心服务与非核心服务隔离
核心服务优先使用高性能服务器
超时设置
异步调用
必须满足可以使用异步调用方式
服务降级
幂等性设计
服务高可用(高可靠)一直是美团外卖的第一要求,为了提高可用性,做了很多策略,包括并不限于上文提出的各种架构设计方案。
其实造成线上问题的很大一部分原因是由于发版造成的,也体现出了SOP的重要性。
关于降级与依赖隔离,可以考虑采用Hystrix实现自动降级与依赖隔离 。
高可用的数据
数据一旦出现问题,对于网站往往是毁灭性的打击,因此保护网站的数据就是保护企业的命脉。
主要手段:数据备份和失效转移
缓存服务高可用
观点一:缓存服务已经承担了业务中绝大多数的数据读取访问,因此需要同样保证高可用
观点二:缓存服务并不是数据存储服务,出现服务不可用导致数据丢失应从别的手段解决,而不是提高缓存服务本身高可用
缓存服务器集群中单机故障,集群规模较大时,数据丢失比例和数据负载压力影响很小。
CAP原理: 一个提供数据服务的存储系统无法同时满足数据一致性(Consistency)、数据可用性(Availibility)、分区耐受性(Parition Tolerance)这三个条件
数据高可用含义:
副本间数据一致
多个副本可读
同时写入数据副本
1)数据持久性
2)数据可访问性
3)数据一致性
数据一致性分类:
1) 数据强一致;
2) 数据用户一致;
3) 数据最终一致
数据备份
1) 异步热备;
2) 同步热备
冷备的优点是简单和廉价,成本和技术难度较低,缺点是不能保证数据最终一致
热备分为两种:
失效转移
1) 心跳检测(Keepalived、Heartbeat);
2) 应用程序访问失败报告
失效确认:
访问转移
数据恢复
高可用网站的软件质量保证
网站发布,它的过程和服务器宕机效果箱单,其对系统可用性的影响也 类似
一般采取批量更新的方式进行,不会一次关掉集群中的全部服务器
自动化测试
一般使用Selenium来进行测试
预发布验证
预发布服务器是一种特殊用途的服务器,它和线上的正式服务器唯一的区别是没有配置在负载均衡服务器上,外部用户无法访问
代码控制
主干开发,分支发布
分支开发,主干发布,这是目前使用的主流方式
自动化发布
火车模型:将每个应用的发布过程看做一次火车旅程,火车定点运行,期间有若干站点,每一站都进行例行检查,不通过的项目下车,通过的项目继续坐着火车旅行,直到火车到达终点。
实际中,可能所有项目在途中都下车了,这样火车不得不回到原点,等待é—...
大型网站图片服务器架构的演进 互联网视频课程
作者:丁浪链接:cnblogs/dinglang/p/4608915.html
知音专栏
程序员的出路
写程序时该追求什么,什么是次要的?
如何准备Java初级和高级的技术面试
公众号注:更多架构技术文章,点击文末阅读原文直达
在主流的Web站点中,图片往往是不可或缺的页面元素,尤其在大型网站中,几乎都将面临“海量图片资源”的存储、访问等相关技术问题。在针对图片服务器的架构扩展中,也会历经很多曲折甚至是血泪教训(尤其是早期规划不足,造成后期架构上很难兼容和扩展)。
本文将以一个真实垂直门户网站的发展历程,向大家娓娓道来。
构建在Windows平台之上的网站,往往会被业内众多技术认为很“保守”,甚至会有点。很大部分原因,是由于微软技术体系的封闭和部分技术人员的短视造成的(当然,主要还是人的问题)。
由于长期缺乏开源支持,所以很多人只能“闭门造车”,这样很容易形成思维局限性和短板。以图片服务器为例子,如果前期没有容量规划和可扩展的设计,那么随着图片文件的不断增多和访问量的上升,由于在性能、容错/容灾、扩展性等方面的设计不足,后续将会给开发、运维工作带来很多问题,严重时甚至会影响到网站业务正常运作和互联网公司的发展(这绝不是在危言耸听)。
很多公司之所以选择Windows(.NET)平台来构建网站和图片服务器,很大部分由创始团队的技术背景决定的,早期的技术人员可能更熟悉.NET,或者团队的负责人认为Windows/.NET的易用性、“短平快”的开发模式、人才成本等方面都比较符合创业初期的团队,自然就选择了Windows。
后期业务发展到一定规模,也很难轻易将整体架构迁移到其它开源平台上了。当然,对于构建大规模互联网,更建议首选开源架构,因为有很多成熟的案例和开源生态的支持(也会有很多坑,就看是你自己最先去踩坑,还是在别人踩了修复之后你再用),避免重复造轮子和支出高额授权费用。对于迁移难度较大的应用,个人比较推荐Linux、Mono、Jexus、Mysql、Memcahed、Redis……混搭的架构,同样能支撑具有高并发访问和大数据量等特点的互联网应用。
单机时代的图片服务器架构(集中式)
初创时期由于时间紧迫,开发人员水平也很有限等原因。所以通常就直接在website文件所在的目录下,建立1个upload子目录,用于保存用户上传的图片文件。如果按业务再细分,可以在upload目录下再建立不同的子目录来区分。例如:upload\QA,upload\Face等。
在数据库表中保存的也是”upload/qa/test.jpg”这类相对路径。
用户的访问方式如下:
http://yourdomain/upload/qa/test.jpg
程序上传和写入方式:
程序员A通过在web.config中配置物理目录D:\Web\yourdomain\upload 然后通过stream的方式写入文件;程序员B通过Server.MapPath等方式,根据相对路径获取物理目录 然后也通过stream的方式写入文件。
优点:实现起来最简单,无需任何复杂技术,就能成功将用户上传的文件写入指定目录。保存数据库记录和访问起来倒是也很方便。
缺点:上传方式混乱,严重不利于网站的扩展。
针对上述最原始的架构,主要面临着如下问题:
随着upload目录中文件越来越多,所在分区(例如D盘)如果出现容量不足,则很难扩容。只能停机后更换更大容量的存储设备,再将旧数据导入。在部署新版本(部署新版本前通过需要备份)和日常备份website文件的时候,需要同时操作upload目录中的文件,如果考虑到访问量上升,后边部署由多台Web服务器组成的负载均衡集群,集群节点之间如果做好文件实时同步将是个难题。集群时代的图片服务器架构(实时同步)
在website站点下面,新建一个名为upload的虚拟目录,由于虚拟目录的灵活性,能在一定程度上取代物理目录,并兼容原有的图片上传和访问方式。
用户的访问方式依然是:
http://yourdomain/upload/qa/test.jpg
优点:配置更加灵活,也能兼容老版本的上传和访问方式。
因为虚拟目录,可以指向本地任意盘符下的任意目录。这样一来,还可以通过接入外置存储,来进行单机的容量扩展。
缺点:部署成由多台Web服务器组成的集群,各个Web服务器(集群节点)之间(虚拟目录下的)需要实时的去同步文件,由于同步效率和实时性的限制,很难保证某一时刻各节点上文件是完全一致的。
基本架构如下图所示:
从上图可看出,整个Web服务器架构已经具备“可扩展、高可用”了,主要问题和瓶颈都集中在多台服务器之间的文件同步上。
上述架构中只能在这几台Web服务器上互相“增量同步”,这样一来,就不支持文件的“删除、更新”操作的同步了。
早期的想法是,在应用程序层面做控制,当用户请求在web1服务器进行上传写入的同时,也同步去调用其它web服务器上的上传接口,这显然是得不偿失的。所以我们选择使用Rsync类的软件来做定时文件同步的,从而省去了“重复造轮子”的成本,也降低了风险性。
同步操作里面,一般有比较经典的两种模型,即推拉模型:所谓“拉”,就是指轮询地去获取更新,所谓推,就是发生更改后主动的“推”给其它机器。当然,也可以采用加高级的事件通知机制来完成此类动作。
在高并发写入的场景中,同步都会出现效率和实时性问题,而且大量文件同步也是很消耗系统和带宽资源的(跨网段则更明显)。
集群时代的图片服务器架构改进(共享存储)
沿用虚拟目录的方式,通过UNC(网络路径)的方式实现共享存储(将upload虚拟目录指向UNC)
用户的访问方式1:
http://yourdomain/upload/qa/test.jpg
用户的访问方式2(可以配置独立域名):
http://img.yourdomain/upload/qa/test.jpg
支持UNC所在server上配置独立域名指向,并配置轻量级的web服务器,来实现独立图片服务器。
优点:通过UNC(网络路径)的方式来进行读写操作,可以避免多服务器之间同步相关的问题。相对来讲很灵活,也支持扩容/扩展。支持配置成独立图片服务器和域名访问,也完整兼容旧版本的访问规则。
缺点 :但是UNC配置有些繁琐,而且会造成一定的(读写和安全)性能损失。可能会出现“单点故障”。如果存储级别没有raid或者更高级的灾备措施,还会造成数据丢失。
基本架构如下图所示:
在早期的很多基于Linux开源架构的网站中,如果不想同步图片,可能会利用NFS来实现。事实证明,NFS在高并发读写和海量存储方面,效率上存在一定问题,并非最佳的选择,所以大部分互联网公司都不会使用NFS来实现此类应用。
当然,也可以通过Windows自带的DFS来实现,缺点是“配置复杂,效率未知,而且缺乏资料大量的实际案例”。另外,也有一些公司采用FTP或Samba来实现。
上面提到的几种架构,在上传/下载操作时,都经过了Web服务器(虽然共享存储的这种架构,也可以配置独立域名和站点来提供图片访问,但上传写入仍然得经过Web服务器上的应用程序来处理),这对Web服务器来讲无疑是造成巨大的压力。所以,更建议使用独立的图片服务器和独立的域名,来提供用户图片的上传和访问。
独立图片服务器/独立域名的好处
图片访问是很消耗服务器资源的(因为会涉及到操作系统的上下文切换和磁盘I/O操作)。分离出来后,Web/App服务器可以更专注发挥动态处理的能力。独立存储,更方便做扩容、容灾和数据迁移。浏览器(相同域名下的)并发策略限制,性能损失。访问图片时,请求信息中总带cookie信息,也会造成性能损失。方便做图片访问请求的负载均衡,方便应用各种缓存策略(HTTP Header、Proxy Cache等),也更加方便迁移到CDN。......
我们可以使用Lighttpd或者Nginx等轻量级的web服务器来架构独立图片服务器。
当前的图片服务器架构(分布式文件系统+CDN)
在构建当前的图片服务器架构之前,可以先彻底撇开web服务器,直接配置单独的图片服务器/域名。但面临如下的问题:
旧图片数据怎么办?能否继续兼容旧图片路径访问规则?独立的图片服务器上需要提供单独的上传写入的接口(服务API对外发布),安全问题如何保证?同理,假如有多台独立图片服务器,是使用可扩展的共享存储方案,还是采用实时同步机制?直到应用级别的(非系统级) DFS(例如FastDFS HDFS MogileFs MooseFS、TFS)的流行,简化了这个问题:执行冗余备份、支持自动同步、支持线性扩展、支持主流语言的客户端api上传/下载/删除等操作,部分支持文件索引,部分支持提供Web的方式来访问。
考虑到各DFS的特点,客户端API语言支持情况(需要支持C#),文档和案例,以及社区的支持度,我们最终选择了FastDFS来部署。
唯一的问题是:可能会不兼容旧版本的访问规则。如果将旧图片一次性导入FastDFS,但由于旧图片访问路径分布存储在不同业务数据库的各个表中,整体更新起来也十分困难,所以必须得兼容旧版本的访问规则。架构升级往往比做全新架构更有难度,就是因为还要兼容之前版本的问题。(给飞机在空中换引擎可比造架飞机难得多)
解决方案如下:
首先,关闭旧版本上传入口(避免继续使用导致数据不一致)。将旧图片数据通过rsync工具一次性迁移到独立的图片服务器上(即下图中描述的Old Image Server)。
在最前端(七层代理,如Haproxy、Nginx)用ACL(访问规则控制),将旧图片对应URL规则的请求(正则)匹配到,然后将请求直接转发指定的web 服务器列表,在该列表中的服务器上配置好提供图片(以Web方式)访问的站点,并加入缓存策略。
这样实现旧图片服务器的分离和缓存,兼容了旧图片的访问规则并提升旧图片访问效率,也避免了实时同步所带来的问题。
整体架构如图:
基于FastDFS的独立图片服务器集群架构,虽然已经非常的成熟,但是由于国内“南北互联”和IDC带宽成本等问题(图片是非常消耗流量的),我们最终还是选择了商用的CDN技术,实现起来也非常容易,原理其实也很简单。
我这里只做个简单的介绍:
将img域名cname到CDN厂商指定的域名上,用户请求访问图片时,则由CDN厂商提供智能DNS解析,将最近的(当然也可能有其它更复杂的策略,例如负载情况、健康状态等)服务节点地址返回给用户。
用户请求到达指定的服务器节点上,该节点上提供了类似Squid/Vanish的代理缓存服务,如果是第一次请求该路径,则会从源站获取图片资源返回客户端浏览器,如果缓存中存在,则直接从缓存中获取并返回给客户端浏览器,完成请求/响应过程。
由于采用了商用CDN服务,所以我们并没有考虑用Squid/Vanish来自行构建前置代理缓存。
上面的整个集群架构,可以很方便的做横向扩展,能满足一般垂直领域中大型网站的图片服务需求(当然,像taobao这样超大规模的可能另当别论)。
经测试,提供图片访问的单台Nginx服务器(至强E5四核CPU、16G内存、SSD),对小静态页面(压缩后大概只有10kb左右的)可以扛住几千个并发且毫无压力。
当然,由于图片本身体积比纯文本的静态页面大很多,提供图片访问的服务器的抗并发能力,往往会受限于磁盘的I/O处理能力和IDC提供的带宽。Nginx的抗并发能力还是非常强的,而且对资源占用很低,尤其是处理静态资源,似乎都不需要有过多担心了。
可以根据实际访问量的需求,通过调整Nginx的参数,对Linux内核做调优,加入分级缓存策略等手段能够做更大程度的优化,也可以通过增加服务器或者升级服务器配置来做扩展,最直接的是通过购买更高级的存储设备和更大的带宽,以满足更大访问量的需求。
值得一提的是,在“云计算”流行的当下,也推荐高速发展期间的网站,使用“云存储”这样的方案,既能帮你解决各类存储、扩展、备灾的问题,又能做好CDN加速。最重要的是,价格也不贵。
总结,有关图片服务器架构扩展,大致围绕这些问题展开:
容量规划和扩展问题。数据的同步、冗余和容灾。硬件设备的成本和可靠性(是普通机械硬盘,还是SSD,或者更高端的存储设备和方案)。文件系统的选择。根据文件特性(例如文件大小、读写比例等)选择是用ext3/4或者NFS/GFS/TFS这些开源的(分布式)文件系统。图片的加速访问。采用商用CDN或者自建的代理缓存、web静态缓存架构。旧图片路径和访问规则的兼容性,应用程序层面的可扩展,上传和访问的性能和安全性等
看完本文有收获?请转发分享给更多人