技术架构设计原则
1 大道至简
避免过度设计
- 努力把代码写得通俗易懂
- 一个工程师好不好就看他能多快简化一个复杂问题,并构建易于理解的解决方案
- 方案好不好的一个检验标准就是看其他人理解的快不快
DID设计方法
- Design设计20倍的容量
- Implement 实施3倍的容量
- Deploy部署1.5倍的容量
三步简化方案 how to DiD?
- 采用帕累托原则(2-8)简化范围(如何简化方案)
先做那能产生80%效益的20%产品功能
- 结合成本与可扩展性简化设计(如何简化设计)
例如不需要的数据列就不要查询出来
- 依靠专家经验简化部署(如何简化部署)
使用成熟的开源解决方案
减少域名解析
- 网站域名资源不要太多,合理利用各级缓存
减少页面目标
- 合并CSS JS 图片
- 压缩各种资源
- 不同资源分配在不同的域名上
采用同构网络
- 确保交换机和路由器源于同一供应商
2 分轴扩展
三维坐标扩展法,X,Y,X轴
X轴扩展
X轴:水平扩展:WEB集群,读写分离
实施速度快,研发成本低,事务处理扩展效果好,运营成本高
Y轴拆分
Y轴:垂直扩展:模块化,分库
从两个维度去分析扩展:功能或资源,一般团队逐渐变大后,业务比重增加,技术比重下降,生产力下降,所以采用专人负责专门模块可以减少业务比重投入,提升生产力
Z轴拆分
Z轴:又称分片:分表,SOA,微服务
一般根据一些独特属性:ID,位置,基础服务等进行拆分
水平扩展(向外扩展)
- 拆分或复制服务与数据库来扩展系统,而不是向上扩展(利用更好的服务器性能)
- 摩尔定律VS安迪比尔定律
- 利用三维坐标扩展法为指导
金鱼而非汗血宝马
- 使用普通PC服务器即可,不要使用性能成本很高的商业服务器
- 金鱼便宜,可以轻易丢弃不用修复;宝马太贵维护成本过高
托管方案扩展
- 系统部署到三个或更多的数据中心
- 三个数据中心是最成本最优的方案
- 避免拥有自己的数据中心,直到公司的规模大到可以通过建设和运行自己的数据中心来节省成本变为可能
利用云服务
- 有效利用云服务,提升系统可伸缩性,节省成本
3 先对其器
不要陷入马斯洛锤子陷阱中:当你只有一个锤子时,任何东西看起来都像是钉子
适当使用数据库
- 当需要ACID属性来保持数据之间的关系和一致性时才选择关系型数据库
- 不要用关系数据库存储所有数据,利用不同NoSql综合存储
慎重使用防火墙
- 不要让防火墙成为系统瓶颈
- 对值得使用防火墙的内容上使用
积极使用日志文件
- 打造完善的日志系统(比如ELK),使其成为追踪,预防,监控,自动化修复重要工具
- 一个好的日志体系,生产环境问题将会越来越少,且越快解决
4 奥卡姆剃刀
避免画蛇添足
- 不要在无需同步的地方一定采用同步
- 利用好缓存技术,不要去查询刚刚入库的数据
停止重定向
- 尽量避免重定向
- 使用服务器配置来实现正确的重定向
放宽时间约束
- 不要过分考虑响应及时性,系统无法扩展而停止服务比让用户有些失望相比更严重
5 缓存为王
利用CDN缓存
- 利用CDN缓存解决区域化响应速度问题
- 注意成本与效率之间的平衡
正确管理缓存
- 正确使用HTTP头来管理缓存(什么头在什么场景下适用,不要生搬硬套)
- 使用HTTP响应头确保Ajax请求响应可缓存
静态资源缓存
- 利用nginx,varnish组合对静态资源,甚至某些动态内容进行缓存
应用数据缓存
- 对热点业务数据采用memcached,redis等技术进行缓存,其可扩展性也可以参考三维坐标法
- 如果是和用户有关的数据,注意分布式缓存扩展性问题(通过哈希一致性算法或数据预热方式来防止雪崩或穿透)
DAO缓存
- 利用数据库持久化工具(如:mybatis)或本地缓存工具(Ecached)做数据持久层的一级缓存和二级缓存
6 前车之鉴
组织必须在深度和广度上学习
有些知识可以培训获得,有些知识必须从外部获得
失败乃成功之母
- 拥有学习文化的组织更易于实现病毒式增长
- 从客户中学习(出的问题,解决的需求)
- 从业务技术的运营中学习
- 关注失败,拒绝简化,牛人心态,谦卑态度
不要依赖QA发现错误
- 做好自动化测试
- 当测试活动获得超过一个工程师的价值时,应该招聘一个QA人员
不能回滚注定失败
- 让每一次上线都具备快速的回滚能力
7 重中之重
从事务处理中清除商务智能
- 尽早使用Nosql
- 不要在关系数据库中使用存储过程,触发器,外键等约束与业务逻辑绑定
设计之初就考虑扩展性
- 特别是关系性数据库结构的设计,提前考虑到其扩展性
- 不要局限于数据库范式设计
正确使用数据库锁
- 注意暗锁 、明锁、行锁、页锁、区间锁、表锁、数据库锁使用正确姿势
禁用分阶段提交
- 最好的方式就是不要使用
慎用Select for Update
- 避免在业务中使用
避免选择所有列
- 遵循用到什么拿什么的原则
8 有备无患
用分布式(泳道)来隔离故障
- 道理就和不要把鸡蛋放在一个篮子里一样
- 不同的服务不要互相影响
拒绝单点故障
- 在分布式系统的各层都要考虑单点故障问题
避免系统串联
- 不要因为某个模块或服务问题,影响整个系统的运行
启用和禁用功能
- 通过缓存刷新,可配置化等方式启用和禁用产品功能
9 超然物外
力求无状态
- 无状态是一些系统可扩展性的基石
在浏览器中保存会话
- 使用H5本地存储,JWT,cookie技术
用分布式缓存处理状态
- 用集中的分布式缓存来保存,使得应用和web服务无状态化
10 意犹未尽
警惕第三方方案
- 不要依赖供应商解决方案来实现可扩展性
- 自己的命运自己来掌控
梯级存储策略
- 做到存储成本与数据价值相匹配
异步通信
- 非实时性响应需求建议采用异步通信方式
分类处理不同负载
- 确保解决方案支持四种基本类型工作负载:归纳(数据形成),演绎(数据使用),批处理,用户交互
- 彼此隔离
- 不要因为非关键性业务影响到关键性业务
保持竞争力
- 保持公司所有岗位人员的竞争力,不仅仅某一个
注:(本文根据《架构真经》内容结合作者本身经验整理修改而得)更加详细的解释会在本人《架构之道》课程里讲述