分布式锁的实现

2023-11-15

分布式锁

分布式锁的引出

单体锁存在的问题:共享数据不安全,超卖现象

  在单体应用中,如果我们对共享数据不进行加锁操作,多线程操作共享数据时会出现共享数据不安全问题。先可以看下面的例子,也可以来看看买票。假设我们使用对共享数据不进行加锁操作,会出现一张票卖给了多个人,这就发生了一个抢票过程中,我们都知道的名词,也就是我们所说的超卖现象
 
在这里插入图片描述

 

  我们的解决办法通常是加锁。如加单体锁(synchronized或RentranLock)来保证单个实例并发安全。

这里拓展一波:

锁的理解

我们为什么需要用到锁?我们在多个线程并发过程中需要用到锁。
用到锁的原因是有一个共享资源,多个线程都需要去修改它或者是扣减库存,那么是谁来修改或者扣减我们用锁来控制。
加了锁的目的是我访问的时候,你不能访问,你访问的时候,我不能访问,是一个互斥现象。

我们用锁分为了三个过程。
以synchronized代码块为例
1、竞争锁,谁先进入synchronized代码块里面,谁就抢到了这把锁。
2、占有锁的过程,在代码块里面,我去修改值,我去看库存,我去扣减库存过程是一个占用锁的过程。
3、释放锁,在我们执行完synchronized代码块之后退出,完成任务之后,还需要一个释放锁的过程
 

在这里插入图片描述
 

上面举例的并发量只是一点点,在这里我们延伸一下。比如我们刚过去的双12或者双11,
举一个例子,在京东中,有一台手机,原价1万块,现在搞特价变成了1000块,可能只有两台,但是在同时全国可能有几百万的人都在抢。

如果在这种情况下面,我们还是使用synchronized关键字能够解决嘛?首先在我们的高并发中,一台Tomcat能不能响应我们几百万人的请求?这肯定是不行的,其实就像我们的人一样,比如假设我们人同时只能处理10件事,但是你同时丢给他100件事,两百件事,它处理不了,它还可能闹脾气,不干了。而这讲到我们的Tomcat上面,我们的Tomcat优化得再好,它请求的并发量一定是有限的,一台Tomcat,我们的机器再牛逼,也不可能处理几百万的并发量。所以就延伸出来我们分布式的要求,集群环境。一台Tomcat处理不了,我们就搞多个Tomcat实例来处理,用多个Tomcat来处理实例,那么就自然而然出现了另外的概念就是,我们如何进行分流

拓展——分流

如果对这部分比较熟悉可以跳过。
什么是分流,假设我们有一个请求req,而我们有多台Tomcat,那么这个时候我们是分给Tomcat1,还是分给Tomcat2?
而关于分流,我们经常使用到我们的Nginx

拓展——分流Nginx简单理解

当一个请求过来了,Nginx根据它的规则,哪台服务器较闲,就把这个请求分给那台较闲的服务器。防止一个忙的时候,另一个人在旁边吃雪糕,看你干活。这就是nginx做的事情。

这个时候,我们可以处理得过来了,那么一个synchronized能不能去处理我们并发的安全问题?
我们一测试,还是发现多个服务在数据层面出现了一票多卖的超卖现象

一个tomocat实例是一个JVM进程,单体锁(synchronized、ReentrantLock)是JVM层面的锁,只能控制单个实例上的并发访问安全,多实例下依然存在一票多卖的超卖现象。

 

在这里插入图片描述
 

分布式锁的引出

由于单体锁是基于 JVM 层面上的锁,只能控制单个实例上的并发访问安全,多个实例下依然存在一票多卖的超卖问题,这个时候,就轮到我们的分布式锁出场了。
分布式锁是指:所有服务中的所有线程都去获取同一把锁,但只有一个线程可以成功获取锁,其他没有获取锁的线程必须全部等待,直到持有锁的线程释放锁。分布式锁可以跨越多个JVM,跨越多个进程的锁。

 

分布式锁的设计思路

 
由于Tomcat是由Java启动的,所以每个Tomcat可以看成一个JVM,JVM内部的锁是无法跨越多个进程的。所以,我们要实现分布式锁,我们只能在这些JVM之外去寻找,通过其他的组件来实现分布式锁。系统的架构如图所示:

