分散トランザクションソリューションのRedis実装
6528 ワード
前言:
マイクロサービスの発展に伴い、分散型事務はほとんど避けられないと言え、関連概念は余計なことではありません.分からないことがあれば、まず理解してから読むこともできますし、伝言もできます.このブログがあなたに役立つことを望んでいます.
本文:
まず、アーキテクチャ図を添付し、私が実現したソリューションが頼りにしているプロジェクトアーキテクチャを簡単に理解します.
以下は分散ロックの取得と解放、メンバー変数:StringRedisTemplate(springboot統合redis取得redis、注入jedisによる実現も可能であり、実現構想は一致しており、文末にredis取得の実現を添付します).
いくつかのredisの基本命令を見てみましょう:
ロックが必要なコードブロックでは、次の操作を行います.
ロックを取得する方法では、ロックを取得する時間が入力され、一定時間以内に取得され、返された識別がNULLでない場合、改善することができる.
Springboot統合reids:
プロファイル:
読んでからあなたたちに収穫があることを望んで、本文は完備しなければなりません.の
マイクロサービスの発展に伴い、分散型事務はほとんど避けられないと言え、関連概念は余計なことではありません.分からないことがあれば、まず理解してから読むこともできますし、伝言もできます.このブログがあなたに役立つことを望んでいます.
本文:
まず、アーキテクチャ図を添付し、私が実現したソリューションが頼りにしているプロジェクトアーキテクチャを簡単に理解します.
以下は分散ロックの取得と解放、メンバー変数:StringRedisTemplate(springboot統合redis取得redis、注入jedisによる実現も可能であり、実現構想は一致しており、文末にredis取得の実現を添付します).
いくつかのredisの基本命令を見てみましょう:
SETNX key value
(stringRedisTemplate.opsForValue().setIfAbsent()キーが存在しない場合は、キー対応文字列valueを設定します.この場合、このコマンドはSETと同じです.keyがすでに存在する場合、何もしません.SETNXは「SET if Not eXists」です.expire KEY seconds
(stringRedisTemplate.expire()キーの有効期限を設定します.keyが期限切れになった場合、自動的に削除されます.del KEY
(stringRedisTemplate.delete()削除key/**
* @auther fanxuebo
* @desc
* @Company
* @create 2019/1/10 17:48
*/
public class DistributedLock {
private static final Logger LOGGER = LoggerFactory.getLogger(DistributedLock.class);
private StringRedisTemplate stringRedisTemplate;
public DistributedLock(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
/**
* @Author fanxuebo
* @Date 2019/1/11 10:10
* @Description
**/
public String lockWithTimeout(String lockName, long timeout) {
String retIdentifier = null;
try {
// value
String identifier = UUID.randomUUID().toString();
// , key
String lockKey = "lock:" + lockName;
// ,
int lockExpire = (int)(timeout / 1000);
while (true) {
if (stringRedisTemplate.opsForValue().setIfAbsent(lockKey, identifier)) {
LOGGER.info("{}: lockKey:{}", Thread.currentThread().getName(), lockKey);
stringRedisTemplate.expire(lockKey, lockExpire, TimeUnit.SECONDS);
// value ,
retIdentifier = identifier;
break;
}
// -1 key , key
if (stringRedisTemplate.getExpire(lockKey) == -1L) {
stringRedisTemplate.expire(lockKey, lockExpire, TimeUnit.SECONDS);
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
} catch (JedisException e) {
e.printStackTrace();
}
return retIdentifier;
}
/**
* @Author fanxuebo
* @Date 2019/1/11 10:09
* @Description
**/
public boolean releaseLock(String lockName, String identifier) {
String lockKey = "lock:" + lockName;
boolean retFlag = false;
try {
while (true) {
// lock,
stringRedisTemplate.watch(lockKey);
// value , , ,
if (identifier.equals(stringRedisTemplate.opsForValue().get(lockKey))) {
LOGGER.info("{}: lockKey:{}", Thread.currentThread().getName(), lockKey);
stringRedisTemplate.delete(lockKey);
retFlag = true;
}
stringRedisTemplate.unwatch();
break;
}
} catch (JedisException e) {
e.printStackTrace();
}
return retFlag;
}
}
ロックが必要なコードブロックでは、次の操作を行います.
DistributedLock distributedLock = new DistributedLock(stringRedisTemplate);
String lockName = XXX;
String identifier = null;
try {
identifier = distributedLock.lockWithTimeout(lockName, 3000);
//
distributedLock.releaseLock(lockName, identifier);
} catch (Exception e) {
distributedLock.releaseLock(lockName, identifier);
}
ロックを取得する方法では、ロックを取得する時間が入力され、一定時間以内に取得され、返された識別がNULLでない場合、改善することができる.
long end = System.currentTimeMillis() + acquireTimeout;
while (System.currentTimeMillis() < end) {}
DistributedLock distributedLock = new DistributedLock(stringRedisTemplate);
String lockName = XXX;
String identifier = null;
try {
identifier = distributedLock.lockWithTimeout(lockName, 3000);
if (StringUtils.isBlank(identifier)) {
//
}
//
distributedLock.releaseLock(lockName, identifier);
} catch (Exception e) {
distributedLock.releaseLock(lockName, identifier);
}
Springboot統合reids:
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
/**
* @auther fanxuebo
* @desc REDIS
* @Company sinosig
* @create 2018/8/6 09:56
*/
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public CacheManager cacheManager(RedisTemplate,?> redisTemplate) {
CacheManager cacheManager = new RedisCacheManager (redisTemplate);
return cacheManager;
}
/**
* @Auther: fanxuebo
* @Description: jdk ,
* @Date: 09:58 2018/8/6
*/
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
RedisTemplate redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
/**
* @Auther: fanxuebo
* @Description: string , string
* @Date: 09:59 2018/8/6
*/
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setConnectionFactory(factory);
return stringRedisTemplate;
}
}
プロファイル:
spring:
redis:
database:
host:
port:
password:
pool:
max-active: 50
max-wait: 5000
# max-idle: 8
# min-idle: 0
timeout: 5000
読んでからあなたたちに収穫があることを望んで、本文は完備しなければなりません.の