当前位置: 首页 > wzjs >正文

建设家具网站的目的及功能定位色无极网站正在建设中

建设家具网站的目的及功能定位,色无极网站正在建设中,app推广联盟,个人网页制作简单方法一、分布式锁的基本原理与需求 在分布式系统中,多个服务实例可能需要访问共享资源,此时需要分布式锁来保证操作的互斥性。Redis凭借高性能和原子操作特性,成为实现分布式锁的理想选择。 1. 分布式锁的核心需求 互斥性:同一时刻只能…

一、分布式锁的基本原理与需求

在分布式系统中,多个服务实例可能需要访问共享资源,此时需要分布式锁来保证操作的互斥性。Redis凭借高性能和原子操作特性,成为实现分布式锁的理想选择。

1. 分布式锁的核心需求

  • 互斥性:同一时刻只能有一个客户端持有锁
  • 安全性:锁只能被持有该锁的客户端释放,不能被其他客户端释放
  • 容错性:在Redis节点宕机的情况下,锁仍能正常工作(可通过Redis集群解决)
  • 可重入性:同一个客户端可以多次获取同一把锁(可选)
  • 锁超时:防止死锁,锁在一定时间后自动释放

2. Redis实现分布式锁的基础

Redis实现分布式锁主要基于以下命令:

SET key value NX PX timeout

  • NX:仅在键不存在时设置键值
  • PX timeout:设置键的过期时间(毫秒)
  • value:建议使用唯一值(如UUID),确保锁只能由持有者释放

二、Java实现Redis分布式锁

1. 基于Jedis客户端的简单实现

import redis.clients.jedis.Jedis;
import java.util.UUID;public class RedisLock {private static final String LOCK_SUCCESS = "OK";private static final Long RELEASE_SUCCESS = 1L;private static final String SET_IF_NOT_EXIST = "NX";private static final String SET_WITH_EXPIRE_TIME = "PX";private Jedis jedis;private String lockKey;private String requestId;private int expireTime;public RedisLock(Jedis jedis, String lockKey, int expireTime) {this.jedis = jedis;this.lockKey = lockKey;this.expireTime = expireTime;this.requestId = UUID.randomUUID().toString();}/**
     * 获取锁
     * @return 是否成功获取锁
     */public boolean acquire() {String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);return LOCK_SUCCESS.equals(result);}/**
     * 释放锁
     * @return 是否成功释放锁
     */public boolean release() {// 使用Lua脚本保证原子性String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";Object result = jedis.eval(script, 1, lockKey, requestId);return RELEASE_SUCCESS.equals(result);}public String getRequestId() {return requestId;}
}

2. 使用示例

import redis.clients.jedis.Jedis;public class RedisLockExample {
    public static void main(String[] args) {
        // 初始化Redis客户端
        Jedis jedis = new Jedis("localhost", 6379);        // 创建锁实例
        RedisLock lock = new RedisLock(jedis, "my_distributed_lock", 30000);        // 获取锁
        boolean acquired = lock.acquire();
        if (acquired) {
            try {
                // 执行临界区代码
                System.out.println("获取锁成功,执行临界区操作");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // 释放锁
                lock.release();
                System.out.println("释放锁");
            }
        } else {
            System.out.println("获取锁失败");
        }        // 关闭Redis连接
        jedis.close();
    }
}

三、Redis分布式锁的进阶问题与解决方案

1. 锁续期问题

为避免业务执行时间超过锁的过期时间导致锁提前释放,可以使用"看门狗"机制自动续期:

import redis.clients.jedis.Jedis;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class RedisLockWithAutoRenew {
    private static final String LOCK_SUCCESS = "OK";
    private static final Long RELEASE_SUCCESS = 1L;
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "PX";    private Jedis jedis;
    private String lockKey;
    private String requestId;
    private int expireTime;
    private ScheduledExecutorService renewExecutor;
    private int renewInterval;
    private boolean isLocked = false;    public RedisLockWithAutoRenew(Jedis jedis, String lockKey, int expireTime) {
        this.jedis = jedis;
        this.lockKey = lockKey;
        this.expireTime = expireTime;
        this.requestId = UUID.randomUUID().toString();
        this.renewExecutor = Executors.newSingleThreadScheduledExecutor();
        this.renewInterval = expireTime / 3; // 每三分之一的过期时间续期一次
    }    /**
     * 获取锁
     * @return 是否成功获取锁
     */
    public boolean acquire() {
        String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
        if (LOCK_SUCCESS.equals(result)) {
            isLocked = true;
            startAutoRenew();
            return true;
        }
        return false;
    }    /**
     * 释放锁
     * @return 是否成功释放锁
     */
    public boolean release() {
        isLocked = false;
        renewExecutor.shutdownNow();        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Object result = jedis.eval(script, 1, lockKey, requestId);
        return RELEASE_SUCCESS.equals(result);
    }    /**
     * 启动自动续期
     */
    private void startAutoRenew() {
        renewExecutor.scheduleAtFixedRate(() -> {
            if (isLocked) {
                String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('pexpire', KEYS[1], ARGV[2]) else return 0 end";
                jedis.eval(script, 1, lockKey, requestId, String.valueOf(expireTime));
            }
        }, renewInterval, renewInterval, TimeUnit.MILLISECONDS);
    }
}