两个Tomcat通过第三方的组件实现跨JVM、跨进程的分布式锁。这就是分布式锁的解决思路,找到所有JVM可以共同访问的第三方组件,通过第三方组件实现分布式锁。

在这里插入图片描述
 

分布式锁的常见应用场景

 
  一般电商网站都会遇到秒杀、特价之类的活动,大促活动有一个共同特点就是访问量激增,在高并发下会出现成千上万人抢购一个商品的场景。虽然在系统设计时会通过限流、异步、排队等方式优化,但整体的并发还是平时的数倍以上,参加活动的商品一般都是限量库存,如何防止库存超卖,避免并发问题呢?分布式锁就是一个解决方案。
 

  我们都知道,在业务开发中,为了保证在多线程下处理共享数据的安全性,需要保证同一时刻只有一个线程能处理共享数据。
 

  Java 语言给我们提供了线程锁,开放了处理锁机制的 API,比如 Synchronized、Lock 等。当一个锁被某个线程持有的时候,另一个线程尝试去获取这个锁会失败或者阻塞,直到持有锁的线程释放了该锁。在单台服务器内部,可以通过线程加锁的方式来同步,避免并发问题,那么在分布式场景下呢?
 
在这里插入图片描述
 

分布式锁的目的是保证在分布式部署的应用集群中,多个服务在请求同一个方法或者同一个业务操作的情况下,对应业务逻辑只能被一台机器上的一个线程执行,避免出现并发问题。分布式场景下解决并发问题,需要应用分布式锁技术。

文章部分内容部分引自:Redis实现分布式锁

 
 

分布式锁方案

实现分布式锁目前有三种流行方案,即基于数据库、Redis、ZooKeeper 的方案。
 
在这里插入图片描述
 

 

数据库的分布式锁如何实现

当我们想使用基于数据库的分布式锁
我们不使用JVM层面的单体锁,我们首先先要创建一张表,而这张表需要一个唯一索引,可以是主键索引或者非主键索引,但是必须保证唯一。
然后我们代码插入insert into ----- xxx(需要包括唯一索引),这个时候谁插入成功了,那么就能接着代码往下走。
如果没有插入成功,那么只能排队等待。
所以基于数据库分布式锁是通过数据库唯一约束条件来进行完成的。基于数据库的锁是比较容易实现的,我们重点来看一下使用Redis缓存数据库来实现分布式锁

 
 

Redis分布式锁如何实现

使用Reds来实现分布式锁的核心思路:
在Redis中有一个命令叫setnx。如果我们的数据库中我们setnx test 1插入数据是可以插入成功的,但是**只要我们插入成功之后我们第二次插入test,那么就会失败。**只要我们使用setnx在我们的数据库中设置了key,那么后面都设置不成功。之后线程操作完之后再delete这个key,我们就是通过setnx来延伸出Redis分布式锁的。

 
但是我们仅仅使用Redis的setnx来设计我们的分布式锁,会出现死锁问题。

我们使用我们Java代码中操作Redis的setnx操作来实现分布式锁,这样成功解决了我们的超卖问题!但是,这样的代码,不够健壮!比如我们一个线程使用setnx进行加锁操作,然后进入了代码块想往下走,这个时候突然间,我们的机器死机了,那么我们下面的代码就不会去走了,并且delete删除锁的操作也不会进行,那么其他线程就只能在外面永远的等待下去,这样就造成了死锁的概念。死锁具体看我们另一篇博客:MySQL高级理解

而我们绝对不会让它一直等待下去,就像我们在网上进行支付的时候,我们会设置一个倒计时支付时间,也就是我们对这个key设置一个超时时间。expire test 10 查看剩余时间ttl test.

设置了这个过期时间,我们就可以解决这个死锁的问题了。

但是,Redis分布式锁现在没有人用setnx,原因在于,如果我们使用setnx,我们在代码中,我们需要写两行代码,如果我们设置完了key,我们在设置超时时间的同时,这个时候宕机了,同样会出现死锁的问题。setnx现在没有人使用是因为它不满足原子性

