国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

工業(yè)級(jí)Netty網(wǎng)關(guān),京東是如何架構(gòu)的?

這篇具有很好參考價(jià)值的文章主要介紹了工業(yè)級(jí)Netty網(wǎng)關(guān),京東是如何架構(gòu)的?。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

說(shuō)在前面

在40歲老架構(gòu)師 尼恩的讀者交流群(50+)中,很多小伙伴拿到一線(xiàn)互聯(lián)網(wǎng)企業(yè)如阿里、網(wǎng)易、有贊、希音、百度、滴滴的面試資格。

最近,尼恩指導(dǎo)一個(gè)小伙伴簡(jiǎn)歷,寫(xiě)了一個(gè)《高并發(fā)網(wǎng)關(guān)項(xiàng)目》,此項(xiàng)目幫這個(gè)小伙拿到 字節(jié)/阿里/微博/汽車(chē)之家 面邀, 所以說(shuō),這是一個(gè)牛逼的項(xiàng)目。

為了幫助大家拿到更多面試機(jī)會(huì),拿到更多大廠offer。

尼恩決定:給大家出一章視頻介紹這個(gè)項(xiàng)目的架構(gòu)和實(shí)操,《33章:10Wqps 高并發(fā) Netty網(wǎng)關(guān)架構(gòu)與實(shí)操》,預(yù)計(jì)月底發(fā)布。然后,提供一對(duì)一的簡(jiǎn)歷指導(dǎo),這里簡(jiǎn)歷金光閃閃、脫胎換骨。

《33章:10Wqps 高并發(fā) Netty網(wǎng)關(guān)架構(gòu)與實(shí)操》 海報(bào)如下:

工業(yè)級(jí)Netty網(wǎng)關(guān),京東是如何架構(gòu)的?,面試,架構(gòu),java,面試,后端,gateway,系統(tǒng)架構(gòu)

配合《33章:10Wqps 高并發(fā) Netty網(wǎng)關(guān)架構(gòu)與實(shí)操》, 尼恩會(huì)梳理幾個(gè)工業(yè)級(jí)、生產(chǎn)級(jí)網(wǎng)關(guān)案例,作為架構(gòu)素材、設(shè)計(jì)的素材。

前面梳理了

  • 《日流量200億,攜程網(wǎng)關(guān)的架構(gòu)設(shè)計(jì)》
  • 《千萬(wàn)級(jí)連接,知乎如何架構(gòu)長(zhǎng)連接網(wǎng)關(guān)?》
  • 《日200億次調(diào)用,喜馬拉雅網(wǎng)關(guān)的架構(gòu)設(shè)計(jì)》
  • 《100萬(wàn)級(jí)連接,愛(ài)奇藝WebSocket網(wǎng)關(guān)如何架構(gòu)》
  • 《億級(jí)長(zhǎng)連接,淘寶接入層網(wǎng)關(guān)的架構(gòu)設(shè)計(jì)》
  • 《單體120萬(wàn)連接,小愛(ài)網(wǎng)關(guān)如何架構(gòu)?》
  • 《100萬(wàn)級(jí)連接,石墨文檔WebSocket網(wǎng)關(guān)如何架構(gòu)?》
  • 《2億用戶(hù),B站API網(wǎng)關(guān)如何架構(gòu)?》

除了以上的8個(gè)案例,這里,尼恩又找到一個(gè)漂亮的生產(chǎn)級(jí)案例:《工業(yè)級(jí)Netty網(wǎng)關(guān),京東是如何架構(gòu)?

注意,這又一個(gè)非常 牛逼的工業(yè)級(jí)、生產(chǎn)級(jí)網(wǎng)關(guān)案例。

這些案例,并不是尼恩的原創(chuàng)。這些案例,僅僅是尼恩在《33章:10Wqps 高并發(fā) Netty網(wǎng)關(guān)架構(gòu)與實(shí)操》備課的過(guò)程中,在互聯(lián)網(wǎng)查找資料的時(shí)候,收集起來(lái)的,供大家學(xué)習(xí)和交流使用。

《尼恩 架構(gòu)筆記》《尼恩高并發(fā)三部曲》《尼恩Java面試寶典》的PDF,請(qǐng)到公號(hào)【技術(shù)自由圈】獲取

工業(yè)級(jí)Netty網(wǎng)關(guān),京東是如何架構(gòu)?

作者:張松然,京東商家研發(fā)部架構(gòu)師

京麥?zhǔn)蔷〇|商城為其商家提供的一款后臺(tái)管理工具,它能夠讓商家在不登錄后臺(tái)的情況下生成訂單,快速完成訂單下載和發(fā)貨流程。這與淘寶的旺旺商家版(現(xiàn)已更名為淘寶千牛)類(lèi)似。

本文主要闡述了京麥 TCP 網(wǎng)關(guān)的技術(shù)架構(gòu)以及 Netty 的應(yīng)用實(shí)踐。

