我們給專案換了個編碼

2021-10-23 01:11:21 字數 1911 閱讀 2567

經過多次的摸索和測試,終於把我們的乙個gbk編碼web專案大致成功轉到了utf-8編碼。之所以沒有實現完美轉換,也是因為這兩種編碼本質上還是有區別的,有部分資料覆蓋不到的地方,確實沒辦法處理。這裡簡單總結下我們的辛路手術歷程,供有需要的人參考。

下面我依次來總結下各個方面的處理:

穩住之前的記錄

要說什麼是最重要的東西,當然是客戶資料。無數血的教訓,警示我們客戶資料一定要保證安全準確。我們的資料主要**mysql, mongodb,es,memcached,redis等,其中mongodb,es,redis資料基本上都是utf-8編碼,所以不需要特殊處理,需要處理的是mysql 和memcached。由於mysql資料量巨大,且不容易在很短的時間內準確無誤的轉換完畢,所以本階段保持了mysql資料編碼不變。memcached的資料型別複雜,字串、陣列、序列化資料,全部遍歷並轉換,也不太現實。故針對這兩個資料來源採取了相容處理,即讀取gbk->utf-8,mysql寫入utf-8 -> gbk,memcached資料寫入更新成utf-8編碼。即增加了乙個中間**層,負責統一轉碼處理。

檔案轉碼

專案檔案編碼轉換相對較容易,iconv和enca都可以,這裡我推薦使用enca,簡單,方便,自動檢測編碼,不需要單獨寫指令碼處理。

例如: 單獨對檔案轉碼的話可以執行:enca -l chinese -x utf-8 file

如需要對目錄遞迴轉碼的話可以執行:find . -type f | xargs -i {} enca -l zh_cn -x utf-8 {}

資料驅動層相容

資料不變的話,只能在驅動層和**層操作轉碼了,mysql那邊做了讀寫轉碼,memcached那邊做了讀取轉碼,寫入更新。mongodb取消了以前轉碼邏輯。es和redis沒動。

處理業務呼叫邏輯

改動較多的是專案**,凡是涉及到轉碼相關函式的地方,都需要原樣返回,很多時候是遞迴操作,所以這裡寫了乙個指令碼,正則轉碼函式,並替換。當然也不是萬能的,有幾個檔案寫法特殊的,是手動修改的。

api相容處理

由於我們的各版本客戶端使用者多達百萬,api介面的輸入、輸出格式和結果不變,必須準確無誤。最早端的介面資料要求gbk,這裡輸入的地方,由於涉及底層改動,本著最小化影響的原則,跟web做了標識區分,檢測資料**是端的,進行轉碼。輸出的地方,重點說下base64編碼
雖然我們對資料邏輯做了可靠性推理和測試驗證,灰度和線上切換的時候,還是遇到了部分資料讀取異常和資料缺失的問題。這裡主要說下

unserialize資料、帶中文key的資料坑。灰度測試的時候,發現memcached資料部分沒讀取出來,檢視了錯誤日誌,發現存在中文key的情況,開始的轉碼邏輯並沒有對中文key做處理,增加之後恢復正常。也有部分序列化的資料解析失敗,檢查日誌發現,不同編碼下的中文長度不一致,導致了序列化解析失敗,於是寫了相容解序列化的方法,替換了全域性函式。還有些是強型別問題帶來的,比如mongodb資料,這裡主要也是以前封裝的方法有些問題。好在都有備份,找到問題之後及時處理了。後來又有部分亂碼的,分析之後發現由於檢測達不到十分準確,存在二次轉碼的問題,又進行了轉碼標記。

在灰度跑了2周之後,我們終於決定在周五晚上10點上了預發布,啟動區域性客戶更新,但是效果並不理想。主要是問題是部分客戶資料複雜,非常慢。部分介面響應時長達到了20多s,抓包分析之後,發現統一轉碼遞迴的次數太多。部分存在二次呼叫;cache層由於轉碼,失去了加速效果等。隨後進行了效能優化,響應時長恢復正常。

看不懂的**不要隨便動。

經驗主義也會害死人。

寫的複雜並不代表效能一定差。

新專案一定要想清楚透徹,千萬不要為了一時快,毀了下一代。

【完】

給新手的 11 個 Docker 免費上手專案

docker 是乙個開源的應用容器引擎,讓開發者可以打包他們的應用以及依賴包到乙個可移植的映象中,然後發布到任何流行的 linux或windows 機器上,也可以實現虛擬化。容器是完全使用沙箱機制,相互之間不會有任何介面。給新手們推薦12個極易上手的docker實踐專案 spug ctop dron...

專案管理 為什麼我們需要乙個需求文件

需求文件,簡單來說,它應包括編寫為客戶所接受的產品或服務時需要知道的所有東西而已。在專案開始設計之前,我們都通常都先整理,撰寫乙個需求文件來描述專案具有哪些功能和服務。那麼為什麼我們需要乙個需求文件呢?l我們需要乙個地方記錄使用者為我們描述的期望的系統行為,需要乙個使用者或他的 人能評審的文件。l我...

如何給別人介紹乙個你做過的專案

很多時候別人會問你在做什麼專案,聊天的時候,面試的時候等等,如何能夠有條理的介紹呢?我覺得可以從如下幾方面入手 專案的意義是什麼,為什麼很重要,具體的目的是要完成哪些東西,達到什麼樣的效果 做技術的,當然還是要說技術,從架構說起,大概分那幾部分,每個部分完成什麼樣的功能,技術上選擇的語言,平台,通訊...