Netty
服務(wù)端啟動(dòng)完成,這時(shí)候客戶端連接就可以接入進(jìn)來(lái)了,下面我們就來(lái)分析下客戶端連接接入的流程。
之前分析過(guò)NioEventLoop
線程啟動(dòng)方法是startThread()
,由于這個(gè)方法里面的邏輯比較復(fù)雜,并沒(méi)有展開(kāi),這一節(jié)就是從這個(gè)方法開(kāi)始分析。
(資料圖片)
private void startThread() { if (state == ST_NOT_STARTED) { if (STATE_UPDATER.compareAndSet(this, ST_NOT_STARTED, ST_STARTED)) { try { doStartThread(); } catch (Throwable cause) { STATE_UPDATER.set(this, ST_NOT_STARTED); PlatformDependent.throwException(cause); } } }}
這個(gè)方法主要主要完成2件事:
利用cas
將NioEventLoop
的狀態(tài)由ST_NOT_STARTED
修改成ST_STARTED
,即表示NioEventLoop
線程啟動(dòng);執(zhí)行doStartThread()
方法;doStartThread()
方法看著比較復(fù)雜,核心邏輯如下,向線程池執(zhí)行器executor
提交一個(gè)任務(wù),而這個(gè)線程池執(zhí)行器類型是ThreadPerTaskExecutor
,即每次執(zhí)行任務(wù)都會(huì)創(chuàng)建一個(gè)新線程,而且這個(gè)任務(wù)是無(wú)限循環(huán)的:事件輪詢selector.select()
、事件處理processSelectedKeys()
和任務(wù)隊(duì)列處理runAllTasks()
,這樣NioEventLoop
就和具體的Thread
線程進(jìn)行了關(guān)聯(lián):
private void doStartThread() { assert thread == null; //executor線程執(zhí)行器,類型是:ThreadPerTaskExecutor,即每次執(zhí)行任務(wù)都會(huì)創(chuàng)建一個(gè)新線程 executor.execute(new Runnable() { @Override public void run() { //將executor線程執(zhí)行器創(chuàng)建的線程:FastThreadLocalThread保存到EventLoop的全局變量中,相當(dāng)于thread和EventLoop的綁定 thread = Thread.currentThread(); if (interrupted) { thread.interrupt(); } boolean success = false; updateLastExecutionTime(); try { //然后調(diào)用EventLoop中的run方法進(jìn)行啟動(dòng) SingleThreadEventExecutor.this.run(); success = true; } catch (Throwable t) { logger.warn("Unexpected exception from an event executor: ", t); } } });}
該方法大致完成2件事:
thread = Thread.currentThread();
:將executor
線程池分配的線程保存起來(lái),這樣就完成了NioEventLoop
和Thread
線程的關(guān)聯(lián);SingleThreadEventExecutor.this.run()
:具體實(shí)現(xiàn)在NioEventLoop.run()
方法,所以,startThread()
核心就是分配一個(gè)線程運(yùn)行NioEventLoop.run()
方法。protected void run() { for (;;) { try { try { switch (selectStrategy.calculateStrategy(selectNowSupplier, hasTasks())) { case SelectStrategy.CONTINUE:// 默認(rèn)實(shí)現(xiàn)下,不存在這個(gè)情況 continue; case SelectStrategy.BUSY_WAIT: case SelectStrategy.SELECT: //selector.select輪詢io事件 select(wakenUp.getAndSet(false)); if (wakenUp.get()) { selector.wakeup(); } default: } } catch (IOException e) { rebuildSelector0(); handleLoopException(e); continue; } cancelledKeys = 0; needsToSelectAgain = false; final int ioRatio = this.ioRatio; if (ioRatio == 100) { try { // 處理 Channel 感興趣的就緒 IO 事件 processSelectedKeys(); } finally { // 運(yùn)行所有普通任務(wù)和定時(shí)任務(wù),不限制時(shí)間 runAllTasks(); } } else { final long ioStartTime = System.nanoTime(); try { // 處理IO事件 processSelectedKeys(); } finally { // 運(yùn)行所有普通任務(wù)和定時(shí)任務(wù),限制時(shí)間 final long ioTime = System.nanoTime() - ioStartTime; runAllTasks(ioTime * (100 - ioRatio) / ioRatio); } } } catch (Throwable t) { handleLoopException(t); } // EventLoop 優(yōu)雅關(guān)閉 try { if (isShuttingDown()) { closeAll(); if (confirmShutdown()) { return; } } } catch (Throwable t) { handleLoopException(t); } }}
該方法主要完成三件事:
select(wakenUp.getAndSet(false))
:主要執(zhí)行selector.select()
方法進(jìn)行事件輪詢processSelectedKeys()
:如果輪詢到事件,會(huì)在這里進(jìn)行處理runAllTasks()
:處理任務(wù)隊(duì)列和定時(shí)任務(wù)隊(duì)列中的任務(wù)下面我們就分別來(lái)分析下這三個(gè)方法。
private void select(boolean oldWakenUp) throws IOException { Selector selector = this.selector; try { int selectCnt = 0;//計(jì)數(shù)器置0 long currentTimeNanos = System.nanoTime(); /** * selectDeadLineNanos是select()方法運(yùn)行的截止時(shí)間 * * currentTimeNanos:可以看成當(dāng)前時(shí)間 * delayNanos(currentTimeNanos):獲取間隔時(shí)間,這里分為兩種情況: * 1、netty里面定時(shí)任務(wù)隊(duì)列scheduledTaskQueue是按照延遲時(shí)間從小到大進(jìn)行排序,如果定時(shí)任務(wù)隊(duì)列中有任務(wù), * 則只需要獲取到第一個(gè)任務(wù)的啟動(dòng)時(shí)間 - 當(dāng)前時(shí)間 = select()方法可以運(yùn)行的時(shí)間間隔,即:select()方法要在第一個(gè)定時(shí)任務(wù)執(zhí)行之前退出,這樣才能去執(zhí)行定時(shí)任務(wù) * 2、如果定時(shí)任務(wù)隊(duì)列沒(méi)有任務(wù),則delayNanos(currentTimeNanos)返回1秒對(duì)應(yīng)的時(shí)間間隔 * */ long selectDeadLineNanos = currentTimeNanos + delayNanos(currentTimeNanos); for (;;) { //計(jì)算超時(shí)時(shí)間 long timeoutMillis = (selectDeadLineNanos - currentTimeNanos + 500000L) / 1000000L; /** * timeoutMillis <= 0表示當(dāng)前已經(jīng)超時(shí)了,不能繼續(xù)向下執(zhí)行select()方法了,需要立即退出select方法,在退出前還有個(gè)判斷:selectCnt == 0 * selectCnt == 0表示第一次進(jìn)入循環(huán),則執(zhí)行下Selector.selectNow()檢出準(zhǔn)備好的網(wǎng)絡(luò)IO事件,該方法不會(huì)阻塞, */ if (timeoutMillis <= 0) { if (selectCnt == 0) { selector.selectNow(); selectCnt = 1; } break; } /** * 如果沒(méi)有超時(shí),但是通過(guò)hasTasks()判斷到taskQueue任務(wù)隊(duì)列中有需要執(zhí)行的任務(wù),這時(shí)也需要退出select()方法 * 1、利用cas將wakeUp值由false變成true,wakeUp=true表示線程處于喚醒狀態(tài),可以執(zhí)行任務(wù),進(jìn)入select()方法前會(huì)把wakeUp設(shè)置成false * 表示線程處于select()方法阻塞中,不能處理任務(wù)隊(duì)列中的任務(wù),這時(shí)只要處理Selector.select() * 2、退出前執(zhí)行一次:selector.selectNow() */ if (hasTasks() && wakenUp.compareAndSet(false, true)) { //有任務(wù),進(jìn)行一次非阻塞式的select selector.selectNow(); selectCnt = 1; break; } //調(diào)用select方法,阻塞時(shí)間為上面算出的最近一個(gè)將要超時(shí)的定時(shí)任務(wù)時(shí)間 /** * 未超時(shí),任務(wù)隊(duì)列中也沒(méi)有需要執(zhí)行的任務(wù),這時(shí)就可以放心的執(zhí)行Selector.select()方法了,這里帶上之前計(jì)算出的超時(shí)時(shí)間 * 如果之前計(jì)算時(shí)存在定時(shí)任務(wù),則保證在第一個(gè)定時(shí)任務(wù)啟動(dòng)前喚醒即可,沒(méi)有定時(shí)任務(wù)則默認(rèn)超時(shí)1秒 */ int selectedKeys = selector.select(timeoutMillis); //輪詢次數(shù)+1 selectCnt ++; /** * 發(fā)生如下幾種情況,select()方法都需要退出: * 1、selectedKeys != 0:表示輪詢到IO事件 * 2、oldWakenUp:這個(gè)是入?yún)ⅲ禐閒alse,是在select()方法中控制是否需要退出,默認(rèn)是沒(méi)有使用到的,沒(méi)有意義 * 3、wakenUp.get():進(jìn)入select()方法之前,wakeUp被設(shè)置成false,如果這里為true,表示已有外部線程對(duì)線程進(jìn)行喚醒操作, * 一般就是addTask()添加新任務(wù)時(shí)會(huì)觸發(fā)喚醒,然后及時(shí)去執(zhí)行taskQueue中的任務(wù) * 4、hasTasks() || hasScheduledTasks():判斷任務(wù)隊(duì)列和定時(shí)任務(wù)隊(duì)列是否有任務(wù)需要執(zhí)行 */ if (selectedKeys != 0 || oldWakenUp || wakenUp.get() || hasTasks() || hasScheduledTasks()) { break; } //線程中斷響應(yīng):如果線程被中斷,計(jì)數(shù)器置1,break退出for循環(huán),則退出select()檢測(cè) if (Thread.interrupted()) { if (logger.isDebugEnabled()) { logger.debug("Selector.select() returned prematurely because " + "Thread.currentThread().interrupt() was called. Use " + "NioEventLoop.shutdownGracefully() to shutdown the NioEventLoop."); } selectCnt = 1; break; } /** * 正常情況下:time >= currentTimeNanos + TimeUnit.MILLISECONDS.toNanos(timeoutMillis) * 但是,jdk nio中存在一個(gè)bug,selector.select(timeoutMillis)在沒(méi)有IO事件觸發(fā)時(shí)并不會(huì)等待超時(shí)而是立即返回,造成空輪詢 * * 下面就是Netty解決空輪詢問(wèn)題 * 1、if (time - TimeUnit.MILLISECONDS.toNanos(timeoutMillis) >= currentTimeNanos) * 表示selector.select(timeoutMillis)經(jīng)過(guò)超時(shí)后才被喚醒,屬于正常情況,把selectCnt重置成1 * 2、如果不是,表示可能發(fā)生空輪詢selectCnt不會(huì)被重置成1,for循環(huán)一次selectCnt就會(huì)被累加1次; * 3、等到 selectCnt > 門限值,默認(rèn)是512,可以通過(guò)io.netty.selectorAutoRebuildThreshold參數(shù)設(shè)置, * 則判斷真正發(fā)生了nio空循環(huán)bug,則重建Selector替換掉當(dāng)前這個(gè)出問(wèn)題的Selector */ long time = System.nanoTime(); //判斷執(zhí)行了一次阻塞式select后,當(dāng)前時(shí)間和開(kāi)始時(shí)間是否大于超時(shí)時(shí)間。(大于是很正常的,小于的話,說(shuō)明沒(méi)有執(zhí)行發(fā)生了空輪詢) if (time - TimeUnit.MILLISECONDS.toNanos(timeoutMillis) >= currentTimeNanos) { selectCnt = 1; } else if (SELECTOR_AUTO_REBUILD_THRESHOLD > 0 && selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD) { selector = selectRebuildSelector(selectCnt); selectCnt = 1; break; } currentTimeNanos = time; } } catch (CancelledKeyException e) { if (logger.isDebugEnabled()) { logger.debug(CancelledKeyException.class.getSimpleName() + " raised by a Selector {} - JDK bug?", selector, e); } }}
select()
方法代碼看著很復(fù)雜,其核心思想理解再來(lái)分析就比較簡(jiǎn)單的。select()
主要是用來(lái)執(zhí)行selector.select()
對(duì)IO
事件進(jìn)行輪詢,作為server
,這里就是輪詢OP_ACCEPT
事件,看是否有客戶端接入進(jìn)來(lái)。但是NioEventLoop
是單線程處理模式,不可能讓線程一直處理selector.select()
,還有輪詢到的事件以及任務(wù)隊(duì)列中任務(wù)等等都需要使用這個(gè)線程進(jìn)行處理,所以,上面一大堆代碼都是用來(lái)判斷什么時(shí)候退出select()
方法的,總結(jié)下退出邏輯主要分為如下幾種情況:
selector.select()
方法之前,計(jì)算出一個(gè)超時(shí)時(shí)間,超時(shí)時(shí)間默認(rèn)是1秒
,如果定時(shí)任務(wù)隊(duì)列有任務(wù),則取出第一個(gè)任務(wù)(按順序存放),保證在該定時(shí)任務(wù)執(zhí)行之前退出select()
方法即可;如果超時(shí)就退出,退出前判斷是否是第一次進(jìn)入for
循環(huán),如果是在退出之前調(diào)用一次無(wú)阻塞的selector.selectNow()
輪詢下判斷任務(wù)隊(duì)列taskQueue
中是否有任務(wù),如果有則將wakenUp
利用cas
設(shè)置成true
,執(zhí)行下無(wú)阻塞的selector.selectNow()
輪詢后退出select()
方法如果上面情況都不存在,開(kāi)始執(zhí)行阻塞selector.select(timeoutMillis)
輪詢,并將之前計(jì)算的超時(shí)時(shí)間帶上;selector.select(timeoutMillis)
執(zhí)行完成后,繼續(xù)判斷是否需要退出select()
方法,發(fā)生如下任一情況則要退出:輪詢到IO
事件,則需要退出select()
方法去處理事件外部線程對(duì)對(duì)線程執(zhí)行過(guò)喚醒操作,比如addTask()
等操作需要喚醒線程執(zhí)行隊(duì)列任務(wù),才能及時(shí)去執(zhí)行taskQueue
中的任務(wù):進(jìn)入select()
方法之前,wakeUp
被設(shè)置成false
,如果這里為true
,表示已有外部線程對(duì)線程進(jìn)行喚醒操作任務(wù)隊(duì)列taskQueue
或定時(shí)任務(wù)隊(duì)列scheduledTaskQueue
中有需要處理的任務(wù),這時(shí)需要退出select()
方法,轉(zhuǎn)去執(zhí)行任務(wù)private void processSelectedKeys() { //selectedKeys != null表示已對(duì)Selector進(jìn)行優(yōu)化過(guò),替換掉Selector內(nèi)部的selectedKeys,正常情況下進(jìn)入這個(gè)流程 if (selectedKeys != null) { processSelectedKeysOptimized(); } else { processSelectedKeysPlain(selector.selectedKeys()); } }
processSelectedKeys()
主要是對(duì)selector.select()
方法輪詢到的事件進(jìn)行處理,作為server
,如果輪詢到OP_ACCEPT
,就表示有客戶端接入進(jìn)來(lái)了,那我們就跟蹤下這個(gè)方法,看接入進(jìn)來(lái)的客戶端處理流程。
Netty
是對(duì)Selector
進(jìn)行了優(yōu)化,將selectedKeys
由Set
實(shí)現(xiàn)替換成了數(shù)組實(shí)現(xiàn),提升性能,所以,這里一般走的是processSelectedKeysOptimized()
這個(gè)流程:
private void processSelectedKeysOptimized() { for (int i = 0; i < selectedKeys.size; ++i) { final SelectionKey k = selectedKeys.keys[i]; selectedKeys.keys[i] = null; //k.attachment()獲取到的就是NioServerSocketChannel final Object a = k.attachment(); if (a instanceof AbstractNioChannel) {//一般是走這個(gè)分支流程 processSelectedKey(k, (AbstractNioChannel) a); } else { @SuppressWarnings("unchecked") NioTask task = (NioTask) a; processSelectedKey(k, task); } if (needsToSelectAgain) { selectedKeys.reset(i + 1); selectAgain(); i = -1; } }}
這里關(guān)鍵一點(diǎn)是Object a = k.attachment();
,之前分析過(guò)向selector
注冊(cè)時(shí)把NioServerSocketChannel
作為attachment
添加進(jìn)去,所以,這里取出來(lái)的就是NioServerSocketChannel
對(duì)象。processSelectedKey()
方法通過(guò)if判斷事件類型進(jìn)行處理,server
端這里肯定是OP_ACCEPT
:
if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) { unsafe.read();}
具體的處理邏輯交由Unsafe
對(duì)象進(jìn)行處理:
public void read() { assert eventLoop().inEventLoop(); final ChannelConfig config = config(); final ChannelPipeline pipeline = pipeline(); final RecvByteBufAllocator.Handle allocHandle = unsafe().recvBufAllocHandle(); allocHandle.reset(config); boolean closed = false; Throwable exception = null; try { try { do { //doReadMessages()讀出來(lái)一個(gè)客戶端連接的Channel int localRead = doReadMessages(readBuf); if (localRead == 0) { break; } if (localRead < 0) { closed = true; break; } allocHandle.incMessagesRead(localRead); } while (allocHandle.continueReading()); } catch (Throwable t) { exception = t; } int size = readBuf.size(); for (int i = 0; i < size; i ++) { readPending = false; pipeline.fireChannelRead(readBuf.get(i)); } readBuf.clear(); allocHandle.readComplete(); pipeline.fireChannelReadComplete(); if (exception != null) { closed = closeOnReadError(exception); pipeline.fireExceptionCaught(exception); } if (closed) { inputShutdown = true; if (isOpen()) { close(voidPromise()); } } } finally { if (!readPending && !config.isAutoRead()) { removeReadOp(); } }}
這個(gè)類主要完成2件事:
doReadMessages(readBuf)
:調(diào)用serverSocketChannel.accept()
接收到客戶端連接socketChannel
,并封裝成Netty中類型:NioSocketChannel
,然后放入到readBuf集合中;pipeline.fireChannelRead(readBuf.get(i));
:將讀入的客戶端連接作為參數(shù),即NioSocketChannel
對(duì)象,通過(guò)pipeline觸發(fā)channelRead
事件進(jìn)行handler
間傳播,注意這里的pipeline
是NioServerSocketChannel
中的,即server
端的。最終會(huì)進(jìn)入到ServerBootstrapAcceptor#channelRead
方法中進(jìn)行處理。public void channelRead(ChannelHandlerContext ctx, Object msg) { final Channel child = (Channel) msg; child.pipeline().addLast(childHandler); setChannelOptions(child, childOptions, logger); for (Entry, Object> e: childAttrs) { child.attr((AttributeKey
這個(gè)方法主要完成3件事:
child.pipeline().addLast(childHandler)
:向NioSocketChannel
中添加ServerBootstrap.childHandler(new TestServerInitializer())
,后面通過(guò)觸發(fā)handlerAdded()
時(shí)回調(diào)initChannel()
實(shí)現(xiàn)向pipeline添加handler
;設(shè)置option
和attr
信息;childGroup.register(child)
:將客戶端連接NioSocketChannel
注冊(cè)到NioEventLoop
實(shí)例上,基本和之前分析NioServerSocketChannel
注冊(cè)邏輯一致,這個(gè)過(guò)程中會(huì)觸發(fā)三個(gè)事件:handlerAdded
、channelRegistered
和channelActive
,之前NioServerSocketChannel
注冊(cè)時(shí)只能觸發(fā)前兩個(gè),綁定端口后才能觸發(fā)第三個(gè)事件,客戶端連接不存在端口綁定問(wèn)題,所以這里會(huì)直接觸發(fā)channelActive
。和NioServerSocketChannel一樣,真正向selector
注冊(cè)感興趣事件就是在channelActive
觸發(fā)這里:public void channelActive(ChannelHandlerContext ctx) { //觸發(fā)channelActive事件傳播 ctx.fireChannelActive(); //向selector注冊(cè)真正關(guān)注的事件 readIfIsAutoRead();}
channelActive
和之前分析NioServerSocketChannel
的處理邏輯一致,就不再分析。
分析到這里,基本搞清楚了客戶端接入的處理流程,現(xiàn)在再次總結(jié)下:
NioServerSocketChannel
綁定的NioEventLoop
不停輪詢OP_ACCEPT
,觸發(fā)后通過(guò)調(diào)用java api
獲取到ServerSocket
,然后包裝成NioSocketChannel
;然后觸發(fā)channelRead
事件傳播,然后會(huì)進(jìn)入server pipeline
中非常重要的一個(gè)handler
:ServerBootstrapAcceptor
,連接處理器專門處理客戶端連接;在ServerBootstrapAcceptor#channelRead()
方法中,完成NioSocketChannel
的設(shè)置:option
、attr
、handler
添加等;最重要的是將channel
注冊(cè)到NioEventLoop
上,注冊(cè)過(guò)程中會(huì)觸發(fā)三種事件:handlerAdded
、channelRegistered
和channelActive
,和之前分析server channel
注冊(cè)過(guò)程一樣,最終在channelActive
這里向selector
注冊(cè)真正感興趣IO事件
,整個(gè)流程全部完成。 關(guān)鍵詞:
最新推薦
1、安民巷古民居位于福州市安民巷。文章到此就分享結(jié)束,希望對(duì)大家有
對(duì)于selfiecity是什么軟件這個(gè)問(wèn)題感興趣的朋友應(yīng)該很多,這個(gè)也是目前
夫妻離婚一方出軌財(cái)產(chǎn)的分割可以由雙方協(xié)商處理,協(xié)商的時(shí)候還可以在自
謝帆是WE老板的好友,他也是第一個(gè)爆料EDG簽了Uzi的人,并且也爆料過(guò)WE
在比賽中,李詩(shī)灃表現(xiàn)出了極強(qiáng)的競(jìng)技實(shí)力和嚴(yán)謹(jǐn)?shù)谋荣悜B(tài)度,讓人嘆為觀
2023年法網(wǎng)首輪,德約科維奇三盤直落戰(zhàn)勝了首次出戰(zhàn)大滿貫正賽的美國(guó)選
從奧運(yùn)會(huì)期間接濟(jì)被媳婦馬蓉戴了綠帽子的王寶強(qiáng)開(kāi)始,郭斌就被外界認(rèn)為
CSGO最劃算交易網(wǎng)站是哪個(gè)CSGO飾品交易網(wǎng)站最劃算大全還是值得大家去體驗(yàn)一把,如果你擔(dān)心虧錢,可以先...
手機(jī)這種移動(dòng)通訊設(shè)備閑置已經(jīng)相當(dāng)?shù)钠占傲?,大多?shù)的手機(jī)用戶,對(duì)手機(jī)
產(chǎn)假工資如何支付正常進(jìn)行支付。會(huì)由生育保險(xiǎn)賬戶進(jìn)行支出。法律依據(jù):《社會(huì)保險(xiǎn)法》第五十四條 用人...
夫妻沒(méi)有結(jié)婚證財(cái)產(chǎn)怎么分沒(méi)有領(lǐng)取結(jié)婚證的夫妻不是合法的夫妻,不是法律上的夫妻,自然也不用走法律上...
有撫養(yǎng)權(quán)能帶孩子在身邊嗎可以的,撫養(yǎng)權(quán)就是指直接撫養(yǎng)照顧的權(quán)利。法律依據(jù):《婚姻法》第三十六條 ...
自愿離婚需要帶什么資料離婚需要出具雙方的戶口簿、身份證、結(jié)婚證、雙方當(dāng)事人共同簽署的離婚協(xié)議書(shū)等...
撫養(yǎng)費(fèi)該誰(shuí)負(fù)擔(dān)離婚后,一方撫養(yǎng)的子女,另一方應(yīng)負(fù)擔(dān)必要的生活費(fèi)和教育費(fèi)的一部或全部,就是說(shuō),撫養(yǎng)...
女方有理由不出撫養(yǎng)費(fèi)嗎沒(méi)有。因?yàn)楦鶕?jù)婚姻法,一方撫養(yǎng)的子女,另一方應(yīng)負(fù)擔(dān)必要的生活費(fèi)和教育費(fèi)的一...
離婚案件房產(chǎn)的分割分哪兩種可以選擇房產(chǎn)或貨幣補(bǔ)償。法律依據(jù):《物權(quán)法》第一百條 共有人可以協(xié)商確...
夫妻共同財(cái)產(chǎn)的特別規(guī)定是什么法律分析:夫妻對(duì)共同財(cái)產(chǎn),有平等的處理權(quán)。離婚時(shí),夫妻的共同財(cái)產(chǎn)由雙...
1、逆水寒追命支線神秘的箱子任務(wù)攻略介紹:破廟場(chǎng)景,正中間馬車中三
滬深兩市成交額突破8000億元
賽前,國(guó)足球員的號(hào)碼確定,武磊將繼續(xù)身穿7號(hào)球衣,艾克森9號(hào),10號(hào)歸
直播吧6月15日訊RAC1記者RogerSaperas報(bào)道了關(guān)于巴薩引進(jìn)基米希和維克
憑借這一冠,她不但成為2007年的海寧以來(lái)首位在羅蘭·加洛斯實(shí)現(xiàn)衛(wèi)冕的
北京時(shí)間6月15日消息,2023年U19男籃世界杯將于6月24日-7月2日在匈牙利
文|朱志強(qiáng)、宋照康、孫澤志圖|翟一龍、周杰、冉思遠(yuǎn)、李進(jìn)平大漠礪精兵
1、無(wú)人直升機(jī)的構(gòu)造和旋翼飛行器差不多,其工作原理和旋翼式直升機(jī)也
顯然,“梅羅時(shí)代”的誕生離不開(kāi)當(dāng)年西甲的繁榮,皇馬與巴薩兩大豪門的
6月15日消息,利物浦3500萬(wàn)英鎊搞定麥卡利斯特,這給今夏轉(zhuǎn)會(huì)打了一個(gè)
并肩作戰(zhàn)是熱愛(ài)的【無(wú)限】可能,在桀然閃耀的星途之行中,操控【無(wú)線】
搜狐體育消息,北京時(shí)間6月15日,據(jù)媒體人丁旭消息,國(guó)足23名球員的球
為傳承弘揚(yáng)“奉獻(xiàn)、友愛(ài)、互助”的志愿精神,全力為考生以及陪考的家長(zhǎng)
6月12日,五月天演唱會(huì)官方售票平臺(tái)紛玩島APP發(fā)布公告稱,紛玩島APP工
大連航運(yùn)職業(yè)技術(shù)學(xué)院船舶電子電氣技術(shù)(??祁?專業(yè)介紹各位同學(xué)大家好
正義網(wǎng)清遠(yuǎn)6月14日電(通訊員唐艷)為檢驗(yàn)近期開(kāi)展的大數(shù)據(jù)應(yīng)用工具實(shí)操
正義網(wǎng)清遠(yuǎn)6月14日電(通訊員高海蘭)近年來(lái),廣東省英德市檢察院在開(kāi)展未
6月5日有6只新債招標(biāo)。
1、百度文庫(kù)直接下載·······················...
(點(diǎn)擊圖片查看視頻)日前,山西臨汾堯都區(qū)的38萬(wàn)畝小麥進(jìn)入夏收高峰期
處理違章扣分應(yīng)當(dāng)要到車輛轄區(qū)車管所或交警隊(duì)處理,具體需要攜帶的資料
汽車違章罰款扣分網(wǎng)上交罰款的的方式是用車主身份證在交管12123官方應(yīng)
來(lái)為大家解答以上問(wèn)題,拼好貨商城app下載,拼好貨商城很多人還不知道
6月14日是第20個(gè)世界獻(xiàn)血者日,從天津市血液中心獲悉,天津市已連續(xù)12
6月13日,市教育局發(fā)布《關(guān)于做好2023年普通中小學(xué)招生入學(xué)工作的
華夏鼎利債券6月14日每10份分紅0 65元。本次分紅為2023年度的第1次分紅
為加快農(nóng)作物病蟲(chóng)害綠色防控關(guān)鍵技術(shù)的推廣應(yīng)用,促進(jìn)農(nóng)藥減量增效,保
除了放棄姆巴佩之外,皇家馬德里還拒絕了來(lái)自切爾西的“敲竹杠”,老佛
直播吧6月15日訊西班牙媒體Relevo的記者M(jìn)atteoMoretto報(bào)道,AC米蘭和一
作為國(guó)內(nèi)知名的膏藥代加工企業(yè)之一,仙佑集團(tuán)已經(jīng)擁有了多年的歷史,一直致力于膏藥代加工、膏藥加工、...
1、ct是寶石重量單位,克拉。2、1CT=200mg,多用于稱量寶石,克拉(Ct)
很多家庭為了安全起見(jiàn),會(huì)安裝大玻璃,不過(guò)對(duì)于樓層較高的業(yè)主來(lái)說(shuō),最
蘇鐵植物起源于蘇鐵植物還保存得下來(lái)所以它被稱為植物界的活化石最近,
不降價(jià)的蔚來(lái)降價(jià)了 全球熱資訊
1不降價(jià)的蔚來(lái)降價(jià)了 全球熱資訊
2精彩看點(diǎn):乘聯(lián)會(huì):6月1日-11日乘用車市場(chǎng)零售42.5萬(wàn)輛
3理想汽車CEO李想發(fā)文稱:“同行在干什么,我們的天眼系統(tǒng)都能監(jiān)測(cè)到”
4“青春版”起售價(jià)不到10萬(wàn)元,入門即高配 上汽大眾朗逸新銳正式上市-速讀
5百臺(tái)一汽豐田格瑞維亞成達(dá)沃斯官方貴賓用車
和達(dá)?云頂 | 與夏日院墅 來(lái)一場(chǎng)臻情邂逅
和達(dá)?云頂 | 與夏日院墅 來(lái)一場(chǎng)臻情邂逅
RNG老板辟謠:沒(méi)有強(qiáng)制Uzi退役,也沒(méi)有卡合同!慘遭2位大佬打臉-全球視點(diǎn)
李詩(shī)灃2-戰(zhàn)勝新加坡選手駱建佑,晉級(jí)印尼羽毛球公開(kāi)賽男單八強(qiáng)-世界報(bào)資訊
天天日?qǐng)?bào)丨上周ATP網(wǎng)壇 ,屬于穆雷,屬于德約,更屬于80后選手(下)
環(huán)球信息:王楠億萬(wàn)家產(chǎn)老公曾因故意開(kāi)日本酒店水管被罵,他真是個(gè)壞人嗎?
國(guó)足最新球員號(hào)碼,武磊7號(hào)艾克森9號(hào),泰山隊(duì)5人號(hào)碼確定
全球看點(diǎn):《廣西“最美撐傘女孩”找到了》后續(xù):她用獎(jiǎng)金購(gòu)買慰問(wèn)品回報(bào)鄉(xiāng)鄰
每日精選:用法治力量推動(dòng)濕地保護(hù)高質(zhì)量發(fā)展 2023年廣西環(huán)保世紀(jì)行宣傳活動(dòng)啟動(dòng)
重實(shí)效 強(qiáng)實(shí)干 抓落實(shí)丨廣州市國(guó)資國(guó)企入桂開(kāi)展產(chǎn)業(yè)合作 全球訊息
前5月廣西外貿(mào)增速快于全國(guó)48.5個(gè)百分點(diǎn) 進(jìn)出口2875.1億元,同比增長(zhǎng)53.2%|全球短訊
形容煙花的詞語(yǔ)有哪些?古人形容煙花漂亮詩(shī)詞合集來(lái)了
房地產(chǎn)工作總結(jié)怎么寫(xiě)?房地產(chǎn)新入職早上自我介紹來(lái)了
浪漫情書(shū)范本來(lái)了!一段簡(jiǎn)短而深情的告白看這里
激勵(lì)人心的電影金句有哪些?人生必看的十大勵(lì)志電影一覽
表達(dá)父愛(ài)的古詩(shī)有哪些?《我的父親》艾青原文看這里
賣電視機(jī)的廣告文案怎么寫(xiě)?品質(zhì)宣傳經(jīng)典廣告詞都在這兒
最新快訊!拒續(xù)約后,姆巴佩爆猛料,梅西平反,巴黎演砸,皇馬卷入,太黑暗
當(dāng)前視點(diǎn)!記者:AC米蘭和一些西班牙球隊(duì)均有意免簽盧卡-羅梅羅
晚上8點(diǎn),國(guó)際足聯(lián)重磅官宣!24天后實(shí)行2大變革,K聯(lián)賽先做榜樣 熱議
曝趙泰隆孫喆加盟廣西威壯 扣籃+三分雙料冠軍離開(kāi)CBA
群眾一句“有曹睿在,我心里就踏實(shí)”,是對(duì)他最好的褒獎(jiǎng)
中新網(wǎng)丨張家川:派出所打造矛盾糾紛解決新機(jī)制專解群眾煩心事 每日消息
盛夏游太行,暑中覓清涼!這才是打開(kāi)八泉峽的正確方式
電腦怎么添加打印機(jī) 電腦怎么添加打印機(jī)掃描功能 世界關(guān)注
瑞星安全瀏覽器怎么卸載刪除 瑞星安全網(wǎng)址導(dǎo)航卸載-天天觀點(diǎn)
全球簡(jiǎn)訊:怎樣手機(jī)開(kāi)店 金元寶微店手機(jī)開(kāi)店軟件使用圖文教程
百度地圖App中怎么查看衛(wèi)星圖和熱力圖 百度地圖怎么看衛(wèi)星地圖實(shí)景 快看
父親三周年祭奠對(duì)聯(lián)有哪些?祭祀對(duì)聯(lián)大全來(lái)了
高一英語(yǔ)語(yǔ)法知識(shí)點(diǎn)總結(jié)來(lái)了!英語(yǔ)語(yǔ)法基礎(chǔ)知識(shí)大全筆記一覽
6月14日上海期貨交易所鋅錠倉(cāng)單統(tǒng)計(jì)
離休和退休的區(qū)別有哪些?離退休人員死亡一次性撫恤金發(fā)放辦法看這里
關(guān)于籃球的論文題目有哪些?籃球技術(shù)論文3000字看這里
羅體:國(guó)米關(guān)注馬馬達(dá)什維利,但維卡里奧仍是奧納納替代者首選
快播:2023印尼羽毛球公開(kāi)賽:劉雨辰、歐烜屹逆轉(zhuǎn)晉級(jí)
世界訊息:拒離隊(duì)!巴薩亂了!虧5600萬(wàn),哈維沉默,下最后通牒,拿他沒(méi)辦法
聚焦:溫網(wǎng)獎(jiǎng)金再創(chuàng)新高,德約科維奇若冠軍將拿2000萬(wàn),沖擊第24冠!
世界動(dòng)態(tài):檢車過(guò)期多久要處罰新規(guī)定了
2023年西安市中考政策發(fā)布 2所初中學(xué)業(yè)水平考試被新納入城六區(qū)管理-焦點(diǎn)精選
重點(diǎn)聚焦!穩(wěn)經(jīng)濟(jì) 促發(fā)展 強(qiáng)信心|簡(jiǎn)化行政審批 提升服務(wù)效率
當(dāng)前要聞:測(cè)血糖用的稀有GBA卡帶,被收錄進(jìn)了游戲歷史基金會(huì)
羅體:羅馬近日將官宣恩迪卡 米蘭巴黎試圖截胡但穆帥說(shuō)服了球員 環(huán)球最資訊
今頭條!意甲媒體透露:楚克烏澤已同意加盟米蘭,雙方就合同問(wèn)題正在溝通
【獨(dú)家焦點(diǎn)】記者:拜仁將和曼聯(lián)競(jìng)爭(zhēng)金玟哉,也在關(guān)注凱塞多
天天實(shí)時(shí):馬琳下課!孔令輝回歸?李隼發(fā)言透露態(tài)度,國(guó)乒球迷爭(zhēng)議不斷
全球微速訊:省級(jí)名單!宜昌4個(gè)鄉(xiāng)鎮(zhèn)35個(gè)村入選
美聯(lián)儲(chǔ)暫停加息 美股收盤漲跌不一 科技股多數(shù)上漲英偉達(dá)大漲超4%|今日觀點(diǎn)
最新戰(zhàn)報(bào)!印尼公開(kāi)賽第二比賽日,中國(guó)隊(duì)7勝3負(fù),陳雨菲繼續(xù)抗日
克羅斯不點(diǎn)名批評(píng)阿扎爾:他花了皇馬很多錢 但職業(yè)生涯已經(jīng)完蛋了
聯(lián)系我們:55 16 53 8@qq.com
關(guān)于我們| 聯(lián)系方式| 版權(quán)聲明| 供稿服務(wù)| 友情鏈接
塞北網(wǎng) 版權(quán)所有,未經(jīng)書(shū)面授權(quán)禁止使用
京ICP備2021034106號(hào)-10 營(yíng)業(yè)執(zhí)照公示信息
Copyright©2008-2020 By www.twwot.com All Rights Reserved