京東京麥商家管理平臺(tái)從 2014 年開(kāi)始搭建網(wǎng)關(guān),從 HTTP 網(wǎng)關(guān)逐步升級(jí)為 TCP 網(wǎng)關(guān)。到了 2016 年,基于 Netty4.x+Protobuf3.x 技術(shù),京麥構(gòu)建了一個(gè)高可用、高性能和高穩(wěn)定的 TCP 長(zhǎng)連接網(wǎng)關(guān),支持 PC 端和應(yīng)用程序的上下行通信。

早期的京麥主要依靠 HTTP 和 TCP 長(zhǎng)連接來(lái)發(fā)送消息通知,而沒(méi)有將其應(yīng)用于 API 網(wǎng)關(guān)。

然而,隨著對(duì) NIO 技術(shù)的深入了解和對(duì) Netty 框架的熟練掌握,以及對(duì)系統(tǒng)通信穩(wěn)定性要求的提高,京麥開(kāi)始嘗試運(yùn)用 NIO 技術(shù)來(lái)實(shí)現(xiàn) API 請(qǐng)求調(diào)用。這一設(shè)想在 2016 年終于實(shí)現(xiàn),并成功支持業(yè)務(wù)運(yùn)營(yíng)。

得益于采用了 TCP 長(zhǎng)連接容器、Protobuf 序列化、服務(wù)泛化調(diào)用框架等多種優(yōu)化措施,京麥的 TCP 網(wǎng)關(guān)性能比 HTTP 網(wǎng)關(guān)提升了 10 倍以上,穩(wěn)定性也顯著超過(guò)了 HTTP 網(wǎng)關(guān)。

1、TCP網(wǎng)關(guān)的網(wǎng)絡(luò)結(jié)構(gòu)

通過(guò) Netty 構(gòu)建京麥 TCP 網(wǎng)關(guān)的長(zhǎng)連接容器,作為網(wǎng)關(guān)接入層提供服務(wù) API 請(qǐng)求調(diào)用。

客戶(hù)端通過(guò)域名 + 端口訪問(wèn) TCP 網(wǎng)關(guān),不同域名對(duì)應(yīng)不同運(yùn)營(yíng)商的 VIP,VIP 發(fā)布在 LVS 上,LVS 將請(qǐng)求轉(zhuǎn)發(fā)給后端的 HAProxy,然后由 HAProxy 將請(qǐng)求轉(zhuǎn)發(fā)給后端的 Netty 的 IP+Port。

主要,這個(gè)是高并發(fā)接入層的標(biāo)準(zhǔn)架構(gòu)。

LVS 將請(qǐng)求轉(zhuǎn)發(fā)給后端的 HAProxy,經(jīng)過(guò) LVS 的請(qǐng)求,但響應(yīng)是由 HAProxy 直接返回給客戶(hù)端,這就是 LVS 的 DR 模式。

工業(yè)級(jí)Netty網(wǎng)關(guān),京東是如何架構(gòu)的?,面試,架構(gòu),java,面試,后端,gateway,系統(tǒng)架構(gòu)

注意:請(qǐng)點(diǎn)擊圖像以查看清晰的視圖!

LVS+Keepalived(DR模式)的深入學(xué)習(xí),尼恩給大家寫(xiě)了一篇非常詳細(xì)的、全面的文章, 建議大家收藏起,好好掌握:

《10Wqps網(wǎng)關(guān)接入層,LVS+Keepalived(DR模式)如何搭建?》

2、TCP網(wǎng)關(guān)長(zhǎng)連接容器架構(gòu)

TCP網(wǎng)關(guān)的核心組件是Netty,而Netty的NIO模型是Reactor反應(yīng)堆模型(Reactor相當(dāng)于有分發(fā)功能的多路復(fù)用器Selector)。

每一個(gè)連接對(duì)應(yīng)一個(gè)Channel(多路指多個(gè)Channel,復(fù)用指多個(gè)連接復(fù)用了一個(gè)線(xiàn)程或少量線(xiàn)程,在Netty指EventLoop),一個(gè)Channel對(duì)應(yīng)唯一的ChannelPipeline,多個(gè)Handler串行的加入到Pipeline中,每個(gè)Handler關(guān)聯(lián)唯一的ChannelHandlerContext。TCP網(wǎng)關(guān)長(zhǎng)連接容器的Handler就是放在Pipeline的中。

我們知道TCP屬于OSI的傳輸層,所以建立Session管理機(jī)制構(gòu)建會(huì)話(huà)層來(lái)提供應(yīng)用層服務(wù),可以極大的降低系統(tǒng)復(fù)雜度。所以,每一個(gè)Channel對(duì)應(yīng)一個(gè)Connection,一個(gè)Connection又對(duì)應(yīng)一個(gè)Session,Session由Session Manager管理,Session與Connection是一一對(duì)應(yīng),Connection保存著ChannelHandlerContext (ChannelHanderContext可以找到Channel), Session通過(guò)心跳機(jī)制來(lái)保持Channel的Active狀態(tài)。

每一次Session的會(huì)話(huà)請(qǐng)求(ChannelRead)都是通過(guò)Proxy代理機(jī)制調(diào)用Service層,數(shù)據(jù)請(qǐng)求完畢后通過(guò)寫(xiě)入ChannelHandlerConext再傳送到Channel中。

