当前位置:首页 > 黑客服务 > 正文内容

php分布式框架(PHP分布式框架有哪些官网)

访客3年前 (2021-09-27)黑客服务671

分布式锁的实现方式有三种:1。基于数据库实现分布式锁;2.实现基于缓存的分布式锁(Redis等)。);3.基于Zookeeper实现分布式锁。从性能角度(从高到低):“缓存模式Zookeeper模式=数据库模式”。

操作环境:windows系统,redis 6.0,thinkpad t480电脑。

分布式锁的三种实现方法;

1.基于数据库实现分布式锁;2.实现基于缓存的分布式锁(Redis等)。);3.基于Zookeeper实现分布式锁;

1、基于数据库实现分布式锁定

1.悲观锁

使用select … where …更新排他锁

注:其他附加功能与实现1基本相同。这里要注意“凡名=锁”。名称字段必须建立索引,否则表将被锁定。在某些情况下,例如,如果表不大,mysql优化器将不会采用这个索引,从而导致锁定表的问题。

2.乐观锁定

所谓的乐观锁和前者最大的区别是基于CAS,不互斥,不会造成锁等待,消耗资源。在操作过程中,认为不存在并发冲突,只有更新版本失败后才能注意到。我们利用这种认识来防止我们的抢购和尖峰信号的超卖。乐观锁定是通过增加增量版本号字段来实现的

第二,基于缓存(Redis等。)来实现分布式锁

1.使用命令介绍:(1)SETNXSETNX key val:当且仅当key不存在时,设置一个key为val的字符串并返回1;如果键存在,则什么也不做并返回0。(2)expireexpire key timeout:为key设置一个超时,单位为秒,之后锁会自动释放,避免死锁。(3)deletedelete键:delete键

使用Redis实现分布式锁时,主要使用这三个命令。

2.实现思路:(1)获取锁时,使用setnx锁定,使用expire命令为锁添加超时时间,之后锁会自动释放,锁的值是随机生成的UUID,可以用来判断何时释放锁。(2)获取锁时,设置一个获取超时时间,超过这个时间就放弃获取锁。(3)开锁时,由UUID判断是否是锁,如果是,执行delete开锁。

3.分布式锁的简单实现代码:

/** *分布式锁的简单实现代码*/ public class DistributedLock {

私有最终JedisPool jedisPool

公共分布式锁(JedisPool jedisPool) { this.jedisPool = jedisPool }

/** *锁定 * @param lockName锁的密钥 * @param acquireTimeout获取超时值 * @param超时锁定超时 * @返回锁id */ 公共字符串锁定超时(字符串锁定名称,长获取超时,长超时){ Jedis conn = null 字符串重标识符=空; 尝试{ //获取连接 conn = JedisPool . GetResource; //随机生成一个值 字符串标识符= UUID.randomUUID。toString; //锁名,即键值 string LockKey = lock:+LockName; //超时时间,锁定后,锁会自动解除。 int lockExpire =(int)(time out/);

//获取锁的超时时间。如果超过这个时间,放弃获取锁。 long end = system . current timemillis+acquire time out; while(system . CurrentMemillis& lt;end) { if (conn.setnx(lockKey,identifier)=){ conn.expire(lockKey,LockExpire); //返回值,用于确认锁的释放时间 retIdentifier =标识符; 返回重新标识符; } //return-表示key没有设置超时,而是为key设置了超时。 if(conn . TTL(LockKey)=-){ conn.expire(lockKey,LockExpire); }

尝试{ thread . sleep; } catch(中断异常e) { Thread.currentThread。interrupt; } } } catch (JedisException e) { e . printstacktrace; }最后{ if (conn!= null) { conn . close; } } 返回重新标识符; }