所以我们使用set key value EX time NX来解决,原子性的加锁加过期时间
 
在这里插入图片描述

 

但是,在这个过程中,还会出现另外一种问题。

假设我们有3个请求,请求1、请求2、请求3.
我们在线程加锁的时候,同时会设置一个过期时间来防止死锁。而我们在执行业务的时候,会有一个执行业务的时间。所以另外一种问题就是,我们的锁的过期时间 < 业务执行时间。
比如我们请求1抢到锁之后,加锁的时间为5s钟,但是由于今天我们的网络不好或者是机器性能下降,我们的业务执行了10s钟的时间。我们在到达5s钟的时候,锁的过期时间就到了,这个时候,请求2也就可以抢到锁并设置了,这个时候,请求2和请求1就同时进行,违反了锁的互斥条件

还有一种情况同样是锁的过期时间 < 业务执行时间,而请求1正在执行,请求2也在执行,但是在这个过程中,请求1完成了,所以请求1会执行删除锁的操作,这个时候请求3依然可以抢占锁。而这个过程中,真正持有锁的是请求2,而请求1把请求2的锁给删除了,导致请求3也来抢占锁,这个时候,出现了第二个问题,就是锁的误删。(解决需要加一个唯一的标识)

出现这个原因在于,没有验证这个锁是不是自己加的,所以我们要验证一下,在进行删除之前,我们要验证一下锁是不是我加的,如果是我加的就删,如果不是就不管它。这个时候,我们可以设置我们Value的值,来确定是哪一个人来加的锁,也就是判断value中的值。

 

在这里插入图片描述 
删除锁的时候要进行判断

 
在这里插入图片描述

在这里插入图片描述 

这个过程也不是一个原子性操作,而Redis也并没有删除的扩展命令,而我们在分布式环境下去删除某些东西的时候,需要用到原子性操作的时候,一定呀结合lua脚本实现。
 

在这里插入图片描述
 
在这里插入图片描述
 

Redis的分布式锁的租约问题

而我们回过头来看,解决互斥被破坏的情况。
出现互斥被破坏,出现锁的误删的原因在于我们的业务执行时间 > 锁的超时时间,我们的锁过期了,我们依旧在执行业务,这个时候我们能不能实现,如果我们的业务没有完成之前,我们不要去删除这把锁呢?
其实这就是一个Redis分布式锁的租约问题,具体租约问题可以看我另一篇问题:Redis分布式锁的租约
解决这个问题需要用锁的续期,而这个锁的续期,我们使用守护线程来实现。
 

在这里插入图片描述
 
如果我们像淘宝、京东那些有几百个Tomcat,那么我们一个redis节点,能100%顶住么?答案肯定是不可用的,所以我们想使用我们Redis集群来实现我们的分布式锁的问题。

我们解决了第一个,第二个,看第三个,我们就可以来说我们的Redis集群了。Redis集群具体看我的另一篇博客:Redis缓存数据库

但是我们的三种Redis集群也不能解决高可用的问题。
我们一个一个来看
主从模式:我们主从模式,主节点负责我们写部分,而我们从节点是负责读,而我们那么多的读请求都到我们的主节点上面。而我们使用Redis分布式锁,我们用的命令是set命令,是写的命令,所以根据我们的主从架构,我们只能走左边这条线,而没有分担一点压力的目的,而我们的主节点挂掉之后,我们的从节点依然是接收不了服务的,所以没有实现高可用,主从模式在我们Redis实现分布式锁是不行的。

 
在这里插入图片描述
 

哨兵模式:哨兵对主从模式中的每个节点进行监控,当 master 节点出现故障时通知投票机制,选择新的 master 节点,实现了故障转移。那这样子set命令还是有人执行的,为什么又不可以呢?

但是我们要明白一个问题:Master写完的数据一定要同步到Slave节点,而主从数据之间的同步是直接写Master,Master如果写成功了那就直接返回,从的不关心,从的定期从Master去同步就可以了,我们回过头来看,如果我们Redis实现分布式锁的过程中,我们主节点进行加锁set操作,而这个时候从节点还没有同步master里面的数据,这个时候master节点挂掉了,丢失了master中的数据,根据哨兵,此时选举一个slave变成master,而这个时候新的master可以响应加锁请求。而这个情况对于我们的业务来说,同时有两个请求加锁成功,还是违反了互斥特点,出现超卖现象,所以哨兵也不行。

 

