五个要素能不能都要呢?
网站的性能是客观的指标,可以具体体现到响应时间、吞吐量等技术指标,同时也是主观感受。
用户视角的性能:
就是用户在浏览器上直观感受到的网站响应速度快还是慢。
开发人员眼中的性能:
相关的优化手段有:
运维人员视角的性能主要是基础设施性能和资源利用率,包括:
主要优化手段:
性能测试指标主要有:
*响应时间
并发数
反映系统的负载特性
网站系统用户数>>网站在线用户数>>网站并发用户数
吞吐量
体现系统的整体处理能力,TPS、HPS和QPS
性能计数器
性能测试方法:
性能优化策略:
思路:如果性能测试结果不满足设计或业务需求,那么就需要寻找系统瓶颈,分而治之,逐步优化
性能分析
基本方法:检查请求处理的各个环节日志,分析哪个环节响应时间不合理、超过预期;然后检查监控数据,分析影响性能的主要因素是内存、磁盘、网络或CPU,是代码还是架构设计不合理,或者系统资源确实不足。
性能优化
根据网站分层架构,可分为Web前端性能优化、应用服务器性能优化、存储服务器性能优化。
主要优化手段:优化浏览器访问、使用反向代理、CDN
减少HTTP请求
使用浏览器缓存
启用压缩
CSS放最上面,JS放最先
浏览器会在下完全部CSS后才对页面进行渲染,最好的做法是将CSS放在最上面,尽快下载CSS。JS相反,浏览器在加载JS后立即执行,有可能会阻塞整个页面,造成显示缓慢,因此JS最好放在页面最下面。
减少cookie传输
反向代理的功能= 请求转发+负载均衡+缓存
优化手段主要有缓存、集群和异步
网站性能优化第一定律:优先考虑使用缓存优化性能
缓存穿透 缓存击穿 缓存雪崩
缓存的优势在于:1. 提升IO速度;2. 减少重复计算,同时因为局部性原理的存在,所以缓存很实用
合理使用缓存
使用缓存要注意的问题:
一个集群要解决什么问题?
分布式缓存集群的第一个问题:各个集群直接需不需要互相通信?需不需要同步?
代表之作,Memcached,一致性哈希算法等路由算法
Memcached的特点:
简单的通信协议
使用TCP协议
丰富的客户端程序
支持Memcached的通信协议就可以和Memcached的机器通信
高性能的网络通信
通信模块:Libevent,一个支持事件出发的网络通信程序库。
高效的内存管理
固定空间分配,使用LRU算法。
互不通信的服务器集群架构
使其拥有更好的伸缩性,几乎可以做到线性增长。
主要是消息队列。
名言:任何可以晚点做的事情都应该晚点再做
将请求分散到集群上的不同机器去解决。
多线程(多协程)
解决线程安全的一些手段:
资源复用
主要的复用方法:减少资源创建时的消耗
数据结构
随机散列算法一般是通过先对字符串取信息指纹,再对信息指纹取hashcode。
垃圾回收
提高利用率。
B+树:
B+树一般两层索引,最后一层是叶子ID,一般更新一个记录需要5次磁盘IO(三次磁盘访问获得数据索引及行ID,然后再进行一次数据文件读操作及一次写操作)
LSM树(日志结构合并树):https://zhuanlan.zhihu.com/p/181498475
LSM树一般用在NoSQL数据库。简单介绍一下,之后必须要补充一下LSM树的结构。
LSM树可以看成是N阶合并树,数据写操作都在内存中进行,并且都会创建一个新纪录(修改会记录新数据值,而删除会记录一个删除标志),这些数据在内存中仍然还是一颗排序树,当数据量超过设定的内存阈值后,会将这颗排序树与磁盘上最新的排序树合并。当这颗排序树的数据量也超过设定阈值后,和磁盘上下一级的排序树合并。合并过程中,会用最新更新的数据覆盖旧的数据(或者记为不同版本)。在需要读时,从内存开始,再去磁盘。可以极大地减少磁盘访问次数,加快速度。
如果要查找以前的数据,性能会比较差。适合读最近数据比较多,写操作集中在最近数据的情况。
RAID廉价磁盘冗余阵列技术主要是为了改善磁盘的访问延迟,增强磁盘的可用和容错能力。本质上是用多块磁盘,提供并发读写和数据备份。
一般有六档:
RAID0
不做备份,将数据分成N份写入N块磁盘,速度提升N倍。
RAID1
将一份数据同时写入两块磁盘。
RAID10
将所有磁盘均分成两份,数据同时在两份磁盘写入,但是在每一份磁盘里面的N/2块磁盘上,利用RAID0技术并发读写。利用率较低。
RAID3
将数据分成N-1份写入N-1块磁盘,第N块磁盘写入1+2+3+…+N-1块磁盘的数据,这样当有一块磁盘损坏时可以恢复。
RAID5
与3类似,但是校验数据不是写入第N块磁盘,而是螺旋式地写入所有磁盘。
RAID6
和5类似,但是用了2块磁盘存储数据(所以只有N-2块能用),并螺旋式地在两块磁盘中写入校验信息。
HDFS(Hadoop分布式文件系统):
系统在整个存储集群的多台服务器上进行数据并发读写和备份,可以看做在服务器集群上实现了类似RAID的功能。
网站的高可用架构设计的主要目的就是保证服务器硬件故障时服务依然可用、数据依然保存并且能被访问。
怎么实现?每个节点down了都有副节点可以实时切换。
主要手段有:
一个网站设计典型的是三层架构模型:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VeqdLWe9-1642606730729)(C:\Users\Lao qigui\AppData\Roaming\Typora\typora-user-images\image-20220109005118836.png)]
应用层主要负责具体业务逻辑处理;服务层负责提供可复用的服务;数据层负责数据的存储与访问。
原则:大型网站的分层架构及物理服务器的分布式部署使得位于不同层次的服务器具有不同的可用性特点。关闭服务器或者服务器宕机时产生的影响也不相同,高可用的解决方案也差异甚大。
(集群YYDS)
一个集群需要一个master作为任务的分发,同时监听各个机器的状态。
应用的一个显著特点(必备):无状态性。也即服务器不保存业务的上下文信息,仅仅根据每次请求提交的数据进行相应的业务逻辑处理,多个服务器实例之间完全对等,这样就使得请求提供到任意服务器都是一样的
总归不可能全部无状态。
Session管理的手段:
Session复制
消耗太大,比较占内存,适合小型集群
Session绑定
会变成会话粘滞(Session绑定服务器),缺点是该服务器宕机,那么相关的Session都会消失
利用Cookie记录Session
局限性多,但代价比较低。缺点:记录信息有限、每次请求都要传输Cookie
Session服务器
需要使用Session的时候都使用Session服务器。这种成本高,但一劳永逸。事实上是将应用服务器的状态分离,分为无状态的应用服务器和有状态的Session服务器,然后针对这两种服务器的不同特性分别设计其架构。
可复用的服务和应用类似,应该也是无状态的服务,因此可以使用类似负载均衡的失效转移策略实现高可用的服务。
一些可用的策略:
分级管理
服务区分高优先级和低优先级,高优先级使用更好的硬件,同时在服务器部署上也要进行必要的隔离。
超时设置
一旦超时,转移请求
异步调用
适用性及广。
服务降级
确保必要基本功能的正常。包括拒绝服务和关闭功能。拒绝服务: 拒绝低优先级应用的调用,减少并发数目。关闭功能:关闭部分不重要的功能。
幂等性设计
麻烦点在于数据一致性。
保证数据存储高可用的手段主要是数据备份+失效转移。数据备份:多个副本;失效转移:当某个副本不可用时,可以转移到其它副本。
争执点在于:缓存算不算数据存储服务。
高可用的数据要求包括:
数据持久性
数据可访问性
数据一致性
数据强一致
数据总是一致的,不会处于不稳定状态
数据用户一致
各个副本的数据可能不一致,但会通过纠错机制使得最终返回正确的数据给用户
数据最终一致
比较弱,中间存在不一致的时间段,最终走向一致。
CAP原理认为:一个提供数据服务的系统无法同时满足数据一致性(Consistency)、数据可用性(Availibility)、分区耐受性(Partition Tolerance, 系统具有网络分区的伸缩性)。一般大型数据存储服务都是集群,所以P是必须的,剩下的就是在C和A之间斟酌。
一般是偏向AP。
冷备与热备。****
冷备:成本低,技术难度较低,但缺点在于不能保证数据最终一致(存在时间差)。同时也不能保证数据可用性。
数据热备:分为异步和同步两种。异步是指多份数据副本的写入操作异步完成。在回复操作成功响应时,往往只写了一份(主数据库),需要时间慢慢更新其它数据库。主从结构就用的是异步的。
同步是指多份数据副本的写入操作同时完成,即应用程序收到数据服务系统的写成功响应时,多份数据都已经写操作成功。(失败意味着可能有部分已经写入完成),服务器在这种模式下没有主从之分。
关系数据库热备机制就是主从同步机制。
失效转移三部曲:
失效确认
一般通过心跳信号。
访问转移
完全对等的模式可以直接切换,存储不对等需要重新计算路由选择存储服务器。
数据恢复
从健康的服务器处恢复数据
值不需要改变网站的软硬件设计,仅仅通过改变部署的服务器数量就可以扩大或者缩小网站的服务处理能力。
只要技术上能够达到每加入一台服务器对集群的处理能力的提升都是线性关系,那么就可以了。
一般来说,网站的伸缩性设计分成两类,一类是根据功能进行物理分离实现伸缩,一类是单一功能通过集群实现伸缩。前者是不同服务器部署不同服务,提供不同功能;后者是集群内的多台服务器部署相同服务,提供相同功能。
早期通过增加服务器提高网站处理能力时,新增服务器总是从现有服务器中分离出部分功能和服务。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j7FSAEAv-1642606730730)(C:\Users\Lao qigui\AppData\Roaming\Typora\typora-user-images\image-20220111233117672.png)]
每次分离都会有更多服务器加入网站,使用新增的服务器处理某种特定服务。
分离主要分为两种:
纵向分离:
将业务处理流程上的不同部分分离部署,实现系统伸缩性。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KJ5aHhcF-1642606730731)(C:\Users\Lao qigui\AppData\Roaming\Typora\typora-user-images\image-20220111233746317.png)]
横向分离:
业务分割后分离,将不同的业务模块分离部署,实现系统伸缩性。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9PQXc4zt-1642606730731)(C:\Users\Lao qigui\AppData\Roaming\Typora\typora-user-images\image-20220111233758969.png)]
最终的归宿:单一功能通过集群规模实现伸缩
必备:负载均衡服务器——负载转发HTTP请求
负载均衡服务器的实现有两个部分:
负载均衡的实现技术(具体怎么把一个HTTP请求转发到不同的服务器):
负载均衡算法(选择服务器的依据):
分布式缓存集群的最大难点:必须让新上线的缓存服务器对整个分布式缓存集群影响最小,也就是说新加入缓存服务器后应使整个缓存服务器集群中已经缓存的数据尽可能还被访问到,这是分布式缓存集群伸缩性设计的最主要目标。
redis vs memcached:
https://www.redis.com.cn/redis-vs-memcached.html
https://zhuanlan.zhihu.com/p/370976423
研究下redis吧,memcached有点过时了
这一方面的设计和产品有哪些?
出了数据库主从读写分离,前面提到的业务分割模式也可以用在数据库,不同业务数据表部署在不同的数据库集群上,即数据分库。这种方式的制约条件是跨库的表不能进行join操作。
可用的有cobar——分布式关系型数据库。
一般而言,NoSQL数据库产品都放弃了关系数据库的两大重要基础:以关系代数为基础的结构化查询语言(SQL)和事务一致性保证(ACID),而强化其它一些大型网站更关注的特性:高可用性和可伸缩性。
良好的伸缩性设计可以走在业务发展的前面,在业务需要处理更多访问和服务之前就已经做好充足准备。
伸缩性架构需要综合考虑网站的商业模板、演化路线等等。
没有银弹。
扩展性与伸缩性的区别(虽然我觉得很好理解):
扩展性指对系统影响最小的情况下,系统功能可持续扩展或提升的能力;系统架构层面的开闭原则。
伸缩性指系统能够通过增加(减少)自身资源规模的方式增强(减少)自己计算处理事务的能力。
低耦合是可扩展系统的关键。
低耦合的系统更容易扩展,低耦合的系统更容易复用。
软件设计最有挑战的部分在于,如何分解模块、
设计网站可扩展架构的核心思想是模块化,并在此基础之上,降低模块间的耦合性,提高模块的复用性。
事件驱动架构(Event Driven Architecture):通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间合作,典型如生产者消费者模式。
好处:
分布式消息队列可以看作将这种数据结构部署到独立的服务器上,应用程序可以通过远程访问接口使用分布式消息队列,进行消息存取操作,进而实现分布式的异步调用。
消息生产者应用程序通过远程访问接口将消息推送给消息队列服务器,消息队列服务器将消息写入本地内存队列后立即返回成功响应给消息生产者。消息队列服务器根据消息订阅列表查找订阅该消息的消息消费者应用程序,将消息队列中的消息安装FIFO的原则将消息通过远程通信接口发送给消息消费者程序。
现在的消息队列在可用性、伸缩性、数据一致性、性能和可管理性做了优化。
伸缩性:因为数据是即时处理(无状态),所以伸缩性很容易,只要加入集群,通知服务器即可。
可用性:为了避免消费者进程处理缓慢,分布式消息队列服务器内存不足造成的问题,如果内存满了,会先写入磁盘,后续处理完内存中的数据,会再处理磁盘中的数据。
MQ会等消息真正被消息消费者服务器处理后才删除信息。
使用分布式服务是降低系统耦合性的一个重要手段。分布式服务通过接口分解系统耦合性,不同子系统通过相同的接口描述进行服务调用。
大型网站发展的解决方案就是拆分,将模块独立部署,降低系统耦合性。拆分可分为纵向拆分和横向拆分两种。
纵向拆分:将一个大应用拆分为多个小应用,如果新增业务较为独立,那么就直接将其设计部署为一个独立的Web应用系统。
横向拆分:将复用的业务拆分出来,独立部署为分布式服务,新增业务只需要调用这些分布式服务,不需要依赖具体的模块代码,即可快速搭建一个应用系统,而模块内业务逻辑变化的时候,只要接口保持一致就不会影响业务程序和其它模块。
纵向拆分相对简单,梳理业务,将较少相关的业务剥离,使其成为独立的Web应用。而横向拆分,不但需要识别可复用的业务,设计服务接口,规范服务依赖关系,还需要一个完善的分布式服务管理框架。
### 5.3.1 Web Service 与企业级分布式服务
服务提供者通过WSDL(Web Service Description Language)向注册中心(Service Broker)描述自身提供的服务接口属性,注册中心使用UDDI(Universal Description, Discovery, and Intergration, 统一描述、发现和集成)发布服务提供者提供的服务,服务请求者从注册中心检索到服务信息后,通过SOAP( Simple Object Access Protocol, 简单对象访问协议 )和服务提供者通信,使用相关服务。
缺点:
需要其支持如下特性:
负载均衡
失效转移
高效的远程通信*
整合异构系统*
对应用最少侵入
支持应用的各种部署,所以必须做到应用于部署的分离。
版本管理
实时监控
大型网站需要更简单更高效的分布式服务框架构建其SOA (Service Oriented Architecture 面向服务的体系架构 ). 阿里开源了Dubbo。
Dubbo的架构设计:
目标:无需修改表结构就可以新增字段。比如NoSQL数据库使用的ColumnFamily(列族)设计就是解决方案。
开放平台的API接口,吸引第三方开发者为网站开发组件,为用户提供价值。
开放平台的架构设计:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YFv0QZhq-1642606730732)(C:\Users\Lao qigui\AppData\Roaming\Typora\typora-user-images\image-20220117014101961.png)]
API接口:开发平台暴露的一组API,形式可以是RESTful、WebService、RPC等形式。
协议转换:将各种API输入转换成内部服务可以识别的形式,并将内部服务的返回封装成API的格式。
安全:身份识别、权限控制、链接加密、分级的访问宽带限制,保证平台资源被第三方应用公平合理实用,也保护网站内部服务不会被拖垮。
审计:记录第三方使用情况。
路由:将开发平台的各种访问路由映射到具体的内部服务
流程:将一组离散的服务组织成一个上下文相关的新服务,隐藏服务细节,提供统一接口供开发者调用。
最经典的两种攻击:XSS攻击和SQL注入攻击
XSS攻击——跨站点脚本攻击(Cross Site Script),指黑客通过篡改网页,注入恶意HTML脚本,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式。
一般分为:
XSS防攻击的两种方式:
一般分为SQL注入攻击和OS注入攻击。
SQL注入攻击一般是攻击者在HTTP请求中注入恶意SQL命令(drop table users;)
一般需要攻击者对数据库结构有所了解才能进行,所以需要防范攻击者获取数据库表结构信息的手段。常见手段有:
防范方法:
CSRF(Cross Site Request Forgery,跨站点请求伪造). 其核心是利用了浏览器Cookie或Session
主要手段是识别请求者的身份,例如:
常见可能成为的漏洞:
ModSecurity——处理逻辑与攻击规则集合分离的架构模式:
处理逻辑
负责请求和响应的拦截过滤,规则加载执行等功能。比较稳定
攻击规则集合
负载描述对具体攻击的规则定义、模式识别、防御策略等功能。需要经常升级
根据内置规则,构造具有攻击性的URL请求,模拟黑客攻击行为。
主要有三类:单向散列加密、对称加密和非对称加密
可作为密码保存,常用的算法有加盐算法、MD5、SHA,还会用来生成信息摘要(特性利用)
优点:
难点在于密钥地安全传输。
最经典的就是RSA算法,每个节点有一对公钥私钥,公钥加密,私钥解密。
非对称加密通常用在信息安全传输,数字签名等场合。
HTTPS传输中浏览器使用的数字证书实质上就是经过权威机构认证的非对称加密的公钥。
CA认证以及链式证明
常用的信息过滤与反垃圾手段有:
文本匹配
分类算法
黑名单
Trie树算法
构造多级hash文本
贝叶斯算法,TAN算法
布隆过滤器以及哈希表实现。
风险类型:
风控包括机器和人工两种。
机器自动风控的技术手段有:规则引擎和统计模型。
规则引擎
规则引擎将业务规则和规则处理分开,由运营人员管理业务规则。
统计模型
随着规则的增加,规则引擎会出现规则冲突、难以维护的问题。借助训练后的统计模型,可以快速识别。