數(shù)據(jù)下行主動(dòng)推送也是如此,通過(guò)Session Manager找到Active的Session,輪詢(xún)寫(xiě)入Session中的ChannelHandlerContext,就可以實(shí)現(xiàn)廣播或點(diǎn)對(duì)點(diǎn)的數(shù)據(jù)推送邏輯。如下圖所示。

工業(yè)級(jí)Netty網(wǎng)關(guān),京東是如何架構(gòu)的?,面試,架構(gòu),java,面試,后端,gateway,系統(tǒng)架構(gòu)

注意:請(qǐng)點(diǎn)擊圖像以查看清晰的視圖!

京麥TCP網(wǎng)關(guān)使用Netty Channel進(jìn)行數(shù)據(jù)通信,使用Protobuf進(jìn)行序列化和反序列化,每個(gè)請(qǐng)求都將被封裝成Byte二進(jìn)制字節(jié)流,在整個(gè)生命周期中,Channel保持長(zhǎng)連接,而不是每次調(diào)用都重新創(chuàng)建Channel,達(dá)到鏈接的復(fù)用。

我們接下來(lái)來(lái)看看基于Netty的具體技術(shù)實(shí)踐。

3、TCP網(wǎng)關(guān)Netty Server的IO模型

具體的實(shí)現(xiàn)過(guò)程如下

  • 1)創(chuàng)建ServerBootstrap,設(shè)定BossGroup與WorkerGroup線(xiàn)程池;
  • 2)bind指定的port,開(kāi)始偵聽(tīng)和接受客戶(hù)端鏈接(如果系統(tǒng)只有一個(gè)服務(wù)端port需要監(jiān)聽(tīng),則BossGroup線(xiàn)程組線(xiàn)程數(shù)設(shè)置為1);
  • 3)在ChannelPipeline注冊(cè)childHandler,用來(lái)處理客戶(hù)端鏈接中的請(qǐng)求幀。

4、TCP網(wǎng)關(guān)的線(xiàn)程模型

TCP網(wǎng)關(guān)使用Netty的線(xiàn)程池,共三組線(xiàn)程池,分別為BossGroup、WorkerGroup和ExecutorGroup。

其中,BossGroup用于接收客戶(hù)端的TCP連接,WorkerGroup用于處理I/O、執(zhí)行系統(tǒng)Task和定時(shí)任務(wù),ExecutorGroup用于處理網(wǎng)關(guān)業(yè)務(wù)加解密、限流、路由,及將請(qǐng)求轉(zhuǎn)發(fā)給后端的抓取服務(wù)等業(yè)務(wù)操作。

工業(yè)級(jí)Netty網(wǎng)關(guān),京東是如何架構(gòu)的?,面試,架構(gòu),java,面試,后端,gateway,系統(tǒng)架構(gòu)

注意:請(qǐng)點(diǎn)擊圖像以查看清晰的視圖!

NioEventLoop是Netty的Reactor線(xiàn)程,其角色

  • 1)Boss Group:作為服務(wù)端Acceptor線(xiàn)程,用于accept客戶(hù)端鏈接,并轉(zhuǎn)發(fā)給WorkerGroup中的線(xiàn)程;
  • 2)Worker Group:作為IO線(xiàn)程,負(fù)責(zé)IO的讀寫(xiě),從SocketChannel中讀取報(bào)文或向SocketChannel寫(xiě)入報(bào)文;
  • 3)Task Queue/Delay Task Queu:作為定時(shí)任務(wù)線(xiàn)程,執(zhí)行定時(shí)任務(wù),例如鏈路空閑檢測(cè)和發(fā)送心跳消息等。

5、TCP網(wǎng)關(guān)執(zhí)行時(shí)序圖

工業(yè)級(jí)Netty網(wǎng)關(guān),京東是如何架構(gòu)的?,面試,架構(gòu),java,面試,后端,gateway,系統(tǒng)架構(gòu)

注意:請(qǐng)點(diǎn)擊圖像以查看清晰的視圖!

如上圖所示,其中步驟一至步驟九是Netty服務(wù)端的創(chuàng)建時(shí)序,步驟十至步驟十三是TCP網(wǎng)關(guān)容器創(chuàng)建的時(shí)序。

步驟一:創(chuàng)建ServerBootstrap實(shí)例,ServerBootstrap是Netty服務(wù)端的啟動(dòng)輔助類(lèi)。

步驟二:設(shè)置并綁定Reactor線(xiàn)程池,EventLoopGroup是Netty的Reactor線(xiàn)程池,EventLoop負(fù)責(zé)所有注冊(cè)到本線(xiàn)程的Channel。

步驟三:設(shè)置并綁定服務(wù)器Channel,Netty Server需要?jiǎng)?chuàng)建NioServerSocketChannel對(duì)象。

步驟四:TCP鏈接建立時(shí)創(chuàng)建ChannelPipeline,ChannelPipeline本質(zhì)上是一個(gè)負(fù)責(zé)和執(zhí)行ChannelHandler的職責(zé)鏈。

步驟五:添加并設(shè)置ChannelHandler,ChannelHandler串行的加入ChannelPipeline中。

