0%

概述

概念可以简单描述某类事物,这类事物可以是实体也可以是问题。领域驱动设计是为了管理系统复杂性问题而生的一套方法论。

随着业务系统的复杂性不断提高,系统的性能和灵活性要求也会越来越高,如何构建一个扩展性强、可用性高的业务系统是需要我们不断思考的问题。

我们以交易系统为例,在互联网之初,实体商业占据绝对主导地位的时代,电子商务系统最初的目的就是把货物卖出去,业务需求很简单,就是一手付钱,一手交货,而更多的难点是在于如何让人们接受并认可在网络上进行交易。随着这几十年的发展,电商早已不是最初的样子,需求变为如何更快更多的把商品卖出去,于是产生出了层出不穷你算不清楚的促销活动,比如满减、凑单、会员价、拼团、优惠券等。你买东西的价格也许只有系统能真正算清楚。

系统的复杂性比起最初,呈几何倍的增长,如何控制并管理系统复杂度是我们需要在业务发展过程中需要解决的问题。复杂的业务各有各的复杂,而拆解之道也各有各的侧重,今天要介绍的是领域驱动设计如何帮助我们拆解需求,并建立一个灵活性高、可扩展的业务系统。

阅读全文 »

在加乌拉山口拍珠峰,这里可以一眼望尽五座八千米高山。

旅行是为了什么?有的人是为了好吃好玩,有的人是为了看风景。我就是后者,如果你喜欢游览祖国广袤的山川河流,看尽一望无际的高原雪山,那么你一定要来趟西藏,看看还是那么相对纯粹的自然风光。

去西藏的计划是从八月推迟到了十一黄金周,不过今年西藏的十一却少了往日的火爆,人不是那么多,主要还是因为前一段事件疫情的影响,所以路上的体验都还不错。

阅读全文 »

调研环境说明

etcd –version
etcd Version: 3.5.1
Git SHA: d42e8589e
Go Version: go1.17.2
Go OS/Arch: darwin/amd64

参数说明

启动参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
--name etcd-1 // 节点名称
--data-dir /Users/noogel/Debug/data/etcd1 // 数据目录
--initial-advertise-peer-urls http://127.0.0.1:238
--listen-peer-urls http://127.0.0.1:2381
--listen-client-urls http://127.0.0.1:2379
--advertise-client-urls http://127.0.0.1:2379
--initial-cluster-token etcd-lock-cluster-1 // 集群 token
--initial-cluster etcd-1=http://127.0.0.1:2381,etcd-2=http://127.0.0.1:2382,etcd-3=http://127.0.0.1:2383 // 集群节点信息
--initial-cluster-state new // 初始化的集群状态
--heartbeat-interval 1000 // 心跳间隔
--auto-compaction-retention 1 // 开启自动压缩,间隔 1h 执行
--auto-compaction-mode periodic
--quota-backend-bytes 8589934592 // 后端存储大小
--election-timeout 5000 // 选举超时时间
阅读全文 »

概况

作为一个北方汉子对于面食真的是十分热爱的,尤其是发面后的。从小在家兜包子都是只能看不让参与的,长大后在外面都是买现成的,如今也想自己做一做。也许是从小在家耳濡目染,第一次做整体的效果还不错。
宋丹丹老师曾经说过把大象装进冰箱总共要分三步,那么蒸包子总共需要分为如下五步:

  1. 准备原材料
  2. 发面
  3. 调馅
  4. 擀面片
  5. 蒸包子

可是,真的就是只蒸了包子吗?

阅读全文 »

什么是复杂性

复杂或复杂性与简单相对立,那么复杂是什么?它是我们大脑中的一个概念,但是我在网上找不到一个给复杂恰当的定义描述,它会有不同的解释。
其中洛克在《人类理解论》中说道:『一些思想是由简单的思想组合而成,我称此为复杂;比如美、感激、人、军队、宇宙等。』
作为研究复杂系统的专家 Melanie Mitchell,也没有给出一个明确的公认的定义。她在《复杂》一书中给出了复杂系统加以定义:『复杂系统是由大量组分组成的网络,不存在中央控制,通过简单运作规则产生出复杂的集体行为和复杂的信息处理,并通过学习和进化产生适应性。』
上述复杂系统中的组分对应软件系统中的组成部分,基于不同粒度可以是对象、函数、类、包、模块、组件和服务等。每一部分都应该是相对单一的职责,细粒度部分之间耦合提供更粗粒度功能,不同组分之间相互协作来提供系统功能,继而组合成我们复杂的软件系统。

阅读全文 »

初步认知

以 Drools 为例子

这个组件是什么,有什么功能?