2. Redisson框架的使用

Redisson是一个基于Redis的Java驻内存数据网格(In-Memory Data Grid),提供了分布式锁的实现:

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class RedissonLockExample {
    public static void main(String[] args) {
        // 配置Redisson
        Config config = new Config();
        config.useSingleServer().setAddress("redis://localhost:6379");        // 创建Redisson客户端
        RedissonClient redisson = Redisson.create(config);        // 获取锁实例
        RLock lock = redisson.getLock("myRedissonLock");        try {
            // 尝试获取锁,最多等待100秒,锁持有时间为30秒
            boolean acquired = lock.tryLock(100, 30, java.util.concurrent.TimeUnit.SECONDS);            if (acquired) {
                try {
                    // 执行临界区代码
                    System.out.println("获取Redisson锁成功,执行临界区操作");
                    Thread.sleep(5000);
                } finally {
                    // 释放锁
                    lock.unlock();
                    System.out.println("释放Redisson锁");
                }
            } else {
                System.out.println("获取Redisson锁失败");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 关闭Redisson客户端
            redisson.shutdown();
        }
    }
}

四、Redis分布式锁的应用场景

1. 库存扣减

public class InventoryService {
    private Jedis jedis = new Jedis("localhost", 6379);    public void deductInventory(String productId, int quantity) {
        RedisLock lock = new RedisLock(jedis, "inventory_lock:" + productId, 30000);        try {
            if (lock.acquire()) {
                // 查询库存
                int stock = getInventoryFromDB(productId);                if (stock >= quantity) {
                    // 扣减库存
                    boolean success = updateInventoryInDB(productId, stock - quantity);
                    if (success) {
                        System.out.println("库存扣减成功");
                    } else {
                        System.out.println("库存扣减失败");
                    }
                } else {
                    System.out.println("库存不足");
                }
            } else {
                System.out.println("获取锁失败,请稍后重试");
            }
        } finally {
            lock.release();
        }
    }    private int getInventoryFromDB(String productId) {
        // 从数据库查询库存
        return 100; // 示例返回值
    }    private boolean updateInventoryInDB(String productId, int newStock) {
        // 更新数据库中的库存
        return true; // 示例返回值
    }
}

2. 定时任务排重

public class ScheduledTask {private RedissonClient redisson;public ScheduledTask() {Config config = new Config();
        config.useSingleServer().setAddress("redis://localhost:6379");
        redisson = Redisson.create(config);}public void executeDailyReport() {RLock lock = redisson.getLock("daily_report_task_lock");try {// 尝试获取锁,5秒内获取不到则放弃boolean acquired = lock.tryLock(5, 30, TimeUnit.SECONDS);if (acquired) {try {// 执行每日报告生成任务generateDailyReport();} finally {
                    lock.unlock();}} else {System.out.println("另一个实例正在执行每日报告任务");}} catch (InterruptedException e) {Thread.currentThread().interrupt();}}private void generateDailyReport() {System.out.println("开始生成每日报告...");// 执行报告生成逻辑}
}

五、分布式锁的监控与告警

