本申请涉及分布式并发控制技术领域,尤其涉及一种基于redis的网络锁处理方法及设备。
背景技术:
目前,为了实现资源共享、通信方便快捷、加快计算机速度、提高可靠性等需求,大多数应用都以分布式的方式进行部署。在常用的分布式系统中,多请求访问同一资源时,最重要的就是通过互斥防止彼此干扰保证数据访问的一致性。
为了解决访问数据不一致的问题,目前存在以下三种技术方案:
1.线程锁。在多个线程访问同一对象的加锁代码段时,同一时间只能有一个线程在执行,其余线程必须等待当前进程结束之后才能执行该代码段。但是,在分布式系统中,线程锁往往并不能支持全部场景的使用。
2.数据库锁。数据库在确定哪些行需要锁的情况下使用行锁,在不确定哪些行需要锁的情况下使用表锁。但是数据库锁不存在锁失效机制,在服务器宕机或者网络突然断开时,无法及时将异常情况下的锁释放。
3.分布式锁。当多个进程不在同一系统中时,分布式锁虽然可以控制多个进程对同一资源的访问,但是在集群模式下,基于redlock算法设置锁失效的时间长短无法确定。若设置的时间太长,进程执行完锁还未释放,其他获取锁的进程就需要延长等待时间;若设置的时间太短,进程未执行完锁就自动释放了,这样会产生并发问题。因此,无法确定设置的锁失效时间的长短。同时,还无法保证基于redlock算法的加锁过程的正确性。
技术实现要素:
本申请实施例提供了一种基于redis的网络锁处理方法及设备,用以解决现有的线程锁、数据库锁及分布式锁处理方法,在分布式系统中多请求访问同一资源时,无法通过互斥防止彼此干扰来保证数据访问的一致性的技术问题。
一方面,本申请实施例提供了一种基于redis的网络锁处理方法,包括:接收用户的业务操作请求;根据请求对应的业务操作的加锁参数,判断业务操作是否存在对应的互斥操作;确定业务操作对应的互斥操作未加锁的情况下,获取信号量;对业务操作加锁,并将加锁信息写入redis中存储。
在本申请的一种实现方式中,根据所述请求对应的业务操作的加锁参数,判断所述业务操作是否存在对应的互斥操作之前,还包括:基于网络控制配置信息表,获取所述业务操作的redismap数据;从所述redismap数据中,获取所述业务操作的加锁参数。
在本申请的一种实现方式中,获取信号量,具体包括:判断信号量是否存在;在信号量存在的情况下,确定所述业务操作未被加锁,获取所述信号量;在信号量不存在的情况下,确定所述业务操作已被加锁,退出等待;其中,首次执行所述业务操作时,初始化所述信号量并获取。
在本申请的一种实现方式中,对所述业务操作加锁之后,还包括:执行所述业务操作;在所述业务操作完成之后,接收所述业务操作的完成指令,对所述业务操作解锁。
在本申请的一种实现方式中,对所述业务操作加锁之后,还包括:确定所述业务操作开始执行时,对所述业务操作解锁。
在本申请的一种实现方式中,对所述业务操作加锁之后,还包括:确定所述业务操作已完成,且所述业务操作仍未解锁,对所述业务操作执行异常解锁操作。
在本申请的一种实现方式中,获取信号量之后,还包括:确定加锁失败;从redis存储的加锁信息表中,获取所述业务操作对应的加锁信息,作为加锁失败原因,返回给用户。
在本申请的一种实现方式中,将加锁信息写入redis中存储之后,还包括:将所述加锁信息持久化到关系型数据库中;若持久化失败,则释放锁并重新加锁。
在本申请的一种实现方式中,将所述加锁信息持久化到关系型数据库中之后,还包括:根据redis中的加锁信息,确定各业务操作的加锁情况;若无法从redis中获取加锁信息,则从所述关系型数据库中获取所述加锁信息。
另一方面,本申请实施例还提供了一种基于redis的网络锁处理设备,处理设备包括:处理器;及存储器,其上存储有可执行代码,当所述可执行代码被执行时,使得所述处理器执行如上述的一种基于redis的网络锁处理方法。
本申请实施例提供了一种基于redis的网络锁处理方法及设备,至少包括以下有益效果:通过获取信号量加锁,进行并发控制更加具有可靠性,且合理性更强,保证了同一时间同一业务操作只有一个用户在执行,防止了多请求访问同一资源时彼此的干扰,进而保证了数据访问的一致性。并且,基于redis的网络锁具有更好的获取锁、释放锁的性能。
附图说明
此处所说明的附图用来提供对本申请的进一步理解,构成本申请的一部分,本申请的示意性实施例及其说明用于解释本申请,并不构成对本申请的不当限定。在附图中:
图1为本申请实施例提供的一种基于redis的网络锁处理方法流程图;
图2为本申请实施例提供的一种具体的基于redis的网络锁处理方法时序图;
图3为本申请实施例提供的另一种基于redis的网络锁处理方法流程图;
图4为本申请实施例提供的另一种基于redis的网络锁处理方法时序图;
图5为本申请实施例提供的一种基于redis的网络锁处理设备结构示意图。
具体实施方式
为使本申请的目的、技术方案和优点更加清楚,下面将结合本申请具体实施例及相应的附图对本申请技术方案进行清楚、完整地描述。显然,所描述的实施例仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
为保证数据访问的一致性,对具有互斥操作的业务操作进行并发控制,常对业务操作及对应的互斥操作进行加锁。常见的并发控制的锁有以下三种:线程锁、数据库锁、分布式锁。
其中,线程锁是指在多个线程访问同一对象的加锁代码块时,同一时间只能有一个线程在执行,其余线程必须等待当前进程结束之后才能执行该代码块。此时,虽然同一对象的加锁代码块只能有一个线程在执行,但是该对象的非加锁代码块可以被其余多个线程访问。并且,在非加锁代码块包括当前进程的互斥操作时,互斥操作线程的执行也会影响数据访问的一致性。此外,在分布式系统中,线程锁还不支持全部场景的使用。
数据库锁虽然可以在确定哪些行需要锁的情况下使用行锁,不确定哪些行需要锁的情况下使用表锁。但是数据库锁不存在锁失效机制,在服务器宕机或者网络突然断开时,无法及时将异常情况下的锁释放。
当多个进程不在同一系统中时,分布式锁虽然可以控制多个进程对同一资源的访问,但是在集群模式下,基于redlock算法设置的锁失效时间的长短无法确定。若设置的时间太长,业务操作执行完了锁还未释放,其他获取锁的进程就需要延长等待时间;若设置的时间太短,业务操作未执行完锁就自动释放了,这样会产生并发问题。因此,分布式锁无法确定异常情况下锁失效时间的长短。
本申请实施例提供了一种基于redis的网络锁处理方法及设备,通过接收的业务操作请求中的加锁参数,判断业务操作是否存在对应的互斥操作,并在确定对应的互斥操作未加锁的情况下获取信号量,对当前业务操作加锁。以解决上述线程锁、数据库锁、分布式锁无法通过互斥操作防止彼此干扰,保证数据访问一致性的技术问题。
下面通过附图对本申请实施例提出的技术方案进行详细的说明。
图1为本申请实施例提供的一种基于redis的网络锁处理方法流程图。如图1所示,本申请实施例提供的基于redis的网络锁处理方法主要包括以下步骤:
步骤101、接收用户的业务操作请求。
服务器接收分布式系统中用户的业务操作请求。
例如,企业资源计划(enterpriseresourceplanning,erp)系统凭证过账时,对过账单据执行编辑、修改、保存、删除等业务操作。
步骤102、根据请求对应的业务操作的加锁参数,判断业务操作是否存在对应的互斥操作。
在执行业务操作时,为了避免业务操作之间产生冲突,通常会对当前正在执行的业务操作加锁。但是,如果每个业务操作执行前都进行加锁,就会产生很多非必要的等待时间,降低工作的效率。因此,对业务操作的并发控制没有必要达到绝对的控制。
服务器在接收到分布式系统中的业务操作请求之后,根据业务操作的加锁参数,判断用户请求的业务操作是否存在对应的互斥操作,以便确定是否需要对业务操作加锁。其中,互斥操作是指业务操作进行时,能对当前业务操作的访问数据产生影响的一个或多个其他业务操作。
在本申请的一个实施例中,由于系统中的业务操作并非全部都是具有互斥操作的,因此,对于不存在互斥操作的业务操作,其相对独立,不受其他业务操作影响,无需对其加锁,而对于存在互斥操作的业务操作,为了保证不同业务操作之间不相互干扰,需要对当前业务操作加锁,进行并发控制。
在本申请的一个实施例中,服务器可预先根据存储的网络控制配置信息表,将各业务操作与对应的互斥操作映射到redismap数据中,并确定各业务操作对应的加锁参数。其中,网络控制配置信息表是存储业务操作之间关联关系的配置信息表,加锁参数表示业务操作对应的互斥操作存在或者不存在。
服务器接收到用户的业务操作请求之后,可先对用户的身份进行判断,以确定是否存在对应的redismap。
若用户为本系统的常用用户,即租户时,表明当前租户的redismap存在,服务器可直接获取租户redismap中的加锁参数,确定该租户请求的业务操作是否存在与之对应的互斥操作。若用户不是本系统的常用用户,即当前租户redismap不存在时,服务器就无法直接获取租户redismap中的加锁参数,而是需要加载网络控制配置信息表,调用当前业务操作的加锁参数并检查,进而确定当前业务操作是否存在与之对应的互斥操作。
在本申请的一个实施例中,服务器还可以通过业务操作的类型判断当前业务操作是否需要加锁。例如,当业务操作的类型为只读操作时,表示用户没有进行修改的权限,则当前业务操作的执行不会对其他业务操作的访问数据产生影响。因此,无需对只读类型的业务操作进行加锁。其中,与只读操作具有相同原理的其他类型的业务操作,在不会对其他业务操作产生影响的情况下,也无需加锁,本申请对此不一一列举。
在本申请的一个实施例中,服务器在确定当前业务操作存在互斥操作时,可判断业务操作对应的互斥操作是否已被加锁。若当前业务操作对应的互斥操作已被加锁,表示该互斥操作正在执行,用户无法执行当前业务操作,则需退出等待,直至互斥操作对应的进程执行完毕。若当前业务操作对应的互斥操作未被加锁,则服务器允许用户继续执行后续操作。
步骤103、确定业务操作对应的互斥操作未加锁的情况下,获取信号量。
服务器在确定业务操作对应的互斥操作未加锁的情况下,可获取信号量,以便执行后续步骤。
其中,信号量应用于多线程环境下,可以保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量。其它想进入该关键代码段的线程必须等待,直到第一个线程执行完毕释放信号量。
在本申请的一个实施例中,服务器在获取信号量时,可判断信号量是否存在。在确定信号量存在的情况下,表示当前线程未被占用,即业务操作未被加锁,则服务器可为当前业务操作获取信号量。在信号量不存在的情况下,表示当前线程已被占用,即业务操作已被加锁。当前业务操作无法获取信号量,需退出等待上一进程执行完毕并将信号量释放。
此外,信号量不存在的情况还包括:任一业务操作第一次执行时,信号量都不存在,且信号量的值为空。服务器需将信号量初始化,以防止业务操作第一次执行时,业务操作未被加锁的情况下,仍获取不到信号量。
具体的,如果信号量初始化成功,则第一次执行业务操作时,可以获取到信号量,并可以对当前业务操作进行加锁。如果信号量没有初始化成功,则信号量的值仍为空,当前业务操作获取不到信号量,无法对业务操作进行加锁。此时,返回初始化失败的信息提示,并且退出当前业务操作,重新初始化信号量。
在本申请的一个实施例中,服务器在执行业务操作时,可能存在业务操作已经执行完毕,但是业务操作的锁还未解除的异常情况。在这种异常情况下,下一进程无法正常获取到信号量,因此,需要对无法正常解锁的业务操作进行异常解锁操作。
具体的,业务操作完成后,若网络异常或者服务器宕机,可能会出现业务操作已完成而未解锁的情况。服务器可通过redis锁失效机制设置的超时长清理解锁以及后台手工解锁等方式进行异常解锁。
具体的,本申请的分布式锁在执行时,可设置默认的过期时间为预设时间段。在加锁成功后,服务器可根据预设时间间隔,在预设时间段内,对业务操作的锁进行检查,确认锁是否已被释放,并在锁还未释放时刷新过期时间,直到进程结束。其中,预设时间段、预设时间间隔可根据需要设置,本申请对此不做限定。
在发生服务器宕机等异常情况时,分布式锁无法进行间隔检查,刷新过期时间,则锁会在默认的过期时间后自动失效,使其他进程可以正常获取信号量。
在一种具体实现方式中,分布式锁可以是基于redisson框架的,设置默认的过期时间为30s、预设时间间隔为10s。服务器可通过redisson框架中的watchdog,每隔10s检查一下锁是否已被释放。如果锁还没有释放,则刷新过期时间将其重新设置为30s,直到进程结束。
步骤104、对业务操作加锁,并将加锁信息写入redis中存储。
服务器执行加锁的逻辑处理,对当前业务操作进行加锁。同时,服务器还将加锁成功业务操作的加锁信息存储到redis的信息表中。其中,该信息表是存储当前各业务操作加锁成功且未释放锁的加锁信息的数据表。
在本申请的一个实施例中,由于存在不同应用场景下的业务操作,所以服务器可根据不同的业务操作进行不同的解锁操作。其中,服务器对业务操作执行解锁操作的方式包括以下两种:
第一,服务器对业务操作加锁成功之后,执行当前业务操作的逻辑处理。业务操作完成之后,服务器接收用户执行完成的请求,并基于业务操作完成的指令,对当前业务操作进行解锁,释放信号量。业务操作解锁完成后,下一业务操作请求可以获取到信号量并对业务操作进行加锁。
具体的,在业务操作所需的场景为需要编辑、修改等时间较长的逻辑处理时,服务器接收到用户的业务操作请求,在业务操作存在对应的互斥操作且业务操作未被加锁的情况下,获取信号量,并对业务操作加锁。加锁成功之后执行业务操作的逻辑处理,当业务操作完成之后,服务器基于用户的完成指令,对当前业务操作进行解锁。
在对当前业务操作进行解锁前,其他进程都无法对当前业务操作进行加锁,这样就防止了多请求同时访问同一资源,进而保证了数据访问的一致性。
如图2所示,用户请求的业务操作为在erp系统中编辑单据。用户点击编辑按钮后,服务器接收编辑请求,并对单据编辑进行加锁。服务器执行加锁前的业务逻辑,在确定加锁成功后,将界面改为录入状态并返回。此时,用户可以执行录入单据的业务操作,并在录入完成后点击保存按钮完成整个业务操作的逻辑处理。此时,服务器会基于保存按钮的触发,接收到单据编辑的完成指令,并将单据编辑的锁解开,供下一业务操作执行时使用。
第二,服务器对业务操作加锁成功后,确定当前业务操作开始执行时,对当前的业务操作进行解锁。
具体的,在业务操作所需的场景为需要保存、删除等时间较短的逻辑处理,且同一业务操作单用户请求时,服务器接收用户的业务操作请求,在业务操作存在对应的互斥操作且业务操作未被加锁的情况下,获取信号量,并对当前业务操作进行加锁。加锁成功之后,当业务操作可以开始执行时,将业务操作的锁释放。
需要说明的是,本申请实施例中的业务操作为逻辑处理的时间较短,用户执行请求也较少的业务操作,且本申请实施例常用于访问同一资源单用户请求的业务操作。通过本申请实施例,可以节省其他进程的等待时间,提高业务操作的执行效率,同时,本申请实施例还具有更好的获取锁、释放锁的性能。
在一种具体的实现方式中,服务器在获取信号量,对当前业务操作加锁成功后,业务操作进入临界区,可以执行相应的逻辑处理。同时,信号量的值由1变为0。下一业务操作无法再进入临界区,必须进行等待。之后,在当前业务操作完成在临界区的逻辑处理,解锁释放信号量后,信号量的值由0变为1。此时,第二业务操作结束等待,可获取信号量,成功进入临界区,执行业务操作。
在本申请的一个实施例中,服务器在确定对业务操作加锁成功之后,将加锁信息写入redis的信息表中存储。同时,redis作为缓存,在网络异常或者服务器宕机的情况下,redis中存储的内容都无法获取。因此,服务器可在加锁成功将加锁信息写入redis中存储之后,再将redis中的加锁信息同步到关系型的数据库中,以使加锁信息持久化。若将加锁信息持久化到关系型数据库中失败,则将业务操作加的锁释放,重新加锁,以保证redis与关系型数据库中的数据保持一致。
在本申请的一个实施例中,服务器在对业务操作加锁时,可根据预存的加锁信息,确定业务操作及对应的互斥操作是否已被加锁,进而确定各业务操作的加锁情况。
并且,在服务器宕机或者网络异常无法通过redis获取加锁信息时,服务器可通过关系型数据库中存储的数据来获取加锁信息。通过持久化可以将加锁信息转化为持久数据,使其在关系型数据库中能够长期保存,作为备份数据。即使在服务器宕机或者网络异常的情况下,服务器也能够正常获取到加锁信息,进而判断业务操作以及对应的互斥操作是否已被加锁。
在本申请的一个实施例中,服务器确定对业务操作加锁失败,当前业务操作已被其他进程占用加锁时,可向用户返回加锁失败的提示信息,并基于上一进程加锁成功时存储到redis信息表中的加锁信息,将当前业务操作的加锁信息调取出来,作为加锁失败的原因返回给当前业务操作请求的用户。
通过本申请实施例提供的网络锁处理方法,进行的并发控制更加具有可靠性,且合理性更强,保证了同一时间同一业务操作只有一个用户在执行,防止了多请求访问同一资源时彼此的干扰,进而保证了数据访问的一致性。并且,基于redis的网络锁具有更好的获取锁、释放锁的性能。
图3为本申请实施例提供的另一种基于redis的网络锁处理方法流程图。如图3所示,本申请实施例提供的基于redis的网络锁处理方法主要包括以下步骤:
服务器接收用户的业务操作请求,并判断当前租户的redismap是否存在。在租户redismap存在的情况下,服务器可直接通过检查加锁参数判断业务操作是否存在对应的互斥操作。而在租户redismap不存在的情况下,服务器需加载网络控制配置信息表,调用当前业务操作的加锁参数并检查,进而确定当前业务操作是否存在与之对应的互斥操作。
在当前业务操作对应的互斥操作不存在时,无需对当前业务操作加锁,用户可直接执行。而当前业务操作对应的互斥操作存在时,需要继续检查互斥操作是否已被加锁。
在互斥操作已被加锁时,当前业务操作退出等待。而在互斥操作未被加锁时,获取信号量。
在信号量不存在的情况下,表示业务操作已被加锁,当前业务操作需退出等待。在信号量存在的情况下,表示业务操作未被加锁,此时,服务器可以获取信号量并对业务操作进行加锁。对业务操作加锁完成后,服务器执行业务操作。
图4为本申请实施例提供的另一种基于redis的网络锁处理方法时序图。如图4所示,本申请实施例提供的基于redis的网络锁处理方法主要包括以下步骤:
用户发出业务操作请求,通过开源云erp系统(insuite)发出加锁请求至网络控制(netcontrol),对当前业务操作进行加锁判断,并将加锁结果返回至insuite,insuite根据返回的加锁结果调用相应的业务函数,执行相应的操作。
需要说明的是,图3、图4所示的方法与图1所示的方法本质相同,因此,图3、图4中未详述的部分,具体可参照图1中的相关描述,本申请在此不再赘述。
以上为本申请提出的方法实施例。基于同样的发明构思,本申请实施例还提供了一种基于redis的网络锁处理设备,其结构如图5所示。
图5为本申请实施例提供的一种基于redis的网络锁处理设备结构示意图。如图5所示,设备包括处理器501、及存储器502,其上存储有可执行代码,当可执行代码被执行时,使得处理器501执行如上的一种基于redis的网络锁处理方法。
在本申请的一个实施例中,处理器501用于接收用户的业务操作请求;以及用于根据请求对应的业务操作的加锁参数,判断业务操作是否存在对应的互斥操作;还用于确定业务操作对应的互斥操作未加锁的情况下,获取信号量;还用于对业务操作加锁,并将加锁信息写入redis中存储。
本申请中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于设备实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。
还需要说明的是,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、商品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、商品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、商品或者设备中还存在另外的相同要素。
以上所述仅为本申请的实施例而已,并不用于限制本申请。对于本领域技术人员来说,本申请可以有各种更改和变化。凡在本申请的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本申请的权利要求范围之内。
1.一种基于redis的网络锁处理方法,其特征在于,所述方法包括:
接收用户的业务操作请求;
根据所述请求对应的业务操作的加锁参数,判断所述业务操作是否存在对应的互斥操作;
确定所述业务操作对应的互斥操作未加锁的情况下,获取信号量;
对所述业务操作加锁,并将加锁信息写入redis中存储。
2.根据权利要求1所述的一种基于redis的网络锁处理方法,其特征在于,根据所述请求对应的业务操作的加锁参数,判断所述业务操作是否存在对应的互斥操作之前,所述方法还包括:
基于网络控制配置信息表,获取所述业务操作请求对应的业务操作的redismap数据;
从所述redismap数据中,获取所述业务操作的加锁参数。
3.根据权利要求1所述的一种基于redis的网络锁处理方法,其特征在于,获取信号量,具体包括:
判断信号量是否存在;
在信号量存在的情况下,确定所述业务操作未被加锁,获取所述信号量;
在信号量不存在的情况下,确定所述业务操作已被加锁,退出等待;其中,首次执行所述业务操作时,初始化所述信号量并获取。
4.根据权利要求1所述的一种基于redis的网络锁处理方法,其特征在于,对所述业务操作加锁之后,所述方法还包括:
执行所述业务操作;
在所述业务操作完成之后,接收所述业务操作的完成指令,对所述业务操作解锁。
5.根据权利要求1所述的一种基于redis的网络锁处理方法,其特征在于,对所述业务操作加锁之后,所述方法还包括:
确定所述业务操作开始执行时,对所述业务操作解锁。
6.根据权利要求1所述的一种基于redis的网络锁处理方法,其特征在于,对所述业务操作加锁之后,所述方法还包括:
确定所述业务操作已完成,且所述业务操作仍未解锁,对所述业务操作执行异常解锁操作。
7.根据权利要求1所述的一种基于redis的网络锁处理方法,其特征在于,获取信号量之后,所述方法还包括:
确定加锁失败;
从redis存储的加锁信息表中,获取所述业务操作对应的加锁信息,作为加锁失败原因,返回给用户。
8.根据权利要求1所述的一种基于redis的网络锁处理方法,其特征在于,将加锁信息写入redis中存储之后,所述方法还包括:
将所述加锁信息持久化到关系型数据库中;
若持久化失败,则释放锁并重新加锁。
9.根据权利要求8所述的一种基于redis的网络锁处理方法,其特征在于,将所述加锁信息持久化到关系型数据库中之后,所述方法还包括:
根据redis中的加锁信息,确定各业务操作的加锁情况;
若无法从redis中获取加锁信息,则从所述关系型数据库中获取所述加锁信息。
10.一种基于redis的网络锁处理设备,其特征在于,所述处理设备包括:
处理器;
及存储器,其上存储有可执行代码,当所述可执行代码被执行时,使得所述处理器执行如权利要求1-9任一项所述的一种基于redis的网络锁处理方法。
技术总结