Drools 是一个基于Charles Forgy’s的RETE算法的,易于访问企业策略、易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快、效率高。业务分析师人员或审核人员可以利用它轻松查看业务规则,从而检验是否已编码的规则执行了所需的业务规则。
Drools相关概念

  • 事实(Fact):对象之间及对象属性之间的关系
  • 规则(rule):是由条件和结论构成的推理语句,一般表示为if…Then。一个规则的if部分称为LHS,then部分称为RHS。
  • 模式(module):就是指IF语句的条件。这里IF条件可能是有几个更小的条件组成的大条件。模式就是指的不能在继续分割下去的最小的原子条件。

Drools通过 事实、规则和模式相互组合来完成工作,drools在开源规则引擎中使用率最广,但是在国内企业使用偏少,保险、支付行业使用稍多。

阅读全文 »

模板的好处就在于可以让你快速且全面的规划方案,一些你能想到和不能想到的地方。既能避免你在做旅游规划时漏掉什么,又能节省你思考的时间。有了模板你只需要按照大纲去调研即可。

如果你旅游前需要详细规划,那么这个模板很适合你。
如果你是想走开车就走的那种,可以跳过这篇。

模板按需填充即可,比如去西藏就需要特别关注海拔信息。去三亚就需要关注一下日出日落和潮汐时间。下面是我在做西藏旅游攻略做的一个简单攻略,仅供参考。

阅读全文 »

你有没有遇到过一个函数几百行长度,如果没有可以跳过本文章了,如果没有那么应该看看下面的内容。一个超长函数的复杂性不在于那些胶水代码,而是其中的逻辑分支,大量的逻辑分支导致你的代码难以理解。而重构的过程分为两步:

  1. 编写单元测试,如果覆盖到了函数的每个分支,那么重构的风险性就会降到最低。
  2. 重构代码,对代码进行拆分重写,为了使代码变得易于维护。

重构分为三个层次:

  1. 小重构
    • 消除重复代码
    • 拆分小函数(单一职责)
  2. 设计模式
    • GoF 23种
  3. 抽象建模
    • 四色建模法
    • 风暴建模法

复杂度问题的应对办法,防止偶然复杂性。

TODO

背景介绍

首先介绍一下实体电商通用的售后流程。

  1. 用户申请:在用户申请操作时需要填写退货、换货,以及原因。
  2. 商家审核:商家会根据沟通情况审核售后申请。
  3. 用户回寄:审核通过后需要用户回寄商品。
  4. 确认退换:商家收货确认后会给用户退款或者邮寄新货。

虚拟商品的售后通用流程如下:

  1. 管理员发起退换操作
  2. 处理退换
    • 退:先退货后退款
    • 换:先退货后发货

在以上两个流程的处理流程有个共通的地方,就是一次操作需要涉及多个子流程的处理,这就是接下来需要讲的通用售后流程抽象。多个子流程的处理意味着要和多个子系统分别进行沟通处理退货、换货和退款。

这里就涉及到分布式系统的一致性问题了,售后模块作为资源的协调方,我们是否可以采用 TCC 的强一致性方案?答案是 No,成本有点高。普遍的做法是采用弱一致性方案保证最终一致性,我们可以考虑采用 Pipeline 机制。

阅读全文 »

本文主要介绍知乎订单系统后端语言栈的转型升级过程,包括其间踩过的一些坑和遇到的一些问题。一来是想通过本篇文章为其它应用服务转型提供借鉴经验,二来是总结对于订单系统的理解。鉴于文字功底不足,对于业务理解不充分的地方,欢迎留言交流。文章大纲如下:

  • 迁移背景
  • 前期准备
    • 迁移方案
    • 接口验证
    • 指标梳理
  • 可用性保障
    • MTTR 快速响应
    • MTBF 降低故障率
  • 一致性保障
  • 事后总结
    • 目标回顾
    • 执行计划
    • 执行结果
    • 问题整理
  • 业务沉淀
  • 方法论实践
  • 参考文章
  • 招聘信息

迁移背景

随着知乎整体技术栈的变化,原有的 Python 技术栈逐渐被抛弃,新的 Go 和 Java 技术栈逐渐兴起。知乎交易系统的稳定性相比其它业务系统的稳定性重要很多,因为交易系统核心链路发生故障不仅会造成数据问题,还会造成严重的资损问题。
随着公司业务的不断壮大发展,交易场景变得复杂,重构和优化难以避免,因为语言特性,Python 虽然开始撸代码很爽,但是后期的维护成本慢慢变高,不过 Python 在数据分析和人工智能方向上还是有很大优势的,只是在交易领域目前看起来不太合适。从技术生态上来说,用 Java 做交易系统会更有优势,所以接下来要说的知乎订单系统语言栈转型。
另外一个因素是 Python 的 GIL 锁导致它无法发挥多核的优势,性能上受到很大限制,在实际情况中遇到过多次主线程被 hang 住导致的可用性故障,所以坚定决心来迁移掉旧系统。

阅读全文 »