Java NIO WatchService奇遇記

在擴展Apache Flume的Taildir Source的過程中,由于感覺其采用IO輪詢的方式,而不是Java NIO,會有性能問題,于是就打算通過Java NIO將相關(guān)的部分重寫一遍.

我們的想法是這樣的,先監(jiān)控某個目錄,然后當有文件修改事件觸發(fā)時,判斷一下被修改的文件是否是某些特定的文件,如果是,則讀取其新增的內(nèi)容,并發(fā)送給Channel.

通過Google,我們找到了WatchService這個東西,然后參考官方的源代碼實現(xiàn)了一遍.

開始沒有什么問題.實際上是有問題,但是我沒有注意到.

用WatchService實現(xiàn)的代碼如下:

我們可以看到,其中有一個死循環(huán),不斷地讀取新的事件,判斷是否是我們要監(jiān)控的文件,如果是,則讀取新的內(nèi)容并發(fā)送給Channel.

問題是,它是死循環(huán)啊!!!

昨天下午在系統(tǒng)的其他部分時,由于擴展后的Flume也是其中的一個必須的組件,所以就一直開著Flume.期間,我就納悶,怎么電量這么不耐用呢?之前都是能夠撐兩個小時的,怎么這次只用不到一個小時就沒電了?

用top命令查看了一下,發(fā)現(xiàn)一個Java應用的CPU利用率一直都是100%+.

用ps命令查看了一下對應的進程,發(fā)現(xiàn)就是我們的Flume進程.

此時,我恍然大悟.想到了可能是死循環(huán)導致的CPU利用率太高.

這時,想起了自己在改寫這部分時的初衷,是希望能夠有這么一個接口,我們可以傳入要監(jiān)聽的事件,然后傳入一個回調(diào)函數(shù).當觸發(fā)相應的事件時,就調(diào)用回調(diào)函數(shù).

而WatchService顯然不是我需要的.

再次Google了一下之后,發(fā)現(xiàn)有人推薦用一款叫JNotifier的庫.從StackOverflow上得知,這個庫需要調(diào)用一個本地庫,而這個本地庫是封裝了Linux上的某個調(diào)用,用C語言封裝的,打包成了一個so文件.

所以,我們想用的話,就得先將這個so文件下載下來,然后加入java.native.path中.開始我是拒絕的,但是看到它的API那么簡單,楚楚動人,我就忍不住想要嘗試一下.然而,官網(wǎng)上并沒有明確說明我們要如何來做.

結(jié)合出現(xiàn)的問題,StackOverflow了好長時間,用他們提供的方法都沒有解決.直到發(fā)現(xiàn)有一個人提問說他在Java 1.7和Java 1.8下都嘗試過,但是都出現(xiàn)那個錯誤,底下有人回答說,Java 1.8就不行.看到這,我終于失去了耐心!我用的就是Java 1.8.

最終,我刪除了一切跟JNotify相關(guān)的內(nèi)容,然后重新踏上了尋找之路.

后來,我發(fā)現(xiàn)了一個庫,叫Apache Commons VFS.畢竟是Apache的產(chǎn)品,用起來更放心一些.使用起來,發(fā)現(xiàn)它的API甚至更加簡單,最終實現(xiàn)的代碼如下:

現(xiàn)在,F(xiàn)lume的CPU利用率就保持正常了.

但是,Apache Commons VFS的具體實現(xiàn),我并沒有查看.我不知道它到底是如何實現(xiàn)的,內(nèi)部是否還是通過輪詢的方式實現(xiàn)的.雖然它現(xiàn)在能正常工作,但是我們并沒有對它進行過深度測試,所以,實際上,我們是不能信任它的.我們并不能認為它就完美無暇.因為它現(xiàn)在對我們就是一個黑匣子!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容