高并发web系统设计

核心技术点

  • 前端优化

    前端优化主要包括动态内容静态化,增加前端缓存。页面静态化是指将指含有大量动态元素的动态网页,如jsp、php等,转换为html静态页面,静态页面由于不用加载动态元素,其访问速度要比动态页面快得多,可以增加访问速度,减小数据库压力;前端页面缓存在系统前端对Web服务器上的页面进行缓存。

  • CDN技术

    CDN即内容分发网络,其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。

  • 负载均衡

    负载均衡的基本思想是把高并发的访问平均分配到每一个服务器节点上,从而减小分布式数据库中每一个节点的压力。

  • 中间件

    数据库的中间件技术是指把应用层与数据库层分离,在中间增加一个部分,避免应用直接访问数据库。因为系统可能采用读写分离的技术,因而会使用不同的数据库,中间件可以屏蔽数据库直接的不同,提供统一的接口。中间件还负责事务的协调处理,起到数据连接管理的作用,多个客户端连接通过中间件可以共用一个数据库连接。

  • memcached

    memcached是一个高性能的分布式内存对象缓存系统,通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度,它是基于一个存储键/值对的hashmap。

  • 并发控制

    数据库限流,达到数据库的最大并发数,进入行锁状态。如不进行控制,一旦其中一个连接卡住,会引发雪崩效应,从而影响整个系统

  • 排队系统

    锁机制导致排队

  • 并行复制

    采用并行复制的技术可以解决主备库复制延迟问题

  • 数据库拆分

    分为水平拆分和垂直拆分,垂直拆分即按列拆分,把数据按应用分离,降低单个事务的数据处理量;水平拆分即按行拆分,降低节点的并发量

  • 读写分离

    有些系统读操作频繁,而有些系统写操作频繁,读写分离能有效提高访问速度

高并发带来的问题和解决方案

事务问题(一致性)

  • 容器事务管理
  • 锁机制
  • 隔离机制

状态问题(session)

  • 用cooke记录sesion

    缺点是有大小限制,另外不稳定,客户端可能关闭浏览器导致数据丢失,且不安全

  • session复制

    即集群中的服务器都持有一份sesion,每次有数据变化时需要同步给其他服务器,适合小规模网站

  • session绑定

    由负载均衡服务器将客户的IP/cookie与session绑定,实现会话粘滞。
    但这种方案缺乏高可用性,因为客户的关闭浏览器可能会改变cookie,客户端IP也可能变化,服务器端也可能宕机导致session丢失。

  • session服务器

    包含两个层面,
    一个是利用分布式缓存,可以实现会话的保持,适合一般集群需求
    另一个是独立session服务器,适合更高要求的需求,例如单点登录(SSO)

设计原则

  • 墨菲定律

    任何事没有表面看起来那么简单 - 所有的事都会比预计的时间长 - 可能出错的事情总会出错 - 担心某种事情发生,那么它就更有可能发生

  • 康威定律

    系统架构师公司组织架构的反映 - 按照业务闭环进行系统拆分/组织架构划分,实现闭环、高内聚、低耦合,减少沟通成本 - 如果沟通出现问题,应该考虑进行系统和组织架构的调整 - 适合时机进行系统拆分,不要一开始就吧系统、服务拆分拆的非常细,虽然闭环,但是每个人维护的系统多,维护成本高 - 微服务架构的理论基础 - 康威定律

  • 二八定律

    80%的结果取决于20%的原因

高并发原则

  1. 无状态

    无状态应用,便于水平扩展
    有状态配置可通过配置中心实现无状态

  2. 拆分

    系统维度:按照系统功能、业务拆分,如购物车,结算,订单等
    功能维度:对系统功能在做细粒度拆分
    读写维度:根据读写比例特征拆分;读多,可考虑多级缓存;写多,可考虑分库分表
    AOP维度: 根据访问特征,按照AOP进行拆分,比如商品详情页可分为CDN、页面渲染系统,CDN就是一个AOP系统
    模块维度:对整体代码结构划分Web、Service、DAO

  3. 服务化

    服务化演进: 进程内服务-单机远程服务-集群手动注册服务-自动注册和发现服务-服务的分组、隔离、路由-服务治理
    考虑服务分组、隔离、限流、黑白名单、超时、重试机制、路由、故障补偿等

  4. 消息队列

    目的: 服务解耦(一对多消费)、异步处理、流量削峰缓冲等
    大流量缓冲: 牺牲强一致性,保证最终一致性(案例:库存扣减,现在Redis中做扣减,记录扣减日志,通过后台进程将扣减日志应用到DB)
    数据校对: 解决异步消息机制下消息丢失问题

  5. 数据异构

    数据异构: 通过消息队列机制接收数据变更,原子化存储
    数据闭环: 屏蔽多从数据来源,将数据异构存储,形成闭环

  6. 缓存银弹

  7. 并发化

高可用原则

  1. 降级

    降级开关集中化管理:将开关配置信息推送到各个应用
    可降级的多级读服务:如服务调用降级为只读本地缓存
    开关前置化:如Nginx+lua(OpenResty)配置降级策略,引流流量;可基于此做灰度策略
    业务降级:高并发下,保证核心功能,次要功能可由同步改为异步策略或屏蔽功能

  2. 限流

    目的: 防止恶意请求攻击或超出系统峰值
    实践:
    恶意请求流量只访问到Cache
    穿透后端应用的流量使用Nginx的limit处理
    恶意IP使用Nginx Deny策略或者iptables拒绝

  3. 切流量

    目的:屏蔽故障机器
    实践:
    DNS: 更改域名解析入口,如DNSPOD可以添加备用IP,正常IP故障时,会自主切换到备用地址;生效实践较慢
    HttpDNS: 为了绕过运营商LocalDNS实现的精准流量调度
    LVS/HaProxy/Nginx: 摘除故障节点

  4. 可回滚

    发布版本失败时可随时快速回退到上一个稳定版本

业务设计原则

  • 防重设计
  • 幂等设计
  • 流程定义
  • 状态与状态机
  • 后台系统操作可反馈
  • 后台系统审批化
  • 文档注释
  • 备份