/** *松开锁 * @param lockName锁的密钥 * @param标识符释放锁的标识符 * @返回 */ 公共布尔释放锁(字符串锁名,字符串标识符){ Jedis conn = null string LockKey = lock:+LockName; boolean retFlag = false 尝试{ conn = JedisPool . GetResource; while (true) { //监控锁,准备开始交易 conn . watch(LockKey); //通过前面返回的值判断是否是锁。如果是,删除它并释放它 if(identifier . equals(conn . get(LockKey))){ transaction transaction = con . multi; transaction . del(LockKey); 列表&lt。object results = transaction . exec; if (results == null) { 继续; } retFlag = true } conn . unwatch; 打破; } } catch (JedisException e) { e . printstacktrace; }最后{ if (conn!= null) { conn . close; } } 返回retFlag } }4.测试刚刚实现的分布式锁

在该示例中,50个线程用于模拟杀死一个商品,而–运算符用于减少商品。是否锁定,从结果的有序性可以看出。

模拟尖峰服务,其中配置了jedis线程池,该线程池被传输到分布式锁,供其在初始化期间使用。

公共级服务{

私有静态JedisPool池= null

私有分布式锁=新分布式锁(池);

int n = 500

静态{ JedisPoolConfig = new JedisPoolConfig; //设置最大连接数 config . SetMaxTotaL(200); //设置最大空闲数 config . SetMaxidle(8); //设置最大等待时间 config . setmaxwaitmillis(1000 * 100); //当您请求jedis实例时,是否需要验证?如果为真,则所有jedis实例都可用 config . settestonborrow(true); pool = new JedisPool(config,127.0.0.1,6379,3000); }

public void seckill { //释放锁时返回锁的值以供判断 字符串标识符= lock.lockWithTimeout(资源,5000,1000); 系统。out.println(线程。currentthread。getname+得到了锁); system . out . println(-n); lock.releaseLock(资源,标识符); } }为spike服务模拟线程;

公共类ThreadA扩展Thread { 私人服务;

公共线程(服务){ this.service = service }

@覆盖 public void run { service . seckill; } }

公共类测试{ 公共静态void main(String[] args) { 服务服务=新服务; for(int I = 0;i &lt。50;i++) { ThreadA threadA = new ThreadA(服务); threada . start; } } }结果如下,结果有序:

如果您注释掉使用锁的部分:

public void seckill { //释放锁时返回锁的值以供判断 //String identifier = lock . lockhittime out(资源,5000,1000); 系统。out.println(线程。currentthread。getname+得到了锁); system . out . println(-n); //lock.releaseLock(resource,identifier); }从结果可以看出,其中一些是异步的:

第三,基于动物园管理员实现分布式锁

ZooKeeper是一个开源组件,为分布式应用程序提供一致的服务。其内部是分层的文件系统目录树结构,规定同一目录下只能有一个唯一的文件名。基于ZooKeeper实现分布式锁的步骤如下:

(1)创建目录mylock;(2)如果线程a想要获取锁,它在mylock目录中创建一个临时序列节点;(3)获取mylock目录下的所有子节点,然后获取比自己小的兄弟节点。如果不存在,则表示当前线程序号最小,获得锁;(4)线程B获取所有节点,判断不是最小节点,设置一个小于自身的节点;(5)线程A处理完毕后,删除自己的节点,线程B监控变化事件,判断是否是最小节点,如果是,获取锁。

在这里我们推荐一个Apache开源库馆长,是ZooKeeper的客户端。馆长提供的进程间互斥是分布式锁的实现。获取方法用于获取锁,释放方法用于释放锁。

实现源代码如下:

import lombok . extern . SLF 4j . SLF 4j; import org . Apache . comes . lang . Stringuils; import org.apache .策展人. org.apache.curator.framework.CuratorFramework import org.apache .策展人. framework . curatorframeworkFactory; import org.apache .策展人. retry . retry ntimes; import org . Apache . zoo keeper . create mode; import org . Apache . zoo keeper . data . Stat; import org . spring framework . beans . factory . annotation . value; import org . spring framework . context . annotation . Bean; import org . spring framework . stereotype . component;

/** *分布式锁Zookeeper实现 * */ @Slf4j @组件 公共类ZkLock实现分布式锁{ private String ZkADdress = ZK _ adress; 私有静态最终字符串根=包根; 私有CuratorFramework zkClient

私有最终字符串LOCK _ PREFX =/LOCK _;

@豆 public DistributionLock InitzkLock{ if (StringUtils.isBlank(root)) { 抛出新的RuntimeException(zoo keeper & # 39;根& # 39;can & # 39t为空); } zkClient = CuratorFrameworkFactory 。构建器 。连接字符串(zkAddress) 。retryPolicy(新RetryNTimes(2000,20000)) 。命名空间(根) 。build; zkclient . start; 归还这个; }

公共布尔tryLock(字符串锁名){ lockName = LOCK _ PREFIX+lockName; 布尔锁定=真; 尝试{ Stat stat = zkClient.checkExists。for path(LockName); if (stat == null) { log.info(tryLock:{},lockName); stat = zkClient.checkExists。for path(LockName); if (stat == null) { 独立线程 。创建 。creatingParentsIfNeeded 。withMode(创建模式。短命) 。forPath(lockName,1 . GetBytes); } else { log.warn(双击stat.version:{},stat . GetVersion); locked = false } } else { log.warn(check stat.version:{},stat . GetVersion); locked = false } }捕获(例外e) { locked = false } 返回锁定; }

公共布尔tryLock(字符串键,长超时){ 返回false }

公共无效释放(字符串锁名){ lockName = LOCK _ PREFIX+lockName; 尝试{ 独立线程 。删除 。保证 。deletingChildrenIfNeeded 。for path(LockName); log.info(发布:{},lockName); }捕获(例外e) { log.error (delete,e); } }

public void setZkAddress(String zkAddress){ this.zkAddress = zkAddress } }优点:具有高可用性、重入性和阻塞锁的特点,可以解决无效死锁问题。

缺点:由于节点需要频繁创建和删除,性能不如Redis。

第四,对比

数据库分布式锁实现的缺点;

1.db操作性能差,有锁表的风险。2.非阻塞操作失败后,需要轮询,占用cpu资源;3.长时间不提交或长时间轮询可能会占用更多的连接资源

Redis分布式锁实现的缺点;

1.锁删除失败的到期时间难以控制。2.非阻塞,操作失败后,需要轮询,占用cpu资源;

ZK分布式锁实现的缺点:它的性能不如redis实现,主要是因为所有的写操作(获取锁和释放锁)都需要在Leader上执行,然后同步到follower。

总之,ZooKeeper的性能和可靠性更好。

从易于理解的角度来看(从低到高),数据库缓存Zookeeper

从实现的复杂度来看(从低到高),Zookeeper = cache数据库

缓存管理员=从性能角度看的数据库(从高到低)

动物园管理员从可靠性角度(从高到低)缓存数据库

扫描二维码推送至手机访问。

版权声明:本文由黑客接单发布,如需转载请注明出处。

本文链接:http://therlest.com/71361.html

分享给朋友:

“php分布式框架(PHP分布式框架有哪些官网)” 的相关文章

洗米华被抓(沙美华最近怎么了)

据中国电子商务研究中心2021年11月26日23:49:12的最新发布,微博网友@魔鬼管理学 爆料。 平安夜来临之际,事件,在网上炒得沸沸扬扬,引发全网热议! 据悉,洗米华被抓后来我换了俱乐部。。。 1.洗米华出什么事了...

约茶app约茶APP

最新约茶app都是哪些?整理了30本这篇文章主要介绍了约茶app,包括约茶app ios下载,下面小编整理了约茶app的图文教程,看看约茶app苹果版详细步骤吧! 觉得网上的一些答 据新快网2021年10月20日03:31:27的新闻报道,微博网友@R卜傲晴 爆料。 平安夜来临之际,事件,在网上...

贾秀东个人资料简介(简历及图片)

贾秀东人物概况 本页面提供了贾秀东个人资料简介(简历及图片),贾秀东是谁?贾秀东个人简介资料完整设计了网页求职找工作编辑个人简历作品所需要的贾秀东网站常用模板元素,不保证贾秀东人物数据真实,任何问题请联系管理员调整。 贾秀东图片 贾秀东个人资料简介 贾秀东,中国国际问题研究所特聘研究员。1...

古文化常识(中国古代文化常识大全)

1.中国古代文化常识 文学常识? 四本书:《论语》、《中庸》、《孟子大学》 五经:《诗经》《礼记》《周易》《春秋》 乐府双壁:木兰诗孔雀东南飞 三个字:警告世界,说真话,说真话,唤醒世界,说同样的话 第二枪:第一枪很厉害,第二枪也很厉害 三官:石渠官、潼关官、新安官 三次告别:新婚、老...

青岛新闻网房产 - 青岛个人房源出售

估计那个时候,0以上的住房为普通住宅。来说几句. 3500左右,我建议你来沧口找房子吧,青岛房产网51青岛信息港-房产,市北区的现在也到了新闻网7000了。提供覆盖青岛的别墅、一小时车程的房子大约在虎山以外,台南路。 还有的别墅个人150一般的房子都要,我就在黄岛住,早下手吧!沿海一带,2手放一般都...

鸡业行情网今日鸡价,鸡业行情网下载安装

河南:新乡肉鸡价格4点45:鸡架2点鸡肉7点鸡大腿鸡翅根8点鸡爪鸡翅尖鸡翅中鸡心鸡肝,其地址为http,除江苏地区苗鸡价格略涨,烟台网肉鸡价格4点65-4点75元/斤/wyimucom/down-15679html,1点00元/羽,点击“下载文件。以市斤为单位/羽 菏泽鸡苗价格3点90-4点30元/...

评论列表

离鸢婼粥
2年前 (2022-08-08)

lockName;尝试{独立线程。删除。保证。deletingChildrenIfNeeded。for path(LockName);log.info(发布:{},lockName);}捕获(例外e)

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。