在这里插入图片描述
 
而还有一种情况就是,如果此时,我们的并发量很高,一瞬间有数以万计的请求过来,我们都需要进行加锁,远远超过了我们的单节点能处理的情况,所以我们的master响应加锁的(写)请求很容易就挂掉了,而哨兵模式中slave也不能分担master节点加锁(写)的压力,而哨兵选举新的master之后,也可能因为请求冲击挂掉,以此进行出现连环雪崩现象。哨兵情况下不能达到一个分担压力的目的

集群cluter模式:

集群模式最基本的来说就是三主三从。
集群模式中数据通过数据分片的方式被自动分割到不同的master节点上,每个Redis集群有16384个哈希槽,进行set操作时,每个key会通过CRC16校验后再对16384取模来决定放置在哪个槽。

而我们使用Redis去实现分布式锁的时候,我们使用的是set test 1 ex 10 nx,而我们这个test这个key,有且只可能落在某一个节点上面。而如果我们此时用了cluster模式,我们一台节点的请求并发量为10w,而我们来了20w的并发加锁(写)请求,那么又是一个master在干活,另外两个节点在空闲着。又是哨兵模式的那两个问题
 

在这里插入图片描述
 
在这里插入图片描述
 
所以说,Redis高可用集群的三种模式都不能作为Redis集群下实现分布式锁的高可用方式。

那么有什么方法可以解决?
第一个方案:
首先来解决数据丢失导致的同时有两个请求加锁的情况。怎么会触发数据丢失的问题,原因在于新的master选举出来之后,里面并没有老的master节点中部分数据,导致了同时有两个请求加锁的情况。而我们在Redsi加锁的请求中我们会设置一个expire过期时间,所以解决方法就来了,我们牺牲掉一定的服务可用时间,我们在我锁的过期时间之后,我们再去启动新的master的上位(延迟启动)。当我们的锁超过超时时间之后,我们再去启动新的master节点,这个时候,即使我们master节点中有一部分数据没有同步过来,这个时候没有问题,因为过了expire超时时间,这部分数据一定会失去的,而我们延迟启动,就自然而然,解决了数据丢失而导致的同时有多个请求加锁的情况。这个延迟启动在Redis哨兵模式中的参数中可以配置。

第二个方案:
Redis高可用方案,一般我使用RedLock算法来 解决redis分布式锁的高可用问题,原因可以从我们上述Redis分布式锁的高可用方案分析可知道,RedLock算法是就是为了解决我们Redis主从之间同步数据使用异步的方式造成锁数据丢失而无法利用多个Redis节点达到高可用的问题。

我们平常使用jedis
但是还有一个redission,在redission里面就提供了Redlock算法的 分布式锁,具体实现很简单。
 
在这里插入图片描述
 
RedLock要求:
1、用多台服务器来确保redis分布式锁的高可用状态,但是上面这五个redis节点之间是相互独立的,之间没有任何的主从哨兵cluster关系,只是我们在电脑1/2、3/4、5中安装了redis服务的关系。
2、我们锁的过期时间,一定要远远大于我们的加锁时间。
3、如果我们加锁失败,有三个客户端,1/2、3. 客户端1弄redis1和redis2。客户端2弄redis3和redis4,客户端3弄redis5。而RedLock算法而已,加锁要过半数才觉得分布式锁加锁成功,而此时的情况是221,没过半。所以会不停地重试,所以要弄重试次数。

RedLock算法:
第一步:加锁,加锁的时候,首先会获取一个时间戳,拿到这个时间戳之后,我们的Client会按顺序用key value去访问我们redis的服务器来看看锁有没有加载成功,假设1/2、3插入成功之后,超过半数了,此时,认为分布式锁加载成功了。

第二步:释放锁,只要向所有的redis实例发送delete命令,不用关系关系里面到底有没有释放成功即可,有就删除,没有就不管了。

这就是redlock算法的基本使用。
理论挺麻烦,实现很简单。

