在我加入Ruxit作為一名技術(shù)推廣之前更早期時(shí)是一名軟件開發(fā)人員,我們以一種錯(cuò)誤的方式在兩個(gè)項(xiàng)目之間共享一個(gè)數(shù)據(jù)庫。這篇文章就是關(guān)于一個(gè)糟糕的決定教給我們的兩個(gè)重要教訓(xùn)。
幾年前我作為團(tuán)隊(duì)的開發(fā)主管為客戶開發(fā)一個(gè)JAVA web應(yīng)用。我們叫它“項(xiàng)目A”。我們?cè)诳蛻衄F(xiàn)場構(gòu)建這個(gè)web應(yīng)用,除我們之外還有其它幾個(gè)團(tuán)隊(duì)在做相關(guān)的項(xiàng)目。因?yàn)樵诟绲捻?xiàng)目上我們?cè)诤献髦斜舜耸煜ぃ覀儠?huì)在一個(gè)常用的基本信息方面交流軟件架構(gòu)方面的想法。
一天一個(gè)新項(xiàng)目(項(xiàng)目B)啟動(dòng)了。這個(gè)項(xiàng)目由其他團(tuán)隊(duì)中的一個(gè)來實(shí)施。在我的腦海里我仍能看到我們站在那的樣子,我們完全了解這個(gè)項(xiàng)目并計(jì)劃在項(xiàng)目B上共享項(xiàng)目A的關(guān)于用戶,角色和權(quán)限的數(shù)據(jù)庫架構(gòu)。畢竟,兩個(gè)項(xiàng)目都是服務(wù)于相同用戶的內(nèi)部web項(xiàng)目。哦,對(duì)了,我忘了說明所有這些項(xiàng)目沒有一個(gè)中心用戶數(shù)據(jù)庫——每一個(gè)新項(xiàng)目需要從開頭開始。我們認(rèn)為通過共享已經(jīng)存在的基礎(chǔ)架構(gòu)和實(shí)踐不僅節(jié)約了開發(fā)時(shí)間也節(jié)約了令人頭疼的用戶支持方面的人力,因?yàn)樗麄儾恍杼幚愍?dú)立的用戶目錄。
我們通過配置使項(xiàng)目B可以通過一個(gè)數(shù)據(jù)庫賬戶訪問我們的數(shù)據(jù)庫表,因?yàn)槟阒牢覀儾幌氘a(chǎn)生混亂的局面。
一切正常運(yùn)行一段時(shí)間...
畢竟存儲(chǔ)用戶,角色和權(quán)限并不是火箭科學(xué)那樣難。一年之后,項(xiàng)目A的新版本計(jì)劃開始。我們很激動(dòng)因?yàn)槲覀冇袡C(jī)會(huì)在維護(hù)現(xiàn)有好的部分的同時(shí)改進(jìn)我們認(rèn)為不好的部分。我們甚至改進(jìn)一些原本就工作很好的部分——這其中就包括用戶,角色和權(quán)限的數(shù)據(jù)庫表結(jié)構(gòu)。說實(shí)話,我們并沒有考慮到項(xiàng)目B。當(dāng)然,項(xiàng)目B很快就停止工作了。我們的錯(cuò)誤決定就是允許項(xiàng)目B直接訪問我們的數(shù)據(jù)庫。不僅僅準(zhǔn)對(duì)現(xiàn)在的標(biāo)準(zhǔn),甚至對(duì)于以前的標(biāo)準(zhǔn),正確的決定應(yīng)該是創(chuàng)建一個(gè)獨(dú)立的認(rèn)證服務(wù),然后通過共享API而不是直接訪問數(shù)據(jù)庫。
但是,還有更多的...
是的,我們犯了一個(gè)嚴(yán)重的架構(gòu)錯(cuò)誤,但是有另一個(gè)問題出現(xiàn)。有點(diǎn)諷刺意味的是項(xiàng)目B是一個(gè)完全沒有人使用的產(chǎn)品。盡管已經(jīng)根據(jù)產(chǎn)品經(jīng)理實(shí)現(xiàn)了,也有非常好的測試覆蓋率和代碼質(zhì)量,但是項(xiàng)目B并沒有被需要它的部門使用。項(xiàng)目B卡在了”友好的用戶”的煉獄階段,準(zhǔn)備發(fā)布,但有沒有正式發(fā)布。所以知道兩周后才有人發(fā)現(xiàn)它不能正常工作。
直到第一個(gè)不幸的用戶報(bào)告了問題,我們的開發(fā)人員已經(jīng)正在另一個(gè)項(xiàng)目上工作。作為分析根本原因的第一步,我們?cè)噲D通過檢查錯(cuò)誤日志文件來發(fā)現(xiàn)問題在哪里。從事后諸葛亮的角度來看,在本應(yīng)該有自動(dòng)探測應(yīng)用問題的地方?jīng)]有一個(gè)復(fù)雜的監(jiān)控解決方案同樣是一個(gè)糟糕的決定。
盡管這可能是一個(gè)有趣的軼事,但是我真的希望你能從中學(xué)到些東西。確保你通過一個(gè)穩(wěn)定的API訪問數(shù)據(jù)庫,因?yàn)樗押唵蔚臄?shù)據(jù)庫變成一個(gè)服務(wù)并且使它在以后更容易使用。此外一定確保你已經(jīng)適當(dāng)?shù)乇O(jiān)控你的應(yīng)用和服務(wù)。通過API構(gòu)建的環(huán)境將使你的基礎(chǔ)架構(gòu)在很長一段時(shí)間保持靈活性。監(jiān)控能夠確保復(fù)雜性的增加在可控的范圍內(nèi)。
我希望你喜歡這個(gè)小小的推薦在未來某一天當(dāng)你打開Eclipse選擇文件菜單,然后選擇“導(dǎo)出為war...”的時(shí)候。
原文鏈接: https://blog.ruxit.com/how-to-fail-at-sharing-a-database/