当前位置: 首页 > news >正文

上海国际网站建设电脑版传奇排行榜

上海国际网站建设,电脑版传奇排行榜,家装设计能自学吗,ppt模板免费下载图片文章目录 执行Lua脚本后一直查询不到Redis中的数据#xff08;附带详细问题排查过程#xff0c;一波三折#xff09;问题背景问题1#xff1a;Lua脚本无法切库问题2#xff1a;RedisTemlate切库报错问题3#xff1a;序列化导致数据不一致问题4#xff1a;Lua脚本中单引号… 文章目录 执行Lua脚本后一直查询不到Redis中的数据附带详细问题排查过程一波三折问题背景问题1Lua脚本无法切库问题2RedisTemlate切库报错问题3序列化导致数据不一致问题4Lua脚本中单引号无法拼接字符串总结 执行Lua脚本后一直查询不到Redis中的数据附带详细问题排查过程一波三折 这个问题坑惨我了估计耗费了我两个小时中间走了不少弯路好在我灵光一闪GPT给我的灵感否则就栽在这上面了 问题背景 问题背景 在使用 Redis 实现接口调用次数扣减操作时发现响应结果一直返回的是 -1也就是查询不到数据 问题1Lua脚本无法切库 问题排查过程1 经过一段排查加上GPT的提示信息我快速定位到了是可能是参数的问题但是通过 Debug 断点调试我可以百分百肯定这个参数肯定没有问题然后我又到 redis-cli 执行原生的 Redis 指令发现也查不到数据(○´д)懵逼了捣鼓了半天突然想起来有没有可能是这个数据库中压根没有数据于是我使用 keys *指令查看数据库中是否有数据结果发现有数据但是压根就没有我预热的数据这是什么原因呢一看 REP 就恍然大悟了我操作的数据库1但是由于我配置文件中使用的是数据库 0导致我预热的数据 都在 数据库1中而 Lua脚本默认操作的数据库0那么问题就简单了直接使用 redis(select,1)这条指令切换一下数据库不久OK了吗我真聪明然后我先在redis-cli上实验发现的确是这个的原因嘿嘿问题成功解决了你不会以为这就完了吧 问题原因Lua脚本默认使用的数据库0我的数据在数据库1中 问题解决 在执行Lua脚本前先切换一下数据库 redis(SELECT, 1)结果发现在 Lua 脚本中添加了redis(SELECT, 1)之后压根就没有用┭┮﹏┭┮ 只能继续排查问题 问题排查过程2 在lua脚本中查询数据前加上redis(select,1)结果发现嘿嘿还是返回-1这下彻底懵逼了结果经过询问ChartGPT发现Lua脚本不能切换数据库还是太天真了 既然Lua脚本无法完成切库那么就需要使用 RedisTemplate 进行切库 问题解决 RedisConnection connection redisTemplate.getConnectionFactory().getConnection();connection.select(1);你不会以为这么快就解决了这个问题吧 问题2RedisTemlate切库报错 问题排查过程2 redisTemplate 切库引发的新问题在添加了上面代码后结果又报错Selecting a new database not supported due to shared connection. Use separate ConnectionFactorys to work with multiple databases. 在此询问GPT发现是由于 Redis 的共享连接限制无法直接在同一个连接上切换到不同的数据库。如果你需要在执行 Lua 脚本之前切换 Redis 数据库可以尝试使用不同的连接工厂来处理多个数据库 问题解决 解决方案一直接关闭RedisTemplate的共享连接不推荐 详情请参考这篇文章Springboot整合redis切库问题 在使用 Spring Data Redis 时默认情况下是共享连接的因为这可以提高性能和效率。然而如果你确实需要关闭共享连接并为每个数据库创建一个独立的连接也是可以的。但是需要注意一些潜在的问题 性能影响共享连接可以减少连接的开销而独立连接则需要更多的资源来维护和管理。因此关闭共享连接可能会对系统的整体性能产生一定的影响。连接池限制Redis 连接池有着最大连接数的限制每个连接都占用一部分连接资源。如果为每个数据库都创建独立的连接那么连接池中可用的连接数量将被均分这可能导致每个数据库可用连接数的减少。连接管理复杂性对于每个独立的连接你需要额外管理和维护连接的生命周期包括创建、销毁、异常处理等。这可能增加代码的复杂性和维护成本。 总之关闭共享连接并为每个数据库创建独立的连接可能会带来性能和连接管理方面的一些负面影响。因此在进行决策时请权衡利弊并根据具体需求和系统规模做出选择。 解决方案二新建一个RedisTemplate 为了提高代码的复用性我就打算利用 单例模式原型模式 对IOC容器中的RedisTemplate进行一个拷贝然后将这个新的RedisTemplate来切库相对于方案一要更加方便 下面是代码 package com.ghp.admin.redis;import com.ghp.common.utils.BeanConvertorUtils; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.RedisTemplate;/*** author ghp* title* description*/ public class RedisUtils {private RedisTemplate redisTemplate;private static RedisUtils instance;static {instance new RedisUtils();}public RedisUtils getInstance(RedisTemplate redisTemplate){this.redisTemplate redisTemplate;return instance;}/*** 创建一个新的RedisTemplate并且切换数据库* param databaseIndex* return*/public RedisTemplateString, String createRedisTemplate(int databaseIndex) {// 进行拷贝这里是是使用自己封装的工具类你可以选择使用Spring框架自带的拷贝工具类RedisTemplate newRedisTemplate BeanConvertorUtils.copyBean(redisTemplate,RedisTemplate.class);RedisConnection connection redisTemplate.getConnectionFactory().getConnection();connection.select(databaseIndex);return newRedisTemplate;} }看上去好像已经成功解决了但是还没完经过测试发现执行 Lua 脚本后仍然无法从Redis中查询到数据库w(Д)w 这些我又陷入了懵逼中 问题3序列化导致数据不一致 问题排查过程3 我开始陷入怀疑当中因为我在 redis-cli 中经过切库后发现执行指令是可以查询到数据的难道是切库失败了经过检验发现切库是成功的因为我在 Lua 脚本中执行硬编码local leftNum redis.call(HGET, cache:interface:pathMethod:, /api/name/user-POST) 是的的确确查询到了数据的 我开始怀疑是不是我参数传递错了但是经过 return leftNum发现是有数据的而且数据是真确的这是什么原因呢 虽然返回结果是一样的可能不可能Lua脚本中的值不一样呢我继续抱着试一试的态度执行下面的代码 local key1 KEYS[1] if key1 /api/name/user thenreturn 1 end return 2结果意料之外的居然返回了 2也就是说我 传入了 ’/api/name/user‘然后从 Lua 中 返回的是 ’/api/name/user‘但是 Lua 中两个值竟然不相等 我开始怀疑难道是编码的问题吗因为之前在看微信公众号上的一篇文章有个大佬就是因为编码全角和半角的问题导致查询不到数据于是我抱着试一试的心态测试了一下编码有看了一下编译器使用的编码格式发现是全局 UTF-8 所以可以排除编码问题了那会是什么原因呢百思不得其解突然灵光一闪会不会是序列化的问题我全局为RedisTemplate配置了序列化转换器但是我还是不敢相信因为我在Lua脚本中返回的 retrun ARGV[1]和我查询使用的 key也就是/api/name/user是一摸一样的 发现仍然照样没有查询到数据在 Lua 脚本中返回 pathJson发现是\/api/name/user\这一下又给了灵感会不会是传入的JSON多了有个\于是我做出如下实验 local key1 KEYS[1] if key1 \/api/name/user\ thenreturn 1 end return 2惊奇的发现这回终于返回 1也就是说传入的 path 是 竟然是 \/api/name/user\结果很震惊因为之前我在Lua脚本中返回path时结果就是/api/name/user返回的结果根本没有我猜测应该是RedisTemplate在处理Lua的返回结果时会多做一层序列化登录参数的传递过程中需要经过一层序列化至此问题终于解决了你不会以为这就成功解决了吧 解决方案 在接收参数后进行预处理也就是去掉传入参数中多余的 ” local key1 string.gsub(KEYS[1], \, ) -- cache:interface:pathMethod: local key2 string.gsub(KEYS[2], \, ) -- cache:interface:leftNum: -- 获取hashKey local path string.gsub(ARGV[1], \, ) local method string.gsub(ARGV[2], \, ) local userId string.gsub(ARGV[3], \, )问题4Lua脚本中单引号无法拼接字符串 问题排查4 后面我改造了代码发现仍然不成功 ┭┮﹏┭┮ 经过测试我发现 local key1 path .. - .. method return key1发现只会返回 -前面的字符串 也就是 path如果调换path和method的未知那么只会返回method我又陷入了沉思。 后面我突然想起来了是Lua中双引号和单引号的区别使用 .. 运算符可以用来拼接字符串。这个运算符可以连接两个字符串或者将其他数据类型转换为字符串后连接。然而.. 运算符只能用于连接双引号字符串。单引号字符串在 Lua 中表示字符而不是字符串。如果你试图使用 .. 运算符连接两个单引号字符串会得到一个语法错误。 解决方法 local key1 tostring(path) .. - .. tostring(method) return key1成功解决了。如果你对Lua感兴趣的可以参考这篇文章Lua快速入门笔记_知识汲取者的博客-CSDN博客 总结 终于解决了这个问题感觉好舒爽 总的来说我遇到的问题是 Java 代码使用 RedisTemplate.execute 执行 Lua脚本的时候由于我配置了全局序列化所以导致 传入Lua脚本中的参数 会先被序列化而Lua脚本的参数被传出来时同样会被反序列化这个序列化和反序列化对我而言是透明的所以导致我没有想到居然序列化了一遍从而导致我走了好多弯路 这里提一嘴前面那个Lua脚本默认使用数据库 0不完全正确如果我们在配置文件中配置了使用哪一个数据库那么在Lua脚本中就会使用哪一个数据库所以我们可以不用切库也能保障 Lua脚本能够操作数据库1所以前面的 问题1 和 问题2 不需要根本原因在于序列化和反序列化问题 参考资料 ChartGPT3.5Springboot整合redis切库问题
http://www.tj-hxxt.cn/news/222893.html

