谨以此文记录一下今天发生的糗事。
今天下午,在我吃完晚餐,悠哉的逛着博客,准备下班的时候,线上报了个问题,说是移动端的H5登陆不上去了。老大让我查一下。我一查之下发现,新生成的token都是过期token。显然是生成token的逻辑出了问题。但是具体是哪里出了问题,我看了好一会儿也没看出来。最后还是组里两位大哥看出来了,原来是我在前两天优化代码的时候,把过期时间秒数的类型从Long换成了Integer,在生成token的逻辑中,需要把这个参数转成毫秒(乘以1000),就发生了数据溢出,最终导致新生成的token都是过期token。
写个小小的示意demo:
import java.util.Date;
public class DataOverflowTest {
static Integer wrongExpireSeconds = 2592000;
static Long correctExpireSeconds = 2592000L;
public static void main(String[] args) {
Date wrongExpireTime = new Date(System.currentTimeMillis() + wrongExpireSeconds * 1000);
System.out.println("wrong expire time: " + wrongExpireTime);
Date correctExpireTime = new Date(System.currentTimeMillis() + correctExpireSeconds * 1000);
System.out.println("correct expire time: " + correctExpireTime);
}
}
打印出来的结果(今天是2022年4月7日):
wrong expire time: Sat Mar 19 05:21:50 CST 2022
correct expire time: Sat May 07 22:24:37 CST 2022
问题的关键在于wrongExpireSeconds * 1000,究竟算出个什么玩意儿呢?答案是-1702967296。这是因为预期的结果(2592000000)超出了Integer类型的最大值(2147483647),数据溢出成了负的。用当前时间戳加上一个负数,过期时间就成了过去时了。
在这里我也反省一下,这件事反映出我有三个问题:第一个是Java基本功不够扎实,第二个是做开发不够谨慎,第三个是定位问题不够快也不够准。这三个问题导致我今天着实丢了一回人。俗话说知耻而后勇,我现在已然知耻,下一步就是拿出勇气付诸行动来解决这三个问题了。