指路牌
- RedisJSON 中文編碼問(wèn)題
- Java RedisJSON - JReJSON 中文編碼問(wèn)題
背景
Redis本身是不支持的Json格式的,而JSON又一個(gè)當(dāng)下非常常見的數(shù)據(jù)類型口柳,當(dāng)下常規(guī)的解決方案是使用redis4.0之后推出的modules模塊系統(tǒng)來(lái)集成rejson捻勉,讓redis支持json格式,這是通過(guò)搜索引擎找到的大部分解決方案揍堰,但是親身實(shí)踐后發(fā)現(xiàn),這并不是一個(gè)適合“初學(xué)者”的解決發(fā)方案,尤其是已經(jīng)使用apt等工具已經(jīng)安裝了redis的情形秕狰,環(huán)境清理不干凈,更不要提二進(jìn)制包配置與安裝躁染,這個(gè)時(shí)候怎么才能夠簡(jiǎn)單快速獲得一個(gè)支持json格式的redis呢鸣哀?
答案就是,拉一個(gè)已經(jīng)繼承好模塊的docker image......
這是我目前發(fā)現(xiàn)的最快速吞彤,做簡(jiǎn)單我衬,最友好的讓redis支持json的當(dāng)時(shí),而本次blog解決問(wèn)題,也是在這個(gè)前提下的低飒。
redisLabs
首先貼上兩個(gè)鏈接
- Redis Lab官網(wǎng)地址
Redis Labs - 打包好的支持json格式的Redis在Docker Hub的地址许昨,打開后里面有基礎(chǔ)教程以及不同語(yǔ)言的客戶端使用鏈接
Redislabs/rejson
問(wèn)題分析
回到問(wèn)題本身,首先介紹一下項(xiàng)目基本技術(shù)選型褥赊,數(shù)據(jù)庫(kù)為redis糕档,后臺(tái)為SpringBoot
本次問(wèn)題的發(fā)現(xiàn)由于項(xiàng)目中同事在測(cè)試時(shí)輸入中文出現(xiàn)的,問(wèn)題的初始癥狀是Springboot報(bào)數(shù)據(jù)庫(kù)連接超時(shí)拌喉,初步排查發(fā)現(xiàn)是由于數(shù)據(jù)庫(kù)某字段長(zhǎng)度過(guò)長(zhǎng)(由于過(guò)長(zhǎng)客戶端在使用JSON.GET獲取該數(shù)據(jù)后直接崩潰了)速那,導(dǎo)致讀取時(shí)間過(guò)長(zhǎng),導(dǎo)致數(shù)據(jù)庫(kù)連接超時(shí)尿背,而后臺(tái)幾數(shù)據(jù)庫(kù)本身端仰,都沒(méi)有出現(xiàn)崩潰的情況。
經(jīng)詢問(wèn)得知田藐,同事測(cè)試時(shí)荔烧,只是輸入了十幾個(gè)中文字符,而數(shù)據(jù)庫(kù)內(nèi)的汽久,字段長(zhǎng)度明顯不符鹤竭,而且字段為亂碼并非中文。
字段無(wú)故變得異常長(zhǎng)的問(wèn)題暫時(shí)沒(méi)有找到原因景醇,暫未復(fù)現(xiàn)臀稚,暫未解決
集中到中文亂碼這條分支,首先在通過(guò)本地調(diào)試排除掉了Springboot引起的亂碼問(wèn)題三痰,確認(rèn)寫入redis的編碼格式是沒(méi)有問(wèn)題的吧寺,再將問(wèn)題鎖定在Redis內(nèi)
打開redis-cli,簡(jiǎn)單復(fù)現(xiàn)復(fù)現(xiàn)一下情形
127.0.0.1:6379> JSON.Set test . '{"test":"測(cè)試"}'
OK
127.0.0.1:6379> JSON.GET test
"{\"test\":\"\\u00e6\\u00b5\\u008b\\u00e8\\u00af\\u0095\"}"
解決方案
經(jīng)過(guò)查詢散劫,在RedisJson的github issue找到了一個(gè)國(guó)內(nèi)開發(fā)者在2017年9月11日創(chuàng)建的issue 35, 里面有問(wèn)題描述稚机,以及解決方案“NOESCAPE”
使用格式如下:
127.0.0.1:6379> JSON.GET test NOESCAPE
"{\"test\":\"\xe6\xb5\x8b\xe8\xaf\x95\"}"
然后,如何在Springboot使用呢获搏?
issue內(nèi)沒(méi)有詳細(xì)的描述該問(wèn)題如何在各客戶端內(nèi)使用(實(shí)際上有人提到了赖条,只是一開始沒(méi)理解),此處補(bǔ)充如下:
JReJSON redisClient = new JReJSON(redisHost, redisPort);
// redisClient.get(key, new Path(".")); 此條語(yǔ)句或出現(xiàn)編碼問(wèn)題
redisClient.get(key, new Path("NOESCAPE"));