步驟六:綁定監(jiān)聽(tīng)端口并啟動(dòng)服務(wù)端,將NioServerSocketChannel注冊(cè)到Selector上。

步驟七:Selector輪訓(xùn),由EventLoop負(fù)責(zé)調(diào)度和執(zhí)行Selector輪詢(xún)操作。

步驟八:執(zhí)行網(wǎng)絡(luò)請(qǐng)求事件通知,輪詢(xún)準(zhǔn)備就緒的Channel,由EventLoop執(zhí)行ChannelPipeline。

步驟九:執(zhí)行Netty系統(tǒng)和業(yè)務(wù)ChannelHandler,依次調(diào)度并執(zhí)行ChannelPipeline的ChannelHandler。

步驟十:通過(guò)Proxy代理調(diào)用后端服務(wù),ChannelRead事件后,通過(guò)發(fā)射調(diào)度后端Service。

步驟十一:創(chuàng)建Session,Session與Connection是相互依賴(lài)關(guān)系。

步驟十二:創(chuàng)建Connection,Connection保存ChannelHandlerContext。

步驟十三:添加SessionListener,SessionListener監(jiān)聽(tīng)SessionCreate和SessionDestory等事件。

6、TCP網(wǎng)關(guān)源碼分析

6.1 Session管理

Session是客戶(hù)端與服務(wù)端建立的一次會(huì)話(huà)鏈接,會(huì)話(huà)信息中保存著SessionId、連接創(chuàng)建時(shí)間、上次訪問(wèn)事件,以及Connection和SessionListener,在Connection中保存了Netty的ChannelHandlerContext上下文信息。Session會(huì)話(huà)信息會(huì)保存在SessionManager內(nèi)存管理器中。

創(chuàng)建Session的源碼

@Override
public synchronized Session createSession(String sessionId, ChannelHandlerContext ctx){
    Session session = sessions.get(sessionId);
    if (session != null){
        session.close();
    }
    session = new ExchangeSession();
    session.setSessionId(sessionId);
    session.setValid(true);
    session.setMaxInactiveInterval(this.getMaxInactiveInterval());
    session.setCreationTime(System.currentTimeMillis());
    session.setLastAccessedTime(System.currentTimeMillis());
    session.setSessionManager(this);
    session.setConnection(createTcpConnection(session, ctx));
    for (SessionListener listener : essionListeners){
        session.addSessionListener(listener);
    }
    return session;
}

通過(guò)源碼分析,如果Session已經(jīng)存在銷(xiāo)毀Session,但是這個(gè)需要特別注意,創(chuàng)建Session一定不要?jiǎng)?chuàng)建那些斷線(xiàn)重連的Channel,否則會(huì)出現(xiàn)Channel被誤銷(xiāo)毀的問(wèn)題。因?yàn)槿绻谝呀?jīng)建立Connection(1)的Channel上,再建立Connection(2),進(jìn)入session.close方法會(huì)將cxt關(guān)閉,Connection(1)和Connection(2)的Channel都將會(huì)被關(guān)閉。在斷線(xiàn)之后再建立連接Connection(3),由于Session是有一定延遲,Connection(3)和Connection(1/2)不是同一個(gè),但Channel可能是同一個(gè)。

所以,如何處理是否是斷線(xiàn)重練的Channel,具體的方法是在Channel中存入SessionId,每次事件請(qǐng)求判斷Channel中是否存在SessionId,如果Channel中存在SessionId則判斷為斷線(xiàn)重連的Channel,代碼如下圖所示。

private String getChannelSessionHook(ChannelHandlerContext ctx){
    return ctx.channel().attr (Constants.SERVER_SESSION_HOOK).get();
}

private void setChannelSessionHook(ChannelHandlerContext ctx, String sessionId){
    ctx.channel().attr(Constants.SERVER_SESSION_HOOK).set(sessionId);
}

6.2 心跳

心跳用于檢測(cè)保持連接的客戶(hù)端是否仍然活躍,客戶(hù)端每隔一段時(shí)間發(fā)送一次心跳包到服務(wù)端,服務(wù)端收到心跳后更新 Session 的最后訪問(wèn)時(shí)間。

在服務(wù)端,長(zhǎng)連接會(huì)話(huà)檢測(cè)通過(guò)輪詢(xún) Session 集合來(lái)判斷最后訪問(wèn)時(shí)間是否過(guò)期,如果過(guò)期,則關(guān)閉 Session 和 Connection,包括從內(nèi)存中刪除,同時(shí)注銷(xiāo) Channel 等。如下面代碼所示。

Session session = tcpSessionManager.createSession(wrapper.getSessionId(), ctx);
session.addSessionListener(tcpHeartbeatListener);
session.connect();

tcpSessionManager.addSession(session);

通過(guò)源碼分析,在每個(gè)Session創(chuàng)建成功之后,都會(huì)在Session中添加TcpHeartbeatListener這個(gè)心跳檢測(cè)的監(jiān)聽(tīng),TcpHeartbeatListener是一個(gè)實(shí)現(xiàn)了SessionListener接口的守護(hù)線(xiàn)程,通過(guò)定時(shí)休眠輪詢(xún)Sessions檢查是否存在過(guò)期的Session,如果輪訓(xùn)出過(guò)期的Session,則關(guān)閉Session。如下面代碼所示。

