大型网站技术架构03

永无止境:网站的伸缩性架构

  1. 所谓网站的伸缩性是指不需要改变网站的软硬件设计,仅仅通过改变部署的服务器数量就可以扩大或者缩小网站的服务能力。

  2. 网站架构的伸缩性设计:

    1). 不同功能进行物理分离实现伸缩性:通过增加服务器提高网站处理能力,新增服务器总是从现有服务器中分离出部分功能和服务

     纵向分离(分层后分离):将业务处理流程上不同部分分离部署,实现系统伸缩性。
    
     横向分离(业务分割后分离):将不同的业务模块分离部署,实现系统伸缩性。横向分离的粒度可以非常小,甚至可以一个关键网页部署一个独立服务。
    

    2). 单一功能通过集群规模实现伸缩:使用集群,即将相同服务部署在多台服务器上构成一个集群整体对外提供服务。

      集群伸缩性又可以分为应用服务器集群伸缩性和数据服务集群伸缩性,而数据服务器集群又可分为缓存数据服务器集群和存储数据服务器集群。
    
  3. 应用服务器集群的伸缩性设计:应用服务器应该设计成无状态的,即应用服务器不存储请求上下文信息,如果将部署有相同应用的服务器组成一个集群,每次用户请求都可以发送到集群中任意一台服务器上去

    处理,任何一台服务器的处理结果都是相同的。

    如果HTTP请求分发装置可以感知或者可以配置集群的服务器数量,可以及时发现集群中新上线或下线的服务器,并能向新上线的服务器分发请求,停止向已下线的服务器分发请求,那么就实现了应用服务器集群的伸缩性。

    负载均衡的几种方式:

    1). HTTP重定向负载:简单,但需要两次请求服务器才能完成一次访问,性能差。可能会成为网站访问的瓶颈,使用不多。

    2). DNS域名解析负载均衡:这是利用DNS处理域名解析请求的同时进行负载均衡处理的一种方案。

     优点:将负载均衡的工作转交给DNS,同时许多DNS还支持基于地理位置的域名解析,即会将域名解析成举例用户地理最近的一份服务器地址。
    
     缺点:可能也会将域名解析到已经下线的服务器,导致用户访问失败。
    
     事实上,大型网站总是部分使用DNS域名解析,利用域名解析作为第一级负载均衡手段,即域名解析得到的一组服务器并不是实际提供Web服务的物理服务器,而是将同样提供负载均衡服务的内部服务器,
    
     这组内部负载均衡服务器再次负载均衡,经请求分发到真正的Web服务器。
    

    3). 反向代理负载均衡:大多数反向代理同时提供负载均衡的功能,管理一组Web服务器,将请求根据负载均衡算法转发到不同的Web服务器上。

     优点:负载均衡和反向代理服务器功能集成在一起,部署简单。
    
     缺点:反向代理是所有请求和响应的中转站,其性能可能会成为瓶颈。
    

    4). IP负载均衡:在网络层通过修改请求目标地址进行负载均衡。

    5). 数据链路层负载均衡:数据链路层负载均衡方式是指在通信协议的数据链路层修改mac地址进行负载均衡,又称为三角传输模式,直接路由方式。

     使用三角传输模式的链路层负载均衡是目前大型网站使用最广泛的一种负载手段。在Linux平台最好的链路层负载均衡开源产品时LVS(Linux Virtual Server).
    
  4. 一般对负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术。具体的应用需求还得具体分析,如果是中小型的Web应用,比如日PV小于1000万,用Nginx就完全可以了;如果机器不少,可以用DNS轮询,

    LVS所耗费的机器还是比较多的;大型网站或重要的服务,且服务器比较多时,可以考虑用LVS。

    参考:http://www.ha97.com/5646.html

  5. 负载均衡算法:

    负载均衡服务器的实现可以分成两个部分:

    a. 根据负载均衡算法和Web服务器列表计算得到集群中的一台Web服务器地址

    b. 将请求数据发送到该地址对应的Web服务器上

    具体的轮询算法有一下几种:

    a. 轮询

    b. 加权轮询:根据应用服务器硬件性能的情况,在轮询的基础上,按照配置的权重将请求分发到每个服务器,高性能的服务器能分配更多的请求。

    c. 随机:请求被随机分配到各个应用服务器,在许多场合下,这种方案都很简单实用,因为好的随机数本身就很均衡。即使应用服务器硬件配置不同,也可以使用加权随机算法。

    d. 最少连接:记录每个应用服务器长在处理的连接数(请求数),将新到的请求分发到最少连接的服务器上,应该说,这是最符合负载均衡定义的算法。同样,最少连接算法也可以实现加权最少连接。

    e. 源地址散列:根据请求来源的IP地址进行Hash计算,得到应用服务器,这样来自同一个IP地址的请求总是在同一个服务器地址上,该请求的上下文信息可以存储在这台服务器上,在一个会话周期内重复使用,从而实现会话粘滞。

  6. 分布式缓存集群的伸缩性设计

  7. 数据存储服务器集群的伸缩性设计

    1). 关系型数据库集群的伸缩性设计:

     a. 主从读写分离
    
     b. 数据分库,这种方式的制约条件时跨库表不能进行Join操作
    
     在大型网站的实际应用中,即使进行了分库和主从复制,对一些单表数据仍然很大的表,还需要进行分片,将一张表拆开分别存储在多个数据库中。目前网站在线业务应用中比较成熟的支持数据分片的
    
     分布式关系数据库产品主要有开源的的Amoeba和Cobar。这两个产品有相似的架构:
    
     Cobar是一个分布式关系数据库访问代理,介于应用服务器和数据库服务器之间。应用程序通过JDBC驱动访问Cobar集群,Cobar服务器根据SQL和分库规则分解SQL,分发到MYSQL集群不同的数据库实例上执行(每
    
     个MySQL实例都部署为主从结构,保证数据高可用),执行完将结果返回至SQL执行模块,通过结果合并模块将两个返回值合并成一个结果集,最终返回给应用程序,完成分布式数据库的一次访问。
    
     select * from users where userid in (12,22,23)  可以被拆分为:select * from users where userid in (12,22) 和  select * from users where userid in (23)              
    
     那么Cobar如何做集群的伸缩性呢?
    
     Cobar的伸缩有两种:Cobar服务集群的伸缩和MySQL服务集群的伸缩。
    
     Cobar服务器可以看作是无状态的应用服务器,因此其集群伸缩可以简单实用负载均衡的手段实现。而MySQL中存储着数据,要想保证集群扩容后数据一致负载均衡,必须做数据迁移,将集群中原来机器中的
    
     数据迁移到新添加的机器中。实践中,Cobar利用了MySQL的数据同步功能进行数据迁移,数据同步不是以数据为单位,而是以Schema为单位。
    

    2). NoSQL数据库的伸缩性设计:NoSQL,主要指非关系的、分布式的数据库设计模式。也有许多专家将NoSQL解读为Not Only SQL ,表示NoSQL这是关系数据库的补充,而不是替代方案。一般而言,NoSQL数据库

      都放弃了关系数据库的两大重要基础:以关系代数为基础的结构化查询语言(SQL)和事务一致性保证(ACID)。而强化其他一些大型网站更关注的特性:高可用性和可伸缩性。
    

