新聞中心
前言
這個問題持續(xù)了大概半個小時,最后發(fā)現竟然是我的鍋。

成都創(chuàng)新互聯公司是專業(yè)的方山網站建設公司,方山接單;提供做網站、網站制作,網頁設計,網站設計,建網站,PHP網站建設等專業(yè)做網站服務;采用PHP框架,可快速的進行方山網站開發(fā)網頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網站,專業(yè)的做網站團隊,希望更多企業(yè)前來合作!
這個事情怎么說呢,完全是我自己把自己坑了。到底怎么回事呢?
1. 從需求說起
1.1 背景
由于我們這個迭代是個大版本,上線的日子要臨近了。這次上線需要運營配合提供很多商品屬性的數據,他們需要把第三方的屬性和我方系統的屬性,在excel表格中匹配起來。
原本是這樣規(guī)劃的:由運營同學在excel表格中手動對應雙方屬性的映射關系。
但后來,他們覺得屬性太多了,如果他們人工在excel表格中對應屬性映射關系,可能時間上有點來不及。
于是,他們在某次會議上,特意給我提了需求,希望我可以通過程序幫他們在excel中,把雙方的屬性值映射上。
有一個要求就是要:快。
因為其他同事,還要基于這份excel數據,做一些后續(xù)處理。
1.2 原始需求
剛開始開會時,運營說的需求是:他們提供一個excel表格,里面有分類和屬性字段,然后讓我在程序中全匹配,把能夠匹配上的屬性編號和屬性,在excel的另外兩列中返回給他們。
然后,他們根據這份excel數據,把匹配不上的(即另外兩列為空)數據,在我們系統中手動錄入,這樣最終都能匹配上。
1.3 加戲了
本來我覺得這個需求挺簡單的。
但后來,運營加戲了(加新需求)。
其實,剛開始運營沒說完。
后來發(fā)現,他們要接入兩個廠商。
而且運營提供的兩個廠商的excel表格中字段的格式不一樣,沒法用一套程序搞定。
而且,我們發(fā)現有部分屬性中包含了一個區(qū)間范圍,跟我們系統的數據肯定是對應不上的,必須要拆分屬性后再匹配。
很顯然,運營是不愿意做這種手動拆分的工作的,這事他們想我?guī)退麄冇贸绦蛱幚?,這就給我增加了不少工作量。
此外,廠商1還有一個特殊需求:運營手動把excel中的部分數據剔除掉,然后基于這份新數據重新匹配一份新excel數據。
2. 最快的方案
了解運營的需求之后,我簡單的分析了一下。按需求的優(yōu)先級,排了一個順序:
- 導出廠商1的屬性數據。
- 導出廠商2的屬性數據。
- 給廠商1導一份特殊的屬性數據。
- 導出區(qū)間范圍能匹配上的數據。
如果這些需求都寫程序處理,可能要寫4個程序,而且還需要花時間部署代碼,我怕時間上來不及。
于是我想了一個快速處理需求1、2、3的辦法即:直接通過sql語句查詢出所需數據。
不過這套方案的前提是:需要把excel中的數據導入到生產環(huán)境中。
為了保險起見,我先把excel中的數據導入dev環(huán)境中。等我寫好sql,測試好數據之后,再導入生產環(huán)境。
使用數據庫管理工具:Navicat Premium的Import Wizard功能,可以輕松將excel表格中的數據直接導入一張新表中。
它里面可以指定excel的sheet對于哪張表,指定excel中的列對應表中哪些列。
由于這些需求都是新表,無需特別指定,我就按默認的表名和字段名導入數據了。
但有個問題就是:表名和字段名都是中文的,因為excel中的sheet名和sheet中的字段名都是中文的。
其實,我當時已經發(fā)現了這個問題。
但當時又想了想,表中字段比較多,要一一改成英文的,光起名字要花些時間。這些字段最終還是要轉換成運營可以看得懂的中文的字段名,這樣轉來轉去有點畫蛇添足,浪費時間。
而且這張表導入生產環(huán)境之后,是一張臨時表,用完了就會被刪除的,影響不大。
此外,這張表是新加的,如果沒有程序使用的話,應該是不會有問題的。
所以,當時沒多想,就找人把數據導入生產環(huán)境了。
導出數據的方法很簡單:
使用Navicat Premium的Dump SQL File中的Structure + Data即可。
這樣該數據庫工具,就會把相關表的建表的create語句,和插入數據的insert語句,導出到一個.sql后綴的文件中。
有個小問題就是:每條數據會生成一個insert語句,如果太多了放到生成環(huán)境執(zhí)行,執(zhí)行效率會比較低。
這時可以將insert腳本復制到idea或者其他的工具中打開,然后全文替換一下,去掉多余的insert,拼接成一個insert語句。
然后再用在線的sql壓縮工具,比如:https://tool.lu/sql,壓縮一下去掉多余的空格。
這樣插入數據的sql放到生產環(huán)境執(zhí)行,效率要快很多。
運營提供的excel表格中的數據,被導入生產環(huán)境之后。按計劃,通過一條sql語句,把運營所需要的結果直接查詢出來,然后把結果復制到excel表格中。(注意:如果查詢結果的數據太多,不建議這么玩)。
按上面的做法,我很快完成了需求:1、2、3,并且把運營所需要的數據及時給他們了。
3. 一個插曲
原本按計劃,導完數據之后,生產環(huán)境中臨時表是要刪除的。
但出現了一個小插曲,運營給我提了一個臨時需求:需要重新導一份廠商2的數據給他們。
他們已經按照表格中的內容,把需要添加的屬性已經添加到系統中了。需要我們重新導一份數據,確認一下,現在是否所有數據都能匹配上。
此時,我當時在慶幸幸好數據沒刪。
運營的這個臨時需求,在線上執(zhí)行相同的sql很快就把數據導出來了。
1分鐘實現需求,當時那叫一個:爽。
而且我觀察了一下,系統沒有出現異樣。
給運營把數據導完之后,我就忙其他事情去了,把刪除數據這個事情給忘了。
4. 線上出現問題
第二天上午,領導把我叫過去說:canal服務掛了。
我們分析canal了異常日志后發(fā)現,這個問題是由于canal訂閱者,讀取中文的表名時,出現了亂碼,沒有成功讀取到。該程序直接拋了異常,導致canal訂閱者不能正常工作了。
這個問題對用戶的影響是:用戶創(chuàng)建了商品,在商城的商品列表頁看不到,也搜索不到,有用戶投訴到運營那邊了。
我當時的第一反應是:這也能掛?
我當時不知道下游的業(yè)務系統,通過canal監(jiān)聽了我這邊的整個數據庫。
話不多說,先把問題解決了吧。
我們當時為了快速解決問題,先把中文的臨時表都刪了,然后把canal重啟一下。
果然,這個辦法是有效的。
canal監(jiān)聽者立馬恢復正常了。
當天,沒有再出現過問題。
第二天,領導把我叫過去說:canal服務又掛了。
我當時一臉懵逼。我什么都沒干呀。
Canal解析數據報錯:column size is not match for table xxxx 8 vs 9。
后來,我們經過分析之后發(fā)現,canal有一份緩存,如果canal出現異常,可能跟數據庫真實的情況不一致。
然后,我們把canal的meta.dat刪除了,然后重啟服務,果然恢復正常了。
后面也一直沒出現過問題。
5. 確定需求4的方案
前面說過運營總共提了4個需求,我通過前面的騷操作,完成了3個需求。
但第4個需求,里面還有點特殊要求,通過sql腳本不容易搞定,只能硬著頭皮寫java程序了。
運營的需求是把他們提供的excel表格中的數據導入系統,然后由系統匹配某個區(qū)間范圍內的數據,把結果寫入excel的另外兩列中,最后返回該excel文件。
拿到這個需求我腦子里想了三個方案:
- 寫一個可執(zhí)行的springboot工具項目,直接放到線上環(huán)境中執(zhí)行jar包。
- 使用一個job處理,本身已經有xxl-job了,接入非常方便。
- 寫一個api接口。
最終我選擇了第3個方案。
為什么?
其實這3個方案代碼的工作量差不多,但前面兩個方案需要先上傳excel到應用服務器,或者到OSS等文件服務器。
而如果運營需要導多次數據,每次都需要上傳一次excel,不僅浪費服務器資源,而且比較費時,還麻煩。
如果用api接口的話,可以直接使用postman遠程調用,直接上傳文件,通過輸入流的形式讀取數據,不保存到服務器。然后處理完數據,在將excel內容以輸出流的形式返回給我們下載即可。
使用postman調用遠程接口時,入參選擇form-data格式,key那里輸入File,然后在右側下拉列表中選擇File,就會出現Select Files按鈕。
通過該按鈕,就能選擇我們需要上傳的excel文件。
如果想調用接口后直接下載excel文件:
在postman中可以選擇Send and Download按鈕,即可下載文件。
注意,在圖片中的請求api接口地址是localhost,我只是舉了個例子,實際情況中是接口的域名。
此時,有些小伙伴可能會問題:這個接口不需要登錄就能訪問?
答:確實不需要登錄,我在網關層放開了該接口的訪問權限。
那不是有安全問題?
答:為了解決接口安全問題,也避免發(fā)版影響正常用戶的使用。我的想法是基于master分支新拉一個分支:hotfix,而pre環(huán)境(預生產環(huán)境,能訪問生產環(huán)境的數據庫)部署hotfix分支的代碼。
還有一個非常關鍵,而且我們一直在用的策略是:訪問pre的所有接口都必須使用指定的代理。
公司外面的人肯定是不知道這個代理的存在的,換句話說,只有我們公司內部的人才能訪問pre環(huán)境的接口。
因此,新加的excel處理接口是非常安全的,而且該接口只部署pre環(huán)境,對正常用戶不會造成影響
這個方案看似挺完美的。
然后三下五除二,我把代碼寫完,本地測試通過了,準備發(fā)到pre環(huán)境導數據。
6. jar包沖突
該功能部署pre環(huán)境其實非常簡單,只需要部署hotfix分支的代碼即可。
代碼部署好之后,我準備開始訪問接口。
先在postman的這個地方配置pre的代理。
代碼部署好之后,就能通過上一節(jié)中介紹的內容上傳excel文件,然后下載結果excel文件了。
但我第一次調用接口時,沒有返回想要的數據。從應用服務器的日志中看到,該接口報錯了。
報的竟然是某個類找不到。。。。
我這次為了快速導入和導出excel文件,選擇了阿里的easyexcel工具類。
本地開發(fā)環(huán)境,我確認過,那個類是有的。而且我這個功能是可以正常運行的,我都導出數據了。
但pre環(huán)境卻報了類找不到。
我猜可能是有jar包版本不兼容。
于是,調整了一下pom文件中引入的jar包的版本,之后,重新部署pre環(huán)境。
還真是這個原因,這一次接口能正常訪問,能夠返回數據了。
我心里暗自竊喜。
后來,把運營所需要的excel文件及時發(fā)給他們了。
7. pre環(huán)境網絡異常
又過了兩天,需求4有點調整。我把代碼改了,還是那個hotfix分支,找人重新部署了pre環(huán)境。
打算用之前相同的方法導數據的。
但馬上被啪啪打臉。
用postman請求該接口很久都不返回,我知道肯定是出了什么幺蛾子。
查了一下pre環(huán)境應用服務器的日志,竟然沒有查到請求該數據處理接口的記錄。
接著,我查了一下pre環(huán)境應用網關層的日志,竟然也沒有記錄。
不對呀。
然后又查了一下生產環(huán)境應用網關層的日志,原來是請求到生產環(huán)境了。
不是配置了代理嗎?
為什么會訪問到生產環(huán)境?
我?guī)е@兩個問題咨詢了一下公司的IT部門同事。他們追查了一下原因,發(fā)現原來網絡帶寬被打滿,導致pre環(huán)境的代理出問題了。
經過一段時間之后,pre環(huán)境的代理恢復正常了。
其實,pre環(huán)境代理出問題后,我們也嘗試了一下登錄到遠程服務器上,執(zhí)行相關curl命令,直接調用服務器的本地接口。最后,發(fā)現用這種方式不太好下載文件。
8. 部署錯分支了
pre環(huán)境代理恢復之后,我滿懷希望去用postman請求數據處理接口導數據。
但我發(fā)現導出的數據不對。
導出的excel文件根本打不開。
我打開excel文件看數據內容時,提示excel文件格式不對,或者已經被損壞了。
然后,我趕緊看應用服務器的日志,有請求記錄,但是沒有返回記錄,從這個日志中看不出問題。
當時我靈機一動:既然保存成.xlsx后綴的excel文件打不開,如果把文件后綴改成.csv格式呢?
于是,我把導出的excel文件后綴改成了.csv格式,果然可以打開文件。
文件內容中提示404。
這時我就明白了,可能是pre環(huán)境的接口沒發(fā)成功,被其他分支的代碼沖掉了。
然后,跟部署代碼的同學溝通之后,他當時操作失誤,部署的master分支的代碼,果然把hotfix的代碼沖掉了。
后來,他重新部署了hotfix的代碼,我順利的把數據導給運營了。
至此,這4個需求順利完成了。
總結
這次給運營導數據,是一次比較難得的經歷,遇到了很多問題,值得總結一下。
當然這其中有一部分是自己給自己挖的坑,也有一部分是被其他人坑了。
不要怕踩坑,其實踩坑,也是成長的機會,我通過這次經歷也收獲了不少寶貴的經驗。
生產環(huán)境的表名或字段名,一定不能用中文的。不要抱僥幸心里,說不定哪天就出問題了。
生產環(huán)境創(chuàng)建的臨時表,用完之后,一定要記得及時清理。
使用canal時,最好別全庫監(jiān)聽。用到什么表,就監(jiān)聽什么表,避免出現一些意外事故。
版本不兼容,會導致類找不到問題。
如果使用了代理,要考慮代理出現問題的情況。
代碼發(fā)版之后,一定要再三確認分支是否正確。
刪除meta.dat文件,重新canal服務,可以解決canal的很多問題。
postman真的非常強大,建議大家都好好用一下。
把多條insert語句合成一條執(zhí)行,效率更高??梢允褂胔ttps://tool.lu/sql,這里在線工具,壓縮一下sql去掉多余的空格。
excel導入和導出用阿里的easyexcel工具,真的非常方便。
還有挺多收獲的,這里就不一一列舉了。
希望你看了我的文章,自己也會有點收獲,能從我的經歷中,學到一點點東西,我就已經心滿意足了。
文章題目:一個被自己坑的線上事故
文章網址:http://m.fisionsoft.com.cn/article/dhdejsi.html


咨詢
建站咨詢
