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

四举措加强网站建设网站公司做网站

四举措加强网站建设,网站公司做网站,电池网站建设 中企动力,枣庄网站建设多少钱Redis 如何实现分布式锁1. 什么是分布式锁1.1 分布式锁的特点1.2 分布式锁的场景1.3 分布式锁的实现方式2. Redis 实现分布式锁2.1 setnx expire2.2 set ex px nx2.3 set ex px nx 校验唯一随机值#xff0c;再删除2.4 Redisson 实现分布式锁1. 什么是分布式锁 分布式锁其实… Redis 如何实现分布式锁1. 什么是分布式锁1.1 分布式锁的特点1.2 分布式锁的场景1.3 分布式锁的实现方式2. Redis 实现分布式锁2.1 setnx expire2.2 set ex px nx2.3 set ex px nx 校验唯一随机值再删除2.4 Redisson 实现分布式锁1. 什么是分布式锁 分布式锁其实就是控制分布式系统不同进程共同访问共享资源的一种锁的实现。如果不同的系统或同一个系统的不同主机之间共享了某个临界资源往往需要互斥来防止彼此干扰以保证一致性。 1.1 分布式锁的特点 互斥性任意时刻只有一个客户端能持有锁 可重入性一个线程获取锁之后可以再次对其请求加锁 锁超时释放持有锁超时释放防止不必要的资源浪费也可以防止死锁 高效、高可用加锁和解锁需要高效同时也需要保证高可用防止分布式锁失效 安全性锁只能被持有的客户端删除不能被其他客户端删除。 1.2 分布式锁的场景 使用分布式锁的场景一般需要满足以下场景 系统是一个分布式系统Java 的锁已经锁不住了操作共享资源比如库里唯一的用户数据同步访问即多个进程同时操作共享资源。 分布式锁的业务场景 扣减库存抢红包… 1.3 分布式锁的实现方式 数据库乐观锁 基于 ZooKeeper 的分布式锁; 基于 Redis 的分布式锁。 这里主要介绍使用 Redis 实现分布式锁的方案。 2. Redis 实现分布式锁 2.1 setnx expire SETNX 是 SET IF NOT EXISTS 的简写。命令格式是 SETNX key value如果 lockKey 不存在则 SETNX 成功返回 1如果这个 lockKey 已经存在了则返回 0。 伪代码 // 1. 加锁 ifjedis.setnx(lockKey, lockValue) 1{// 2. 设置过期时间jedis.expire(lockKey, expireTime);try {// 3. 业务处理do something;} catch (Exception e) {log.error(处理失败, e);} finally {// 4. 释放锁jedis.del(lockKey);} }在这个方案中 setnx 与 expire 「不是原子操作」如果执行完第一步 jedis.setnx() 加锁后异常了第二步 jedis.expire() 未执行相当于这个锁没有过期时间「有产生死锁的可能」。正对这个问题如何改进 2.2 set ex px nx 基于 Redis 的 SET 扩展命令SET key value[EX seconds][PX milliseconds][NX|XX]保证 SETNX EXPIRE 两条指令的原子性。 EX second 设置键的过期时间为 second 秒 PX millisecond 设置键的过期时间为 millisecond 毫秒 NX 表示 key 不存在的时候才能 set 成功也即保证只有第一个客户端请求才能获得锁而其他客户端请求只能等其释放锁才能获取 XX 只在键已经存在时才对键进行设置操作。 伪代码 // 1. 加锁并设置过期时间 ifjedis.set(lockKey, lockValue, NX, EX, 100s) 1{try {// 2. 业务处理do something;} catch (Exception e) {log.error(处理失败, e);} finally {// 3. 释放锁jedis.del(lockKey);} }在这个方案中存在两个问题 锁过期释放了业务还没执行完。假设线程a获取锁成功一直在执行临界区的代码。但是100s过去后它还没执行完。但是这时候锁已经过期了此时线程b又请求过来。显然线程b就可以获得锁成功也开始执行临界区的代码。那么问题就来了临界区的业务代码都不是严格串行执行的了。 锁被别的线程误删。假设线程a执行完后去释放锁。但是它不知道当前的锁可能是线程b持有的线程a去释放锁时有可能过期时间已经到了此时线程b进来占有了锁。那线程a就把线程b的锁释放掉了但是线程b临界区业务代码可能都还没执行完。 2.3 set ex px nx 校验唯一随机值再删除 既然锁可能被别的线程误删那我们给 value 值设置一个标记当前线程唯一的随机数在删除的时候校验一下就可以了。 伪代码 // 1. 加锁并设置过期时间ifjedis.set(lockKey, uni_lockValue, NX, EX, 100s) 1{try {// 2. 业务处理do something;} catch (Exception e) {log.error(处理失败, e);} finally {// 3. 判断是不是当前线程加的锁if (uni_lockValue.equals(jedis.get(lockKey))) {// 4. 释放锁jedis.del(lockKey);}}}这里的 3. 是非原子性的我们使用 lua 脚本来优化一下 if redis.call(get,KEYS[1]) ARGV[1] then return redis.call(del,KEYS[1]) elsereturn 0 end;这个方案还是会存在**「锁过期释放业务没执行完」**的问题有些小伙伴认为稍微把锁过期时间设置长一些就可以了。其实我们设想一下是否可以给获得锁的线程开启一个定时守护线程每隔一段时间检查锁是否还存在存在则对锁的过期时间延长防止锁过期提前释放。 2.4 Redisson 实现分布式锁 只要线程一加锁成功就会启动一个 watch dog 看门狗它是一个后台线程会每隔 10s 检查一下如果 线程1 还持有锁那么就会不断的延长锁 key 的生存时间。Redisson 完美解决了「锁过期释放业务没执行完」问题。 Redisson lock 和 tryLock 原理解析 package com.pointer.mall.common.util;import lombok.extern.slf4j.Slf4j; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.stereotype.Component;import javax.annotation.Resource; import java.util.concurrent.TimeUnit;/*** author gaoyang* date 2023-02-23 20:24*/ Slf4j Component public class RedissonUtil {Resourceprivate RedissonClient redissonClient;/*** 加锁** param lockKey*/public void lock(String lockKey) {RLock lock redissonClient.getLock(lockKey);lock.lock();}/*** 带过期时间的锁** param lockKey key* param leaseTime 上锁后自动释放锁时间*/public void lock(String lockKey, long leaseTime) {RLock lock redissonClient.getLock(lockKey);lock.lock(leaseTime, TimeUnit.SECONDS);}/*** 带超时时间的锁** param lockKey key* param leaseTime 上锁后自动释放锁时间* param unit 时间单位*/public void lock(String lockKey, long leaseTime, TimeUnit unit) {RLock lock redissonClient.getLock(lockKey);lock.lock(leaseTime, unit);}/*** 尝试获取锁** param lockKey key* return*/public boolean tryLock(String lockKey) {RLock lock redissonClient.getLock(lockKey);return lock.tryLock();}/*** 尝试获取锁** param lockKey key* param waitTime 最多等待时间* param leaseTime 上锁后自动释放锁时间* return boolean*/public boolean tryLock(String lockKey, long waitTime, long leaseTime) {RLock lock redissonClient.getLock(lockKey);try {return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);} catch (InterruptedException e) {log.error(RedissonUtils - tryLock异常, e);}return false;}/*** 尝试获取锁** param lockKey key* param waitTime 最多等待时间* param leaseTime 上锁后自动释放锁时间* param unit 时间单位* return boolean*/public boolean tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit) {RLock lock redissonClient.getLock(lockKey);try {return lock.tryLock(waitTime, leaseTime, unit);} catch (InterruptedException e) {log.error(RedissonUtils - tryLock异常, e);}return false;}/*** 释放锁** param lockKey key*/public void unlock(String lockKey) {RLock lock redissonClient.getLock(lockKey);lock.unlock();}/*** 是否存在锁** param lockKey key* return*/public boolean isLocked(String lockKey) {RLock lock redissonClient.getLock(lockKey);return lock.isLocked();} }
http://www.hkea.cn/news/14586230/

