系統設計與架構筆記:審計日志系統的設計


    公司要為一些系統做一個記錄審計日志的功能。這些日志不是我們開發人員常用的系統日志功能(用來記錄我們程序運行情況的,比如用log4j記錄下來的日志),而是為了今后對審計部門所使用,具有很強的業務要求的日志功能。架構已經被公司里的其他同事設計好了,雖然我現在只是做些邊角料的輔助工作,不過這個命題我很感興趣,我今天仔細琢磨了一下這樣的一個業務需求,覺得還是很有意思,真正把這個做起來是會有一定技術含量。下面就是我的思考,這些思考不全是我自己獨立想出來的,也借鑒了些同事的設計。

  首先我要設定一個業務場景:我們是為一個重要的商業支付網站做一套審計系統。最重要的技術要求是審計系統不能影響到業務系統的性能以及業務系統的穩定性。

  下面是我想到的設計:

  1. 如果想讓審計系統不會影響到業務系統的性能,我個人覺得最后是把審計的系統從業務系統里獨立出來,如果資源充足最好有一台專門的服務器獨立部署審計系統,如果實在沒有新的服務器作為資源,我們可以在裝有業務系統的服務器上開辟有限的資源供給審計系統,但是審計系統和業務系統所占該服務器的計算機資源的比率一定要控制好。
  2. 審計日志往往是包含了很多業務要求,所以用戶記錄審計的代碼一定會和業務操作的代碼耦合,特別是如果審計需要很變態可能會導致我們業務系統中每個功能點都會記錄審計日志的代碼(導致我們每個業務方法的代碼都要更改,痛苦啊),這種耦合必然會給系統帶來風險那么審計系統和業務系統的交互如何設計最好了?由於我的設計里是把兩個系統都獨立出來,那么這就表明兩個系統是一套異構的系統,異構的系統的信息交互就得通過通訊,通訊的方式有很多:webservice、http方式、消息隊列或者是企業內部電文系統。(我對消息隊列不太熟悉,前兩種我比較熟悉,后面的理解不代表消息隊列也會存在同樣的缺陷)在我的理解里不管哪個通訊方式都會存在請求和響應的過程,而這個請求和響應過程並不是總是安全的,假如某種原因導致通訊的阻塞使得請求和相應過程不能順利完成就會使得系統產生錯誤,為系統的穩定性產生風險,因此嵌入到業務系統代碼中的記錄審計日志的代碼最好不能包含請求和相應功能,讓請求相應的功能耦合到業務功能中去。我個人覺得最好是把記錄日志的功能獨立到一個線程中去,這個線程不能干擾到用戶請求的線程,而放在業務方法代碼的接口只要傳值就行,傳值成功如否業務代碼完全不用關心。因為我就得在業務系統里嵌入一個線程池,這個線程池里的線程都是用來記錄日志功能的。這個線程池在web服務啟動時候也會附帶運行,業務系統記錄日志的信息的方法作為一個線程記錄添加到線程里去,業務系統記錄日志的方法只要放入值就行,那么在業務系統里記錄日志和業務操作被獨立開來了,大伙互不干擾,這樣就減少了記錄審計日志的功能對業務系統的干擾從而降低了日志記錄系統對業務系統不安全的影響。對這個線程池里線程就是負責把數據傳輸到審計系統,只要數據傳到了審計系統,審計系統就返回一個success標識,線程不關心審計系統里操作是否成功。
  3. 對於審計系統里的設計也是值得考量的,我個人是這么想的,我們把從業務系統接收到數據放到一個隊列里(queue)。為了提高日志請求的效率我還是為審計系統審計一個線程池,這個線程池所使用到的數據就是我們構建的隊列(queue),這么做的好處在哪里:
  • 並發操作一定會提高系統運行的效率,這個我想誰都沒有異議吧;
  • 假如我們把審計系統和業務系統布置到一台服務器上,我們可以通過控制queue的大小以及線程池的大小來限定審計日志系統所消耗的系統資源。
  • 或許有人會有疑問我為什么不把數據直接傳到線程而是使用隊列存儲,我的目的有兩個:一是數據先進隊列,這個操作很簡單不容易出錯,進入隊列后馬上給業務系統一個響應回復,這樣會減少系統的不穩定因素,一是我們先讓數據進隊列而不是線程池,那么我們可以為縮減線程池大小做好准備,特別是在審計系統部署到業務系統服務器上時候這個做法很有效的。

  以上就是我的初步想法,我的設計里牽涉到的比較難點的技術有:異構系統的通訊方式、線程池技術以及一個高效安全的queue的設計。

  我個人感覺到一個難點:我要在業務系統里獨立設計一個線程池用來記錄日志信息,這個線程池里的線程要獨立於用戶請求的線程,在我們用java開發的web系統里該如何做才是最好了?不知道哪位童鞋可以給我一點建議。

  或許有的童鞋會有這樣的疑問:我在業務系統里開辟新線程記錄日志不是一樣的影響到了業務系統的性能。這個問題其實比較好解決,因為開辟新線程記錄日志只是消耗了服務器資源而非消耗到業務系統每個用戶請求所負載的系統資源,加入了審計日志記錄功能應該是影響了部署業務系統服務器所能承受用戶並發量,而不是給每個用戶系統帶來了負擔,至於如何提高並發解決方法就比較簡單,提高業務服務器的性能(比如加cpu,內存等)或者加幾台服務器就行。

  這里面牽涉到的線程池技術我是最感興趣的,我最近查閱了些線程池技術,發現線程池並不是我想象中那么簡單,對於jdk自帶的ThreadPool技術就很值得研究。

  最后希望博客園里的大牛看到此文能否給我一些建議,看看我的設計到底好不好,合不合理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM