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

北京自己怎么做网站自己做网站需要固定ip吗

北京自己怎么做网站,自己做网站需要固定ip吗,技能网站建设项目需求,现在出入郑州最新规定什么是分布式锁#xff0c;为什么需要分布式锁 在多线程并发请求当中#xff0c;为了保证我们的资源同一时刻只有一个线程进行操作#xff08;如商品超卖问题、购票系统等#xff09;#xff0c;我们通常要添加锁机制#xff0c;如ReentrantLock#xff0c;也就是可重入…什么是分布式锁为什么需要分布式锁 在多线程并发请求当中为了保证我们的资源同一时刻只有一个线程进行操作如商品超卖问题、购票系统等我们通常要添加锁机制如ReentrantLock也就是可重入的互斥锁与synchronized功能类似因为比较灵活所以经常使用。这在单机情况下是没有问题的但在多节点的情况下也就意味着有多个进程ReentrantLock锁机制可能就会不起作用所以我们需要一种能够跨进程的锁也就是同一时刻只能让一个进程获取锁来控制共享资源的访问。 分布式锁有哪些实现方式 基于数据库分布式锁悲观锁如select xxx for update、乐观锁如version版本号机制基于 Redis 实现分布式锁基于分布式协调服务 ZooKeeper 实现分布式锁 核心也是使用了每个节点都会用到的第三方组件例如mysql、redis、zookeeper Redis 实现分布式锁 使用setnx命令在 Redis 中setnx 命令是可以帮助我们实现互斥setnx 即 set if not exists (对应 Java 中的 setIfAbsent 方法)如果 key 不存在的话会设置 key 的值如果 key 已经存在 则啥也不做。 if(redisTemplate.opsForValue().setIfAbsent(key, value , time, TimeUnit)){ //加锁try {do something //业务处理}catch(){}finally {// 释放锁String delVal valueOperations.get(key).toString();if (value.equals(delVal)){redisTemplate.delete(key);}} }通常情况下我们一般使用setnx expire来实现防止死锁但仍然会有锁被别的线程误删的问题查询删除不是一个原子操作会有并发问题 为什么会有锁被别的线程误删假如线程A和线程B都执行同一段代码进行加锁线程A加锁成功当出现业务执行时间过长超过了过期时间这时线程A释放了锁此时线程B就能加锁成功接下来执行线程B业务操作这个时候线程A业务操作执行完了在finally方法中执行delete key这个时候线程A就会把线程B的锁给释放了。 所以一般释放的锁的时候最好使用lua脚本来进行释放来实现原子性的查询比较并删除锁。 if redis.call(get,KEYS[1]) ARGV[1] then return redis.call(del,KEYS[1]) elsereturn 0 end;lua脚本的话可以保证我们执行的时候多个命令执行期间不回被其他线程打断或出现竞争状态也就是可以看作一次请求保证了我们命令的原子性。 但这个方案仍然有个缺点锁过期释放了业务还没执行完。对于可能存在锁过期释放业务没执行完的问题。我们可以稍微把锁过期时间设置长一些让其大于正常业务处理时间。如果你觉得不是很稳还可以给获得锁的线程开启一个定时守护线程每隔一段时间检查锁是否还存在存在则对锁的过期时间延长防止锁过期提前释放如每5秒查看一下锁的过期时间如果小于10秒就延期针对这种锁续约机制redission框架就帮我们解决了这个问题 基于Redisson的分布式锁的实现 首先redission使用方式也比较简单 引入依赖 dependencygroupIdorg.redisson/groupIdartifactIdredisson/artifactIdversion3.17.0/version /dependency 写redisson的配置类 Bean public RedissonClient redissonClient(){...// 添加redis地址// 设置锁的超时时间// 创建 RedissonClient 对象 }使用redissonClient客户端加锁 Autowired private RedissonClient redissonClient;public void test() throws InterruptedException {RLock lock redissonClient.getLock(anyLock);boolean locked lock.tryLock(1,10,TimeUnit.SECONDS);// 参数1.获取锁的最大等待时间期间会重试2.锁自动释放时间3.时间单位if(locked){try{// 业务操作}finally{//释放锁lock.unlock();}} }假如我们加锁没有传参数直接使用tryLock()Redisson则会设置默认的锁过期时间为30s并且如果任务超过了30s还没有执行完毕则后台会有一个线程默认没隔10s执行task重置过期时间也就是WatchDog机制 redisson看门狗自动续期源码 private T RFutureLong tryAcquireAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId) {RFutureLong ttlRemainingFuture;if (leaseTime ! -1) {ttlRemainingFuture tryLockInnerAsync(waitTime, leaseTime, unit, threadId, RedisCommands.EVAL_LONG);} else {ttlRemainingFuture tryLockInnerAsync(waitTime, internalLockLeaseTime,TimeUnit.MILLISECONDS, threadId, RedisCommands.EVAL_LONG);}ttlRemainingFuture.onComplete((ttlRemaining, e) - {if (e ! null) {return;}// lock acquiredif (ttlRemaining null) {if (leaseTime ! -1) {internalLockLeaseTime unit.toMillis(leaseTime);} else {scheduleExpirationRenewal(threadId);}}});return ttlRemainingFuture;}tryAcquireAsync方法 如果没有设置过期时间就会执行默认的过期时间lockWatchdogTimeout 30 * 1000(ms)执行回调函数即看门狗机制 protected void scheduleExpirationRenewal(long threadId) {ExpirationEntry entry new ExpirationEntry();// 将线程放入缓存操作ExpirationEntry oldEntry EXPIRATION_RENEWAL_MAP.putIfAbsent(getEntryName(), entry);if (oldEntry ! null) {// 如果已经有该线程则不再延期oldEntry.addThreadId(threadId);} else {entry.addThreadId(threadId);renewExpiration();}} //--------------------------------------------------------------- private void renewExpiration() {ExpirationEntry ee EXPIRATION_RENEWAL_MAP.get(getEntryName());if (ee null) {// 缓存不存在则不再续约return;}Timeout task commandExecutor.getConnectionManager().newTimeout(new TimerTask() {Overridepublic void run(Timeout timeout) throws Exception {ExpirationEntry ent EXPIRATION_RENEWAL_MAP.get(getEntryName());if (ent null) {return;}Long threadId ent.getFirstThreadId();if (threadId null) {return;}// 执行续约的lua脚本RFutureBoolean future renewExpirationAsync(threadId);future.onComplete((res, e) - {if (e ! null) {log.error(Cant update lock getRawName() expiration, e);EXPIRATION_RENEWAL_MAP.remove(getEntryName());return;}if (res) {// 延期成功回调自己继续续约renewExpiration();}});}// 每隔internalLockLeaseTime/310秒检查一次}, internalLockLeaseTime / 3, TimeUnit.MILLISECONDS);ee.setTimeout(task);}// ----------------------------------------------------------------------- protected RFutureBoolean renewExpirationAsync(long threadId) {return evalWriteAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,if (redis.call(hexists, KEYS[1], ARGV[2]) 1) then redis.call(pexpire, KEYS[1], ARGV[1]); return 1; end; return 0;,Collections.singletonList(getRawName()),internalLockLeaseTime, getLockName(threadId));}关键方法renewExpiration() 函数开启了一个定时任务在10s后执行并且会在调用成功后再次调用“自己”即续约机制可以看到Redisson也是使用Lua脚本进行锁续约的lua脚本里会进行判断锁是否存在如果存在则重置过期时间为30s 最后关于Redisson Redisson是Java的redis客户端之一提供了一些api方便操作redis。锁只是它的一个工具类其他还包括分布式对象、分布式集合等等详细可参考https://github.com/redisson/redisson/wiki/
http://www.yutouwan.com/news/82120/

