亿级流量网站架构核心技术
2017-08-10第1部分 概述
- 交易系统设计的一些原则
- 墨菲定律
- 任何事情都没有表面看起来那么简单
- 所有的事情都会比你预计的时间长
- 可能出错的事情总会出错
- 如果你担心某种情况发生,那么它就更有可能发生
- 系统划分时,也需要思考康威定律
- 系统架构是公司组织架构的反映
- 应该按照业务闭环进行系统拆分/组织架构划分,实现闭环/高内聚/低耦合,减少沟通成本
- 如果沟通出现问题,那么应该考虑进行系统和组织架构的调整
- 在合适时机进行系统拆分,不要一开始就把系统/服务拆得非常细,虽然闭环,但每个人维护的系统多,维护成本高。
- 二八定律
- 墨菲定律
高并发原则
- 无状态
- 拆分
- 系统维度:按照系统功能/业务拆分,比如商品系统,购物车,结算,订单系统等
- 功能维度:对一个系统进行功能再拆分,比如优惠券系统可以拆分为后台券创建系统,领券系统,用券系统等
- 读写维度:根据读写比例特性进行拆分。读量大采用缓存,写量大采用分库分表。聚合读取场景,考虑数据异构拆分系统,将分散在多处的数据聚合到一起存储,提升系统的性能和可靠性。
- AOP维度:根据访问特性,按照AOP进行拆分。
- 模块维度:比如按照基础或者代码维护特性进行拆分,如基础模块分库分表,数据库连接池等。代码结构按照三层架构Web,Service,DAO进行划分。
- 服务化:进程内服务-》单机远程服务-》集群手动注册服务-》自动注册和发现服务-》服务的分组/隔离/路由-》服务治理如限流/黑名单
- 消息队列:大流量缓冲,数据校对
- 数据异构:数据异构,数据闭环
- 缓存银弹: 浏览器端缓存,APP客户端缓存,CDN缓存,接入层缓存,应用层缓存,分布式缓存
- 并发化
高可用原则
- 降级:流量降级,业务降级
- 限流:目的防止恶意请求流量,恶意攻击,以及防止流量超出系统峰值。
- 切流量:DNS,HttpDNS,LVS/HaProxy/Nginx
- 可回滚
业务设计原则
- 防重设计,重复提交表单,下单扣库存,考虑防重key,防重表。
- 幂等设计,接口幂等,异步回调
- 流程可定义
- 状态与状态机
- 后台系统操作可反馈
- 后台系统审批化
- 文档和注释
- 备份
总结
第2部分 高可用
负载均衡与反向代理
- LVS/F5 + Nginx + OpenResty + Tomcat
- 对于负载均衡关心如下方面:
- 上游服务器配置:使用upstream server配置上游服务器
- 负载均衡算法:配置多个上游服务器时的负载均衡机制
- 失败重试机制:配置当超时或上游服务器不存活时,是否需要重试其他上游服务器
- 服务器心跳检查:上游服务器的健康检查/心跳检查
- 给Nginx 配置上游服务器,即负载均衡到真实处理业务的服务器,通过http指令下配置upstream即可
upstream backend {
server 192.168.61.1:9080 weight=1;//权重:默认为1,权重越大分配给这台服务器的请求越多,需要根据服务器的实际处理能力设置权重
server 192.168.61.1:9090 weight=2;
}
// proxy_pass
location / {
proxy_pass http://backend; //当访问Nginx时,会将请求反向代理到backend配置的upstream server
}
- 负载均衡算法,用来解决用户请求到来时如何选择服务器进行处理.
- 默认round-robin(轮询,通过配合weight配置实现基于权重轮询);
- ip_hash:根据客户IP进行负载均衡即相同的IP将负载均衡到同一个upstream server.
upstream backend {
ip_hash;
server 192.168.61.1:9080 weight=1;//权重:默认为1,权重越大分配给这台服务器的请求越多,需要根据服务器的实际处理能力设置权重
server 192.168.61.1:9090 weight=2;
}
- hash key [consistent]:对某一个key进行哈希或者使用一致性哈希算法进行负载均衡。问题是:当添加/删除一台服务器时,导致很多key被重新负载均衡到不同的服务器,从而可能导致后端出现问题,因此建议考虑一致性哈希算法,当添加/删除一台机器,只有少数key被重新负载均衡到不同的服务器
- 哈希算法:此处是根据请求uri进行负载均衡,可以使用Nginx变量,因此可以实现复杂的算法。
upstream backend {
hash $uri;
server 192.168.61.1:9080 weight=1;//权重:默认为1,权重越大分配给这台服务器的请求越多,需要根据服务器的实际处理能力设置权重
server 192.168.61.1:9090 weight=2;
}
- 一致性哈希算法:consistent_key动态指定。
upstream nginx_local_server {
hash $consistent_key consistent;
server 192.168.61.1:9080 weight=1;//权重:默认为1,权重越大分配给这台服务器的请求越多,需要根据服务器的实际处理能力设置权重
server 192.168.61.1:9090 weight=2;
}
location / {
set $consistent_key $arg_cat; //优先考虑请求参数cat,如果没有再根据uri进行负载均衡
if ($consistent_key = "") {
set $consistent_key $request_uri;
}
}
- 基于Lua设置一致性哈希key TODO
- 失败重试
upstream backend {
server 192.168.61.1:9080 max_fails=2 fail_timeout=10s weight=1;//表示10s内失败了2次就任务该服务器不可用/不存活,然后摘掉,10s后会再次将该服务器加入存活上游服务器列表进行重试
server 192.168.61.1:9090 max_fails=2 fail_timeout=10s weight=2;
}
location /test {
proxy_connect_timeout 5s;
proxy_read_timeout 5s;
proxy_send_timeout 5s;
proxy_next_upstream_error timeout;
proxy_next_upstream_timeout 10s;
proxy_next_upstream_tries 2;
proxy_pass http://backend;
add_header upstream_addr $upstream_addr;
}
- 健康检查:TCP心跳检查,HTTP心跳检查
- 域名上游配置
upstream backend {
server c0.3.cn;
server c1.3.cn;
}
- 备份上游服务器
- 不可用上游服务器
- 长连接
- HTTP反向代理
- HTTP动态负载均衡
- Nginx四层负载均衡
隔离术
- 线程池隔离
- 进程隔离
- 集群隔离
- 机房隔离
- 读写隔离
- 动静隔离
- 爬虫隔离,1. 限流 2. 在负载均衡层面将爬虫路由到单独集群,从而保证正常流量可用。 IP+Cookie避免误杀
- 热点隔离
- 资源隔离
- 使用Hystrix实现隔离