關於Netty對於Channel超時機制缺陷的一點想法

咱們看看ReadTimeoutHandler下面這個初始化方法,在初始化的時候作的一些事情,Netty的2個改進點我認爲都在這裏能夠體現出來(下面紅體):git


    private void initialize(ChannelHandlerContext ctx) {github

        // Avoid the case where destroy() is called before scheduling timeouts.異步

        // See: https://github.com/netty/netty/issues/143oop

        switch (state) {spa

        case 1:操作系統

        case 2:netty

            return;資源

        }it


        state = 1;io


        lastReadTime = System.currentTimeMillis();

        if (timeoutMillis > 0) {

            timeout = ctx.executor().schedule(

                    new ReadTimeoutTask(ctx),

                    timeoutMillis, TimeUnit.MILLISECONDS);

        }

    }

一個過於頻繁的調用System.currentTimeMillis();這個調用要從操做系統取得超時時間,這個是須要消耗必定資源的。然而咱們能夠看到這個類裏面,該方法被反覆的調用。假若有10000個channel,那麼就有10000個這個handler,System.currentTimeMillis();被調用的頻率就會很是高,而這麼高的調用頻率實際上是沒什麼意義的。兩次調用之間可能相差連1ms都不到,請問在這種狀況下,如此精確意義何在呢?

更好的作法多是在主循環裏面取得一次時間,而後在全部handler裏面用同一個時間。(關於主循環的位置後面再說)


另一處就是這個ctx.executor().schedule方法的調用了,爲了處理channel過時,咱們往主循環裏面提交了一個過時處理任務(關於主循環的位置後面再說),一樣,若是1萬個channel,那麼就有1萬個runnable被執行。這裏一樣,若是在1個runnable裏面處理這1萬個channel是否效率會更高?


主循環就是NioEventLoop的run方法,這裏是,讀,flush全部異步IO操做的發起點。

咱們能夠在run方法裏面獲取1個系統時間,而後在後面的handler裏面統一使用這個NioEventLoop級別的時間。

一樣,咱們也能夠在NioEventLoop裏面維護一個過時任務,處理全部的channel。


綜上,因爲netty裏面把過時處理放到了channel hanlder級別,而不是nioeventloop級別,致使效率上值得商榷。

相關文章
相關標籤/搜索