public void checkHeartBeat(){
    Session[] sessions = tcpSessionManager.getSessions();
    for (Session session : sessions){
        if (session.expire()){
            session.close();
            logger.info("heart is expire, clear sessionId:"+ session.getSessionId());
        }
    }
}

同時(shí),注意到session.connect方法,在connect方法中會(huì)對(duì)Session添加的Listeners進(jìn)行添加時(shí)間,它會(huì)循環(huán)調(diào)用所有Listner的sessionCreated事件,其中TcpHeartbeatListener也是在這個(gè)過(guò)程中被喚起。如下面代碼所示。

private void addSessionEvent(){
    SessionEvent event = new SessionEvent(this);
    for (SessionListener listener : listeners){
        try{
            listener.sessionCreated(event);
            logger.info("SessionListener" + listener + ".sessionCreated() is invoked successfully!");
        } catch (Exception e){
            logger.error("addSessionEvent error.", e);
        }
    }
}

6.3 數(shù)據(jù)上行

數(shù)據(jù)上行特指從客戶(hù)端發(fā)送數(shù)據(jù)到服務(wù)端,數(shù)據(jù)從ChannelHander的channelRead方法獲取數(shù)據(jù)。數(shù)據(jù)包括創(chuàng)建會(huì)話(huà)、發(fā)送心跳、數(shù)據(jù)請(qǐng)求等。這里注意的是,channelRead的數(shù)據(jù)包括客戶(hù)端主動(dòng)請(qǐng)求服務(wù)端的數(shù)據(jù),以及服務(wù)端下行通知客戶(hù)端的返回?cái)?shù)據(jù),所以在處理object數(shù)據(jù)時(shí),通過(guò)數(shù)據(jù)標(biāo)識(shí)區(qū)分是請(qǐng)求-應(yīng)答,還是通知-回復(fù)。如下面代碼所示。

public void channelRead(ChannelHandlerContext ctx, Object o) throws Exception{
    try{
        if (o instanceof MessageBuf.JMTransfer) {
            SystemMessage sMsg = generateSystemMessage(ctx);
            MessageBuf.JMTransfer message = (MessageBuf.JMTransfer) o;
            //inbound
            if(message.getFormat() == SEND) {
                MessageWrapper wrapper = proxy.invoke(sMsg, message);
                if (wrapper != null)
                    this.receive(ctx, wrapper);
            }
            // outbound
            if (message.getFormat() == REPLY) {
                notify.reply(message);
            }
        }else{
            logger. warn("TcpServerHandler channelRead message is not proto.");
        }
    }catch (Exception e) {
        logger.error("TcpServerHandler TcpServerHandler handler error.", e);
        throw e;
    }
}

6.4 數(shù)據(jù)下行

數(shù)據(jù)下行通過(guò)MQ廣播機(jī)制到所有服務(wù)器,所有服務(wù)器收到消息后,獲取當(dāng)前服務(wù)器所持有的所有Session會(huì)話(huà),進(jìn)行數(shù)據(jù)廣播下行通知。

如果是點(diǎn)對(duì)點(diǎn)的數(shù)據(jù)推送下行,數(shù)據(jù)也是先廣播到所有服務(wù)器,每個(gè)服務(wù)器判斷推送的端是否是當(dāng)前服務(wù)器持有的會(huì)話(huà),如果判斷消息數(shù)據(jù)中的信息是在當(dāng)前服務(wù),則進(jìn)行推送,否則拋棄。如下面代碼所示。

private Notifyfuture doSendAsync(long seq, Messagelrapper wrapper, int timeout) throws Exception {
    if (wrapper == null) {
        throw new Exception("wrapper cannot be null.");
    }
    String sessionId = wrapper.getSessionId();
    if (StringUtils.isBlank(sessionId)) {
        throw new Exception("sessionId cannot be null.")
    }
    if (tcpConnector.exist sessionId)) {
        //start.
        final NotifyFuture future = new NotifyFuture(timeout);
        this.futureMap.put(seq, future);
        tcpConnector.send(sessionId, wrapper.getBody());
        future.setSentTime(System.currentTimeMillis()); // 置為已發(fā)送return future.
    } else {
        // tcpConnector not exist sessionId
        return null;
    }
}

通過(guò)源碼分析,數(shù)據(jù)下行則通過(guò)NotifyProxy的方式發(fā)送數(shù)據(jù),需要注意的是Netty是NIO,如果下行通知需要獲取返回值,則要將異步轉(zhuǎn)同步,所以NotifyFuture是實(shí)現(xiàn)java.util.concurrent.Future的方法,通過(guò)設(shè)置超時(shí)時(shí)間,在channelRead獲取到上行數(shù)據(jù)之后,通過(guò)seq來(lái)關(guān)聯(lián)NotifyFuture的方法。如下面代碼所示。

