• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Aquarius:

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

Aquarius

开源软件地址:

https://gitee.com/nepxion/Aquarius

开源软件介绍:

Nepxion Aquarius

Total visits Total lines License Maven Central Javadocs Build Status Codacy Badge Stars Stars

           

Nepxion Aquarius是一款基于Redis + Zookeeper的分布式应用组件集合,包含分布式锁,缓存,ID生成器,限速限流器。它采用Nepxion Matrix AOP框架进行切面架构,提供注解调用方式,也提供API调用方式

简介

  • 分布式应用组件集合
    • Nepxion Aquarius Lock 分布式锁(支持Redis、Zookeeper、ReentrantLock本地锁)
    • Nepxion Aquarius Cache 分布式缓存(支持Redis,同时多键值缓存)
    • Nepxion Aquarius ID Generator 分布式全局唯一ID(支持Redis)、全局唯一序号生成(支持Zookeeper、Twitter雪花ID算法的支持),支持单个和批量获取
    • Nepxion Aquarius Limit 分布式限速限流(支持Redis、Guava本地限速限流)
  • 支持Spring Boot集成
    • 提供Start模式,在类头部加注解@EnableXXX,同时结合配置文件xxx.enabled=true/false进行相关Aop功能的关闭和开启
    • 支持Aop异常的中断业务方法调用和忽略中断两种选择
  • 支持Spring Cloud集成
  • 支持Swagger集成打开http://localhost:2222/swagger-ui.html访问
  • 支持组件扩展适配,再次编程
    • RedissonAdapter,扩展实现可默认覆盖原生组件

兼容

  • 1.x.x版本是基于Spring开发的,相对使用较繁琐,不建议使用
  • 2.x.x版本是基于Spring Boot开发的,相对简单,功能也更加强大
  • 默认支持Spring 5.x.x和Spring Boot 3.x.x,也兼容Spring 4.x.x和Spring Boot 1.x.x

依赖

分布式锁<dependency>    <groupId>com.nepxion</groupId>    <artifactId>aquarius-lock-starter</artifactId>    <version>${aquarius.version}</version></dependency>分布式缓存<dependency>    <groupId>com.nepxion</groupId>    <artifactId>aquarius-cache-starter</artifactId>    <version>${aquarius.version}</version></dependency>分布式全局唯一ID<dependency>    <groupId>com.nepxion</groupId>    <artifactId>aquarius-id-generator-starter</artifactId>    <version>${aquarius.version}</version></dependency>分布式限速限流<dependency>    <groupId>com.nepxion</groupId>    <artifactId>aquarius-limit-starter</artifactId>    <version>${aquarius.version}</version></dependency>

Nepxion Aquarius Lock

基于Redisson(Redis)、Curator(Zookeeper)分布式锁和本地锁,构建于Nepxion Matrix AOP framework,你可以在这三个锁组件中选择一个移植入你的应用中

提示

介绍

  • 锁既支持Redisson(基于Redis)和Curator(基于Zookeeper)机制的分布式锁,也支持ReentrantLock机制的本地锁
  • 锁既支持普通可重入锁,也支持读/写可重入锁
    • 普通可重入锁都是互斥的
    • 读/写可重入锁必须配对使用,规则如下:
      • 当写操作时,其他分布式进程/线程无法读取或写入数据;当读操作时,其他分布式进程/线程无法写入数据,但可以读取数据
      • 允许同时有多个读锁,但是最多只能有一个写锁。多个读锁不互斥,读锁与写锁互斥
  • 锁既支持公平锁,也支持非公平锁
  • 锁既支持同步执行方式,也支持异步执行方式(异步拿锁,同步阻塞)
  • 锁既支持持锁时间后丢弃,也支持持锁超时等待时间
  • 锁注解既可以加在接口上,也可以加在实现类上,也可以加在没有接口只有类的情形下
    • 注解说明
      • 注解com.nepxion.aquarius.lock.annotation.Lock,普通可重入锁
      • 注解com.nepxion.aquarius.lock.annotation.ReadLock,读可重入锁
      • 注解com.nepxion.aquarius.lock.annotation.WriteLock,写可重入锁
    • 参数说明
      • name 锁的名字
      • key 锁的Key。锁Key的完整路径是prefix + "" + name + "" + key,prefix为config.propertie里的namespace值
      • leaseTime 持锁时间,持锁超过此时间则自动丢弃锁(Redisson支持,Curator和本地锁不支持)
      • waitTime 没有获取到锁时,等待时间
      • async 是否采用锁的异步执行方式(默认都支持同步执行方式,Redisson三种锁都支持异步,Curator三种锁都不支持异步,本地锁三种锁都不支持异步)
      • fair 是否采用公平锁(默认都支持非公平锁,Redisson三种锁只有普通可重入锁支持公平锁,Curator三种锁都不支持公平锁,本地锁三种锁都支持公平锁)
  • 锁由于是可重入锁,支持缓存和重用机制
  • 锁组件采用通过改变Pom中对锁中间件类型的引用,达到快速切换分布式锁的目的
    • 实现对redisson支持若干种部署方式(例如单机,集群,哨兵模式),并支持json和yaml(默认)两种配置方式,要切换部署方式,只需要修改相应的config-redisson.yaml文件即可。具体参考如下:

      https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95

    • 实现对Curator的多种重试机制(例如exponentialBackoffRetry, boundedExponentialBackoffRetry, retryNTimes, retryForever, retryUntilElapsed),可在配置文件里面切换

  • 锁支持两种调用方式,注解方式和直接调用方式