相关文章:

  • 淘宝客网站主题模版手机网站 触屏
  • 网站建设单元格边距网上平面设计
  • 网站通常用什么编程做宝山青岛网站建设
  • 怎么让网站被收录为什么别的电脑能打开的网站我的电脑打不开
  • 重庆家居网站制作公司wordpress钢琴导航
  • 网站建设贰金手指科捷9wordpress4.8.3下载
  • 网站建设的主要工作网站建设合同 模板 下载
  • 架设网站费用网站排名是怎么做
  • 网站建设和管理专业大连企业网站制作
  • 网站建设丶金手指花总12wordpress没法登陆
  • 企业检索网站建设青岛seo公司网站
  • 佛山新网站制作机构温州谷歌优化公司
  • 手机网站自适应屏幕为什么现在建设银行要下载网站激活
  • seo建站推广wordpress 建站容易吗
  • 网站建设售后莆田网站建设方案优化
  • 大渡口网站建设哪家好wordpress 站长
  • 做社群的网站有哪些土特产网站建设状况
  • 织梦pc怎么做手机网站长沙装修公司性价比最高的是哪个
  • 郑州网站推广多少钱网站建设中的注册和登录页面
  • 郑州建网站的公司gps建站教程
  • 校园网站建设报价阿里 wordpress插件
  • 北京哪家做网站好如何避免网站被攻击
  • 做推广任务的网站有哪些快速做网站公司
  • 做网站怎么拿框架的原代码网站系统解决方案
  • 网站营销策划公司网站排序
  • 聊城建设路小学网站wordpress 4.8.6
  • 酒厂网站源码工作时做网站使用软件
  • go语言有啥好的网站开发框架汕头企业建站模板
  • 谢岗网站建设廊坊免费推广
  • 网站如何实现微信登录界面学校网站首页设计图片