Skip to content

Latest commit

 

History

History
213 lines (121 loc) · 15.4 KB

《大型网站技术架构》学习笔记4 评价网站的五项指标.md

File metadata and controls

213 lines (121 loc) · 15.4 KB

核心五要素:性能 可用性 伸缩性 扩展性 安全性

高可用性

硬件故障和软件升级是常态,如何在这两种情况下保证网站的可用性:数据和服务的冗余备份,失效转移。

集群管理

只要其架构形式为分布式的架构,就需要分布式的管理方法

位于应用层的服务器通常为了应对高,发的访问请求,会通过负载均衡设备将一组服务器组成一个集群共同对外提供服务,当负载均衡设备通过心跳检测等手段监控到某台应用服务器不可用时,就将其从集群列表中剔除,并将请求分发到集群中其他可用的服务器上,使整个集群保持可用,从而实现应用高可用。 位于服务层的服务器情况和应用层的服务器类似,也是通过集群方式实现高可用。

应用服务器的Session管理

应用服务器的状态分离: 无状态的应用服务器 + 有状态的Session服务器

应用服务器的高可用架构设计主要基于服务无状态这一特性,但是事实上,业务总是有状态的,在交易类的电子商务网站,需要有购物车记录用户的购买信息,用户每次购买请求都是向购物车中增加商品;在社交类的网站中,需要记录用户的当前登录状态、最新发布的消息及好友状态等,用户每次刷新页面都需要更新这些信息。 Web应用中将这些多次请求修改使用的上下文对象称作会话(Session),单机情况下,Session可由部署在服务器上的Web容器(如JBoss)管理。在使用负载均衡的集群环境中,由于负载均衡服务器可能会将请求分发到集群任何一台应用服务器上,所以保证每次请求依然能够获得正确的Session比单机时要复杂很多。

四种方案。

  1. 同步,每个应用服务器存全部session –- 小服务规模可用

  2. 负载均衡,根据客户端的IP地址,让其访问固定的服务器 -- 可用性较差,宕机服务器中的session丢失

  3. 把Session转Cookie -- 常用,小Session适用

  4. Session服务器集群 -- 常用,应用服务器每次读写Session时,都访问Session服务器 应用服务器的状态分离: 无状态的应用服务器 + 有状态的Session服务器

    对于有状态的Session服务器,一种比较简单的方法是利用分布式缓存、数据库等,在这些产品的基础上进行包装,使其符合Session的存储和访问要求。如果业务场景对Session管理有比较高的要求,比如利用Session服务集成单点登录(SSO)、用户服务等功能,则需要开发专门的Session服务管理平台。

其他高可用方案

  1. 分级管理 核心应用和服务,优先使用更好的硬件。

  2. 超时设置 在应用程序中设置服务调用的超时时间,一旦超时,通信框架就抛出异常,应用程序根据服务调度策略,可选择继续重试或将请求转移到提供相同服务的其他服务器上。

  3. 异步调用 应用对服务的调用通过消息队列等异步方式完成,避免一个服务失败导致整个应用请求失败的情况。

    当然不是所有服务调用都可以异步调用,对于获取用户信息这类调用,采用异步方式会延长响应时间,得不偿失。对于那些必须确认服务调用成功才能继续下一步操作白应用也不合适使用异步调用。

  4. 服务降级 访问高峰期,只保证核心应用和服务的正常运行。 两种手段:拒绝服务 + 关闭功能

    拒绝服务:拒绝低优先级应用的调用,减少服务调用并发数,确保核心应用正常使用;或者随机拒绝部分请求调用,节约资源,让另一部分请求得以成功,避免要死大家一起死的惨剧。貌似Twittr比较喜欢使用随机拒绝请求的策略,经常有用户看到请求失败的故障页面,但是问下身边的人,其他人都正常使用,自己再刷新页面,也好了。 关闭功能:关闭部分不重要的服务,或者服务内部关闭部分不重要的功能,以节约系统开销,为重要的服务和功能让出资源。淘宝在每年的“双十一”促销中就使用这种方法,在系统最繁忙的时段关闭“评价”、“确认收货”等非核心服务,以保证核心交易服务的顺利完成。

  5. 交易编号 对于转账交易等操作,可能出现服务重复调用(应用服务器需要重试到成功为止,但可能出现虚假的失败),需要对其交易进行编号操作。

数据高可用

数据一致性

CAP原理:CAP原理认为,一个提供数据服务的存储系统无法同时满足数据一致性(Consistency)、数据可用性(Availibility)、分区耐受性(Patition Tolerance,系统具有跨网络分区的伸缩性)这三个条件。

对于大网站来说,伸缩性和可用性必不可少。大型网站中,通常会选择强化分布式存储系统的可用性(A)和伸缩性(P),而在某种程度上牺牲一定的一致性(C).

