常见分布式高并发系统设计

高并发系统

高并发系统的设计其实主要围绕四点:高性能、高可用、高可扩展性、高可维护性

https://cloud.tencent.com/developer/article/1653881

<<分布式应用系统架构设计与实践>>

IM系统设计

https://xie.infoq.cn/article/19e95a78e2f5389588debfb1c

https://juejin.cn/post/7032512073502294053

https://www.bilibili.com/read/cv11325774?from=search

读扩散和写扩散

读扩散和写扩散的概念一般是出现在feed流或者IM消息系统中,一个用户关注或者被关注了多个人,那么当有人发消息时,其他跟该用户关联的用户如何获取消息的方式

读扩散

接收人维护了多个"信箱", 比如A关注了B, C,D, 那么B,C,D有人发了消息,就会往AB,AC, AD信箱发送数据, 服务端可以维护那些信箱有新数据,那么A用户拉取的时候就从这些信箱拉取。(如果群有消息,那么群信箱加入数据,服务端可以标记某个群是否有消息)。

写扩散

接收人只有一个信箱,跟用户关联的人只要发了消息,那么就会将消息发到这个用户的信箱中,如果有群消息,那么会给群里所有人都发消息。

对比之下,读扩散,写操作时很方便,写扩散时,读操作很方便

底层数据结构

消息系统底层数据结构,一般情况下,message作为单独的表,message Id全局自增,另一张表是会话表,比如有to uid, from uid, message id的概念

推拉模式

一般可以采用推拉模式结合,比如一有新消息,就往客户端推送表示有新消息,然后客户端进行主动拉取具体的消息

消息的顺序性

在一对一聊天时,一般在客户端使用序列号,这样的话,消息就有顺序,接收方可以再排序

在群聊中,由于是不同的人发出的,客户端是没办法生成序列号,有两种方式:

1、一个专门的id序号服务,两个人发消息时都会生成一个序号,这样在所有人看到的群里,就是连续的。

2、同一个群消息,打到相同的service实例上,在实例上进行排序

http://www.52im.net/thread-714-1-1.html

比较完整的消息系统架构设计

https://www.cnblogs.com/hanease/p/16268095.html

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PyvPgAsF-1686538151922)(C:\Users\13045\AppData\Roaming\Typora\typora-user-images\1677984046075.png)]

一般来说消息主动推送,可以接外部的, 比如google,融云的服务,他们来负责,本质上就是一个长连接。所以推送部分不是重点。

重点是整体的架构。

  • 端:作为消息的发送和接收端,通过连接消息服务器来发送和接收消息。
  • 消息服务器:一组无状态的服务器,可水平扩展,处理消息的发送和接收请求,连接后端消息系统。
  • 消息队列:新写入消息的缓冲队列,消息系统的前置消息存储,用于削峰填谷以及异步消费。
  • 消息处理:一组无状态的消费处理服务器,用于异步消费消息队列中的消息数据,处理消息的持久化和写扩散同步。
  • 消息存储和索引库:持久化存储消息,每个会话对应一个Timeline进行消息存储,存储的消息建立索引来实现消息检索。
  • 消息同步库:写扩散形式同步消息,每个用户的收件箱对应一个Timeline,同步库内消息不需要永久保存,通常对消息设定一个生命周期。
    新消息会由端发出,通常消息体中会携带消息ID(用于去重)、逻辑时间戳(用于排序)、消息类型(控制消息、图片消息或者文本消息等)、消息体等内容。消息会先写入消息队列,作为底层存储的一个临时缓冲区。消息队列中的消息会由消息处理服务器消费,可以允许乱序消费。消息处理服务器对消息先存储后同步,先写入发件箱Timeline(存储库),后写扩散至各个接收端的收件箱(同步库)。消息数据写入存储库后,会被近实时的构建索引,索引包括文本消息的全文索引以及多字段索引(发送方、消息类型等)

Feed流

feed流的本质也是读扩散+写扩散结合

https://cloud.tencent.com/developer/article/1744756

秒杀系统

https://zhuanlan.zhihu.com/p/89518837

https://juejin.cn/post/6990307911117307934#heading-11

超买: 每个用户用redis锁

超卖: lua脚本控制原子性。

红包

发红包

发红包主要的是拆解步骤,如果是我,我会这么设计:

发红包时就使用算法将红包拆成用户指定数量的多个小部分,入库,状态置为未发放,然后发起微信支付付款,再更新发放红包的状态,并把红包列表写入缓存中。 另外,红包有一个ID

领取红包时,根据红包ID打入到固定的一个server中,server中对每个相同的ID进行排队处理,保证并发性,领取完毕后,写入用户领取红包的记录,然后发到MQ中,MQ再给用户进行微信零钱打入

如果中间有异常,那么客户端可以一直loading尝试几次。

最后,使用对账,微信支付和微信红包平台进行对账,保证数据一致性。

http://www.52im.net/thread-2564-1-1.html

摇一摇红包

https://www.woshipm.com/pd/232838.html

火车票系统

https://www.cnblogs.com/crazymakercircle/p/15058702.html

https://www.infoq.cn/article/12306-core-model-design

火车票系统的难点主要在于两个:

  • 1、抢票,这个跟秒杀系统设计类似
  • 2、模型设计

火车票比单纯的秒杀系统更难,因为它的库存是浮动的,比如A,B,C三个连续站点,某个座位,假如有人在B站点下车,那么显然这个座位,就会空出来,允许从B到C的车次中进行订票。

如果从DDD的设计来讲,一般将一个车次作为一个聚合跟,这个车次的信息有:

1、车次名

2、经过的站点

3、座位数

4、出发时间

在一个车次进行买票,要想成功,那么这个车次经过的所有站点之间都需要至少有一个座位,那么也就是在一个车次上进行买票,扣除的库存,就是每两个站点之间的座位数,全部扣减了,才算成功。

所以数据库层设计,库存就是每两个站点之间,然后每个座位相当于是一个明细资源,买票后就会扣库存,然后到站后就会还原库存。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值