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

企业网站的建设的目标人物是桌面百度

企业网站的建设的目标人物是,桌面百度,网站开发策划案,什么样的网站需要备案最终代码(通用类) 1 面试中、实际工作中&#xff0c;经常涉及到 redis 分布式锁&#xff0c;正确写法如下。先奉上代码&#xff0c;再讲解。 <?php namespace app\common\library; /*** 通用分布式锁(原子操作)*/ class Lock {/*** 获取redis实例* return \Redis* throws…

最终代码(通用类)

1 面试中、实际工作中,经常涉及到 redis 分布式锁,正确写法如下。先奉上代码,再讲解。

<?php
namespace app\common\library;
/*** 通用分布式锁(原子操作)*/
class Lock
{/*** 获取redis实例* @return \Redis* @throws \RedisException*/public static function redis(){$redis = new \Redis();$redis->connect('192.168.4.147',6179);return $redis;}/*** 加锁(原子操作)* @param string $key 要加锁的key* @param string $value 必须是唯一值* @param int $expires 锁的过期时间(秒)* @return bool* @throws \RedisException*/public static function lock(string $key,string $value,int $expires): bool{# redis实例$redis = self::redis();# 原子操作 -- 设置锁且设置过期时间return $redis->set($key,$value,['nx','ex'=>$expires]);}/*** 解锁(原子操作)* @param string $key 要解锁的key* @param string $value 加锁时的值* @return mixed|\Redis* @throws \RedisException*/public static function unlock(string $key,string $value){# redis实例$redis = self::redis();# lua 脚本$lua = "if redis.call('GET',KEYS[1]) == ARGV[1] thenreturn redis.call('DEL',KEYS[1])elsereturn 0end";return $redis->eval($lua,[$key,$value],1);}/*** 生成唯一值* @return string*/public static function generateValue(): string{return microtime(true).mt_rand(10000,99999);}
}

2 使用方式

use app\common\library\Lock;
# 抢到锁
if(Lock::lock($key,$value,300)){try{# 业务逻辑}catch (\Exception $e){}finally {# 释放锁Lock::unlock($key,$value);}
}

讲解

使用场景

抢红包、秒杀下单、扣库存、…

目的

在并发情况下,避免业务逻辑的重复执行,导致性能低下,或数据不一致。重复执行没意义的工作,浪费性能,比如数据清理、数据归档、检测日志等 。重复执行有意义的工作,导致数据出错,比如重复多扣了库存。

一些常见的写法

1 setnx + expire
说到 redis 的分布式锁,很多同学马上会想到 setnx + expire,先用 setnx 抢锁,如果抢到之后,再用expire 给锁设置一个过期时间防止忘记释放。

setnx 是 set if not exists 的缩写,表示如果 key 不存在,则去设置,成功返回1,否则返回0。

//抢锁
if($redis->setnx($key,$value)){//设置过期时间$redis->expire($key,300);try{//业务逻辑}catch (\Exception $e){}finally {//释放锁$redis->del($key);}
}

注:这个方案的问题在于,setnx 和 expire 两个命令分开了,不是原子操作。如果执行完加锁操作(setnx)后正要执行 expire 设置过期时间,进程崩了或者要重启维护,那么这个锁就长生不老了,别的线程永远也获取不到这个锁了。

2 使用Lua脚本(包含setnx + expire两条指令)
抢锁的改进如下,解决了上面写法1抢锁时的非原子操作。利用 lua 脚本把多个指令一起执行,达到原子操作的目的。

 # lua脚本$lua = "if redis.call('setnx',KEYS[1],ARGV[1]) == 1 thenredis.call('expire',KEYS[1],ARGV[2])elsereturn 0end";# 执行lua脚本,并传入参数return $redis->eval($lua,[$key,$value,$expires],1);

3 SET的扩展命令(SET EX PX NX)
效果等同于写法2,也是原子性的。

//抢锁
if($redis->set($key,$value,['NX','EX'=>300])){try{//业务逻辑}catch (\Exception $e){}finally {//释放锁$redis->del($key);}
}

SET key value[EX seconds][PX milliseconds][NX|XX]

NX :表示key不存在的时候,才能set成功,也即保证只有第一个客户端请求才能获得锁,而其他客户端请求只能等其释放锁,才能获取。
EX seconds :设定key的过期时间,时间单位是秒。
PX milliseconds: 设定key的过期时间,单位为毫秒
XX: 仅当key存在时设置值

注:但是,这个方案还有个问题:「锁被别的线程误删」
比如线程A执行完后,去释放锁,但它不知道当前的锁可能是线程B持有。线程A就把线程B的锁释放了,但线程B临界区业务代码可能还没执行完成。

释放锁的代码改进如下,判断所有者是否是自己,然后再释放。也用原子操作:

# redis实例
$redis = $this->redis();
# lua 脚本
$lua = "
if redis.call('GET',KEYS[1]) == ARGV[1] thenreturn redis.call('DEL',KEYS[1])
elsereturn 0
end
";
return $redis->eval($lua,[$key,$value],1);

4 SET EX PX NX + 校验所有者,再删除
改进后,最终的代码,见文章开头。

后记

注意,请根据实际业务情况合理设置锁的过期时间 expires 。

一、
无论如何,依然存在一个问题:「锁过期释放了,业务还没执行完」
假设线程A获取锁成功,一直在执行业务代码,300秒过后,它还没执行完。这时候锁就过期了,别的线程又请求进来获取到锁了,也开始执行业务代码。问题就来了,业务代码并不是严格串行执行。

一般情况中小项目中,做好日志、容错判断等即可。如果你项目到了一定规模,如果你追求锁的决定安全性,解决方案是:自动续期。

这个话题,值得再另写一篇文章讲解。自行上网搜索学习,此处省略。

JAVA 提供了很好的一个分布式锁框架: Redisson ,它很好的解决了此问题。PHP 暂时我还没找到好的类库。

还有就是,自己实现自动续期。

二、
多个 redis 实例、集群模式时,解决方案请看官方提供的 RedLock。这又值得另写一篇文章讲解。自行上网搜索学习,此处省略。

http://www.hkea.cn/news/684992/

相关文章:

  • wordpress大流量专业的网站优化公司
  • 做进口零食批发网站百度站长管理平台
  • 网站栏目建设存在的问题关键词简谱
  • 网站备案怎么那么麻烦google chrome 网络浏览器
  • 小米手机做网站服务器nba东西部最新排名
  • 做写字楼用哪个网站更好郑州seo代理外包
  • 做网站 淘宝营销策划思路
  • 网页设计要用到什么软件聊城seo优化
  • 用wordpress做网站百度推广管理
  • 一个空间可以放两个网站吗html模板网站
  • 做试用网站的原理网站推广优化平台
  • 软件工程培训机构学费亚马逊seo什么意思
  • 做恶搞网站软件有哪些苏州seo怎么做
  • 怎么做微信小说网站企业网络营销策划方案
  • 网站后台上传图片失败百度下载免费安装最新版
  • 镇江做网站需要多少钱企业网站模板设计
  • 西安seo优化系统网页seo
  • 如何用网站模板做网站广州网络营销推广
  • 承德手机网站建设seo推广排名
  • wordpress块引用一个网站可以优化多少关键词
  • 360网站卖东西怎么做的无锡seo优化公司
  • 邢台人民网站百度视频推广怎么收费
  • 常州天启建设公司网站高端快速建站
  • ppt模板免费下载网站不用登录seo测试工具
  • 四川建设人才网官网查询阜新网站seo
  • 太原网站开发定制百度网盘官网下载
  • 业主装修日记那个网站做的好片多多可以免费看电视剧吗
  • 租车网站建设站长之家源码
  • 昌吉州回族自治州建设局网站地产渠道12种拓客方式
  • 北京市网站公司网络项目免费的资源网