相关文章:

  • 南宁网站建设公司如何为老板打造网站赚钱的WordPress实现登陆提醒
  • 怎么查网站是哪家公司做的美橙网站维护
  • 学校网站的作用和意义深圳小区封闭最新通知
  • 做网站 用什么做数据库最好seo快速排名上首页
  • 山东省建设教育信息网站首页重庆注册公司网上申请入口
  • 上海网站制作网络推广方法网站建设新闻发布注意什么
  • 个人备案网站可以做淘宝客网站建设运营合作合同
  • 国内html5网站案例泊头那家做网站
  • 公司网站关键词优化怎么做网站建设实验原理
  • 互动创意网站上海网站分站建设
  • wap网站平台网站开发需要哪些资料
  • 网站编程用什么语言好东莞网络优化哪家好
  • 如何做自己的淘宝优惠券网站c程序设计课程网站建设论文
  • 网络推广网站优化中国城乡与住房建设部网站
  • 不用框架做网站网站标题就一个关键词
  • 政务服务网站建设情况汇报在线图片制作生成
  • 免费空间域名可以做淘宝客网站推广吗浙江建设信息港咨询电话
  • 猪八戒 网站开发支付深圳网站制作建设服务公司
  • 换空间网站备案花店电子商务网站建设课题设计
  • 浏阳网站建设公司帝国网站系统做专题
  • 网站建设代码结构世界十大网络公司排名
  • 建德网站优化公司网站设计过程
  • 腾冲住房和城乡建设局门户网站网站搜索建设
  • 图片直链在线生成网站合肥专业网站建设
  • 凡科建站微信小程序什么网站下载素材做图的
  • 佛山市网站建设分站多少钱工程门户网站建设
  • 流量多网站深圳flash网站建设
  • 订货网站怎么做网站用ps如何做
  • 江苏分销网站建设seo排名优化软件有用
  • 做公司网站需注意什么在线音乐网站开发