public void reply (MessageBuf.JMTransfer message) throws Exception {
    try {
        long seg = message.getSeq();
        final NotifyFuture future = this.futureMap.get(seg);
        if (future != null){
            future.setSuccess(true);
            futureMap.remove(seg);
        }
    } catch (Exception e) {
        throw e;
    }
}

下行的數(shù)據(jù)通過(guò)TcpConnector的send方法發(fā)送,send方式則是通過(guò)ChannelHandlerContext的writeAndFlush方法寫(xiě)入Channel,并實(shí)現(xiàn)數(shù)據(jù)下行,這里需要注意的是,之前有另一種寫(xiě)法就是cf.await,通過(guò)阻塞的方式來(lái)判斷寫(xiě)入是否成功,這種寫(xiě)法偶發(fā)出現(xiàn)BlockingOperationException的異常。如下面代碼所示。

ChannelFuture cf = cxt.writeAndFlush(message);
cf.addListener(new ChannelFutureListener() {
    @Override
    public void operationComplete(ChannelFuture future) throws PushException{
        if (future.isSuccess()) {
            logger.debug("send success.");
        } else {
            throw new PushException("Failed to send message.");
        }
        Throwable cause = future.cause() ;
        if (cause != null) {
            throw new PushException(cause);
        }
    }
});

使用阻塞獲取返回值的寫(xiě)法

boolean success = true;
boolean sent = true;
int timeout = 60;
try {
    ChannelFuture cf = cxt.write(message);
    cxt.flush();
    if (sent){
        success = cf.await(timeout);
    }
    if (cf.isSuccess()) {
        logger.debug("send success.");
    }
    Throwable cause = cf.cause();
    if (cause != null) {
        this.fireError(new PushException(cause));
    }
} catch (Throwable e) {
    this.fireError(new PushException("Failed to send message, cause:" + e. getMessage(),e));
}

關(guān)于BlockingOperationException的問(wèn)題我在StackOverflow進(jìn)行提問(wèn),非常幸運(yùn)的得到了Norman Maurer(Netty的核心貢獻(xiàn)者之一)的解答

工業(yè)級(jí)Netty網(wǎng)關(guān),京東是如何架構(gòu)的?,面試,架構(gòu),java,面試,后端,gateway,系統(tǒng)架構(gòu)

最終結(jié)論大致分析出,在執(zhí)行write方法時(shí),Netty會(huì)判斷current thread是否就是分給該Channe的EventLoop,如果是則行線(xiàn)程執(zhí)行IO操作,否則提交executor等待分配。

當(dāng)執(zhí)行await方法時(shí),會(huì)從executor里fetch出執(zhí)行線(xiàn)程,這里就需要checkDeadLock,判斷執(zhí)行線(xiàn)程和current threads是否時(shí)同一個(gè)線(xiàn)程,如果是就檢測(cè)為死鎖拋出異常BlockingOperationException。

說(shuō)在最后:有問(wèn)題可以找老架構(gòu)取經(jīng)

架構(gòu)之路,充滿(mǎn)了坎坷

架構(gòu)和高級(jí)開(kāi)發(fā)不一樣 , 架構(gòu)問(wèn)題是open/開(kāi)放式的,架構(gòu)問(wèn)題是沒(méi)有標(biāo)準(zhǔn)答案的

正由于這樣,很多小伙伴,盡管耗費(fèi)很多精力,耗費(fèi)很多金錢(qián),但是,遺憾的是,一生都沒(méi)有完成架構(gòu)升級(jí)。

所以,在架構(gòu)升級(jí)/轉(zhuǎn)型過(guò)程中,確實(shí)找不到有效的方案,可以來(lái)找40歲老架構(gòu)尼恩求助.

前段時(shí)間一個(gè)小伙伴,他是跨專(zhuān)業(yè)來(lái)做Java,現(xiàn)在面臨轉(zhuǎn)架構(gòu)的難題,但是經(jīng)過(guò)尼恩幾輪指導(dǎo),順利拿到了Java架構(gòu)師+大數(shù)據(jù)架構(gòu)師o(wú)ffer 。所以,如果遇到職業(yè)不順,找老架構(gòu)師幫忙一下,就順利多了。

推薦閱讀

《百億級(jí)訪問(wèn)量,如何做緩存架構(gòu)設(shè)計(jì)》

《多級(jí)緩存 架構(gòu)設(shè)計(jì)》

《消息推送 架構(gòu)設(shè)計(jì)》

《阿里2面:你們部署多少節(jié)點(diǎn)?1000W并發(fā),當(dāng)如何部署?》

《美團(tuán)2面:5個(gè)9高可用99.999%,如何實(shí)現(xiàn)?》

《網(wǎng)易一面:?jiǎn)喂?jié)點(diǎn)2000Wtps,Kafka怎么做的?》

《字節(jié)一面:事務(wù)補(bǔ)償和事務(wù)重試,關(guān)系是什么?》

《網(wǎng)易一面:25Wqps高吞吐寫(xiě)Mysql,100W數(shù)據(jù)4秒寫(xiě)完,如何實(shí)現(xiàn)?》

《億級(jí)短視頻,如何架構(gòu)?》

《炸裂,靠“吹?!边^(guò)京東一面,月薪40K》

