您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“如何使用Netty實(shí)現(xiàn)多路復(fù)用的client”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
Netty只提供的異步傳輸數(shù)據(jù)的方式,但是并沒(méi)有實(shí)現(xiàn)多路復(fù)用的client。
一個(gè)分布式的客戶端代碼基本是這個(gè)樣子的:
public Response sent(final Request request) { channel.writeAndFlush(request); return clientChannelInitializer.getResponse(request.getMessageId()); }
首先通過(guò)channel發(fā)送一個(gè)請(qǐng)求到server,然后等待server返回的結(jié)果。
但是Netty是異步的,writeAndFlush這個(gè)方法,只是告訴server,我要發(fā)數(shù)據(jù)了,然后就馬上返回了。所以這時(shí)直接調(diào)用getResponse,會(huì)得不到值。因?yàn)閚etty是在回調(diào)里面寫返回值的。
解決的辦法是,使用BlockingQueue接收返回的數(shù)據(jù)。一旦BlockingQueue有數(shù)據(jù)了,就take出來(lái)。如果沒(méi)數(shù)據(jù),就一直等待。
在單線程里,這個(gè)辦法沒(méi)問(wèn)題。這就要確保Netty的client只被一個(gè)線程訪問(wèn)。如果是多線程同時(shí)訪問(wèn),因?yàn)楫惒降脑?,有可能第二個(gè)線程的返回值被第一個(gè)線程拿到。舉個(gè)例子:
線程A使用client發(fā)送請(qǐng)求
線程A從BlockingQueue中取數(shù)據(jù)。這時(shí)Queue為空,線程A等待。
server接受并開啟一個(gè)線程處理請(qǐng)求A
線程B使用client發(fā)送請(qǐng)求
線程B從BlockingQueue中取數(shù)據(jù)。這時(shí)Queue為空,線程B也等待。
server接受并開啟另一個(gè)線程處理請(qǐng)求B
線程B的請(qǐng)求處理速度較快,先返回
client將返回值B寫入BlockingQueue
BlockQueue有數(shù)據(jù)了,線程A take到數(shù)據(jù),但是是線程B的結(jié)果
這就導(dǎo)致request和response不匹配。
要解決這個(gè)問(wèn)題有3個(gè)辦法。
使用短連接,每次請(qǐng)求new一個(gè)client,接收的response后close掉這個(gè)client。這個(gè)的缺點(diǎn)很明顯,這就相當(dāng)于http服務(wù)器了,不能發(fā)揮內(nèi)網(wǎng)長(zhǎng)連接的優(yōu)勢(shì)。
使用連接池,每次從連接池里拿一個(gè)client,接收完response后將這個(gè)client返還連接池。這個(gè)就有點(diǎn)像數(shù)據(jù)庫(kù)連接池。這個(gè)方法沒(méi)什么缺點(diǎn),但是需要自己實(shí)現(xiàn)連接池。
使用單一client,但是在request中生成一個(gè)唯一的messageId,可以是nanoTime。然后server處理完后,在response中也返回這個(gè)messageId。這樣在client不是維護(hù)一個(gè)BlockingQueue,而是維護(hù)一個(gè)ConcurrentHashMap,key是messageId,value是一個(gè)空的BlockingQueue。當(dāng)client發(fā)送resquest到server時(shí),在Map里寫入messageId,并實(shí)例化一個(gè)BlockingQueue(為了優(yōu)化,size可以是1)。然后等待這個(gè)BlockingQueue有值。在接收到response的回調(diào)方法里,根據(jù)messageId取出blockingQueue的值,然后刪除掉這個(gè)Key。
我自己實(shí)現(xiàn)了第三種方式,具體代碼請(qǐng)參見(jiàn):
https://github.com/terrymanu/miracle-framework/tree/master/miracle-framework-remote/miracle-framework-remote-netty
“如何使用Netty實(shí)現(xiàn)多路復(fù)用的client”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。