随需应变:网站的可扩展性架构

扩展性(Extensibility):指对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力

伸缩性(Scalability):指系统通过增加(减少)自身资源规模的方式强化(减少)自己计算处理事务的能力。

  1. 构架可扩展的网站架构:开发低耦合系统是软件设计的终极目标之一。

    软件架构师最大的价值不在于掌握多少先进的技术,而在于将具有将一个大系统分成N个耦合的子模块的能力,这些子模块包含横向的业务模块,也包括纵向的基础技术模块。

    设计网站可扩展架构的核心思想是模块化,并在此基础上,降低模块间的耦合性,提高模块的复用性。分层和分割也是模块化设计的重要手段,利用分层和分割的方式将软件分割为若干个低耦合的独立的组件

    模块,这些组件模块以消息传递及依赖调用的方式聚合成一个完整系统。

    模块分布式部署以后具体聚合方式主要有分布式消息队列和分布式服务。

  2. 利用分布式消息队列降低系统耦合性

    1). 事件驱动架构:通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间的合作。消息发布-订阅的模式。

    2). 分布式消息队列:队列是一种先进先出的数据结构,分布式消息队列可以看作将这种数据结构部署到独立的服务器上,应用程序可以通过远程访问接口使用分布式消息队列,进行消息存储操作,进而实现分布式异步调用。

     开源的分布式消息队列有很多,比较有名的是ActiveMQ等。伸缩性(分布式),可用性(如果队列已满,会将消息写入磁盘,消息推送模块在将内存队列消息处理完成以后,将磁盘内容添加到内存队列继续处理)
    
     为了避免消息队列宕机造成消息丢失,会将消息成功发送到消息队列的消息存储在消息生产者服务器,等消息真正被消息消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列
    
     服务器集群中的其他的服务器发布消息。
    
  3. 利用分布式服务打造可复用的业务平台:如果说分布式消息队列通过消息对象分解系统耦合性,不同子系统处理同一个消息;那么分布式服务则通过接口分解系统耦合性,不同子系统通过相同的接口描述进行服务调用。

    1). Web Service与企业级分布式服务:服务提供者通过WSDL向注册中心描述自身提供的服务接口属性,注册中心使用UDDI发布服务提供者提供的服务,服务请求者从注册中心检索到服务信息后,通过SOAP和服务

     通信使用相关业务。
    
     缺点:臃肿的注册和发现机制,低效的XML序列化手段,开销相对较高的HTTP远程通信,复杂的部署与维护手段
    

    2). 大型网站分布式服务的需求与特定:

     对于大型网站,除了Web Service所提供的服务器注册与发现,服务调用等标准功能,还需分布式服务框架能够支持如下功能:
    
     a. 负载均衡
    
     b. 失效转移
    
     c. 高效的远程通信
    
     d. 整合异构系统:不同语言的系统
    
     e. 对应用侵入最少
    
     f. 版本控制:分布式框架需要支持服务多版本发布,服务提供者先升级接口发布新版本的服务,并同时提供旧版本的服务供请求者调用,当请求者调用接口升级后才可以关闭旧版本服务。
    
     g. 实时监控
    

    3). 分布式服务框架设计:

     以阿里巴巴分布式开源框架Dubbo为例,分析其架构设计:
    
     服务消费者程序通过服务接口使用服务,而服务接口通过代理加载具体服务,具体服务可以是本地的代码模块,也可以是远程服务,因此对应用较少侵入:应用程序只需要调用服务接口,服务框架根据
    
     配置自动调用本地或远程实现。
    
     服务架构客户端模块通过服务注册中心加载服务提供者列表(服务提供者启动后自动向服务注册中心注册自己可提供的服务接口列表),查找需要的服务接口,并根据配置的负载均衡策略将服务请求发送
    
     到某台服务提供者服务器。如果服务调用失败,客户端模块会自动从服务提供者列表选择一个可提供同样服务的另一台服务器重新请求服务,实现服务的自动失效转移,保证服务高可用性。
    
     Dubbo的远程服务通信模块支持多种通信协议和数据序列化协议,使用NIO通信框架,具有较高的网络通信性能。
    
  4. 可扩展的数据结构:mongoDB ?

  5. 利用开放平台建设网站生态圈:

    大型网站为了更好地服务自己的用户,开发更多的增值业务,会把网站内部的服务封装成一些调用接口开放出去,供外部的第三方开发者使用,这个提供开放接口的平台被称为开放平台。第三方开发者利用

    这个开放的接口开发应用程序或网站,为更多的用户提供价值。网站、用户、第三方开发者互相依赖,形成一个网站的生态圈。

    开放平台的架构设计:API接口,协议转换,安全,审计,路由,流程