相关文章:

  • 张家口建设厅官方网站宁波网站排名优化报价
  • 模板下载网站河北省建设项目环保备案网站
  • 在线小公司网站制作住院证明图片在线制作
  • 宝安网站制作哪家强wordpress商城主题破解
  • 科技公司网站设计方案wordpress怎样增加移动端
  • 站长之家网站网站设计字体最好用
  • 阿里云上做网站套模板怎么做济南 网站设计公司
  • 江门网站主机壳 安装wordpress
  • server 2008 iis 部署网站wordpress自定义选项
  • 网站cms系统sem优化是什么意思
  • 网站开发通用流程安徽专业建网站
  • 网站建设平台资讯玉石网站建设的定位
  • 旅游网站建设流程步骤绍兴企业建站模板
  • 外贸网站平台都有哪些 免费的wordpress淘宝客免费版
  • 免费微信网站开发什么网站对护肤品测评做的很好
  • 中国建设银行 网站登录网站营销推广公司
  • php整站开发 企业网站教程朋友圈推广平台
  • 校园 网站建设 知乎wordpress.conf
  • 生物公司网站建设广告建设网站
  • 做网站注册验证码电脑传奇游戏哪个好玩
  • 传奇网站制作网中壹建设工程有限公司官方网站
  • xp花生壳做自己的网站同性男做的视频网站
  • 建设商城网站视频教学建设银行官方网站广州
  • 视频网站建设的意义论文saas小程序开发费用
  • 首页网站怎么做的wordpress 用户登录
  • 钓鱼网站网站怎么做1 分析seo做的不好的网站
  • 2017做网站挣钱吗在线生成电子印章
  • 为什么要选择做花卉网站wordpress 蛋花儿收费主题
  • 长沙手机网站建设哪些内容网站搜索排名查询
  • 网站自己怎么制作网站建设中企动力最佳a4