@Scheduled(cron = "0 0/30 ?")
public void UpdateSmsUnList(){
try {
//使用redis分佈式鎖來保證同一時刻只有一個定時任務在執行
if (redisUtil.getLock(Constants.MSG_SMS_UN_REDIS_KEY,"doing job",60
3)) {
logger.info("任務開始執行");
msgSmsUnService.aliyunUpdateSmsUnList();//調用阿里數據服務
msgSmsUnService.unicomUpdateSmsUnList();//調用聯通數據服務
}
} catch (Exception e) {
logger.info("阿里、聯通更新數據異常",e.getMessage().toString());
}
}
Constants 類
public static final String MSG_SMS_UN_REDIS_KEY = MSG_REDIS_KEY + ":msg_sms_un_list";
redisUtil 工具類
import io.lettuce.core.SetArgs;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.cluster.api.async.RedisAdvancedClusterAsyncCommands;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import java.nio.charset.StandardCharsets;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;@Component
public class RedisUtil {Logger logger = LoggerFactory.getLogger(RedisUtil.class); @Autowired // 操作字符串的template,StringRedisTemplate是RedisTemplate的一個子集 private StringRedisTemplate stringRedisTemplate; @Autowired // RedisTemplate,可以進行所有的操作 private RedisTemplate<Object, Object> redisTemplate; private ThreadLocal<String> lockValue = new ThreadLocal<>(); private static final String REDIS_LIB_MISMATCH = "Failed to convert nativeConnection. " + "Is your SpringBoot main version > 2.0 ? Only lib:lettuce is supported."; public void set(String key, String value) { stringRedisTemplate.opsForValue().set(key, value); } public void set(String key, String value, long time) { stringRedisTemplate.opsForValue().set(key, value, time); } public void setIfAbsent(String key, String value, long time) { stringRedisTemplate.opsForValue().setIfAbsent(key,value,time,TimeUnit.SECONDS); } public void set(String key, String value, long time, TimeUnit unit) { // 向redis裏存入數據和設置緩存時間 stringRedisTemplate.opsForValue().set(key, value, time, unit); } public String get(String key) { return stringRedisTemplate.opsForValue().get(key); } public Set<String> getKeys(String pattern) { return stringRedisTemplate.keys(pattern); } public void delete(String key) { stringRedisTemplate.delete(key); } public boolean getLock(String key, String value, int expireSeconds) { String uuid = UUID.randomUUID().toString(); try { String result = redisTemplate.execute(new RedisCallback<String>() { @Override public String doInRedis(RedisConnection connection) throws DataAccessException { try { Object nativeConnection = connection.getNativeConnection(); byte[] keyByte = key.getBytes(StandardCharsets.UTF_8); byte[] valueByte = uuid.getBytes(StandardCharsets.UTF_8); String resultString = ""; if (nativeConnection instanceof RedisAsyncCommands) { RedisAsyncCommands command = (RedisAsyncCommands) nativeConnection; resultString = command .getStatefulConnection() .sync() .set(keyByte, valueByte, SetArgs.Builder.nx().ex(expireSeconds)); } else if (nativeConnection instanceof RedisAdvancedClusterAsyncCommands) { RedisAdvancedClusterAsyncCommands clusterAsyncCommands = (RedisAdvancedClusterAsyncCommands) nativeConnection; resultString = clusterAsyncCommands .getStatefulConnection() .sync() .set(keyByte, keyByte, SetArgs.Builder.nx().ex(expireSeconds)); } else { logger.error(REDIS_LIB_MISMATCH); } return resultString; } catch (Exception e) { logger.error("Failed to lock, closing connection", e); closeConnection(connection); return ""; } } }); boolean eq = "OK".equals(result); if (eq) { lockValue.set(uuid); } return eq; } catch (Exception e) { logger.error("Set redis exception", e); return false; } } private void closeConnection(RedisConnection connection) { try { connection.close(); } catch (Exception e2) { logger.error("close connection fail.", e2); } }
}