数据一致性的三种级别:

  • 数据强一致 各个副本的数据在物理存储中总是一致的;数据更新操作结果和操作响应总是一致的,即操作响应通知更新失败,那么数据一定没有被更新,而不是处于不确定状态。(类似数据库的表锁,锁的串行状态)
  • 数据用户一致 即数据在物理存储中的各个副本的数据可能是不一致的,但是终端用户访问时,通过纠错和校验机制,可以确定一个一致的且正确的数据返回给用户。
  • 数据最终一致 这是数据一致性中较弱的一种,即物理存储的数据可能是不一致的,终端用户访问到的数据可能也是不一致的(同一用户连续访问,结果不同;或者不同用户同时访问. 结果不同),但系统经过一段时间(通常是一个比较短的时间段)的自我恢复和修正,数据最终会达到一致。

因为难以满足数据强一致性,网站通常会综合成本、技术、业务场景等条件,结合应用服务和其他的数据监控与纠错功能,使存储系统达到用户一致,保证最终用户访问数据的正确性。

备份

冷备份,技术简单易操作,但是备份点之后的数据丢失,单使用冷备份可能丢失重要数据;实时网站需要在定期冷备份的基础上,进行热备份

热备份:异步、同步两种方案

关系数据库热备份:异步,Master - Slave同步机制。读写分离:写操作只访问Master数据库,读操作只访问Slave数据库

伸缩性

应用服务器 -- 负载均衡

负载均衡是基础技术,可用于任意的无状态服务器集群

两层多叉树结构:第一层,DNS负载均衡指向一堆内部负载均衡服务器;第二层,由这些负载均衡服务器来指向实际的服务器。

分布式缓存服务器集群的扩容 -- 一致性Hash算法

p127

使用余数hash,会在扩容时出现大规模缓存不能命中,导致数据库宕机!

一致性hash算法的hash环会引入负载不均衡问题。解决:添加一层虚拟层:加入新节点时,是将一组虚拟节点(150个)加入hash环中。

关系数据库的伸缩性

Cobar:添加负载均衡层 -- 路由模块

Cobar被称为数据库中间件,常用于分库分表。MySQL主流中间件:Atlas,cobar(继承者MyCAT),TDDL等。

Cobar:

阿里巴巴B2B开发的关系型分布式系统,管理将近3000个MySQL实例。 在阿里经受住了考验,后面由于作者的走开的原因cobar没有人维护 了,阿里也开发了tddl替代cobar。

MyCAT:

社区爱好者在阿里cobar基础上进行二次开发,解决了cobar当时存 在的一些问题,并且加入了许多新的功能在其中。目前MyCAT社区活 跃度很高,目前已经有一些公司在使用MyCAT。

访问流程:

