SpringBoot実装分散ロック(Spring integration+redis)
5405 ワード
SpringBoot実装分散ロック(Spring integration+redis)
一、redisインストール
docker-composeを使用してインストールするために必要なredis環境
二、プロジェクトのpom.xml加入依存
1)Spring integration依存
2)spring integration redis依存
3)spring data redis依存
application.yml構成の追加
RedisLockRegistry構成
三、コードの中で分布式ロックを使う
1)カスタムロック注記LzxLockDistributed
2)aopはロックの取得と解放を実現する
3)注釈による方法のロック
一、redisインストール
docker-composeを使用してインストールするために必要なredis環境
version: '3'
services:
redis:
image: redis # redis
container_name: my_redis
command: redis-server --requirepass 123456 # redis
ports:
- "6379:6379"
volumes:
- ./data:/data
phpredisadmin: # redis web
environment:
- ADMIN_USER=admin #
- ADMIN_PASS=admin #
- REDIS_1_HOST=redis #redis
- REDIS_1_PORT=6379 #redis
- REDIS_1_AUTH=123456 #redis
image: 172.26.206.220/library/phpredisadmin:1.0
depends_on:
- redis
links:
- redis
ports:
- "10001:80"
二、プロジェクトのpom.xml加入依存
1)Spring integration依存
org.springframework.boot
spring-boot-starter-integration
2)spring integration redis依存
org.springframework.integration
spring-integration-redis
3)spring data redis依存
org.springframework.boot
spring-boot-starter-data-redis
application.yml構成の追加
spring:
redis:
port: 6379
host: ***.***.***.***
password: 123456
RedisLockRegistry構成
package com.lzx.demo.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.integration.redis.util.RedisLockRegistry;
/**
* :
*
* @Auther: lzx
* @Date: 2019/6/17 15:06
*/
@Configuration
public class RedisLockConfiguration {
@Bean
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory){
return new RedisLockRegistry(redisConnectionFactory,"spring-cloud");
}
}
三、コードの中で分布式ロックを使う
1)カスタムロック注記LzxLockDistributed
package com.lzx.demo.annotation;
import java.lang.annotation.*;
/**
* :
*
* @Auther: lzx
* @Date: 2019/6/17 16:24
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LzxLockDistributed {
String value() default "";
int time() default 30;
}
2)aopはロックの取得と解放を実現する
package com.lzx.demo.aop;
import com.lzx.demo.annotation.LzxLockDistributed;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
/**
* : LzxLockDistributed Aop
*
* @Auther: lzx
* @Date: 2019/6/18 10:56
*/
@Component
@Aspect
@Slf4j
public class MethodLockAop {
private WebApplicationContext webApplicationContext;
public MethodLockAop(WebApplicationContext webApplicationContext) {
this.webApplicationContext = webApplicationContext;
}
@Pointcut("@annotation(com.lzx.demo.annotation.LzxLockDistributed)")
private void apiAop(){
}
@Around("apiAop()")
public Object aroundApi(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
LzxLockDistributed lzxLockDistributed = method.getAnnotation(LzxLockDistributed.class);
String localRegistry = lzxLockDistributed.value();
if(StringUtils.isBlank(localRegistry)){
throw new RuntimeException(" Registry beann ");
}
RedisLockRegistry redisLockRegistry = (RedisLockRegistry) webApplicationContext.getBean(lzxLockDistributed.value());
Lock lock = redisLockRegistry.obtain(signature.getName());
boolean b = false;
for(int i =0 ; i<3;i++){
b = lock.tryLock(lzxLockDistributed.time(), TimeUnit.SECONDS);
if(b){
break;
}else {
continue;
}
}
log.info(" ====="+b);
Object proceed = null;
try{
proceed = point.proceed();
}catch (Exception e){
throw e;
}finally {
try{
lock.unlock();
}catch (Exception e){
log.error(e.getMessage(),e);
}
}
return proceed;
}
}
3)注釈による方法のロック
@LzxLockDistributed(value = "redisLockRegistry",time = 60)
public String redisLockTest() throws InterruptedException {
if(inventory >= 5){
return " ~~~";
}
String s = strArr[inventory];
Thread.sleep(10*1000);
inventory++;
return s;
}