diff --git a/pangu-cache-spring-boot-starter/pom.xml b/pangu-cache-spring-boot-starter/pom.xml index 688bf93e8c924da8643a375c9eeb7b1a09a2a941..529a4d40ffe9dadac0b2d402483bd817c2717c86 100644 --- a/pangu-cache-spring-boot-starter/pom.xml +++ b/pangu-cache-spring-boot-starter/pom.xml @@ -52,6 +52,10 @@ com.github.xiaolyuh layering-cache-starter + + com.baomidou + lock4j-redis-template-spring-boot-starter + org.aspectj aspectjweaver diff --git a/pangu-examples/README.md b/pangu-examples/README.md index 03ef882133f4ca6a666ab515baf51a8e2d8cf828..e0873e317fbcb548c571c52d3242caa25ac8f944 100644 --- a/pangu-examples/README.md +++ b/pangu-examples/README.md @@ -29,6 +29,9 @@ - **pangu-examples-cache-single** 1. 如何使用原生的一级缓存RedisTemplate API +- **pangu-examples-lock-redis-based** + 1. 如何使用基于Redis的分布式锁(注解式、API式) + - **pangu-examples-dubbo-api** 1. 开发Dubbo服务时接口文件和POJO相关类的打包模块 diff --git a/pangu-examples/pangu-examples-cache-single/src/main/resources/application-dev.properties b/pangu-examples/pangu-examples-cache-single/src/main/resources/application-dev.properties index 8a0b9e6103d55c12fc27b057228dc294bd035dea..d7c507474a097e5dd2cda1aacafbfbb419f4af8a 100644 --- a/pangu-examples/pangu-examples-cache-single/src/main/resources/application-dev.properties +++ b/pangu-examples/pangu-examples-cache-single/src/main/resources/application-dev.properties @@ -16,7 +16,7 @@ # spring.application.name=pangu-examples-cache-single -# spring-cache \u4E00\u7EA7\u7F13\u5B58 +# spring-redis \u4E00\u7EA7\u7F13\u5B58 spring.redis.host=localhost spring.redis.database=1 spring.redis.port=6379 diff --git a/pangu-examples/pangu-examples-lock-redis-based/.gitignore b/pangu-examples/pangu-examples-lock-redis-based/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c28c61a9cdd9e7bfeca42b43d3d56831f369f72f --- /dev/null +++ b/pangu-examples/pangu-examples-lock-redis-based/.gitignore @@ -0,0 +1,26 @@ +/target/ +/bin/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ diff --git a/pangu-examples/pangu-examples-lock-redis-based/README.md b/pangu-examples/pangu-examples-lock-redis-based/README.md new file mode 100644 index 0000000000000000000000000000000000000000..55de4630ad9d0b0a5211521650a8e6c2db38d884 --- /dev/null +++ b/pangu-examples/pangu-examples-lock-redis-based/README.md @@ -0,0 +1,5 @@ +#### :mushroom: 本范例演示功能 + +1. 如何使用基于Redis的分布式锁(注解式、API式)。 + +**更多开发指南请参考盘古平台相关文档说明。** \ No newline at end of file diff --git a/pangu-examples/pangu-examples-lock-redis-based/pom.xml b/pangu-examples/pangu-examples-lock-redis-based/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..09f0a0654c9e17bf63055272928a292eebecc934 --- /dev/null +++ b/pangu-examples/pangu-examples-lock-redis-based/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + + com.gitee.pulanos.pangu + pangu-parent + 5.0.7 + + + + com.gitee.pulanos.pangu + pangu-examples-lock-redis-based + jar + 1.0.0 + + + + com.gitee.pulanos.pangu + pangu-spring-boot-starter + + + com.gitee.pulanos.pangu + pangu-cache-spring-boot-starter + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + + + diff --git a/pangu-examples/pangu-examples-lock-redis-based/src/main/java/com/gitee/pulanos/pangu/showcases/lock/redis/LockPanguApplication.java b/pangu-examples/pangu-examples-lock-redis-based/src/main/java/com/gitee/pulanos/pangu/showcases/lock/redis/LockPanguApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..2cd9fa2ee2cdc39e65be63f7062bd64bd73e2cd7 --- /dev/null +++ b/pangu-examples/pangu-examples-lock-redis-based/src/main/java/com/gitee/pulanos/pangu/showcases/lock/redis/LockPanguApplication.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.gitee.pulanos.pangu.showcases.lock.redis; + +import com.gitee.pulanos.pangu.framework.starter.PanGuApplicationBuilder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author xiongchun + */ +@Slf4j +@SpringBootApplication +public class LockPanguApplication { + + public static void main(String[] args) { + PanGuApplicationBuilder.init(LockPanguApplication.class).run(args); + } + +} \ No newline at end of file diff --git a/pangu-examples/pangu-examples-lock-redis-based/src/main/java/com/gitee/pulanos/pangu/showcases/lock/redis/service/AnnotationLockService.java b/pangu-examples/pangu-examples-lock-redis-based/src/main/java/com/gitee/pulanos/pangu/showcases/lock/redis/service/AnnotationLockService.java new file mode 100644 index 0000000000000000000000000000000000000000..101b1d4692d000ecfa9437f5d17a4f00a32b0938 --- /dev/null +++ b/pangu-examples/pangu-examples-lock-redis-based/src/main/java/com/gitee/pulanos/pangu/showcases/lock/redis/service/AnnotationLockService.java @@ -0,0 +1,38 @@ +package com.gitee.pulanos.pangu.showcases.lock.redis.service; + +import cn.hutool.core.thread.ThreadUtil; +import com.baomidou.lock.annotation.Lock4j; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 基于注解方式的分布式锁 + * + * @author xiongchun + */ +@Slf4j +@Component +public class AnnotationLockService { + + /** + * 默认获取锁超时3秒,30秒锁过期 + */ + @Lock4j + public void doBiz() { + log.info("执行doBiz..."); + ThreadUtil.sleep(25*1000); + } + + /** + * 配置获取锁超时时间和锁过期时间 支持SPEL + * @param accountId + */ + @Lock4j(keys = {"#accountId"}, expire = 20000, acquireTimeout = 10000) + public void doBiz2(Long accountId) { + log.info("执行doBiz2..."); + ThreadUtil.sleep(20*1000); + } + + + +} diff --git a/pangu-examples/pangu-examples-lock-redis-based/src/main/java/com/gitee/pulanos/pangu/showcases/lock/redis/service/ApiLockService.java b/pangu-examples/pangu-examples-lock-redis-based/src/main/java/com/gitee/pulanos/pangu/showcases/lock/redis/service/ApiLockService.java new file mode 100644 index 0000000000000000000000000000000000000000..f735ae463d81382459e6db12712dc03c53332c15 --- /dev/null +++ b/pangu-examples/pangu-examples-lock-redis-based/src/main/java/com/gitee/pulanos/pangu/showcases/lock/redis/service/ApiLockService.java @@ -0,0 +1,40 @@ +package com.gitee.pulanos.pangu.showcases.lock.redis.service; + +import cn.hutool.core.thread.ThreadUtil; +import com.baomidou.lock.LockInfo; +import com.baomidou.lock.LockTemplate; +import com.baomidou.lock.exception.LockException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * 基于API方式的分布式锁 + * + * @author xiongchun + */ +@Slf4j +@Component +public class ApiLockService { + + @Autowired + private LockTemplate lockTemplate; + + public void apiLock(String userId) { + //... 各种不需要上锁的操作 + String lockKey = "lock4j:ApiLockService:apiLock:" + userId; + final LockInfo lockInfo = lockTemplate.lock(lockKey); + //申请锁失败 + if (null == lockInfo) { + throw new LockException("业务处理中,请稍后再试..."); + } + //申请锁成功 + try { + ThreadUtil.sleep(10000L); + log.info("执行apiLock, 当前线程{}", Thread.currentThread().getName()); + } finally { + lockTemplate.releaseLock(lockInfo); + } + } + +} diff --git a/pangu-examples/pangu-examples-lock-redis-based/src/main/resources/application-dev.properties b/pangu-examples/pangu-examples-lock-redis-based/src/main/resources/application-dev.properties new file mode 100644 index 0000000000000000000000000000000000000000..9818b723b8c41770f43cff37b8845d906c3933f0 --- /dev/null +++ b/pangu-examples/pangu-examples-lock-redis-based/src/main/resources/application-dev.properties @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +spring.application.name=pangu-examples-lock-redis-based + +# spring-redis +spring.redis.host=localhost +spring.redis.database=1 +spring.redis.port=6379 +spring.redis.password= + +logging.level.root=INFO +logging.level.com.gitee.pulanos.pangu=INFO +logging.level.com.baomidou.lock=DEBUG \ No newline at end of file diff --git a/pangu-examples/pangu-examples-lock-redis-based/src/main/resources/application.properties b/pangu-examples/pangu-examples-lock-redis-based/src/main/resources/application.properties new file mode 100644 index 0000000000000000000000000000000000000000..3ed9e2dbdf6b3f36208fe92b7236d20f422960e6 --- /dev/null +++ b/pangu-examples/pangu-examples-lock-redis-based/src/main/resources/application.properties @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +spring.profiles.active=${spring.profiles.active:dev} \ No newline at end of file diff --git a/pangu-examples/pangu-examples-lock-redis-based/src/test/java/com/gitee/pulanos/pangu/showcases/lock/redis/service/AnnotationLockServiceTest.java b/pangu-examples/pangu-examples-lock-redis-based/src/test/java/com/gitee/pulanos/pangu/showcases/lock/redis/service/AnnotationLockServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..bb99296f3eb581dd823351891ad9e03355926e31 --- /dev/null +++ b/pangu-examples/pangu-examples-lock-redis-based/src/test/java/com/gitee/pulanos/pangu/showcases/lock/redis/service/AnnotationLockServiceTest.java @@ -0,0 +1,32 @@ +package com.gitee.pulanos.pangu.showcases.lock.redis.service; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.*; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class AnnotationLockServiceTest { + + @Autowired + private AnnotationLockService annotationLockService; + + @Test + public void doBiz() { + annotationLockService.doBiz(); + } + + @Test + public void doBizAgain() { + annotationLockService.doBiz(); + } + + @Test + public void doBiz2() { + annotationLockService.doBiz2(100L); + } +} \ No newline at end of file diff --git a/pangu-examples/pangu-examples-lock-redis-based/src/test/java/com/gitee/pulanos/pangu/showcases/lock/redis/service/ApiLockServiceTest.java b/pangu-examples/pangu-examples-lock-redis-based/src/test/java/com/gitee/pulanos/pangu/showcases/lock/redis/service/ApiLockServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..51399449f8f6ce11cf848ef9bee740dff0d918f3 --- /dev/null +++ b/pangu-examples/pangu-examples-lock-redis-based/src/test/java/com/gitee/pulanos/pangu/showcases/lock/redis/service/ApiLockServiceTest.java @@ -0,0 +1,23 @@ +package com.gitee.pulanos.pangu.showcases.lock.redis.service; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.*; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class ApiLockServiceTest { + + @Autowired + private ApiLockService apiLockService; + + @Test + public void apiLock() { + apiLockService.apiLock("1000"); + } + +} \ No newline at end of file diff --git a/pangu-examples/pom.xml b/pangu-examples/pom.xml index da252470f79bacb7b3f50534534ca86408f80462..700aef382318214a33fc273f047495b0b9277d5e 100644 --- a/pangu-examples/pom.xml +++ b/pangu-examples/pom.xml @@ -19,6 +19,7 @@ pangu-examples-crud pangu-examples-cache-single pangu-examples-cache-layering + pangu-examples-lock-redis-based pangu-examples-dubbo-api pangu-examples-dubbo-service pangu-examples-dubbo-consumer diff --git a/pangu-parent/pom.xml b/pangu-parent/pom.xml index 304ee1d598b6c86458f59f98c1cf4271cb1f0c13..89369dbcedaa584d43115df40b2b17445335f879 100644 --- a/pangu-parent/pom.xml +++ b/pangu-parent/pom.xml @@ -52,6 +52,7 @@ 0.2.7 0.2.7 3.4.3.2 + 2.2.1 2.4.1 3.3.4 8.0.26 @@ -135,6 +136,11 @@ mybatis-plus-boot-starter ${mybatis-plus.version} + + com.baomidou + lock4j-redis-template-spring-boot-starter + ${lock4j.version} + com.github.xiaolyuh layering-cache-starter