在和三方服务对接过程中,可能经常遇到一个问题:accessToken过期需要刷新
一般解决办法 我能想到的办法如下(大佬们有其他办法的话麻烦私我一下,我想偷偷学习):
定时job去刷新accessToken
失效报异常,并刷新,本次异常不处理(会被扣钱的吧 o((⊙﹏⊙))o.)
失效后立即刷新并重试业务逻辑
如果24h都要使用accesToken的话 ,方法1也是合理的
但!我!不!乐!意!
我就想要方法3!!!!!
基础业务代码如下:
//基础业务代码
public String getUserInfo(String id){
//从缓存读取accessToken(缓存读取不到会重新调用接口获取新的accessToken)
String accessToken = getAccessToken();
//从三方获取信息
String result = client.getUserInfo(id,accessToken);
return result;
}
第一次改造尝试:
//基础业务代码
public String getUserInfo(String id){
//从缓存读取accessToken(缓存读取不到会重新调用接口获取新的accessToken)
String accessToken = getAccessToken();
//从三方获取信息
try{
String result = client.getUserInfo(id,accessToken);
}catch(accessToken失效){
//重新获取accessToken
refreshAccessToken();
//再来一遍
return getUserInfo(id);
}
return result;
}
漂亮!不出意外的话 我该出意外了!这喵的万一refresh没用不是死循环了么!!!
脑子里过了一遍,这是面向切面吧?提取?公共?环绕?
spring爸爸不会让我写那么多复杂的代码的,他一定有好东西!!
然后我就百度了。。。搜索关键字java 重试,解锁新角色@Retryable
🎖
咱也不知道好不好用,试试吧~~
//基础业务代码
@Retryable(value = InvalidTokenException.class,maxAttempts = 1,backoff = @Backoff(delay = 100))
public String getUserInfo(String id){
//从缓存读取accessToken(缓存读取不到会重新调用接口获取新的accessToken)
String accessToken = getAccessToken();
//从三方获取信息
String result = client.getUserInfo(id,accessToken);
return result;
}
代码又优雅了许多(*≧∪≦)
参数就是照着别人家的博客抄的,我初步理解一下:
InvalidTokenException.class, 就是你要什么异常才需要重试,毕竟那么多异常呢,人生无常,大肠包小肠
maxAttempts = 1, 需要重试的次数,我认为(划重点)我要重试一次,所以是1
backoff = @Backoff(delay = 100)) ,重试间隔时间
我试着run一下,跑起来了!!!就是和原先代码完全没差!!!
没生效,不意外,这是鄙人常态了。。。
第二次改造尝试:
代码没动,听说要配合@EnableRetry
用,我在各个controller都试过了,大型翻车现场。。。。
我突然意识到,我是不是。。。理解错了
maxAttempts = 1, 需要重试的次数,我认为(划重点)我要重试一次,所以是1
其实!!!!
maxAttempts = 1, 总共执行的次数1次(含重试),
如果达到要重试一次的效果,那么应该是本身执行次数+重试次数 =2
//基础业务代码
@Retryable(value = InvalidTokenException.class,maxAttempts = 2,backoff = @Backoff(delay = 100))
public String getUserInfo(String id){
//从缓存读取accessToken(缓存读取不到会重新调用接口获取新的accessToken)
String accessToken = getAccessToken();
//从三方获取信息
String result = client.getUserInfo(id,accessToken);
return result;
}
出效果了!!!家人们!!!!
总结一下
- @EnableRetry 使用在controller即可(必须要,不要不行,我试过了,信我)
- @Retryable(value = Exception.class,maxAttempts =2,backoff = @Backoff(delay = 100))(注意参数的理解)
也不知道会不会产生其他的问题,希望在我跑路之前没问题!