`

分布式系统锁实现

    博客分类:
  • java
阅读更多

    为什么需要分布式系统锁

    比如系统中的注册

    需要先判断用户账号是否被注册 没有被注册则保存用户注册信息数据

    在单系统情况下 可以这样做

    String username = user.getUsername();
     synchronized (username.intern()) {//防止多用户情况下 输入的相同账号都还未保存成功的情况下越过检查
            if(userService.existUsername(username,"")){
                mav.addObject("usernameMessage","用户名已存在");
                return mav;
            }
            userService.save(user);
        }

     集群情况下可能是不同的服务器处理 无法阻止

 

    分布式事务锁 底层借助memcached实现

/**
 * 业务锁
 *
 * 通过 memcache 的 addCache获取锁
 *
 * @author 820381
 *
 */
public class Lock {
    /**
     * 锁
     * @param lockName
     * @return    true 成功/false 失败
     */
    public static boolean lock(String lockName) {
        return getLock(lockName, 0);
    }
   
    /**
     * 解除锁
     * @param lockName
     * @return
     */
    public static boolean unlock(String lockName) {
        return CacheUtil.deleteKeyCache(lockName);
    }
   
    /**
     * 锁,并在获得锁的时候执行回调,回调执行完成后,解除锁
     * @param lockName    锁名
     * @param call        回调函数
     * @return    BusinessRuntimeException: ExceptionCode.CMN_LOCK_FAILED
     * @throws BusinessException
     */
    public static <T> T lock(String lockName, Callback<T> call) throws BusinessException {
        if(lock(lockName)) {
            try {
                return call.handle();
            } finally {
                unlock(lockName);
            }
        } else {
            throw new BusinessException(ExceptionCode.CMN_LOCK_FAILED,
                    MessageFormat.format("连接超时[{0}]", lockName));
        }
    }
   
    private static boolean getLock(String lockName, Integer count) {
        boolean gotLock = false;
       
        if(count > 1000) {
            return gotLock;
        }
       
        while(true) {
            gotLock = CacheUtil.addCache(lockName, true, null);
           
            if(gotLock) {
                return gotLock;
            } else {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    // 不处理异常睡眠异常
                }
               
                return getLock(lockName, ++count);
            }
        }
    }
}

 

 

/**
 *
 * @ClassName: CacheUtil
 * @Description: 缓存工具类
 * @author Fanhy
 * @date 2014-11-27 上午10:55:39
 *
 */
public class CacheUtil {

    /**
     * 缓存客户端
     */
    private static MemCachedClient memCachedClient;

    /**
     * 过期时间
     */
    private String timeLenght;

    /**
     * 默认Key的超时时间(小于1000的值,除以1000以后都是0,即永不过期 )
     */
    private static Date keyTimeOut;

    @SuppressWarnings("unused")
    private void init() {
        keyTimeOut = new Date(Integer.parseInt(timeLenght));// 24小时缓存
    }

    /**
     *
     * @MethodName: getKeyCache
     * @Description: 获取缓存
     * @param keyName
     *            缓存键
     * @return 返回数据
     */
    public static Object getKeyCache(String keyName) {
        if (null != keyName) {
            MemcachedItem item = memCachedClient.gets(keyName);
            if (null != item) {
                return item.getValue();
            }
        }
        return null;
    }

    /**
     *
     * @MethodName: setCache
     * @Description: 设置缓存
     * @param keyName
     *            缓存主键
     * @param value
     *            缓存数据
     * @param date
     *            过期时间(new Date(60000)过期时间是60秒)(如不设置默认缓存24小时)(不得超过30天)
     */
    public static void setCache(String keyName, Object value, Date date) {
        if (null != keyName && !"".equals(keyName)) {
            if (null == date) {
                memCachedClient.set(keyName, value, keyTimeOut);
            } else {
                memCachedClient.set(keyName, value, date);
            }
        }

    }

    /**
     *
     * @MethodName: setCache
     * @Description: 设置缓存
     * @param keyName
     *            缓存主键
     * @param value
     *            缓存数据
     */
    public static void setCache(String keyName, Object value) {
        if (null != keyName && !"".equals(keyName)) {
            memCachedClient.set(keyName, value, keyTimeOut);
        }
    }

    /**
     *
     * @MethodName: deleteKeyCache
     * @Description: 删除缓存
     * @param keyName
     *            key名称
     */
    public static boolean deleteKeyCache(String keyName) {
        if (null != keyName && !"".equals(keyName)) {
            return memCachedClient.delete(keyName);
        }
        return false;
    }

    public void setMemCachedClient(MemCachedClient memCachedClient) {

        CacheUtil.memCachedClient = memCachedClient;
    }

    public void setTimeLenght(String timeLenght) {

        this.timeLenght = timeLenght;

    }

    /**
     *
     * @MethodName: addCache
     * @Description: 设置缓存不重复Key,暂时只用于分布式同步
     * @param keyName
     * @param value
     * @param date
     * @return void 返回类型
     */
    public static boolean addCache(String keyName, Object value, Date date) {
        boolean isTrue = false;
        if (!StringUtils.isBlank(keyName)) {
            if (null == date) {
                Date dt = new Date();
                date = DateUtils.addMinutes(dt, 3);
            }
            isTrue = memCachedClient.add(keyName, value, date);
        }
        return isTrue;
    }
}

 

如何使用

@Aspect
@Component
public class LockAspect {
    @Around("execution(* com.sfiec..*.*(..)) && @annotation(Lock)")
    public Object around(final ProceedingJoinPoint point) throws Throwable {
        String lockName = getLockName(point);
       
        return com.sfiec.oms.common.Lock.lock(lockName, new Callback<Object>() {
            @Override
            public Object handle() throws BusinessException {
                Object result;
               
                try {
                    result = point.proceed();
                } catch (Throwable e) {
                    if(e instanceof BusinessException) {
                        throw (BusinessException) e;
                    }
                   
                    if(e instanceof BusinessRuntimeException) {
                        throw (BusinessRuntimeException) e;
                    }
                   
                    throw new BusinessException("", e);
                }
               
                return result;
            }
        });
    }
   
    private String getLockName(ProceedingJoinPoint point) {

        MethodSignature signature = MethodSignature.class.cast(point.getSignature());
        Lock lock = signature.getMethod().getAnnotation(Lock.class);

        // 不是自定义的锁标志的退出
        if(lock == null) {
            return null;
        }
       
        // 获取默认的锁
        String lockName = lock.value();
       
        // 不存在占位符,则直接返回
        if(lockName.indexOf("${") == -1) {
            return lockName;
        }
       
        // 获取占位符的内容
        final Properties properties = new Properties();
        String[] parameterNames = signature.getParameterNames();
        Object[] args = point.getArgs();
       
        for(int i = 0; i < parameterNames.length; i++) {
            String name = parameterNames[i];
            Object val = args[i];
           
            if(isBaseDataType(val.getClass())) {
                val = String.valueOf(val);
            }
           
            properties.put(name, val);
        }
       
        // TODO 如果存在 ${xx.xx} 属性,则使用反射获取内容
       
        // 一般的 ${xxx},直接获取内容
        PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper("${", "}");
        String lockName2 = helper.replacePlaceholders(lockName, properties);

        return lockName2;
    }
   
    /** 
      * 判断一个类是否为基本数据类型。 
      * @param clazz 要判断的类。 
      * @return true 表示为基本数据类型。 
      */
    @SuppressWarnings("rawtypes")
    private static boolean isBaseDataType(Class clazz) {  
         return
         (
             clazz.equals(String.class) ||  
             clazz.equals(Integer.class)||  
             clazz.equals(Byte.class) ||  
             clazz.equals(Long.class) ||  
             clazz.equals(Double.class) ||  
             clazz.equals(Float.class) ||  
             clazz.equals(Character.class) ||  
             clazz.equals(Short.class) ||  
             clazz.equals(BigDecimal.class) ||  
             clazz.equals(BigInteger.class) ||  
             clazz.equals(Boolean.class) ||  
             clazz.equals(Date.class) ||  
             clazz.isPrimitive()  
         );  
     }
}

 

  @Lock(CommonConstant.LOCK_REGISTER + " ${user.username}")
    public boolean register(User user) {
          if(userService.existUsername(username,"")){
                mav.addObject("usernameMessage","用户名已存在");
                return false;
            }
            userService.save(user);

            return true;
    }

 

0
0
分享到:
评论

相关推荐

    基于Redis的分布式锁的实现方案.pdf

    本文讨论了分布式锁的实现方案,主要基于Redis实现分布式锁,以解决分布式系统中资源访问的同步问题。在分布式系统中,需要协调各个系统或主机之间的资源访问,以避免彼此干扰和保证一致性。分布式锁是控制分布式...

    记录redisson实现redis分布式事务锁

    Redisson是基于Redis的Java客户端,它提供了丰富的数据结构和服务,包括分布式锁、信号量、队列、计数器等,极大地扩展了Redis在分布式系统中的应用能力。本篇文章将详细探讨如何使用Redisson实现Redis分布式事务锁...

    利用分布式共享锁实现防止方法重复调用

    "利用分布式共享锁实现防止方法重复调用"这一主题,主要涉及到如何通过分布式锁来解决这类问题。本文将深入探讨分布式锁的概念、其在防刷单场景中的应用以及如何利用Redis实现分布式锁。 分布式锁是一种在分布式...

    C#.net Redis分布式锁源码实现

    在IT行业中,尤其是在大型分布式系统的设计与开发中,分布式锁是一种关键的同步机制。本篇文章将深入探讨如何在C#.NET环境下利用Redis实现分布式锁,以及相关的核心知识点。 首先,让我们理解什么是分布式锁。...

    基于zookeeper的分布式锁简单实现

    分布式锁是一种在分布式系统中实现同步的技术,它允许多个节点在同一时刻访问共享资源。在大型分布式环境中,由于网络延迟和并发操作,简单的本地锁可能无法有效解决数据一致性问题。这时,Zookeeper,一个高可用的...

    基于zookeeper的分布式锁实现demo

    Curator提供了现成的分布式锁实现,如`InterProcessMutex`和`InterProcessSemaphoreMutex`,并且提供了易用的API,使得开发人员可以更简单地使用Zookeeper进行分布式锁的实现。 在上述代码片段中,`LockUtil`类是...

    Redis分布式锁实现Redisson 15问.doc

    Redis分布式锁实现Redisson 15问 Redis分布式锁是指在分布式系统中,多个服务实例之间对同一个资源...Redisson是一个功能强大且高效的分布式锁实现,它提供了一个可靠的加锁机制,可以满足分布式系统中的加锁需求。

    分布式锁实现(基于redis-mysql)1

    分布式锁是一种在分布式系统中解决资源竞争问题的重要机制。在单机环境中,我们可以通过Java等编程语言内置的并发控制手段,如synchronized关键字或ReentrantLock等实现锁。然而,在分布式环境中,由于多台服务器...

    redis实现分布式锁,自旋式加锁,lua原子性解锁

    在分布式系统中,为了保证数据的一致性和安全性,分布式锁是一种常见的解决方案。Redis作为一个高性能的键值存储系统,常被用作实现分布式锁的工具。本文将深入探讨如何使用Redis实现分布式锁,以及如何利用自旋式...

    zk分布式锁1

    zk分布式锁1 在分布式系统中,分布式锁是必...ZooKeeper分布式锁是一种高效、灵活的分布式锁实现方案,广泛应用于分布式系统中。但是,需要根据不同的分布式系统需求进行选择和配置,以确保分布式锁的正确性和高效性。

    zookeeper分布式锁实现和客户端简单实现

    **Zookeeper的分布式锁实现原理** 1. **节点创建与监视**: Zookeeper允许客户端创建临时节点,这些节点会在客户端断开连接时自动删除。分布式锁的实现通常会为每个请求创建一个临时顺序节点,按照创建的顺序形成一...

    使用zookeeper实现分布式共享锁

    在分布式系统中,由于网络延迟、服务器故障等问题,一致性与协调是常见的挑战。Zookeeper,一个由Apache Hadoop项目开发的分布式协调服务,为解决这些问题提供了强大的支持。它被广泛用于实现分布式锁、配置管理、...

    大规模分布式系统架构与设计实战.完整版

    《大规模分布式系统架构与设计实战》写到,分布式并行计算的基本原理解剖;分布式协调的实现,包括如何实现公共配置管理,如何实现分布式锁,如何实现集群管理等;分布式缓存的实现,包括如何提供完整的分布式缓存来...

    java分布式锁实现代码

    在分布式系统中,为了保证数据的一致性和安全性,分布式锁是一种常见的解决方案。本文将深入探讨如何使用Redisson和Curator框架来实现Java环境中的分布式锁。 首先,让我们来看一下Redisson实现的分布式锁。Redis是...

    redis分布式锁实现抢单秒杀

    在IT行业中,尤其是在高并发的电子商务系统中,"redis分布式锁实现抢单秒杀"是一个常见的挑战。这个场景模拟了多个用户同时参与秒杀活动,系统需要确保库存的准确性和抢单的公平性,避免超卖和数据不一致的问题。...

    分布式锁简单实现

    分布式锁是一种在分布式系统中实现同步访问资源的关键技术。它允许多个节点在同一时间对共享资源进行互斥访问,确保在高并发环境下数据的一致性和完整性。在这个“分布式锁简单实现”项目中,开发者提供了一个基本的...

    东北大学_研究生_期末考试之分布式系统及应用

    4. **负载均衡**:为了提高系统性能,分布式系统需要实现负载均衡,将工作负载合理分配到各个节点。这涉及策略如轮询、权重分配、哈希分布等。 5. **容错与恢复**:分布式系统必须具备处理硬件故障、网络问题和软件...

    分布式系统设计 分布式系统设计

    分布式系统设计是现代互联网服务和企业级应用的核心技术之一,它涉及到多个计算机节点通过网络进行协同工作,共同处理任务和数据。在这个领域,我们需要深入理解并掌握一系列关键知识点,以构建高效、可扩展且容错的...

    基于Redis方式实现分布式锁

    分布式锁是一种常见的分布式系统协调机制,用于控制分布式环境下的多个进程或线程之间的访问顺序,防止多个客户端同时修改共享资源,从而保证数据的一致性和完整性。分布式锁通常有三种实现方式:基于关系数据库的...

    redisson实现分布式锁

    在分布式系统中,锁是保证数据一致性的重要工具,而Redisson的分布式锁则为Java开发者提供了一种高效且可靠的解决方案。 首先,让我们深入理解分布式锁的概念。分布式锁是在分布式系统中,为了确保多个节点对共享...

Global site tag (gtag.js) - Google Analytics