固若金汤:网站的安全架构

  1. 道高一尺魔高一丈的网站应用攻击与防御

    1). XSS攻击:XSS攻击即跨站点脚本攻击(Cross Site Script),指黑客通过篡改网页,注入恶意HTML脚本,在用户浏览网页时,控制用户浏览器恶意操作的一种攻击方式。

     常见的XSS攻击类型有两种:
    
     a. 反射型:攻击者诱使用户点击一个嵌入恶意脚本的链接,达到攻击的目的。
    
     b. 持久性XSS攻击:黑客提交含有恶意脚本的请求,保存在被攻击的Web站点的数据库中,用户浏览网页时,恶意脚本被包含在正常页面,达到攻击的目的。此攻击经常使用在论坛,博客等Web应用中。
    
     防止XSS攻击的手段主要有如下两种:
    
     a. 消毒:XSS攻击者一般都是通过在请求中嵌入恶意脚本达到攻击的目的,这些脚本是一般用户不使用的,如果进行过滤和消毒处理,即对某些html危险字符转义,如">"转义为"&gt"等,就可以防止大部分攻击。
             为了避免对不必要的内容错误转义,如"3<5"中的"<"需要进行文本匹配后的转义,如"<img src"这样的上下问中的"<"才转义。事实上消毒几乎是所有网站必备的XSS防攻击手段。
    
    b. HttpOnly:即浏览器禁止页面JS访问带有HttpOnly属性的Cookie。HttpOnly并不是直接对抗XSS攻击的,而是通过防止XSS攻击者窃取Cookie。对于敏感信息的Cookie,如用户认证信息等。可以通过对该
     Cookie添加HttpOnly属性,避免被攻击脚本窃取。
    

    2). 注入攻击:

     SQL注入需要攻击者对表结构有所了解,获取表结构的方法有一下集中:开源(开源网站搭建,别人也可能知道代码),错误回显(根据错误信息,猜到代码结构),盲注(根据页面变化,猜测SQL结构,难度较大)
    
     防SQK注入攻击:消毒(通过正则表达式匹配,过滤请求数据中可能注入的SQL),参数绑定(使用预编译手段,绑定参数是最好的防SQL注入方法)
    

    3). CSRF攻击:

     CSRF(Cross Site Request Forgery,跨站点请求伪造),攻击者通过跨站点请求,以合法用户身份进行非法操作,如转账交易、发表评论等。CSRF的主要手法是利用跨站点其请求,在用户不知情的情况下,
    
     以用户身份伪造请求。其核心是利用了浏览器的Cookie或服务器Session策略,盗取用户身份。
    
     相应的,CSRF的防御手段主要是识别请求者身份。主要有一下几种方法:
    
     表单Token,验证码(用户体验较差),Referer check(HTTP请求头的Referer域记录着请求来源,可通过检查请求来源验证其是否合法。如防图片盗用)
    

    4). 其他攻击和漏洞

     a. Error Code:错误回显。防御手段也很简单:通过配置Web服务器参数,跳转500页面(HTTP响应码500表示服务器内部错误)到专门错误页面即可,Web引用常用的MVC框架也有这功能。
    
     b. HMTL注释
    
     c. 文件上传:控制文件上传类型
    
     d. 路径遍历:攻击者在请求的URL中使用相对路径,遍历系统未开放地目录和文件。防御方法主要是将JS、CSS等资源文件部署在独立服务器、使用独立域名,其他文件不使用静态URL访问,动态参数不包含文件路径信息。
    

    5). Web应用防火墙:

     ModSecurity是一个开源的Web应用防火墙,探测攻击并保护Web应用程序,既可以嵌入到Web应用服务器中,也可以作为一个独立的应用程序启动。ModSecurity最早只是Apache的一个模块,现在应有Java等多个版本,
    
     并且支持Nginx。
    

    6). 网站安全漏洞扫描

  2. 信息加密技术及密匙安全管理

    1). 单向散列加密:将加密后的内容保存到数据库。用户使用时,拿用户的输入信息加密后比较是否相同。常用算法:MD5,SHA等。

    2). 对称加密:指加密和解密使用的密匙是同一个密匙。 优点:算法简单,加密效率高,系统开销小,适合对大量数据加密。 缺点:远程通信的情况下如何安全交换密匙是一个难题,如果密匙丢失,会导致信息泄露。

                    常用算法:DES算法,RC算法等。
    

    3). 非对称加密:对外界公开的,被称为公钥,另一个只有所有者知道,被称为私匙。用公钥加密的信息必须用私匙才能解开,用私匙加密的信息只有公钥才能解开。

    4). 密匙的安全管理:

     a. 把密匙和算法放在一个独立的服务器上,甚至做成一个专用的硬件设施,对外提供加密和解密服务,应用系统调用这个服务,实现数据的加密。
    
     b. 将加密算法放到应用系统中,密匙放到独立服务器中,为了提高密匙的安全性,实际存储事,密匙被切分成数片,加密后分别保存在不同的存储介质中,兼顾安全性的同时又改善了性能。
    
  3. 信息过滤与反垃圾:

    1). 文本匹配:Trie算法,构造多级hash表进行文本匹配。

    2). 分类算法:

    3). 黑名单

  4. 电子商务风险控制:

    1). 风险:

     a. 账户风险:包括账户被盗用,恶意注册账户等
    
     b. 买家风险:恶意下单,黄牛利用促销抢购,良品拒收等
    
     c. 卖家风险:欺诈行为,虚假发货等
    
     d. 交易风险:信用卡盗刷,支付欺诈,洗钱套现等
    

    2). 风控:

     a. 规则引擎:当交易的某些指标满足一定条件时,就会被认为具有高风险的欺诈可能性。
    
     b. 统计模型:智能统计,得到交易风险分值。