又又又出 Bug 了 —— 签到类业务

82 阅读2分钟

又又又出 Bug 了 —— 签到类业务

国庆回来又出 Bug 了,简单复盘一下,总结下来还是碰到的问题不够多,经验不够老道。

背景

国庆期间上线了一个签到类的业务,且流量较大,节前配合QA测试测了好久,没想到还是出问题了。

图1

图1

问题描述

节后有用户反馈说签到不了,且反馈的用户不止一两个,这时候应该就猜到可能是出现问题了,随即开始排查。

    1. 先检查代码,看了半天也没发现问题。(期间别的同事也帮我看了,也没发现问题)
    1. 查数据,看了下线上的数据发现完成7天(全部)签到的人也挺多的,也没看出来问题。然后再看了下其中几个签到不了的用户的数据,发现了罪魁祸首,如下图2:

    图2

    图2

我立马想到了我写的那段逻辑,问题出现在这里,用户签到时间是 2024-10-06 23:59:59 我计算缓存的过期时间是当天的23:59:59-签到的时间, 导致设置了0 ,0表示这几个缓存永不过期,而这个缓存标志todaySignKey是表示用户当天是否签到了,如果永不过期的话,这个标志的状态一直是今日已签到,这样问题就找到了。

 now := time.Now()
 end := time.Date(now.Year(), now.Month(), now.Day(), 23595959, time.Local)
 ttl := end.Sub(now)
 // 设置过期时间
 err = rdb.Set(ctx, todaySignKey, "1", ttl)
 if err != nil {
  return errors.RedisError
 }

解决方式

方案一:在原有的处理方式上改

加一个判断,如果过期时间大于0才设置缓存

// 今日签到
 now := time.Now()
 end := time.Date(now.Year(), now.Month(), now.Day(), 23595959, time.Local)
 ttl := end.Sub(now)
 if ttl.Milliseconds() > 0 { // 剩余时间大于0
  // 设置过期时间
  err = rdb.Set(ctx, todaySignKey, "1", ttl)
  if err != nil {
   return errors.RedisError
  }
 }

方案二:用key来区分今日是否签到(推荐)

更推荐这种做法,不容易出问题。最终判断今日是否签到的时候只需要判断这个key是否有值即可。

// 今日签到
 now := time.Now()
 dateString := now.Format(time.DateOnly) // 2024-10-08
 RedisKey := "sign_in:" + dateString + ":" + "{用户id}"
 err = rdb.Set(ctx, todaySignKey, "1", time.Hour*24)
 if err != nil {
  return errors.RedisError
 }

欢迎关注我的公众号: 小付同学的开发日常,原创技术文章第一时间推送。

转存失败,建议直接上传图片文件