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

南宁h5建站做网站大概需要多少钱

南宁h5建站,做网站大概需要多少钱,企业宣传如何做网站,黑糖wordpress什么是分布式锁#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.pierceye.com/news/800042/

相关文章:

  • 网站如何做原创广州网站优化关键词公司
  • 海门市城乡建设局网站深圳专业做网站专业
  • 网站首页的快照更新慢凉山建设机械网站
  • 怎么区分营销型网站如何建立公司的网站
  • 宁波网站建设鲤斯设计游戏网站上图片动态怎么做的
  • 重庆php网站建设网站ip地址 转向域名
  • 知名的电子商务网站从化手机网站建设
  • 钓鱼网站 企业形象做一婚恋网站多少钱
  • 南阳网站建设公司wordpress视频无法播放视频
  • 广西防城港建设厅网站wordpress导航栏修改
  • 网站建设桂林永川网站建设公司
  • 英文网站设计制作wordpress搜索不到
  • 企业营销网站建设的基本步骤吉林省建设工程质量监督站网站
  • 现在用什么软件做网站北京工程设计公司排名
  • 烟台网站开发技术找人做网站服务器不是自己的怎么办
  • 网站样式下载pc网站建设的优势是什么
  • 网站是怎么建设的网页制作基础教程第2版葛艳玲答案
  • 企业做一个网站的费用网站设计专业需要什么
  • 昆山住房和城乡建设部网站网站开发用的工具
  • 广州优化网站建设网站建设是怎么赚钱
  • 公司建设网站公司系统软件开发培训机构
  • 小程序分销系统开发成熟的网站怎么做seo推广
  • 网站dns修改wordpress极简清新主题
  • 南京网站建设价位招商门户网站建设方案
  • 中学加强校园网站建设个人博客网站开发的原因
  • 网站域名管理中心广州市外贸网站建设企业
  • wordpress建站位置布吉网站建设价格
  • 网站域名正在维护中企业内网网站建设
  • 广西南宁官方网站企业wordpress和ueeshop
  • access数据库做网站自贸区注册公司有什么优势