使用java進行IOS推送,開源的jar包比較有名的主要有兩個,一個是javapns,一個是notnoop.
對於javapns,之前有介紹過,內存洩漏。這個問題算比較嚴重,表現在:
1.對於已推送的notify會一直保存,不會回收。
2.默認情況下對應的Vertor保存notify,此數組會自動擴容,大批量時,也會有內存極增的問題。
3.為了避免socket發送過程中,與蘋果服務器之間連續失效,從而導致此SOCKET發送的推送都不成功,可以配制一個socket發送一定數量push後,重啟此鏈接,避免重復失敗;
另外在重啟socket前會輪詢已經發送的notify,如果對應的notify推送失敗,選擇重發,javapns這塊的處理有點亂。
以上問題總體來說,通對源碼修改,能修復掉相關問題。主要修復是內存洩漏的問題,提前回收,另外feedback服務及時,推送重發問題也不大。
基於javapns修改的服務運行,一直算正常,每天百萬級別的推送下來,,穩定運行過幾個月沒出現過問題。
但是在通過jmap查看進程中未回收的資源還是比較多,,另外最近有出現FULL GC阻塞的情況,導致重啟的事件。(另一個原因也可能是推送所有結點切到國外的機器了,內存要很省的用,只有512M-.-)
對於此的評估我大體知道,推送較多時,會出現vector量比較大,自動擴容,然後年老代與sur中對應空間都被塞滿了,從而FULL GC沒空間了,進而導致服務DOWN機,另外對javapns的代碼即使改了以後,看著不是很舒服。
以上背景下,講講notnoop!
年前把推送服務基於notnoop進行了擴展,由於上層應用層接口封裝足夠好,只需要在notnoop在現成接口上實現此推送服務,然後使用中通過配制來選擇使用notnoop進行推送即可。
1.notnoop包代碼結果比較清晰,主要是com.notnoop.apns.ApnsServiceBuilder類用於控制push對象池的相關組建以及,com.notnoop.apns.internal.ApnsConnectionImpl控制push具體消息的發送。主要有com.notnoop.apns與com.notnoop.apns.internal兩個包
結構。對應的單元測試也比較全。
2.notnoop通過構造一個線程池對象(當然也可以單線程),用於跟蘋果通信,進行push.
3.notnoop push實現支持基於隊列處理,也可以是設置定時任務,一段時間批量處理下隊列中的push,一般選第一種方式。
4.notnoop通過隊列的方式,然後可以設置一個pools線程對象池,異步處理所有的push.
5.notnoop則只有在第一次發送時創建對應的socket(當然socket為null或者isclosed後,會被重連).之後有單獨的線程對socket對象的InputStream流進行monitor,處理對應的發送失敗的Notifycation,對於失敗的notifycation會存在一個隊列裡面,會對發送失敗的通知進行重發。此處要考慮錯誤隊列的長度問題。
6.notnoop與javapns也一樣,對於發送失敗的notifycation會進行重發,當然失敗分種類,如果是IO異常之類的,會重發三次還不成功就丟棄掉了,中間還會嘗試WAIT一段時間,如果是蘋果返回的錯誤碼失敗之類,才會重新進行發送。
notnoop與javapns有個很大的不同在於對於失敗notify的處理問題上,
javapns依賴重連時然後集中遍歷所有失敗notify,然後進行處理。
notnoop則是開啟了一個monitor進程,對於已處理的notify進行實時處理。
以上兩種機制,monitor方式明顯更合理。
代碼情節上來說,以及完整的單元測試,notnoop可以有一個大大的贊,對於內存開銷上說,下面是jmap查看到的
num #instances #bytes class name
----------------------------------------------
1: 104004 21613440 [C
2: 36928 8768280 [B
3: 14924 7057840 [I
4: 30776 4193072
5: 30776 4132128
6: 2618 2919376
7: 45554 2460160
表現很滿意。
以上是使用中的一些心德,希望對各位有幫忙。