前端通信模块负责和应用程序通信,接收到SQL请求(select from users where useric in(12,22,23)后转交给SQL解析模块,SQL解析模块解析获得SQL中的路由规则查询条件(userid in(12,22,23)再转交给SQL路由模块,SQL路由模块根据路由规则配置userid为偶数路由至数据库A,userid为奇数路由至数据库B)将应用程序提交的SQL分解成两条SQL(selectfrom users where userid in(12,22);selectfrom users where userid in(23);)转交给SQL执行代理模块,发送至数据库A和数据库B分别执行。数据库A和数据库B的执行结果返回至SQL执行模块,通过结果合并模块将两个返回结果集合并成一个结果集,最终返回给应用程序,完成在分布式数据库中的一次访问请求。

Cobar的伸缩有两种:Cobar服务器集群的伸缩和MySQL服务器集群的伸缩。 Cobar服务器可以看作是无状态的应用服务器,因此其集群伸缩可以简单使用负载均衡的手段实现。而MySQL中存储着数据,要想保证集群扩容后数据一致负载均衡,必须要做数据迁移,将集群中原来机器中的数据迁移到新添加的机器中。(拆迁)

在路由模块使用一致性hash算法以决定具体迁移哪些数据(可使迁移量最少)。

使用MySQL的数据同步功能进行数据迁移,以Scheme为单位。

取舍:

相比关系数据库本身功能上的优雅强大,目前各类分布式关系数据库解决方案都显得非常简陋,限制了关系数据库某些功能的使用。但是当网站业务面临不停增长的海量业务数据存储压力时,又不得不利用分布式关系数据库的集群伸缩能力,这时就必须从业务上回避分布式关系数据库的各种缺点:避免事务或利用事务补偿机制代替数据库事务;分解数据访问逻辑避免JOIN操作等。

NoSQL的伸缩性

业界为了解决关系数据库的不足,提出了诸多方案,比较有名的是对象数据库,但是这些数据库的出现只是进一步证明关系数据库的优越而已。直到大型网站遇到了关系数据库难以克服的缺陷--糟糕的海量数据处理能力及僵硬的设计约束,局面才有所改善。为了解决上述问题,NoSQL这一概念被提了出来,以弥补关系数据库的不足。 NoSQL,主要指非关系的、分布式的数据库设计模式。也有许多专家将NosSQL解读为Not Only SQL.表示NoSQL只是关系数据库的补充,而不是替代方案。一般而言,NosQL数据库产品都放弃了关系数据库的两大重要基础:以关系代数为基础的结构化查询语言(SQL)和事务一致性保证(ACID),而强化其他一些大型网站更关注的特性:高可用性和可伸缩性。

可扩展性

如此轻易地就可以开发一个新产品,如此快速地就可以实现一个新功能,他们是如何做到的?

为什么有的网站必须规定系统发布日,一到发布日就如临大敌,整个技术部加班通宵达旦;而有的网站就可以随时发布,新功能可以随时快速上线。

这些都有赖于网站的扩展性架构设计,就是在对现有系统影响最小的情况下,系统功能可持续扩展及提升的能力

设计网站可扩展架构的核心思想模块化,并在此基础上,降低模块间的耦合性,提高模块的复用性。

扩展性(Extensibility)

keyword: 低耦合 开闭原则

指对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力。表现在系统基础设施稳定不需要经常变更,应用之间较少依赖和耦合,对需求变更可以敏捷响应。它是系统架构设计层面的开闭原则(对扩展开放,对修改关闭),架构设计考虑未来功能扩展,当系统增加新功能时,不需要对现有系统的结构和代码进行修改。

笔者认为,软件架构师最大的价值不在于掌握多少先进的技术,而在于具有将一个大系统切分成N个低耦合的子模块的能力。

伸缩性容易和扩展性混淆,一并描述。

伸缩性(Scalability)

keyword: 集群,热插拔

指系统能够通过增加(减少)自身资源规模的方式增强(减少)自己计算处理事务的能力。如果这种增减是成比例的,就被称作线性伸缩性。在网站架构中,通常指利用集群的方式增加服务器数量、提高系统的整体事务吞吐能力。

消息队列

其本质是利用生产者消费者设计模式对通信双方进行解耦合。

事件驱动架构(Event Driven Architecture):通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间合作,典型的EDA架构就是操作系统中常见的生产者消费者模式。在大型网站架构中,具体实现手段有很多,最常用的是分布式消息队列。

发布 - 订阅模式,消息发送者将消息发送至分布式消息队列即结束对消息的处理,而消息接受者只需要从分布式消息队列获取消息后进行处理,不需要知道该消息从何而来。对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原系统和业务没有任何影响。

由于消息发送者不需要等待消息接受者处理数据就可以返回,系统具有更好的响应延迟;同时,在网站访问高峰,消息可以暂时存储在消息队列中等待消息接受者根据自身负载处理能力控制消息处理速度,减轻数据库等后端存储的负载压力。

阿里巴巴开源框架,Dubbo --生产者消费者模式,NIO。服务自动注册与发现。

消息队列 命名格式为xx - MQ的产品

安全性

XSS攻击

JavaScript脚本,通过输入转义进行跳转执行脚本窃取Cookie等信息

防御

消毒

用户输入不可信,限制转义字符的使用,关闭不使用的,常用的严格限制匹配再转义

HttpOnly

浏览器禁止页面JavaScript访问带有HttpOnly属性的Cookie。对Cookie添加HttpOnly属性,避免被攻击脚本窃取

注入攻击

防御

消毒

和防XSS攻击一样,请求参数消毒是一种比较简单粗暴又有效的手段。通过正则匹配,过滤请求数据中可能注入的SQL,如"drop table"、"b(?:updateb.*?bset Ideletebiw?bfrom)b"等。

参数绑定

使用预编译手段,绑定参数是最好的防SQL注入方法。目前许多数据访问层框架。如IBatis,Hibernate等,都实现SQL预编译和参数绑定,攻击者的恶意SQL会被当做SQL的参数,而不是SQL命令被执行。 除了SQL注入,攻击者还根据具体应用,注入Os命令、编程语言代码等,利用程序漏洞,达到攻击目的。

CSRF攻击

CSRF(Cross Site Request Forgery,跨站点请求伪造),攻击者通过跨站请求,以合法用户的身份进行非法操作,如转账交易、发表评论等,如图8.4所示。CSRF的主要手法是利用跨站请求,在用户不知情的情况下,以用户的身份伪造请求。其核心是利用了浏览器Cookie或服务器Session策略,盗取用户身份。

其防御手段主要是识别用户身份。