示例

使用分布式锁示例如下,更多细节见aquarius-spring-boot-example工程下com.nepxion.aquarius.example.lock

普通分布式锁的使用

注解方式

package com.nepxion.aquarius.example.lock.service;/** * <p>Title: Nepxion Aquarius</p> * <p>Description: Nepxion Aquarius</p> * <p>Copyright: Copyright (c) 2017-2050</p> * <p>Company: Nepxion</p> * @author Haojun Ren * @version 1.0 */import com.nepxion.aquarius.lock.annotation.Lock;public interface MyService1 {    @Lock(name = "lock", key = "#id1 + \"-\" + #id2", leaseTime = 5000L, waitTime = 60000L, async = false, fair = false)    String doA(String id1, String id2);    String doB(String id1, String id2);}
package com.nepxion.aquarius.example.lock.service;/** * <p>Title: Nepxion Aquarius</p> * <p>Description: Nepxion Aquarius</p> * <p>Copyright: Copyright (c) 2017-2050</p> * <p>Company: Nepxion</p> * @author Haojun Ren * @version 1.0 */import java.util.concurrent.TimeUnit;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;import com.nepxion.aquarius.lock.annotation.Lock;@Service("myService2Impl")public class MyService2Impl {    private static final Logger LOG = LoggerFactory.getLogger(MyService2Impl.class);    @Lock(name = "lock", key = "#id1 + \"-\" + #id2", leaseTime = 5000L, waitTime = 60000L, async = false, fair = false)    public String doC(String id1, String id2) {        try {            TimeUnit.MILLISECONDS.sleep(2000L);        } catch (InterruptedException e) {            e.printStackTrace();        }        LOG.info("doC - lock is got");        return "C";    }    public String doD(String id1, String id2) {        LOG.info("doD");        return "D";    }}
package com.nepxion.aquarius.example.lock.app1;/** * <p>Title: Nepxion Aquarius</p> * <p>Description: Nepxion Aquarius</p> * <p>Copyright: Copyright (c) 2017-2050</p> * <p>Company: Nepxion</p> * @author Haojun Ren * @version 1.0 */import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import com.nepxion.aquarius.example.lock.service.MyService1;import com.nepxion.aquarius.example.lock.service.MyService2Impl;import com.nepxion.aquarius.lock.annotation.EnableLock;@SpringBootApplication@EnableLock@ComponentScan(basePackages = { "com.nepxion.aquarius.example.lock.service" })public class LockAopApplication {    public static void main(String[] args) throws Exception {        ConfigurableApplicationContext applicationContext = SpringApplication.run(LockAopApplication.class, args);        // 执行效果是doA和doC无序打印,即谁拿到锁谁先运行        MyService1 myService1 = applicationContext.getBean(MyService1.class);        for (int i = 0; i < 5; i++) {            new Thread(new Runnable() {                @Override                public void run() {                    myService1.doA("X", "Y");                }            }).start();        }        MyService2Impl myService2 = applicationContext.getBean(MyService2Impl.class);        for (int i = 0; i < 5; i++) {            new Thread(new Runnable() {                @Override                public void run() {                    myService2.doC("X", "Y");                }            }).start();        }    }    @Bean    public EmbeddedServletContainerFactory createEmbeddedServletContainerFactory() {        TomcatEmbeddedServletContainerFactory tomcatFactory = new TomcatEmbeddedServletContainerFactory();        tomcatFactory.setPort(8087);        return tomcatFactory;    }}

直接调用方式

package com.nepxion.aquarius.example.lock.app2;/** * <p>Title: Nepxion Aquarius</p> * <p>Description: Nepxion Aquarius</p> * <p>Copyright: Copyright (c) 2017-2050</p> * <p>Company: Nepxion</p> * @author Haojun Ren * @version 1.0 */import java.util.concurrent.TimeUnit;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import com.nepxion.aquarius.lock.LockExecutor;import com.nepxion.aquarius.lock.annotation.EnableLock;import com.nepxion.aquarius.lock.entity.LockType;@SpringBootApplication@EnableLock@ComponentScan(basePackages = { "com.nepxion.aquarius.example.lock.service" })public class LockApplication {    private static final Logger LOG = LoggerFactory.getLogger(LockApplication.class);    @SuppressWarnings("unchecked")    public static void main(String[] args) throws Exception {        ConfigurableApplicationContext applicationContext = SpringApplication.run(LockApplication.class, args);        LockExecutor<Object> lockExecutor = applicationContext.getBean(LockExecutor.class);        for (int i = 0; i < 5; i++) {            new Thread(new Runnable() {                @Override                public void run() {                    Object lock = null;                    try {                        lock = lockExecutor.tryLock(LockType.LOCK, "lock", "X-Y", 5000L, 60000L, false, false);                        if (lock != null) {                            try {                                TimeUnit.MILLISECONDS.sleep(2000L);                            } catch (InterruptedException e) {                                e.printStackTrace();                            }                            LOG.info("doA - lock is got");                        }                    } catch (Exception e) {                        e.printStackTrace();                    } finally {                        try {                            lockExecutor.unlock(lock);                        } catch (Exception e) {                            e.printStackTrace();                        }                    }                }            }).start();        }        for (int i = 0; i < 5; i++) {            new Thread(new Runnable() {                @Override                public void run() {                    Object lock = null;                    try {                        lock = lockExecutor.tryLock(LockType.LOCK, "lock", "X-Y", 5000L, 60000L, false, false);                        if (lock != null) {                            try {                                TimeUnit.MILLISECONDS.sleep(2000L);                            } catch (InterruptedException e) {                                e.printStackTrace();                            }                            LOG.info("doC - lock is got");                        }                    } catch (Exception e) {                        e.printStackTrace();                    } finally {                        try {                            lockExecutor.unlock(lock);                        } catch (Exception e) {                            e.printStackTrace();                        }                    }                }            }).start();        }    }    @Bean    public EmbeddedServletContainerFactory createEmbeddedServletContainerFactory() {        TomcatEmbeddedServletContainerFactory tomcatFactory = new TomcatEmbeddedServletContainerFactory();        tomcatFactory.setPort(8088);        return tomcatFactory;    }}

读/写分布式锁的使用

注解方式

package com.nepxion.aquarius.example.lock.service;/** * <p>Title: Nepxion Aquarius</p> * <p>Description: Nepxion Aquarius</p> * <p>Copyright: Copyright (c) 2017-2050</p> * <p>Company: Nepxion</p> * @author Haojun Ren * @version 1.0 */import com.nepxion.aquarius.lock.annotation.ReadLock;public interface MyService3 {    @ReadLock(name = "lock", key = "#id1 + \"-\" + #id2", leaseTime = 5000L, waitTime = 60000L, async = false, fair = false)    String doR(String id1, String id2);}
package com.nepxion.aquarius.example.lock.service;/** * <p>Title: Nepxion Aquarius</p> * <p>Description: Nepxion Aquarius</p> * <p>Copyright: Copyright (c) 2017-2050</p> * <p>Company: Nepxion</p> * @author Haojun Ren * @version 1.0 */import java.util.concurrent.TimeUnit;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;import com.nepxion.aquarius.lock.annotation.WriteLock;@Service("myService4Impl")public class MyService4Impl {    private static final Logger LOG = LoggerFactory.getLogger(MyService4Impl.class);    @WriteLock(name = "lock", key = "#id1 + \"-\" + #id2", leaseTime = 15000L, waitTime = 60000L, async = false, fair = false)    public String doW(String id1, String id2) {        try {            TimeUnit.MILLISECONDS.sleep(10000L);        } catch (InterruptedException e) {            e.printStackTrace();        }        LOG.info("doW - write lock is got");        return "W";    }}
package com.nepxion.aquarius.example.lock.app3;/** * <p>Title: Nepxion Aquarius</p> * <p>Description: Nepxion Aquarius</p> * <p>Copyright: Copyright (c) 2017-2050</p> * <p>Company: Nepxion</p> * @author Haojun Ren * @version 1.0 */import java.util.Timer;import java.util.TimerTask;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import com.nepxion.aquarius.example.lock.service.MyService3;import com.nepxion.aquarius.example.lock.service.MyService4Impl;import com.nepxion.aquarius.lock.annotation.EnableLock;@SpringBootApplication@EnableLock@ComponentScan(basePackages = { "com.nepxion.aquarius.example.lock.service" })public class ReadWriteLockAopApplication {    private static final Logger LOG = LoggerFactory.getLogger(ReadWriteLockAopApplication.class);    public static void main(String[] args) throws Exception {        ConfigurableApplicationContext applicationContext = SpringApplication.run(ReadWriteLockAopApplication.class, args);        // 执行效果是先打印doW,即拿到写锁,再打印若干个doR,即可以同时拿到若干个读锁        MyService4Impl myService4 = applicationContext.getBean(MyService4Impl.class);        Timer timer1 = new Timer();        timer1.scheduleAtFixedRate(new TimerTask() {            public void run() {                LOG.info("Start to get write lock...");                // 写锁逻辑,最高持锁15秒,睡眠10秒,10秒后释放读锁                myService4.doW("X", "Y");            }        }, 0L, 600000L);        MyService3 myService3 = applicationContext.getBean(MyService3.class);        Timer timer2 = new Timer();        timer2.scheduleAtFixedRate(new TimerTask() {            public void run() {                LOG.info("Start to get read lock...");                for (int i = 0; i < 3; i++) {                    new Thread(new Runnable() {                        @Override                        public void run() {                            // 读锁逻辑,最高持锁5秒,睡眠2秒,2秒后释放读锁                            myService3
                      

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap