工作多年,期间既做过要求强一致的系统,也做过要求低延时、高吞吐的系统,还搞过微服务的拆分和管理等工作。
在这个领域里做了这么久,零零散散写过些东西,但是一直没有完整、系统地总结过这个领域里的方法论,现在是时候完成它了。
千言万语一张表:(注意里面子项有链接,可以深入了解)
分层 | 细节 | ||
---|---|---|---|
道 | 生态系统论:像构建一个生态系统一样构建一个IT系统 | 控制逻辑正交:本质是 『做什么(逻辑)』和 『怎么做(控制)』的隔离 |
掌握越多细节,优化空间越大 |
术 | 收容数据 | 处理数据 | 产出数据 |
高性能(资源有限时处理不能慢) | 【怎么划分数据】动静、读写、冷热、时空、业务 【按什么结构存储数据】倒排结构、列存、顺序存、多级存储 【怎么描述数据】二进制描述 【怎么写入数据】并发写:乐观锁 |
分治 优秀的算法喜欢有序的数据 无锁 |
牺牲精确性 缓存 |
高可靠(数据不能丢、不能乱) | WAL(write ahead log) 对象尽量不可变,可变对象要避免线程竞争 |
【失败】fast fail原则 |
幂等 |
高可用(服务不能死) | 多副本、Master-slave、Raft/Paxos | 【状态】无状态设计 【依赖】尽量不依赖, 必须依赖的尽量异步依赖, 必须要同步依赖的就四步曲: 打日志,加超时,加限流,加降级 |
分页切片 探活 |
开发原则总结
- 用下一次的同步来表征上一次同步的ack,减少ack过程
- 运营支撑系统很重要,看不到业务监控等于没有业务
- 实现需求最大的困难不是设计出一个方案并实现出来,而是需要在若干个可能的方案中,甄选出最简单实用的那个。
- 大系统小做:除了最原子的业务(e.g.支付、打标)是开发出来的,大部分业务是涌现出来的(e.g.支付+补全—>下发、微信单聊/群聊 对接收消息逻辑来说是统一的)
- 极简设计:最简单的方案最一致,最一致的方案最可靠
- 监控
- COE报告侧重于:如何避免同类型故障再次发生、提高故障主动发现能力、缩短故障响应和处理过程
- ump key—>agent collect—>统一监控页面和报警配置
- master-master
- 协程
订单系统感悟汇总
在订单二期需求讨论过程中,订单中心的定位和各字段的理解在不断更新和变化。拥抱需求变化,但是要以开发过程有可固化的原则为前提。
以下是讨论过程中形成的订单中心系统构建原则,欢迎拍砖,没被砖拍到的地方就默认可以执行了:
to 产品:
1、订单类型用于区分不同的状态流(如:实物、服务),订单打标用于区分同一状态流下的不同业务分支(如:定时达、周期送)
2、订单中心与外系统的关联关系只通过系统id保持(如:订单号,支付单号,结算单号……),不存储外系统内部业务信息
3、只提供订单号到外系统id的正向翻译功能,不提供逆向翻译功能
4、废除的原则:订单中心不主动改变订单状态,一切状态变更由外系统触发;改为:订单中心只做业务状态(如:等待付款、配送中)和系统状态(系统取消、暂停)的互转
to 研发:
1、如订单状态、订单类型等一切业务属性定义的变更都以支撑业务运转为准,只要系统技术结构不变,开发人员无需过多干预
2、领域系统(订单系统、结算系统)是骨骼,骨骼和骨骼之间要有关节,跨领域的领域语言翻译工作应在“关节”上进行
to All:
个人认为:
系统最后僵化死亡,往往是因为过多的业务限制,而不是技术无法支持,典型:京东现有的订单系统。所以在业务梳理中,最好不要以“流程是通的,流程可用”为目标。
订单中心做为业务核心系统,无论在业务上还是技术上,都应尽量将其设计成功能可插拔的插件式结构,方便扩展维护。
目前,业务上可以认为各系统id就是业务数据上的唯一插件接口,希望各位尽量保持这个插件接口的纯洁性。
技术上的插件式结构还在探索中,欢迎提供好的建议。
另外,有一个观点,欢迎大家拍砖:
系统开发是有边界的,不能和现实世界所有特殊情况都完全对应(例如系统里不会有“配送员发生交通事故,正在就医”这种状态,但是现实世界会有),实际业务开展应该以系统操作和线下灵活处理共同完成,不能一切都依赖系统。实际业务中的特殊情况应首要考虑线下灵活处理,而不是增加系统功能。总之,系统功能应该是可预期的,功能数量应该是可收敛的。