《太猛了,靠“吹?!边^(guò)順豐一面,月薪30K》

《炸裂了…京東一面索命40問(wèn),過(guò)了就50W+》

《問(wèn)麻了…阿里一面索命27問(wèn),過(guò)了就60W+》

《百度狂問(wèn)3小時(shí),大廠offer到手,小伙真狠!》

《餓了么太狠:面?zhèn)€高級(jí)Java,抖這多硬活、狠活》

《字節(jié)狂問(wèn)一小時(shí),小伙offer到手,太狠了!》

《收個(gè)滴滴Offer:從小伙三面經(jīng)歷,看看需要學(xué)點(diǎn)啥?》

《尼恩 架構(gòu)筆記》《尼恩高并發(fā)三部曲》《尼恩Java面試寶典》PDF,請(qǐng)到下面公號(hào)【技術(shù)自由圈】取↓↓↓文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-725065.html

到了這里,關(guān)于工業(yè)級(jí)Netty網(wǎng)關(guān),京東是如何架構(gòu)的?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 工業(yè)級(jí)高性能3D模型渲染引擎,專(zhuān)注于3D Web輕量化!

    工業(yè)級(jí)高性能3D模型渲染引擎,專(zhuān)注于3D Web輕量化!

    一、技術(shù)概覽 HOOPS Communicator?是一個(gè)SDK,用于在Web瀏覽器中開(kāi)發(fā)3D工程應(yīng)用程序,重點(diǎn)在于: 完全訪問(wèn)工程數(shù)據(jù) 使用方便 快速發(fā)展 高性能可視化 快速模型流 靈活使用和部署 點(diǎn)擊此處獲取3D模型輕量化及格式轉(zhuǎn)換解決方案 它的主要組件是?HOOPS?Web查看器,這是一個(gè)功能強(qiáng)大

    2024年02月07日
    瀏覽(28)
  • 工業(yè)級(jí)路由器在智能交通系統(tǒng)(ITS)中的創(chuàng)新應(yīng)用

    工業(yè)級(jí)路由器在智能交通系統(tǒng)(ITS)中的創(chuàng)新應(yīng)用

    智能交通系統(tǒng)(ITS)作為一種先進(jìn)的交通管理與控制系統(tǒng),旨在提高交通運(yùn)輸系統(tǒng)的效率、安全性和便捷性。隨著科技的不斷發(fā)展,智能交通系統(tǒng)已經(jīng)成為城市交通管理的重要組成部分。而工業(yè)級(jí)路由器作為一種可靠的網(wǎng)絡(luò)通信設(shè)備,其在智能交通系統(tǒng)中的創(chuàng)新應(yīng)用正逐漸受

    2024年02月04日
    瀏覽(20)
  • 68元工業(yè)級(jí)雙核A7,全新T113核心板震撼上市!

    68元工業(yè)級(jí)雙核A7,全新T113核心板震撼上市!

    萬(wàn)象奧科全新T113核心板震撼上市,僅68元、工業(yè)級(jí)品質(zhì)、雙核A7處理器、外設(shè)豐富,詮釋極致性?xún)r(jià)比! 參數(shù)速遞 1.全志T113工業(yè)級(jí)處理器,主頻1.2GHz 2.雙核Cortex-A7+玄鐵C906 RISC-V + HiFi4 DSP異構(gòu)多核 3.內(nèi)存128MB/256MB/512MB,存儲(chǔ)256MB/8GB 4.支持Video Decoding H.265/H.264,Video Encoding JPEG/MJPEG

    2024年02月06日
    瀏覽(24)
  • 工業(yè)級(jí)開(kāi)源facechain人物寫(xiě)真sd-webui插件使用方式

    工業(yè)級(jí)開(kāi)源facechain人物寫(xiě)真sd-webui插件使用方式

    facechain人物寫(xiě)真應(yīng)用自8月11日開(kāi)源了第一版證件照生成后。目前在github(https://github.com/modelscope/facechain)上已有近6K的star,論文鏈接:FaceChain:?A?Playground?for?Identity-Preserving?Portrait?Generation:https://arxiv.org/abs/2308.14256。facechain社區(qū)非?;钴S,fork、commit數(shù)都很大,相應(yīng)截圖如下

    2024年01月20日
    瀏覽(30)
  • ToB還是ToC?工業(yè)級(jí)與消費(fèi)級(jí)AR眼鏡都能干什么?

    ToB還是ToC?工業(yè)級(jí)與消費(fèi)級(jí)AR眼鏡都能干什么?

    隨著科技的飛速發(fā)展,增強(qiáng)現(xiàn)實(shí)(AR)技術(shù)逐漸融入我們的日常生活。我國(guó)AR眼鏡消費(fèi)市場(chǎng)分為消費(fèi)級(jí)和工業(yè)級(jí)應(yīng)用。其中消費(fèi)級(jí)主要分為游戲、影視、直播以及社交購(gòu)物與旅游;工業(yè)級(jí)主要應(yīng)用于醫(yī)療、汽車(chē)、工業(yè)、船舶、電力和倉(cāng)儲(chǔ)等專(zhuān)業(yè)領(lǐng)域。我們從以下幾個(gè)方面來(lái)介紹

    2024年02月04日
    瀏覽(29)
  • 【論文閱讀】Paraformer工業(yè)級(jí)非自回歸端到端語(yǔ)音識(shí)別模型

    【論文閱讀】Paraformer工業(yè)級(jí)非自回歸端到端語(yǔ)音識(shí)別模型

    論文下載 目前ASR常用的Transformer模型雖然效果比較好,但是因?yàn)橐肓俗曰貧w的解碼器,所以計(jì)算相對(duì)效率低一些。為了加速推理,設(shè)計(jì)了非自回歸模型并行生成識(shí)別結(jié)果,比如單步自回歸模型。然而由于輸出標(biāo)簽之間的獨(dú)立性假設(shè),單步自回歸模型的效果相比自回歸模型會(huì)

    2024年02月09日
    瀏覽(25)
  • ARM/X86工業(yè)級(jí)數(shù)據(jù)采集 (DAQ) 與控制產(chǎn)品解決方案

    ARM/X86工業(yè)級(jí)數(shù)據(jù)采集 (DAQ) 與控制產(chǎn)品解決方案

    I/O設(shè)備,包括信號(hào)調(diào)理模塊、嵌入式PCI/PCIE卡、便攜式USB模塊、DAQ嵌入式計(jì)算機(jī)、模塊化DAQ系統(tǒng),以及DAQNavi/SDK軟件開(kāi)發(fā)包和DAQNavi/MCM設(shè)備狀態(tài)監(jiān)測(cè)軟件。 工業(yè)I/O產(chǎn)品適用于各種工業(yè)自動(dòng)化應(yīng)用,從機(jī)器自動(dòng)化控制、測(cè)試測(cè)量到設(shè)備狀態(tài)監(jiān)測(cè)。 工業(yè)級(jí)數(shù)據(jù)采集 (DAQ) 與控制產(chǎn)品

    2024年02月09日
    瀏覽(29)
  • 3D模型格式轉(zhuǎn)換工具HOOPS Exchange對(duì)工業(yè)級(jí)3D產(chǎn)品HOOPS的支持與應(yīng)用

    3D模型格式轉(zhuǎn)換工具HOOPS Exchange對(duì)工業(yè)級(jí)3D產(chǎn)品HOOPS的支持與應(yīng)用

    一、概述 HOOPS Exchange是一套高性能模型轉(zhuǎn)換軟件庫(kù),可以給軟件提供強(qiáng)大的模型的導(dǎo)入和導(dǎo)出功能,我們可以將其單獨(dú)作為轉(zhuǎn)換工具使用,也可以將其集成到自己的軟件中。 同樣,HOOPS 的其它產(chǎn)品,也離不開(kāi)HOOPS Exchange的支持,它們也需要HOOPS Exchange為其提供模型的導(dǎo)入和導(dǎo)

    2024年02月07日
    瀏覽(25)
  • 工業(yè)級(jí)成熟航運(yùn)港口人工智能產(chǎn)品全球前三船公司及港口碼頭落地,中國(guó)上海人工智能獨(dú)角獸中集飛瞳全球應(yīng)用最廣規(guī)模最大最先進(jìn)港航AI企業(yè)

    工業(yè)級(jí)成熟航運(yùn)港口人工智能產(chǎn)品全球前三船公司及港口碼頭落地,中國(guó)上海人工智能獨(dú)角獸中集飛瞳全球應(yīng)用最廣規(guī)模最大最先進(jìn)港航AI企業(yè)

    中國(guó)上海人工智能獨(dú)角獸CIMCAI中集飛瞳,是全球應(yīng)用落地最廣,規(guī)模最大的港口航運(yùn)人工智能高科技企業(yè)。中國(guó)人工智能獨(dú)角獸CIMCAI中集飛瞳 巔峰產(chǎn)品行業(yè)第一,產(chǎn)品在全球港區(qū)及集裝箱樞紐規(guī)模投產(chǎn)包括:全球港口碼頭智能閘口;全球港口岸邊卸/裝船;全球航運(yùn)船公司;

    2024年02月05日
    瀏覽(27)
  • 如何優(yōu)化工業(yè)5G網(wǎng)關(guān)的網(wǎng)絡(luò)信號(hào)

    如何優(yōu)化工業(yè)5G網(wǎng)關(guān)的網(wǎng)絡(luò)信號(hào)

    工業(yè)5G網(wǎng)關(guān),通常是指支持5G網(wǎng)絡(luò),具有高速率、低時(shí)延、廣接入等特點(diǎn)的高性能工業(yè)物聯(lián)網(wǎng)智能網(wǎng)關(guān),這類(lèi)網(wǎng)關(guān)具有強(qiáng)大的設(shè)備接入能力、通信協(xié)議轉(zhuǎn)換、運(yùn)算處理能力、聯(lián)動(dòng)控制能力,有助于提升工業(yè)物聯(lián)網(wǎng)整體通信效率,實(shí)現(xiàn)生產(chǎn)管理能力和水平的飛躍。 要發(fā)揮工業(yè)5

    2024年02月08日
    瀏覽(29)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包