大型网站技术架构

最近觉得自己没有什么技术的提升,感觉有些着急,公司任务也不忙,决定先拜读大佬的《大型网站技术架构》一书,从中学习到新的想法思维。不知道能不能坚持到全书看完

第一章 大型网站架构演化

网站优化

  1. 应用服务和数据服务分离。根据需求的不同分配不同的服务器配置
  2. 遵循二八定律(80%的业务访问集中在20%的数据),将经常需要访问的数据进行缓存(缓存分为本地缓存和远程分布式缓存)
  3. 应用服务器集群解决并发问题
  4. 数据库读写分离
  5. CDN(使用户在访问数据的时候请求到离自己最近的服务器获取数据)和反向代理服务器(用户请求到中心机房后,如果反向代理服务器缓存着该请求的资源,则直接返回给用户)
  6. 使用NoSQL和搜索引擎(ES)
  7. 业务拆分,独立部署,分布式,消息队列

大型网站架构模式

  • 网站分层架构

  • 分割

将不同的业务进行分割,部署到不同的服务器,如有必要的话进行细分,比如购物业务将其细分为机票酒店业务、小商品业务、信息家电业务等

  • 分布式

将业务需求细分后,模块独立部署

  • 集群

每个独立的模块部署多台服务器达到一种集群的效果,提高并发性,提高可用性(当某一台服务器宕机时,不影响整体服务)

  • 缓存

将一些热点内容,用户大流量访问的稳定内容放在缓存中,根据需求设置过期时间

  • 异步

分布式消息队列,模块之间异步通信,典型的是生产者消费者模式,提高系统可用性(消费者服务器发生故障,不影响生产者服务器),加快网站响应速度(异步的原因,不需等待消费服务器的反馈),消除并发访问高峰

  • 自动化

自动化测试,自动化代码管理,自动化部署等等

第二章 架构

前端优化

  1. 减少http请求,请求合并CSS,JS
  2. 使用浏览器缓存,采用该策略更新静态资源时,应该批量更新,有一定时间间隔的更新,以免用户浏览器突然大量缓存失效,造成服务器负载骤增
  3. 启用压缩
  4. 尽量减少Cookie传输

CDN加速

反向代理、服务器集群

用户访问静态资源时将它缓存在nginx中,其他用户再访问相同资源时,直接从NG上返回

缓存

缓存的本质是一张Hash表,存储KV

缓存不是一个可靠稳定的数据来源,如果新启的缓存没有任何数据,都需要后期的请求添加,那么会大大影响性能,所以在缓存启动的时候我们就可以将一些固定死的资源加载进缓存,比如地名、列表信息等,这种手法叫缓存预热

为了防止缓存穿透,所以当出现高并发的请求某个不存在的数据时,我们也对他进行缓存。值为null。

异步操作

@Async作用

使用消息队列将调用异步化

Springboot结合MQ技术

关于消息队列需要注意的是,因为是异步操作,对于生产者你没有办法第一时间知道是否业务操作成功,比如用户提交订单,可以返回订单正在提交字样,然后根据确切的成功与否进行二次提示或者邮件

代码优化

  • 多线程

一台服务器最优启动线程数= [ 任务执行时间 / ( 任务执行时间 - IO等待时间 ) ] * CPU内核数,最佳启动线程数和CPU内核数量成正比,和IO阻塞成反比。如果任务都是计算型任务,那么线程最多不超过内核数,如果都是等待磁盘的操作,那么启动多线程有助于提高任务并发量。

解决线程安全问题

  1. 使用局部对象,在方法内部创建对象,这些对象被每个进入该方法的线程进行重新创建
  2. 并发访问资源时,使用锁,通过锁的方式使多线程并发操作转化为进行顺序操作,但是对系统性能会产生严重影响

资源复用

对象池(连接池、线程池)的使用

数据结构

垃圾回收

理解垃圾回收机制,有助于程序优化和参数调优。

  • 新创建的对象放在Eden区
  • 当Eden区空间满时,触发Young GC,将Eden区还在使用的对象复制到From区,Eden区被清空
  • 此时被清空的Eden区可以继续存放新创建的对象,直到Eden区再次空间满,再次触发Young GC
  • 将Eden区和From区还在使用的对象复制到To区,Eden区和From区被清空
  • Eden区再次空间满,将Eden区和To区还在使用的对象复制到From区,这样一直重复到某一个设定的阈值(调优点)
  • 如果某些对象达到某一个阈值点后还没有被释放,则将该对象放入老年代
  • 如果老年代空间也满了,那么触发FULL GC,该回收对系统性能会产生较大的影响

合理设计年轻代和老年代的大小,做到尽量少执行FULL GC

网站的高可用架构

集群Session管理

  1. Session复制 几台服务器集群同步共享Session,缺点是用户量很大的时候Session复制会占用大量的资源
  2. Session绑定 根据Nginx的规则,将同一IP的请求发放到同一台服务器
  3. 使用Cookie记录Session
  4. Session服务器 单独将Session抽离出来独立部署Session集群,可实现SSO登录

高可用服务

  1. 超时时间 每台服务器的调用超时时间需要设置,一旦超时,根据策略将请求提交到其他服务器上
  2. 异步调用 一些可以用异步调用的场景,比如说注册服务,一些不需要立即返回结果的请求
  3. 服务降级 一些服务降级将展示其他业务逻辑,还有关闭功能,比如关闭一些高峰时期不重要的功能,比如双11时期的用户评价等
  4. 幂等性设计 接口的幂等性

关于接口的幂等性,通常我需要注意的是增和改两个操作

  • 代码逻辑层实现:状态的确立,比如在改操作是,添加限制条件,where status = ‘未支付’,只有在未支付的情况下才能进行支付
  • 使用token机制实现接口幂等性:提交操作时附带token,redis进行删除该token(如果删除成功,说明操作执行成功,删除失败,则说明请求重复,如果进行select+del则会存在并发问题),并将新的token存入redis,返回给前端

高可用数据

  • CAP原理(数据持久性、数据可访问性、数据一致性) 通常我们会放宽数据一致性这个要求,不要求强一致性,达到用户一致性或者最终一致性即可,用缓存辅助数据库,对于一些不经常更改的数据可以放入缓存
赏个🍗吧
0%