大型网站技术架构-读后感
传统特点及解决方案:
- 高并发,大流量
- 高可用
- 大数据
- 用户广泛,网络情况复杂
- 需求变更频发,发布频繁
- 渐进式发展
- 1.1解决方案:
- 分层
- 业务分割,比如将论坛,购物搜索分别放在不同的服务器上,如果业务庞大,还可以继续分割。
- CDN(内容分发网络用户请求首先到达距离终端最近的网络服务商那里,缓存网站的一些静态资源或者热点内容,以最快的速度返回给用户)和反向代理(属于网站前端架构的一部分,部署在前端,缓存静态资源)
- 负载均衡(多台服务器部署相同的应用构成一个集群,通过负载均衡设备共同对外提供服务)
- 分布式服务器,多个服务器组成集群,将多个业务拆分到不同的服务器上(1.分布式应用和服务 2.分布式静态资源并采用独立域名,即动静分离,3.分布式数据和存储,4.分布式计算)
- 本地缓存(直接从内存中访问数据)和分布式缓存服务器,【缓存前提:一是数据访问热点不均匀,二是数据在某个时间段内不会过期】
- 分布式文件服务器,分布式数据库服务器
- NoSQL和搜索引擎服务器
- 异步+消息队列,单一服务器通过多线程共享内存队列的方式实现异步,典型的生产者消费者模式
- 冗余,服务器和数据都要冗余,定期备份,主从分离,防止服务器宕机,数据丢失。
- 自动化 自动化代码管理,自动化测试,自动化安全检测(测试环境进行安全攻击),自动化部署,自动化监控报警,自动化失效转移和恢复,自动化降级(拒绝部分请求和关闭部分不重要的服务),自动化分配资源(将空闲资源分给重要的服务)。
大型网站架构模式:
- 高性能:响应时间,并发数,吞吐量,性能计数器,TPS(每秒事务处理量)
- 高可用: 主要手段是冗余,任何一台服务器宕机,都不会影响应用的整体使用
- 易伸缩:多台服务器集群
- 可扩展:事件驱动架构(消息队列)和分布式服务
- 安全
网站性能优化:
1. web前段性能优化:
1.1 减少http请求(合并css,js,图片),
1.2使用浏览器缓存(主要是静态资源,可以通过设置HTTP头的Cache-control和Expire来缓存,更新时用过改文件名更新缓存,应该批量更新,并且是一个一个更新,并有间隔时间,避免大量缓存失效,造成服务器负载骤增,网路堵塞),
1.3启用压缩(会对服务器和浏览器产生压力,在服务器资源不足的情况下权衡),
1.4css在页面上面js在下面
1.5减少cookie传输
1.6 CDN和反向代理
2.应用服务器性能优化:(网站优化第一定律:缓存)
2.1 分布式缓存
2.1.0(缓存本质是一个内存Hash表) ,
2.1.1 缓存预热(热点数据,比如分类,城市等等可以在启动是加载数据库中的数据到缓存中进行预热),
2.1.2 缓存穿透(持续高并发的访问某个不存在的数据,对数据库造成巨大压力,对策是将不存在的数据也缓存起来,value是null)
2.1.3 分布式缓存是指缓存部署在多个服务器组成的集群中,其架构方式有两种: 一种是JBossCache为代表的需要更新同步的(缓存主从复制),一种是以Memcached为代表的互不通信的
2.2 异步,包括消息队列,集群
2.3 代码优化
2.3.0 多线程(注意线程安全,解决方法有 1.讲对象设计为无状态对象 2.使用局部对象 3. 并发访问资源时使用锁)
2.3.1 资源复用(尽量减少开销很大的系统资源的创建和销毁,比如数据库连接字符串,网络连接,线程等等,实现模式有两种 单例和对象池)
2.3.2 数据结构(不理解) 垃圾回收
2.3.4 存储性能优化(固态硬盘代替机械硬盘)
2.3.4.1 B+树,是一种专门针对磁盘存储而优化的N叉排序树(机械硬盘具有快速顺序读写,慢速随机读写的特点,文件系统或者数据库系统会对数据进行排序后存储(增删改),加快数据检索速度)
2.3.4.2 LSM树, 是一个N阶合并树,数据库的写操作(增删改)都在内存中进行,,读操作时先从内存的排序树开始,找不到再从磁盘的排序树开始找,(随机访问数据速度更快,常见用NoSql)
2.3.5 RAID(廉价磁盘冗余阵列) 改善磁盘的访问延迟,增强可用性和容错性
HDFS(Hadoop分布式文件系统) 系统在整个存储集群的多台服务器上进行数据并发读写和备份
网站的高可用架构
3.1 公共服务独立部署:分级管理(订单支付比评价服务的优先级更高),超时设置,异步调用(异步+消息队列),服务降级(拒绝优先级低的服务或者随机拒绝服务,或者关闭评价,确认收货等不重要的服务),如果网站过大,发布时可以使用灰度发布,先发布一部分,没问题再发布下一部分。
3.2 网站运行监控
3.1.1 用户行为日志监控,包括用户操作系统,浏览器信息,IP,页面路径,页面停留时间等等,这些对网站的PV/UV指标,分析用户行为,优化网站,个性化营销和推荐非常重要。主要有两种,1是服务器端收集,只需要开启日志记录功能即可 2浏览器收集,需要单写js
3.1.2 服务器性能监控: 收集服务器性能指标,如系统Load,内存占用,磁盘IO,网络IO等等作出及时预警,安排合理的服务器集群,改善系统性能,调整系统伸缩策略。
3.1.3 运行数据报告: 监控具体业务场景相关的技术和业务指标,比如缓冲命中率,平均响应时间,每分钟发送邮件数,待处理的任务总数等等
网站的伸缩性架构
4.1.1 伸缩性是指不需要改变网站的软硬件设计,仅仅通过改变服务器的数量就能扩大或者缩小网站的服务处理能力
4.1.2 物理分离实现伸缩(不同的服务器部署不同的服务) ,相当于业务拆分。
4.1.3 单一功能通过集群实现
秒杀:
技术挑战:
1. 需要部署专门的秒杀系统,如果和原有应用部署在一起,秒杀活动短时间,大并发的特性会使网站瘫痪.
2. 高并发,数据库负载,压力极大
3. 突然增加的网络及带宽,一个页面200K,10000人秒杀就是 200*10000=2G
4. 直接下单,必须到秒杀时间才能下单,秒杀之前只能浏览。
应对策略:
1. 秒杀系统独立部署,需要的话,使用独立的域名
2. 秒杀商品页静态化,不经过业务处理和数据库处理
3. 租借秒杀活动带宽,将秒杀商品页面缓存在CND
4. 动态生成随机下单页面URL,避免用户得到秒杀URL直接下单
5. 秒杀页面尽量简洁,用户更关心快速的刷新商品页面
6. 秒杀商品购买按钮只有在秒杀活动开始时才能点击
7. 秒杀下单页也尽量简洁,数量不能修改
8. 只有第一个订单才能创建成功,别的只能看到活动结束的页面
如何控制秒杀商品购买按钮的点亮可用???
由于秒杀页面是静态页,并且缓存在CDN,反向代理服务器或者用户浏览器中,用户刷新页面,请求不会到达服务器。解决方案是使用javascript控 制,加入是否开始的标志和下单页面url随机数。秒杀开始生成新的js文件并被浏览器加载,控制秒杀页面的展示.这个js文件使用随机版本号,不会被缓存。
如何确定第一个订单创建成功???
每台服务器只接受前10个请求,其它用户进入秒杀结束页面,即使报错也进入秒杀结束页面,对用户友好。
大型网站典型故障分析
1. 写日志故障:
1.1 应用程序日志和第三方日志要分别配置
1.2 log日志级别,至少为warn,如果是全局debug, 就会出现日志不停创建,占用磁盘空间的bug
1.3 关闭不必要的第三方日志,一般遇到问题时才会发现
2. 高并发情况数据库引发下的故障:
2.1 首页数据不应该直接调取数据库获取,应该从缓存服务器或者搜索引擎服务器中获取.
2.2 首页最好是静态的
3. 高并发情况下锁引发的故障
单例中多处使用了锁,如果远程调用也偶尔用锁,但是调用时间长,等用完了就立即释放锁,服务器会出现一会报警,一会又接触的故障,使用锁的时候一定要谨慎。
4. 缓存:
当缓存已经不仅仅是改善性能,而是成为网站不可获取的一部分时,对缓存的管理就要提到和其它服务器一样的高度,避免一下子关闭全部的缓存服务器,导致网站宕机。
5. 应用启动不同步应发的故障
接口没完全启动,前台已经调用了。应该是先返回一个ok,确定程序完全启动才能再启动前台.
6. 大文件读写独占磁盘:
小文件和大文件应该单独存放服务器,如果用一个服务器,大文件上传时,如果磁盘被占用,那么小文件就无法上传。
架构师领导艺术
1. 关注人而不是产品,一群优秀的人做一件他们热爱的事情,就一定会成功。找一个共同的目标,营造一个能让大家最大限度的发挥自我价值的工作氛围,激发员工的热情,而不是员工为了领工资而工作。
2. 发掘人的优秀,比发掘优秀的人更有意义。
3. 共享美好蓝图: 蓝图应该是描述清晰的(产品做什么,不做什么,达到什么目标),形象的(产品能为客户带来什么,实现什么样的市场目标,最终长成什么样),简单的(不管内部还是外部,一句话就能说明白)
4. 共同参与架构,让项目参与者都能染指架构 ,让其他人参与维护框架和文档(除非重大重构),
5. 学会妥协,坦率分享自己的设计思路,让别人理解自己的想法并且理解别人的想法。对于细节应该立即验证而不是接着讨论。项目组越需要架构师,就越表示项目架构缺陷越多。
6. 成就他人, 做项目比仅仅要给客户创造价值,为公司盈利,还要让项目组人员活的成长。
网站架构师职场攻略:
1. 发现问题,寻找突破
2. 提出问题,寻求支持:
2.1 把我的问题这句话,变成我们的问题;
2.2 给上司提供封闭式问题(A和B解决方案您觉得哪个更好),给下属提开放式问题,让他自己找解决方案(元你怎么看);
2.3 指出问题而不是批评人
2.4 用赞同的方式提出意见(我同意你的方案不过我有一个小建议,您看这样是不是更好....)
2.5 解决问题,达成绩效。在解决我的问题之前,先解决你的问题;适当搁置有争议的问题。
# 有的路,走过之后,再回头,一览众山小。