关于如何设计捐款系统的一些问题

  1. 在设计捐款网站的时候,同时有多个捐款者向同一个慈善机构捐款,会出现什么问题?因为不存在缺货的这种情况,那还有别的情况需要考虑吗?这里是不是就需要message queue来handle async事务了?

  2. 个人捐款的话,如何解决race conditions e.g. double charge, insufficient funds。double charge的话,是不是也是存一个系统内部的 transaction ID,如果出现过了,就abort掉后面进来的,那么这时候是不是也需要TimeStamp?

  3. 在捐款系统里,charge event如何避免fail,第三方API挂了怎么办?我的方法是transaction DB里加一个column status eg. Pending Complete Cancelled

但如果第三方API不会realtime返回结果,也就是不能立即知道是否charge成功该怎么办?

  1. 在建立慈善机构table的时候,sharding key是不是直接就charity id就可以了,而不是根据s2/geohash 进行sharding了?
  1. 不会有问题。分布式事务需要 Message Queue + Watchdog Service.
  2. 基本正确,不需要 timestamp,如果服务器发现已经接收过同样 Transaction ID 的 request 就当场 reject 就好。
  3. 如果第三方 API 挂了,我们可以在我们的内部数据库中先存下来,等第三方恢复以后再发送过去。第三方不立刻告知付款是否成功的话就需要另一个 API 去读取当前状态。
  4. 根据 Request pattern,我们一般允许用户读取自己的捐赠是否成功,那么用 Donor ID Shard 更合理。

想问一下 实现分布式事务Message Queue是一定需要的吗? 我看电影订票系统里面只画了 watchdog service

message queue 是 watchdog 的信息来源,有比较好。否则的话就是每个服务都会需要向watchdog直接发送信息,会有 tight coupling,没有必要。电影订票系统的设计图是略去了这部分。

想问下 这个第三点,一般第三方API挂了 如果不是transient issue 怎么处理会比较好 还允许其他的customer 捐款吗?一般怎么得知第三方恢复了? 谢谢老师

第三方 API 永久当机的话只能停止服务了。要解决的就得提前 intergrate 多家付费服务商。
如果核心的第三方服务的话,对于企业级服务就得直接跟这家公司取得联系了,同时我们可以持续 ping 这家公司的 API,了解是否回复服务。

想问一下关于double charge, transaction ID是怎么生成的?看Alex Xu的设计书11章里面避免customer click pay button quickly twice使用了Id of the shopping cart right before the checkout? 想问一下在捐款系统里面要用哪个作为idempotent key?

你可以认为捐款系统用户将捐款信息填入之后就会生成一个 unique key。通俗点讲,你可以认为捐款系统也有一个“购物车”,用户把要捐的钱填进去,生成这个 idempotent key。