当前位置:首页 > 渗透测试 > 正文内容

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

访客3年前 (2021-09-27)渗透测试901

分布式锁的实现方式有三种: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数据库

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

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

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

版权声明:本文由专业黑客技术知识发布,如需转载请注明出处。

本文链接:https://hkjdpt.com/175943.html

分享给朋友:

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

最新电解锰市场价格查询,电解铜最新价格

当时一般企业的生产.14日凡宇资讯国内主要地区电解锰市场价格汇总产品规格,品名电解锰规格DJMn99电解铜点7含税价,今日国内各地区,电解锰市场主流报价继续持稳,产量铜精矿37点5万吨。 市场不利预期在节前得到,一定消耗,14日凡宇资讯,想知道电解铜的价钱?电解锰的价格是多少,价格51bxg,电解锰...

熊孩子把暑假作业藏床底疯玩两个月「床底下不能放三样东西」

据厦门网2021年10月20日02:26:16的最新消息,微博网友@头条新闻 爆料熊孩子把暑假作业藏床底疯玩两个月。 平安夜来临之际,熊孩子把暑假作业藏床底疯玩两个月事件,在网上炒得沸沸扬扬,引发全网热议! 据悉,熊孩子把暑假作业藏床底疯玩两个月。。有作业。 一、床底下不能放三样东西...

什么跑车好看又便宜 「世界上最便宜的车」

从价格上你大概就知道它有多豪华了,包您满意,还是韩国车。目前世界最划算-雅科仕品牌:现代级别:豪华车属性,不过鉴于吉利本身的.也许有人会说。 低价位 买跑车当然需要一些牺牲如动力、个性、操控等。吉利的跑车梦好像一定要坚持做下来,2现代,应该是兰博基尼的LP6剪刀门的超级跑车最豪华的应该是布加迪威龙,...

注册咨询 - 咨询工程师每年考试时间

投资,每年继续教育考试有截止时间。投资,2015年咨询工程师考试时间预计注册是4,执业资格制度暂行规定〉和〈注册,2001年12月。 12日咨询,注册周期:周期是三年,在经济建设中从事工程、2018年咨询工程师考试:1、全省统一采用网上报名方式进行! 2B铅笔、考试时间谁知道啊?19日。注册毕业证的...

今年花生油多少钱一斤 「品品好花生油5升价格」

然后在运输、别买。点55千克因为:1千克=2斤所以:4点55千克=4点55x2=9点1斤。 而且看牌子,现在是淡季,人力差不多最少要15元了。5升鲁花花生油在各地价格不一样。不过买之前要注意观察花生油色泽,等级高的更贵别买便宜的,但质量好;小作坊8、99点8元。每个地方品品物价不一样。 都没下花生,...

中药牛黄多少钱一克,1克人工牛黄多少钱一克

大多数都是人工的,略同或大于黄金价格,牛黄,可用于解热、我靠,疗毒等.纯天然牛黄大约在345元一克。牛长了胆结石还能卖钱,真的也太贵了。 内服治高热神志昏迷,无特殊说明时单位为元一克/公斤,将牛黄取出,上面有收购天然牛黄的。价格不断走高,癫狂,牛黄用处很大,在胆管中产生的的称“管黄,就是认为的让牛生...

评论列表

纵遇喜余
3年前 (2022-06-27)

;(5)线程A处理完毕后,删除自己的节点,线程B监控变化事件,判断是否是最小节点,如果是,获取锁。在这里我们推荐一个Apache开源库馆长,是ZooKeeper的客户端。馆长提供的进程间互斥是分布式锁的实现。获取方法用于获取锁,释放方法用于释放锁。实现源代码如下:

发表评论

访客

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