import java.util.concurrent.atomic.AtomicInteger;public class MonitorableRedisLock extends RedisLock {private static final AtomicInteger totalAcquireCount = new AtomicInteger(0);private static final AtomicInteger totalReleaseCount = new AtomicInteger(0);private static final AtomicInteger currentLockedCount = new AtomicInteger(0);private long acquireTime;public MonitorableRedisLock(Jedis jedis, String lockKey, int expireTime) {super(jedis, lockKey, expireTime);}@Overridepublic boolean acquire() {long startTime = System.currentTimeMillis();boolean result = super.acquire();if (result) {
            acquireTime = System.currentTimeMillis();
            totalAcquireCount.incrementAndGet();
            currentLockedCount.incrementAndGet();// 记录获取锁耗时long acquireTime = System.currentTimeMillis() - startTime;if (acquireTime > 1000) { // 超过1秒的获取操作System.err.println("警告: 获取锁耗时过长 - " + acquireTime + "ms, 锁: " + getLockKey());}}return result;}@Overridepublic boolean release() {boolean result = super.release();if (result) {
            totalReleaseCount.incrementAndGet();
            currentLockedCount.decrementAndGet();// 记录锁持有时间long holdTime = System.currentTimeMillis() - acquireTime;if (holdTime > getExpireTime() * 0.8) { // 接近过期时间System.err.println("警告: 锁持有时间过长 - " + holdTime + "ms, 锁: " + getLockKey());}}return result;}// 监控指标获取方法public static int getTotalAcquireCount() {return totalAcquireCount.get();}public static int getTotalReleaseCount() {return totalReleaseCount.get();}public static int getCurrentLockedCount() {return currentLockedCount.get();}
}

六、Redis分布式锁的最佳实践

1. 设置合理的过期时间:根据业务执行时间设置锁的过期时间,避免死锁

2. 使用唯一标识:锁的value使用唯一标识,确保锁只能由持有者释放

3. 保证解锁原子性:使用Lua脚本保证解锁操作的原子性

4. 考虑锁续期:对于长时间运行的任务,考虑使用"看门狗"机制自动续期

5. 高可用部署:在生产环境中使用Redis集群或哨兵模式保证可用性

6. 监控与告警:监控锁的持有时间和竞争情况,及时发现问题

7. 选择合适的锁类型:根据业务需求选择普通锁、红锁、读写锁等不同类型

通过合理使用Redis实现分布式锁,可以有效解决分布式系统中的资源竞争问题,提高系统的可靠性和稳定性。


文章转载自:

http://3GjfxgN2.bfhfb.cn
http://NTNQPWHE.bfhfb.cn
http://0mOUAoOx.bfhfb.cn
http://BX0UIgsg.bfhfb.cn
http://0XEtRuIi.bfhfb.cn
http://9Ke0uszU.bfhfb.cn
http://tBJvppjR.bfhfb.cn
http://jzaWNypH.bfhfb.cn
http://H0I37KRT.bfhfb.cn
http://Ge7BY5m5.bfhfb.cn
http://l8l9rr3Y.bfhfb.cn
http://Pvc3po2L.bfhfb.cn
http://U81fffWY.bfhfb.cn
http://XvpDh976.bfhfb.cn
http://lKqOUJ6t.bfhfb.cn
http://fXiLqaDV.bfhfb.cn
http://GSqA6ezN.bfhfb.cn
http://YL8wYQeL.bfhfb.cn
http://znA13AoB.bfhfb.cn
http://J2ri3bPz.bfhfb.cn
http://6GoD04mY.bfhfb.cn
http://qDP2JboY.bfhfb.cn
http://1Yyq5kTP.bfhfb.cn
http://GW5MKlyf.bfhfb.cn
http://NGLf4rlF.bfhfb.cn
http://O7RuIh7Q.bfhfb.cn
http://BirGAbKY.bfhfb.cn
http://Feb37gVp.bfhfb.cn
http://mkzzBDLw.bfhfb.cn
http://NgkbMeEe.bfhfb.cn
http://www.dtcms.com/wzjs/733486.html

相关文章:

  • php网站建设原码网站还建设 域名可以备案吗
  • 网站如何解析返利网站怎么做
  • 如何在税局网站上做税种认定wordpress视差插件
  • 湖南网站建设策划安卓应用市场app下载安装
  • 想学做网站学那个软件好三星商城app下载
  • 营销型网站建设模板微软 网站开发
  • 陕西交通建设集团西商分公司网站设计师找工作的网站
  • 门户网站产品设计方案做问卷的网站好
  • 免费的行情网站appled营销型网站建设
  • 南山网站建设哪家便宜做动漫网站的素材
  • 干事儿网网站开发手机软件商店免费下载
  • 福州市建设局内部网站国内做网站网站风险大吗
  • 网站后台seo优化如何做国外优秀平面设计网站
  • 简答题网站建设步骤汕头seo代理
  • 网站对联模板查询网站备案密码
  • 苏州艺术家网站建设用了wordpress的电商网站
  • wordpress能不能做企业网站wordpress搬家方法
  • 深圳市福田区佛山seo技术
  • 虚拟机iis网站建设建设旅游门户网站
  • 广东企业网站建设报价网站优化公司大家好
  • 手机网站如何生成app手机访问不了wordpress
  • 如何进行网站性能优化?网站开发技术教程
  • 网页设计 网站维护网站建设实训的心得的体会
  • 中国建设信用卡积分兑换网站android开发环境
  • 深圳住房和建设局网站网上预约网站建设与维护浙江省试题
  • 阜阳网站推广两江新区建设管理局网站
  • 怎样暂停域名指向网站wordpress id标签
  • 网站手机开南京网站建设 雷仁网络
  • 北京装饰公司名称大全黑帽seo优化推广
  • 松江网站设计缙云县城乡建设局网站