场景1:在电商系统中,会有下订单之后发送信息提示给用户。
场景2:订单这么久了还没发放,怎么办啊,我是硬硬点击提醒发货,给商家发送提示消息啊
场景3:现在很流行快递柜,小哥哥把快递放进柜子后,就当当当给手机用户发提示信息。
事实:流量小的话,请忽略。流量稍微大一点的电商,都不会按照信息的发送顺序来给用户发送提示的;商家不会按照消息的顺序发送消息提醒的,一般都会有一个规则,这个规则跟毛爷爷有关系,谁能贡献更多的毛爷爷,那么消息就会越优先发送。
解决方案:为了不影响下单流程的体验感,一般用MQ做解耦,将提示信息交给另外的系统去做。如果团队用的MQ自带优先级还好,不然的话,自己在信息系统中实现一个也不是什么难事。
我再实际应用中,也处理过类似的问题,那么以下就将代码分享出来(由于涉及到保密协议,敏感部分已经去掉,复制黏贴过去可进行扩展开发):
- 定义我们需用用到的结构体:
type Notice struct {
Weight int // 值大者,优先发送
PhoneNumber string // 对方手机号码
Message string // 发送的提示信息
index int
}
type Notices []*Notice
- 定义我们需要用到的插入和弹出:
func (q *Notices) Push(n interface{}) {
length := len(*q)
capacity := cap(*q)
if length + 1 > capacity {
tq := make(Notices, length, capacity * 2)
copy(tq, *q)
*q = tq
}
*q = (*q)[0 : length + 1]
ne := n.(*Notice)
ne.index = length
(*q)[length] = ne
q.up(length)
}
func (q *Notices) Pop() interface{} {
length := len(*q)
capacity := cap(*q)
(*q)[0], (*q)[length-1] = (*q)[length-1], (*q)[0]
q.down(0, length-1)
if length < (capacity / 2) && capacity > 25 {
tq := make(Notices, length, capacity / 2)
copy(tq, *q)
*q = tq
}
ne := (*q)[length - 1]
ne.index = -1
*q = (*q)[0 : length - 1]
return ne
}
- 定义我们进行调整的函数:
func (q *Notices) up(length int) {
for {
i := (length-1)/2
if length == i || (*q)[i].Weight > (*q)[length].Weight {
break
}
(*q)[i], (*q)[length] = (*q)[length], (*q)[i]
length = i
}
}
func (q *Notices) down(i, length int) {
index := i
for {
left := 2 * index + 1
if left >= length || left < 0 {
break
}
swap := left;
if right := left + 1; right < length && (*q)[right].Weight > (*q)[left].Weight {
swap = right
}
if (*q)[swap].Weight < (*q)[index].Weight {
break
}
(*q)[index], (*q)[swap] = (*q)[swap], (*q)[index]
index = swap
}
}
下面就用一下测试代码吧:
func main() {
notices := make(Notices, 0, 100)
fmt.Println(notices)
for len(notices) < 30 {
d := rand.Intn(1000-100)+100
notice := &Notice{
Weight: d,
PhoneNumber: "13000000000",
Message: "我是通知消息",
}
fmt.Printf("add %d\n", d)
notices.Push(notice)
}
for len(notices) > 0 {
n := notices.Pop()
ne := n.(*Notice)
fmt.Printf("Pop %d\n", ne.Weight)
}
}