使用 redis-cli --raw 并配合终端 utf-8 编码(如 windows 执行 chcp 65001)可使订阅中文正常显示;根本原因是 redis-cli 默认以原始字节输出,需终端正确解码 utf-8,而非 redis 服务端配置问题。

redis-cli 订阅时中文显示为 \xc2\xa9 这类字节序列
这不是 Redis 服务端的问题,而是 redis-cli 默认以原始字节流方式输出消息,没做 UTF-8 解码。你看到的 \xc2\xa9 是 UTF-8 编码的某个中文字符(比如“©”或误解析的汉字)在非解码模式下的十六进制表示。
解决方法非常直接:强制 redis-cli 用 UTF-8 解码输出。
- 订阅前先执行
chcp 65001(Windows 控制台切换到 UTF-8 编码) - 然后启动带
--raw的客户端:redis-cli --raw - 再执行
subscribe topic1,此时收到的中文就能正常显示
注意:--raw 不是“关闭转义”,而是让 redis-cli 把服务端发来的字节原样交给终端——前提是终端自己能正确渲染 UTF-8。
Java Jedis 发布中文后,Node.js redis 客户端收不到可读中文
根本原因是两端对字节流的解释不一致:Jedis 默认用平台默认编码(如 Windows 上是 GBK)把字符串转成字节;而 Node.js 的 redis 库默认按 UTF-8 解码字节流,导致错位。
必须统一为 UTF-8 编码路径:
- Jedis 发布前显式编码:
jedis.publish("topic1", "你好".getBytes(StandardCharsets.UTF_8)) - Node.js 订阅时确保接收为 Buffer,再手动
toString('utf8'):client.on('message', (channel, message) => console.log(message.toString('utf8'))) - 避免用
client.get()那套自动字符串转换逻辑处理 pub/sub 消息——它不可控
别依赖 new String(bytes) 这种无参构造,它会调用系统默认编码,跨平台必翻车。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
Python redis-py 中 subscribe 收到 bytes 但 decode('utf-8') 报 UnicodeDecodeError
报错说明消息里混入了非法 UTF-8 字节序列,常见于:上游发布方用了 GBK 编码存入、或中间有二进制数据污染、或日志拼接时插入了控制字符。
稳妥做法不是硬解,而是防御性处理:
- 用
message.decode('utf-8', errors='replace')替换异常字节(显示 ) - 或更严格地先校验:
if message.isascii(): ... else: message.decode('utf-8', errors='ignore') - 发布端务必统一:
r.publish('topic1', '订单已发货'.encode('utf-8'))—— 显式 encode,不靠库自动转换
redis-py 的 decode_responses=True 对 pub/sub 无效,它只影响 get/set 等命令,这点容易被忽略。
为什么改 redis.conf 的 charset 或 client_encoding 没用
因为 Redis 本身是二进制安全的,redis.conf 里根本没有 charset、client_encoding 这类配置项——所有网上说要加这两行的教程都是错的,Redis 官方配置项中从未定义过它们。
真正起作用的是:
- 客户端连接时的终端编码(
chcp 65001/export LANG=en_US.UTF-8) - 客户端库发送前的字节编码(
.encode('utf-8')) - 客户端库接收后的字节解码(
.decode('utf-8')) - pub/sub 协议本身不携带编码信息,全靠两端约定
所以问题永远出在链路某一段的编码/解码缺失或错配,而不是 Redis 服务端需要“设置字符集”。