而RedLock底层是使用Lua脚本来实现的。
 
在这里插入图片描述

 
 

Zookeeper分布式锁如何实现

我们Zookeeper实现分布式锁的方式有两种,一种是使用Java原生API来实现,一种是使用Curator 框架来实现。我们使用Java原生API,可以得知Zookeeper实现分布式锁的大致流程,具体Zookeeper实现分布式锁见我另一篇博客:Zookeeper

 
  
  
  

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

分布式锁的实现 的相关文章

  • Python对象数据库列表[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找 Python 的对象数据库 没有手工制作的泡菜 D 我的选择是什么 除了明显的ZODB h
  • FireStore - 如何绕过数组“不包含”查询

    经过一些研究 很明显我无法使用 FireStore 来查询给定数组不包含的项目 有人有针对这个用例的解决方法吗 用户注册后 应用程序会获取一堆卡片 每张卡片在 FireStore 中都有相应的 卡片 文档 用户与卡片交互后 卡片文档将用户的
  • NoSql DB 和 OO Db 有什么区别?

    NoSql DB 和 OO Db 有什么区别 NoSQL DB 通常是非规范化的 保存对象数据的副本来代替对象 而 OODB 是具有对象关系的规范化数据库 在 OODB 中 数据存储在对象中的一处 并链接 关系 到其他对象 由于上述非规范化
  • 在数据库中存储 JS 数组和对象

    我有一个应用程序 可以让用户用 JS 构建东西 我希望用户能够保存其工作的当前状态以重用或共享它 但他拥有的是存储在 JS 数组中的 JS 对象的集合 具有非常不同的属性 颜色 标签 x y 位置 大小等 SQL 对于该特定任务来说似乎很糟
  • 如何删除 MongoDB 中的所有数据库?

    I have a list of databases in my MongoDB How to delete all databases except local admin and config 您可以使用getDBNames 方法中的m
  • 如何在文档数据库(NoSQL)中设计基本模式?

    我有一个问题如何验证文档中的基本 JSON 字段 我的意思是假设一个字段是否需要 我的意思是基本上字段验证 我知道文档数据库是无模式的 NOSQL 但在 Mongodb 中 有一个选项 这就是我问的原因 例如 在 Mongodb 中 我们有
  • 使用增量计数器在 Couchbase 集群中生成唯一密钥

    我听到的关于 Couchbase 和其他 NoSQL 数据库的最常见问题是如何为记录生成唯一键 或者更具体地说 如何复制常见关系数据库的自动增量功能 Couchbase 中经常提到的解决方案是增量函数 您可以在数字键上调用增量 它将按顺序生
  • 带 Java 客户端的键值数据库

    我基本上想在磁盘上存储一个哈希表 以便以后可以查询它 我的程序是用Java 编写的 哈希表从字符串映射到列表 那里有很多键值存储 但经过大量研究 阅读后 尚不清楚哪一个最适合我的目的 以下是一些对我来说很重要的事情 简单的键值存储 允许您使
  • 获取列位置

    在 Cassandra DB 中 使用有序列族 我知道你能得到切片 但你能得到位置吗 例如 在此数据模型中 我保存如下分数 Scores 1000 bob lucas 900 tim 800 mario 知道用户的分数为 900 并且他的昵
  • neo4j:单向/双向关系?

    所以我研究了 neo4j 我可能会在即将到来的项目中使用它 因为它的数据模型可能非常适合我的项目 我查看了文档 但我仍然需要这个问题的答案 我可以将关系设置为单向吗 看来 Neo4j 的人很喜欢电影 所以我们继续吧 如果我有这样的图表 Ac
  • nosql 是什么意思?有人可以用简单的话向我解释一下吗?

    在这篇文章中堆栈溢出架构 http highscalability com stack overflow architecture我读到了一些叫做 nosql 的东西 我不明白它的意思 我试图在谷歌上搜索 但接缝我无法确切地了解它是什么 谁
  • 一起使用 MongoDB 和 Neo4j

    我正在开始一个新项目 我正在考虑使用 MongoDB 作为文档存储工具 使用 Neo4j 作为映射文档之间关系的机制 然后我想通过 REST API 公开查询结果 人们会说这样做的优点和缺点是什么 是否有更好的方法可以使用不同的 NoSQL
  • dynamoDB 如何存储数据?

    由于Dynamodb以键值对的形式存储数据 其中键是主键的类型 值是与其关联的数据 我想知道dynamo db是否真正理解值 json 我所说的值是指json与键关联的对象 RDBMS 中的一行 dynamo db 是否理解有一些属性以及它
  • NoSQL:如何根据经纬度检索“房子”?

    我有一个用于存储房地产的 NoSQL 系统 我在每栋房子的键值存储中拥有的一条信息是longitude and latitude 如果我想检索地理纬度 经度框中的所有房屋 如下面的 SQL SELECT from houses WHERE
  • 带有版本控制的 json 数据存储

    问题定义 有一个Java服务器存储JSON可以映射到 Java 类的数据 Java 类可能会发生变化 目标是能够更新 Java 类并且仍然能够解码JSON旧版本的数据到新版本的 Java 对象 应该有一个良好的版本控制系统 例如 能够向 J
  • 使用 NoSQL 文档存储数据库有哪些实际用例?

    在过去的几天里 我一直在阅读文档并观看特定于 Mongo DB 的截屏视频 我不知道像这样的解决方案何时会比典型的 pg 或 mysql 环境更好 具体来说 我的问题是在什么情况下 有用例就很好 你会选择 nosql 路线 Thanks 许
  • Neo4j.rb 创建独特的关系

    这是我的 Neo4j 活动节点 class User include Neo4j ActiveNode has many out following type following model class User end john User
  • Mongoose:find() 忽略重复值

    我有一只 聊天 猫鼬Schema它具有以下属性 const schema mongoose Schema recipient type mongoose Types ObjectId required true ref User sende
  • 计算 HBase 表中列族的记录数

    我正在寻找一个 HBase shell 命令来计算指定列族中的记录数 我知道我可以运行 echo scan table name hbase shell grep column family name wc l 然而 这将比标准计数命令运行
  • 删除对象时删除嵌套字段中的索引

    我仍在使用 Firebase 这次我有一个与删除对象相关的问题 我有如下结构 users UsErId1 name Jack email email protected cdn cgi l email protection UsErId2

随机推荐

  • 排序算法-希尔排序

    属性 1 希尔排序是对直接插入排序的优化 2 当gap gt 1时都是预排序 目的是让数组更接近于有序 当gap 1时 数组已经接近有序的了 这样就会很 快 这样整体而言 可以达到优化的效果 我们实现后可以进行性能测试的对比 3 希尔排序的
  • C++ 异常处理 入门

    C 异常处理 入门 异常 程序执行期间 可检测到的不正常情况 例如 0作除数 数组下标越界 打开不存在的文件 远程机器连接超时 malloc失败等等 程序的两种状态 正常状态和异常状态 发生不正常情况后 进入异常状态 从当前函数开始 按调用
  • Flex和Bison协同工作(下)

    Flex和Bison协同工作 下 上一篇文章我们写了一个稍微复杂一点点的词法解析器 这篇我们开始搞定语法分析器 文法与语法分析 语法分析器的任务其实就是找出输入记号之间的关系 通常使用语法分析树 parse tree 例如 算术表达式12
  • [4G&5G专题-62]:架构 - 开放的网络自动化平台ONAP(Open Network Automation Platform)

    目录 第1章 什么是开放的网络自动化平台ONAP 1 1 什么是ONAP 1 2 什么是的网络自动化平台 1 3 ONAP的动机与背景 1 4 ONAP的底层支撑技术 1 5 ONAP的前世 1 6 5G与ONAP 第2章 5G RAN的自
  • 你真的会用read()读【普通文件】吗?

    原型如下 include
  • 如何将json字符串写入table表格中

    JSON JavaScript Object Notation 是一种轻量级的数据交换格式 可以方便的将后台复杂的数据带回到前台进行展示 那么如何把json字符串写入到table表格之中呢 json简单说就是javascript中的对象和数
  • 美通企业日报

    今日看点 2019时尚育儿
  • java 常见错误合集

    java lang NullPointerException 这个异常都是因为调用null对象的方法 就是一个对象还没有没有正常初始化 就先调用它的方法比如 Object obj null obj toString 这就会抛出 这个异常
  • java中strictfp么意思_java中的strictfp的作用

    自Java2以来 Java语言增加了一个关键字strictfp 虽然这个关键字在大多数场合比较少用 但是还是有必要了解一下 strictfp 的意思是FP strict 也就是说精确浮点的意思 在Java虚拟机进行浮点运算时 如果没有指定s
  • 基于STM32控制的数字BUCK电路及程序编写

    本文芯片采用STM32G474CBT6 采用STM32cubeMX进行程序生成 BUCK电路拓扑结构 如图所示 BUCK变换器主要由电源VDC 场效应管MOSFET 续流二极管VD 电感L以及滤波电容C和负载RES组成 当MOSFET开通时
  • linux pxe安装视频,Linux利用PXE安装虚拟机的方法

    之前和友人聊天 知道可以利用PXE安装虚拟机 相信很多用户都和小编一样还不是很清楚 在这小编就把学习到的方法分享给大家 方法如下 1 1 dnsmasq apt get install dnsmasq vim etc dnsmasq con
  • elasticsearch sort script实现字段值等于某值排名靠前

    什么是script语言 script语言是es提供的一种支持自定义编程的用于复杂查询的脚本语言 主要类型有painless expressions等 需求描述 实际业务场景需要将某字段等于某值的排在前面 其他数据靠后 比如 雇员属性 nam
  • 阿里跟腾讯又㕛叒打起来了,这次是在东南亚

    腾讯与阿里的先头部队 已经在东南亚开始新的战争 在这之中 电商的争夺尤其激烈 神经浪游者 作者威廉 吉布森说 未来已来 只是分布得不太均匀 互联网的分布尤其如此 先是欧美 之后中国 如今 投资人和从业者纷纷押注 昔日的好时光将在东南亚将重现
  • sqlite3 提示 not found

    在android开发中使用adb shell下的sqlite3命令来查看SQLite数据库时 出现了 sqlite3 not found 错误 在网上搜索了一下问题的原因 原来是模拟器或真机中的 system xbin 目录下少了sqlit
  • 华为OD机试 - 工作安排 - 动态规划(Java 2023Q1 100分)

    目录 一 题目描述 二 输入描述 三 输出描述 四 动态规划 五 解题思路 六 Java算法源码 七 效果展示 1 输入 2 输出 3 说明 华为OD机试 2023B卷题库疯狂收录中 刷题点这里 一 题目描述 小明每周上班都会拿着自己的工作
  • vue设置全局过滤器

    src目录下新建文件夹filters 新建文件index js内容为 const timefilters getdate data console log data getdatetime data console log data exp
  • 十大Web网站漏洞扫描工具

    1 Nikto 这是一个开源的Web服务器扫描程序 它可以对Web服务器的多种项目 包括3500个潜在的危险文件 CGI 以及超过900个服务器版本 还有250 多个服务器上的版本特定问题 进行全面的测试 其扫描项目和插件经常更新并且可以自
  • 信号槽的返回值(QMetaObject::invokeMethod的用法)——Qt

    前言 之前从未想过信号槽是可以有返回值的 因为虽然信号发出去了 但是它在事件循环中 什么时候执行还不一定 这个想法固然是对的 但是这也不是不能实现的 我查了网上的一些资料 发现差不多有一下三种方法 1 信号槽里加指针或引用 这个不推荐 隐患
  • 并发处理

    1 并发活动 进程的引入 操作系统的特性之一是并发与共享 即在系统中 内存 同时存在几个相互独立的程序 这些程序在系统中既交叉地运行 又要共享系统中的资源 这就会引起一系列的问题 包括 对资源的竞争 运行程序之间的通信 程序之间的合作与协同
  • 分布式锁的实现

    目录 分布式锁 分布式锁的引出 单体锁存在的问题 共享数据不安全 超卖现象 锁的理解 拓展 分流 拓展 分流Nginx简单理解 分布式锁的引出 分布式锁的设计思路 分布式锁的常见应用场景 分布式锁方案 数据库的分布式锁如何实现 Redis分