前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >捉“虫”记:Wireshark在手,Redis我有

捉“虫”记:Wireshark在手,Redis我有

作者头像
烟雨平生
发布2023-03-07 14:29:58
6380
发布2023-03-07 14:29:58
举报
文章被收录于专栏:数字化之路数字化之路
蓝海原来是真的 问题: 使用Java Redis客户端 stringRedisTemplate将数据存放到 Redis后,使用 redisTemplate却取不出来 !!!??? 原因: Java Redis客户端在将数据存放在Redis时,会对key,value,field进行编码。从Redis中取数据时,如果key、field的编码和存放时不一样,就会取不出来。 就像中文乱码一样,同样的中文字符串,存放时使用不同的编码,编码后的字符串之间就不equals了。 解决办法: 存取Redis中的数据时,发送的指令要使用相同的Serializer进行序列化/反序列化

问题复盘及分析过程:

  1. 问题描述:

(1)使用下面代码将数据放到 Redis服务器

代码语言:javascript
复制
stringRedisTemplate.opsForHash().put("CATALOG_DEV","KEY_INDEX_CATALOG",list);

(2)使用方式1,可以 HGET到的value和存放时的一致:

代码语言:javascript
复制
stringRedisTemplate.opsForHash().get("CATALOG_DEV","KEY_INDEX_CATALOG")

(3)使用方式2HGET得到的value是nulll:

代码语言:javascript
复制
redisTemplate.opsForHash().get("CATALOG_DEV","KEY_INDEX_CATALOG")

2. 抓包分析 使用Wireshark抓包: 方式1时, HGET命令发送到 Redis服务器的指令:

方式2时, HGET命令发送到 Redis服务器的指令:

由上可见,虽然代码中, Redis的Java客户端发送的key和field都是相同的字符串,但 Redis收到的field却是不同的。

3. 看看 Redis服务器上存放的field是什么样的:

再来看一个使用 redisTemplate客户端存放的数据:

对比看下方式1存放到 Redis服务器上的数据

为什么有这个差异呢?来看看 Spring容器中的 stringRedisTemplateredisTemplate实例有什么区别: RedisTemplate的实例化代码如下:

代码语言:javascript
复制
    @Bean
    @SuppressWarnings({"rawtypes", "unchecked"})
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 设置value的序列化采用Jackson2JsonRedisSerializer
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // 设置key的序列化采用StringRedisSerializer
        template.setKeySerializer(stringSerializer);
//        template.setHashKeySerializer(stringSerializer);
//        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

HashKeySerializerHashValueSerializer没有指定,应该会使用默认的Serializer, 如下图所示:

StringRedisTemplate的实例化代码如下:

代码语言:javascript
复制
@Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

可以看到, HashKeySerializerHashValueSerializer都使用了 StringRedisSerializer,与上面的情况一致。O了

扩展:

1. WireShark抓Redis包的利器: https://github.com/jzwinck/redis-wireshark

上面用到的lua plugin已经上传到baidu网盘:

链接:https://pan.baidu.com/s/1M9tXDN54FODU7NftkLfwKQ 提取码:kzhc

2. 查看WireShark插件配置目录及已经配置插件的信息:

lua插件需要copy到的目录: 帮助--》关于--》文件夹--》Personal configuration

已经安装的插件列表:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 的数字化之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档