作者文章

fwq

FWQ
服务器教程
基于Redis验证码发送及校验方案实现
基于Redis验证码发送及校验方案实现 收藏 大家好,今天本人给大家带来文章《基于Redis验证码发送及校验方案实现》,文中内容主要涉及到发送、校验、Redis验证码,如果你对数据库方面的知识点感兴趣,那就请各位朋友继续看下去吧~希望能真正帮到你们,谢谢! 在我们的业务中,经常存在需要通过发送验证码、校验验证码来完成的一些业务逻辑,比如账号注册、找回密码、用户身份确认等。 在该类业务中,发送验证码的方式可以有各种各样,比如最常见的手机验证,最古老的邮箱验证,到现在相对少见的微信公众号、钉钉通知等;而验证码服务端存储的方式也可以各式各样,比如存储在关系型数据库中,当然也可以如本文标题所示,存储在Redis中。 既然已经预见到了各式各样的发送方式,也预见到了各式各样的存储方式,所以,虽然本文标题是基于Redis,但Redis其实只是其中的一种存储方式,如果需要,我们也应该可以和方便的切换到其它存储方式。 上代码前,我们先看下设计中的接口关系 ICodeHelper是最终提供发送验证码和校验验证码的最终接口,其关联了ICodeSender和ICodeStorage,ICodeSender即为验证码发送方式的约定接口,ICodeStorage则为验证码服务端持久化方式的约定接口。我们可以看到ICodeSender同样关联了IContentFormatter,因为作为发送方ICodeSender其实是不知道如何将要发送的内容组织成一段完整的文本内容的,这时候就需要IContentFormatter来组织文本内容,至于继承自IContentFormatter的IComplexContentFormatter,则只是IContentFormatter一个容器封装,毕竟对于不同的业务类型,我们需要组织成不同的文本内容,通过IComplexContentFormatter,我们可以将不同业务类型文本内容的组织过程,分散到不同的IContentFormatter中。 下面我们来看下上述接口的规范约定,考虑到代码的简便性,此处我们简单的将receiver接收方定义为了string,而不是泛型 ;业务标志bizFlag为了方便接入时无需调整代码,所以此处也没有将该值定义为枚举,而是同样定义成了通用性最强的string。 ICodeStorage /// /// 校验码信息存储接口 /// public interface ICodeStorage { /// /// 将校验码进行持久化,如果接收方和业务标志组合已经存在,则进行覆盖 /// /// 接收方 /// 业务标志 ///…
2025-05-10 阅读全文 →
FWQ
服务器教程
面试常问:如何保证Redis缓存和数据库的数据一致性
面试常问:如何保证Redis缓存和数据库的数据一致性 收藏 本篇文章向大家介绍《面试常问:如何保证Redis缓存和数据库的数据一致性》,主要包括面试、RedisMySQL,具有一定的参考价值,需要的朋友可以参考一下。 首先,我们先来看看有哪几种一致性的情况呢? 一、一致性 1、强一致性 如果你的项目对缓存的要求是强一致性的,那么请不要使用缓存。这种一致性级别是最符合用户直觉的,它要求系统写入什么,读出来的也会是什么,用户体验好,但实现起来往往对系统的性能影响大。 2、弱一致性 这种一致性级别约束了系统在写入成功后,不承诺立即可以读到写入的值,也不承诺多久之后数据能够达到一致,但会尽可能地保证到某个时间级别(比如秒级别)后,数据能够达到一致状态。 3、最终一致性 最终一致性是弱一致性的一个特例,系统会保证在一定时间内,能够达到一个数据一致的状态。这里之所以将最终一致性单独提出来,是因为它是弱一致性中非常推崇的一种一致性模型,也是业界在大型分布式系统的数据一致性上比较推崇的模型。一般情况下,高可用只确保最终一致性,不确保强一致性。 强一致性,读请求和写请求会串行化,串到一个内存队列里去,这样会大大增加系统的处理效率,吞吐量也会大大降低。 二、redis缓存和mysql数据库数据一致性解决 这张图,大多数人的很多业务操作都是根据这个图来做缓存的。但是一旦设计到双写或者 数据库和缓存更新等操作,就很容易出现数据一致性的问题。无论是先写数据库,在删除缓存,还是先删除缓存,在写入数据库,都会出现数据一致性的问题。列举两个小例子。 1、 先删除了redis缓存,但是因为其他什么原因还没来得及写入数据库,另外一个线程就来读取,发现缓存为空,则去数据库读取到之前的数据并写入缓存,此时缓存中为脏数据。 2、 如果先写入了数据库,但是在缓存被删除前,写入数据库的线程因为其他原因被中断了,没有删除掉缓存,就也会出现数据不一致的情况。 总的来说,写和读在多数情况下都是并发的,不能绝对保证先后顺序,就会很容易出现缓存和数据库数据不一致的情况,还怎么解决呢? 1、方案一:采用延时双删策略 基本思路: 在写库前后都进行删除缓存操作,并且设置合理的超时时间 基本步骤: 先删除缓存–再写数据库—休眠一段时间—再次删除缓存 注:休眠的时间是根据自己的项目的读数据业务逻辑的耗时来确定的。这样做主要是为了保证在写请求之前确保读请求结束,写请求可以删除读请求造成的缓存脏数据。 该方案的弊端: 集合双删策略+缓存超时策略设置,这样最差的结果就是在超时时间内数据存在不一致,又增加了写请求的耗时。…
2025-05-10 阅读全文 →
FWQ
服务器教程
Redis实战之Jedis使用技巧详解
Redis实战之Jedis使用技巧详解 收藏 偷偷努力,悄无声息地变强,然后惊艳所有人!哈哈,小伙伴们又来学习啦~今天我将给大家介绍《Redis实战之Jedis使用技巧详解》,这篇文章主要会讲到RedisJedis等等知识点,不知道大家对其都有多少了解,下面我们就一起来看一吧!当然,非常希望大家能多多评论,给出合理的建议,我们一起学习,一起进步! 一、摘要
2025-05-10 阅读全文 →
FWQ
服务器教程
SpringBoot怎么结合Aop+Redis防止接口重复提交
SpringBoot怎么结合Aop+Redis防止接口重复提交 收藏 学习数据库要努力,但是不要急!今天的这篇文章《SpringBoot怎么结合Aop+Redis防止接口重复提交》将会介绍到等等知识点,如果你想深入学习数据库,可以关注我!我会持续更新相关文章的,希望对大家都能有所帮助! 在实际的开发项目中,一个对外暴露的接口往往会面临很多次请求,我们来解释一下幂等的概念:任意多次执行所产生的影响均与一次执行的影响相同。按照这个含义,最终的含义就是 对数据库的影响只能是一次性的,不能重复处理。如何保证其幂等性,通常有以下手段: 1、数据库建立唯一性索引,可以保证最终插入数据库的只有一条数据。 2、token机制,每次接口请求前先获取一个token,然后再下次请求的时候在请求的header体中加上这个token,后台进行验证,如果验证通过删除token,下次请求再次判断token。 3、悲观锁或者乐观锁,悲观锁可以保证每次for update的时候其他sql无法update数据(在数据库引擎是innodb的时候,select的条件必须是唯一索引,防止锁全表) 4、先查询后判断,首先通过查询数据库是否存在数据,如果存在证明已经请求过了,直接拒绝该请求,如果没有存在,就证明是第一次进来,直接放行。 为什么要防止接口重复提交?对于有些敏感操作接口,比如新增数据接口、付款接口,要是用户操作不当多次点击提交按钮,这些接口就会被多次请求,最后可能导致系统异常。 前端可以如何控制?前端可以通过js进行控制,当用户点击提交按钮,1.按钮设置多少秒内不可点击状态2.按钮点击后弹出loading提示框,避免再次点击,直到接口请求返回后3.按钮点击后跳转到新的页面 但是,请记住,永远不要相信用户的行为,因为你不知道用户会做哪些奇葩的操作,所以,最重要的还是要在后端处理。 使用aop+redis进行拦截处理一.创建切面类RepeatSubmitAspect实现过程:接口请求后,token+请求路径作为key值去redis中读取数据,若能找到这个key,则证明是重复提交的,反之不是。若不是重复提交,则直接放行,并将这个key写入redis中,并设置一定时间过期(我这里是设置的5s过期) 在传统的web项目中,为了防止重复提交,通常做法是:后端生成唯一的提交令牌(uuid),存储在服务端,页面在发起请求时,携带次令牌,后端验证请求后删除令牌,保证请求的唯一性。但是,上诉的做法是需要前后端都需要进行改动,如果在项目初期,是可以实现的,但是,在项目的后期,很多功能都实现好了,不可能大范围的去改动。 思路1.自定义注解@NoRepeatSubmit 标记所有Controller中提交的请求2.通过AOP对所有标记了@NoRepeatSubmit 的方法进行拦截3.在业务方法执行前,获取当前用户的token或者JSessionId+当前请求地址,作为一个唯一的key,去获取redis分布式锁,如果此时并发获取,只有一个线程能获取到。4.业务执行后,释放锁 关于Redis分布式锁使用Redis是为了在负载均衡部署,如果是单机的项目可以使用一个本地线程安全的Cache替代Redis 代码自定义注解  import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /**  * @ClassName NoRepeatSubmit  * @Description 这里描述  * @Author admin…
2025-05-10 阅读全文 →
FWQ
服务器教程
Redis单机安装和哨兵模式集群安装的实现
Redis单机安装和哨兵模式集群安装的实现 收藏 本篇文章给大家分享《Redis单机安装和哨兵模式集群安装的实现》,覆盖了数据库的常见基础知识,其实一个语言的全部知识点一篇文章是不可能说完的,但希望通过这些问题,让读者对自己的掌握程度有一定的认识(B 数),从而弥补自己的不足,更好的掌握它。 前言: 本文使用的是操作系统为:linux centos7 本文使用的Redis版本为:redis-5.0.13 其他系统或者版本也可以按照以下步骤安装 1、Redis单机版安装 1.1:下载安装包 官网地址: 下载地址为: cd /usr/local/src/ wget https://download.redis.io/releases/redis-5.0.13.tar.gz 看到redis-5.0.13.tar.gz 文件就说明下载成功了 1.2:解压安装包 tar -zxvf redis-5.0.13.tar.gz 解压完成后进入解压后的文件夹会看到如下的文件内容  cd redis-5.0.13 ll -rw-rw-r--.…
2025-05-10 阅读全文 →
FWQ
服务器教程
如何使用Redis实现分布式计数器
如何使用Redis实现分布式计数器 一分耕耘,一分收获!既然打开了这篇文章《如何使用Redis实现分布式计数器》,就坚持看下去吧!文中内容包含等等知识点…希望你能在阅读本文后,能真真实实学到知识或者帮你解决心中的疑惑,也欢迎大佬或者新人朋友们多留言评论,多给建议!谢谢! Redis是一种高性能的缓存数据库,被广泛应用于Web应用程序中。其中,一种常用的场景是使用Redis实现分布式计数器。在本文中,我们将介绍如何使用Redis实现分布式计数器,并提供具体的代码示例。 一、什么是分布式计数器? 分布式计数器是一种用于计数的共享资源,其特点在于被多个客户端同时访问。在传统的单机环境下,计数器可以通过简单的变量或文件实现。但在分布式环境中,需要考虑多个客户端同时访问的情况。在这种情况下,如果仅使用本地变量或文件,会出现多个客户端同时更新的情况,可能导致计数器的不一致性。 二、如何使用Redis实现分布式计数器? Redis提供了一种原子性操作——INCR,该操作可以在Redis中操作计数器,并保证计数器的一致性。在Redis中,可以使用INCR命令来实现分布式计数器。INCR命令具有原子性,即多个客户端同时调用INCR命令,每次调用会使计数器的值增加1,并返回增加后的值。INCR命令的执行过程如下: 1、检查计数器是否存在,如果不存在则将其初始化为0 2、将计数器的值加1 3、返回计数器的值 在使用INCR命令时,需要注意以下两点: 1、计数器的初始值应为0,否则第一次调用INCR命令将无法获得正确结果 2、对于较长时间不使用的计数器,可以使用EXPIRE命令设置过期时间,以避免占用过多的内存资源。 接下来,我们将提供一个具体的代码示例来介绍如何使用Redis实现分布式计数器。 三、代码示例 以下是一个使用Redis实现分布式计数器的Python代码示例: import redis # 连接Redis数据库 r = redis.StrictRedis(host='localhost', port=6379) # 定义计数器的关键字 counter_key =…
2025-05-10 阅读全文 →
FWQ
服务器教程
使用Redis和Swift开发可靠的数据同步应用
使用Redis和Swift开发可靠的数据同步应用 来到golang学习网的大家,相信都是编程学习爱好者,希望在这里学习数据库相关编程知识。下面本篇文章就来带大家聊聊《使用Redis和Swift开发可靠的数据同步应用》,介绍一下,希望对大家的知识积累有所帮助,助力实战开发! 使用Redis和Swift开发可靠的数据同步应用 引言:在现代软件开发领域中,数据的同步和共享是非常重要的。特别是在移动应用和分布式系统中,确保数据一致性和可靠性是一项挑战性的任务。本文将介绍如何使用Redis和Swift开发一个可靠的数据同步应用,并提供相应的代码示例。 一、Redis简介Redis是一个开源的基于内存的键值存储数据库。它以其高性能和灵活的数据结构而著称,并提供了多种功能,如缓存、排行榜、消息队列等。在数据同步应用中,Redis可以作为一个中心化的数据存储服务,并提供强大的持久化支持。 二、Swift简介Swift是一种用于开发iOS、macOS、watchOS和tvOS应用程序的编程语言。它具有面向对象的特性,并集成了现代编程语言的一些最佳实践。在本文中,我们将使用Swift来编写数据同步应用的客户端。 三、数据同步应用示例在本文中,我们将开发一个简单的数据同步应用示例,用于在多个设备之间同步笔记。 1.安装和配置Redis首先,需要在开发环境中安装和配置Redis。可以从Redis官方网站下载源代码,并按照说明进行编译和安装。安装完成后,启动Redis服务器并确保其正常运行。 2.创建数据模型在Swift中,我们首先需要创建一个数据模型来表示笔记。可以使用以下代码示例: struct Note { var id: Int var title: String var content: String } 3.连接到Redis在Swift中,可以使用第三方库来连接和操作Redis服务器。在本示例中,我们将使用SwiftRedis库。可以通过使用CocoaPods或手动下载库的源代码来添加它。 要连接到Redis服务器,可以使用以下代码示例: import SwiftRedis let redis…
2025-05-10 阅读全文 →
FWQ
服务器教程
详解RedisTemplate下Redis分布式锁引发的系列问题
详解RedisTemplate下Redis分布式锁引发的系列问题 收藏 IT行业相对于一般传统行业,发展更新速度更快,一旦停止了学习,很快就会被行业所淘汰。所以我们需要踏踏实实的不断学习,精进自己的技术,尤其是初学者。今天golang学习网给大家整理了《详解RedisTemplate下Redis分布式锁引发的系列问题》,聊聊分布式锁、RedisTemplate,我们一起来看看吧!       自己的项目因为会一直抓取某些信息,但是本地会和线上经常一起跑,造成冲突。这其实就是我们常说的分布式集群的问题了,本地和线上的服务器构成了集群以及QPS为2的小并发(其实也不叫并发,不知道拿什么词形容?)。      首先,分布式集群的问题大家都知道,会造成数据库的插入重复问题,会造成一系列的并发性问题。      解决的方式呢也大概如下几点,百度以及谷歌上都能搜到的解决方式:      1:数据库添加唯一索引      2:设计接口幂等性      3:依靠中间件使用分布式锁,而分布式锁又分为Redis和Zookeeper     由于Zookeeper我没怎么接触过,并且我项目中本来就引用了Redis,所以就想着用Redis来做分布式锁,也高端洋气上档次点。     首先基于Redis的操作,我们必须要保证其原子性,也就是要么全部成功,要么全部失败,先从Redis的客户端入手。    …
2025-05-10 阅读全文 →
FWQ
服务器教程
Redis缓存穿透处理:原因及解决方案
Redis缓存穿透处理:原因及解决方案 大家好,今天本人给大家带来文章《Redis缓存穿透处理:原因及解决方案》,文中内容主要涉及到,如果你对数据库方面的知识点感兴趣,那就请各位朋友继续看下去吧~希望能真正帮到你们,谢谢! Redis缓存穿透指的是一个恶意用户或攻击者通过发送大量的无效查询来绕过缓存,直接访问数据库的情况。当一个请求查询一个不存在于缓存中的数据时,Redis会将请求发送给数据库进行查询,此时如果查询条件不合法,数据库会返回空的查询结果,但因为大量无效查询压力的存在,数据库会使用太多的资源来处理这些查询,造成系统性能瓶颈。 造成Redis缓存穿透的原因有很多,比如查询无效的条件、大量的恶意请求和缓存失效等。为了解决这个问题,我们需要采取一些措施,包括但不限于以下几点: Bloom Filter过滤器 Bloom Filter是一个典型的概率型数据结构,它可以用于处理海量数据的集合查询问题,同时它不需要存储所有的元素,可以节省空间。在Redis中,我们可以使用Bloom Filter过滤器来快速地检查一个Key是否存在于缓存中。如果这个Key不存在于Bloom Filter中,Redis就不会去查询数据库,从而避免了缓存穿透问题。 建立缓存空值信息 当Redis在数据库中查询一个Key对应的数据不存在时,我们可以选择将这个信息存储到Redis中,而不是直接返回空值。这样当再次查询这个Key时,就可以快速地判断这个Key对应的数据不存在于缓存中。这项技术称为“缓存空值”。 设置缓存过期时间 缓存的过期时间是一个重要的概念,如果我们设置的过期时间太短,就会使缓存的效果变得不够明显;如果设置的过期时间太长,又会导致缓存中的数据不够实时。所以我们需要根据不同的业务场景设置合适的过期时间。另外,当缓存的过期时间到期时,Redis会自动将这个Key从缓存中删除,从而保证缓存的可靠性。 热点数据预热 在系统运行的初始阶段,我们可以通过一些手段预先把最常访问的数据加载到缓存中,这样可以减轻系统负载压力,并且避免缓存穿透问题的发生。这个过程称为“热点数据预热”。 总结起来,为了解决Redis缓存穿透问题,我们需要采用多种策略和手段,包括过滤器技术、缓存空值、缓存过期时间和热点数据预热等方法,从而确保缓存的可靠性和系统性能。 Golang学习之基于Liferay的Web应用程序开发 助力文博艺术数字化,上海将打造文旅元宇宙新赛道
2025-05-10 阅读全文 →
FWQ
服务器教程
如何优雅地使用Redis之位图操作
如何优雅地使用Redis之位图操作 收藏 本篇文章向大家介绍《如何优雅地使用Redis之位图操作》,主要包括操作、Redis、位图,具有一定的参考价值,需要的朋友可以参考一下。  在进入今天的主题前,先简单地解释下Redis中的位图到底是什么。Redis官方文档对于位图的介绍如下: 位图不是一个真实的数据类型,而是定义在字符串类型上的面向位的操作的集合。由于字符串类型是二进制安全的二进制大对象,并且***长度是 512MB,适合于设置 2^32个不同的位。 位操作分为两组:常量时间单个位的操作,像设置一个位为 1 或者 0,或者获取该位的值。对一组位的操作,例如计算指定范围位的置位数量。 位图的***优势是有时是一种非常显著的节省空间来存储信息的方式。例如,在一个系统中,不同用户由递增的用户 ID 来表示,可以使用 512MB 的内存来表示 400 万用户的单个位信息(例如他们是否需要接收信件)。  简而言之,位图操作是用来操作比特位的,其优点是节省内存空间。为什么可以节省内存空间呢?假如我们需要存储100万个用户的登录状态,使用位图的话最少只需要100万个比特位(比特位1表示登录,比特位0表示未登录)就可以存储了,而如果以字符串的形式存储,比如说以userId为key,是否登录(字符串“1”表示登录,字符串“0”表示未登录)为value进行存储的话,就需要存储100万个字符串了,相比之下使用位图存储占用的空间要小得多,这就是位图存储的优势。 位图常用操作 位图的常用操作如下: setbit 设置特定key对应的比特位的值。 getbit 获取特定key对应的比特位的值。 bitcount 统计给定key对应的字符串比特位为1的数量。 使用位图存储用户登录状态…
2025-05-10 阅读全文 →