国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Node - 異步IO和事件循環(huán)

MyFaith / 2668人閱讀

摘要:它是在的基礎(chǔ)上改進(jìn)的一種方案,通過對(duì)文件描述符上的事件狀態(tài)進(jìn)行判斷。檢索新的事件執(zhí)行與相關(guān)的回調(diào)幾乎所有情況下,除了關(guān)閉的回調(diào)函數(shù),它們由計(jì)時(shí)器和排定的之外,其余情況將在此處阻塞。執(zhí)行事件的,例如或者。

前言

學(xué)習(xí)Node就繞不開異步IO, 異步IO又與事件循環(huán)息息相關(guān), 而關(guān)于這一塊一直沒有仔細(xì)去了解整理過, 剛好最近在做項(xiàng)目的時(shí)候, 有了一些思考就記錄了下來, 希望能盡量將這一塊的知識(shí)整理清楚, 如有錯(cuò)誤, 請(qǐng)指點(diǎn)輕噴~~

一些概念 同步異步 & 阻塞非阻塞

查閱資料的時(shí)候, 發(fā)現(xiàn)很多人都對(duì)異步和非阻塞的概念有點(diǎn)混淆, 其實(shí)兩者是完全不同的, 同步異步指的是行為即兩者之間的關(guān)系, 而阻塞非阻塞指的是狀態(tài)即某一方

以前端請(qǐng)求為一個(gè)例子,下面的代碼很多人都應(yīng)該寫過

$.ajax(url).succedd(() => {
    ......
    // to do something
})

同步異步
如果是同步的話, 那么應(yīng)該是client發(fā)起請(qǐng)求后, 一直等到serve處理請(qǐng)求完成后才返回繼續(xù)執(zhí)行后續(xù)的邏輯, 這樣client和serve之間就保持了同步的狀態(tài)。

如果是異步的話, 那么應(yīng)該是client發(fā)起請(qǐng)求后, 立即返回, 而請(qǐng)求可能還沒有到達(dá)server端或者請(qǐng)求正在處理, 當(dāng)然在異步情況下, client端通常會(huì)注冊(cè)事件來處理請(qǐng)求完成后的情況, 如上面的succeed函數(shù)。

阻塞非阻塞
首先需要明白一個(gè)概念, Js是單線程, 但是瀏覽器并不是, 事實(shí)上你的請(qǐng)求是瀏覽器的另一個(gè)線程在跑。

如果是阻塞的話, 那么該線程就會(huì)一直等到這個(gè)請(qǐng)求完成之后才能被釋放用于其他請(qǐng)求

如果是非阻塞的話, 那么該線程就可以發(fā)起請(qǐng)求后而不用等請(qǐng)求完成繼續(xù)做其他事情。

總結(jié)
之所以經(jīng)常會(huì)混亂是因?yàn)闆]有說清楚討論的是哪一部分(下面會(huì)提到), 所以同步異步討論的對(duì)象是雙方, 而阻塞非阻塞討論的對(duì)象是自身

IO和CPU

Io和Cpu是可以同時(shí)進(jìn)行工作的。

IO:

I/O(英語(yǔ):Input/Output),即輸入/輸出,通常指數(shù)據(jù)在內(nèi)部存儲(chǔ)器和外部存儲(chǔ)器或其他周邊設(shè)備之間的輸入和輸出。

cpu

解釋計(jì)算機(jī)指令以及處理計(jì)算機(jī)軟件中的數(shù)據(jù)。
Node中的異步IO模型

IO分為磁盤IO和網(wǎng)絡(luò)IO, 其具有兩個(gè)步驟

等待數(shù)據(jù)準(zhǔn)備 (Waiting for the data to be ready)

將數(shù)據(jù)從內(nèi)核拷貝到進(jìn)程中 (Copying the data from the kernel to the process)

Node中的磁盤Io

以下的討論基于*nix系統(tǒng)。
理想的異步Io應(yīng)該像上面討論的一樣, 如圖:

而實(shí)際上, 我們的系統(tǒng)并不能完美的實(shí)現(xiàn)這樣的一種調(diào)用方式, Node的異步IO, 如讀取文件等采用的是線程池的方式來實(shí)現(xiàn), 可以看到, Node通過另外一個(gè)線程來進(jìn)行Io操作, 完成后再通知主線程:

而在window下, 則是利用IOCP接口來完成, IOCP從用戶的角度來說確實(shí)是完美的異步調(diào)用方式, 而實(shí)際也是利用內(nèi)核中的線程池, 其與nix系統(tǒng)的不同在于后者的線程池是用戶層提供的線程池。

Node中的網(wǎng)絡(luò)Io

在進(jìn)入主題之前, 我們先了解下Linux的Io模式, 這里推薦大家看這篇文章, 大致總結(jié)如下:

阻塞 I/O(blocking IO)

所以,blocking IO的特點(diǎn)就是在IO執(zhí)行的兩個(gè)階段都被block了。

非阻塞 I/O(nonblocking IO)

當(dāng)用戶進(jìn)程發(fā)出read操作時(shí),如果kernel中的數(shù)據(jù)還沒有準(zhǔn)備好,那么它并不會(huì)block用戶進(jìn)程,而是立刻返回一個(gè)error。從用戶進(jìn)程角度講 ,它發(fā)起一個(gè)read操作后,并不需要等待,而是馬上就得到了一個(gè)結(jié)果。用戶進(jìn)程判斷結(jié)果是一個(gè)error時(shí),它就知道數(shù)據(jù)還沒有準(zhǔn)備好,于是它可以再次發(fā)送read操作。一旦kernel中的數(shù)據(jù)準(zhǔn)備好了,并且又再次收到了用戶進(jìn)程的system call,那么它馬上就將數(shù)據(jù)拷貝到了用戶內(nèi)存,然后返回。

I/O 多路復(fù)用( IO multiplexing)

所以,I/O 多路復(fù)用的特點(diǎn)是通過一種機(jī)制一個(gè)進(jìn)程能同時(shí)等待多個(gè)文件描述符,而這些文件描述符(套接字描述符)其中的任意一個(gè)進(jìn)入讀就緒狀態(tài),select()函數(shù)就可以返回。

異步 I/O(asynchronous IO)

用戶進(jìn)程發(fā)起read操作之后,立刻就可以開始去做其它的事。而另一方面,從kernel的角度,當(dāng)它受到一個(gè)asynchronous read之后,首先它會(huì)立刻返回,所以不會(huì)對(duì)用戶進(jìn)程產(chǎn)生任何block。然后,kernel會(huì)等待數(shù)據(jù)準(zhǔn)備完成,然后將數(shù)據(jù)拷貝到用戶內(nèi)存,當(dāng)這一切都完成之后,kernel會(huì)給用戶進(jìn)程發(fā)送一個(gè)signal,告訴它read操作完成了。

而在Node中, 采用的是I/O 多路復(fù)用的模式, 而在I/O多路復(fù)用的模式中, 又具有read, select, poll, epoll等幾個(gè)子模式, Node采用的是最優(yōu)的epoll模式, 這里簡(jiǎn)單說下其中的區(qū)別, 并且解釋下為什么epoll是最優(yōu)的。

read
read。它是一種最原始、性能最低的一種,它會(huì)重復(fù)檢查I/O的狀態(tài)來完成數(shù)據(jù)的完整讀取。在得到最終數(shù)據(jù)前,CPU一直耗用在I/O狀態(tài)的重復(fù)檢查上。圖1是通過read進(jìn)行輪詢的示意圖。

select
select。它是在read的基礎(chǔ)上改進(jìn)的一種方案,通過對(duì)文件描述符上的事件狀態(tài)進(jìn)行判斷。圖2是通過select進(jìn)行輪詢的示意圖。select輪詢具有一個(gè)較弱的限制,那就是由于它采用一個(gè)1024長(zhǎng)度的數(shù)組來存儲(chǔ)狀態(tài),也就是說它最多可以同時(shí)檢查1024個(gè)文件描述符。

poll
poll。poll比select有所改進(jìn),采用鏈表的方式避免數(shù)組長(zhǎng)度的限制,其次它可以避免不必要的檢查。但是文件描述符較多的時(shí)候,它的性能是十分低下的。

epoll
該方案是Linux下效率最高的I/O事件通知機(jī)制,在進(jìn)入輪詢的時(shí)候如果沒有檢查到I/O事件,將會(huì)進(jìn)行休眠,直到事件發(fā)生將它喚醒。它是真實(shí)利用了事件通知,執(zhí)行回調(diào)的方式,而不是遍歷查詢,所以不會(huì)浪費(fèi)CPU,執(zhí)行效率較高。

除此之外, 另外的poll和select還具有以下的缺點(diǎn)(引用自文章):

每次調(diào)用select,都需要把fd集合從用戶態(tài)拷貝到內(nèi)核態(tài),這個(gè)開銷在fd很多時(shí)會(huì)很大

同時(shí)每次調(diào)用select都需要在內(nèi)核遍歷傳遞進(jìn)來的所有fd,這個(gè)開銷在fd很多時(shí)也很大

select支持的文件描述符數(shù)量太小了,默認(rèn)是1024

epoll對(duì)于上述的改進(jìn)

epoll既然是對(duì)select和poll的改進(jìn),就應(yīng)該能避免上述的三個(gè)缺點(diǎn)。那epoll都是怎么解決的呢?在此之前,我們先看一下epoll和select和poll的調(diào)用接口上的不同,select和poll都只提供了一個(gè)函數(shù)——select或者poll函數(shù)。而epoll提供了三個(gè)函數(shù),epoll_create,epoll_ctl和epoll_wait,epoll_create是創(chuàng)建一個(gè)epoll句柄;epoll_ctl是注冊(cè)要監(jiān)聽的事件類型;epoll_wait則是等待事件的產(chǎn)生。
  對(duì)于第一個(gè)缺點(diǎn),epoll的解決方案在epoll_ctl函數(shù)中。每次注冊(cè)新的事件到epoll句柄中時(shí)(在epoll_ctl中指定EPOLL_CTL_ADD),會(huì)把所有的fd拷貝進(jìn)內(nèi)核,而不是在epoll_wait的時(shí)候重復(fù)拷貝。epoll保證了每個(gè)fd在整個(gè)過程中只會(huì)拷貝一次。
  對(duì)于第二個(gè)缺點(diǎn),epoll的解決方案不像select或poll一樣每次都把current輪流加入fd對(duì)應(yīng)的設(shè)備等待隊(duì)列中,而只在epoll_ctl時(shí)把current掛一遍(這一遍必不可少)并為每個(gè)fd指定一個(gè)回調(diào)函數(shù),當(dāng)設(shè)備就緒,喚醒等待隊(duì)列上的等待者時(shí),就會(huì)調(diào)用這個(gè)回調(diào)函數(shù),而這個(gè)回調(diào)函數(shù)會(huì)把就緒的fd加入一個(gè)就緒鏈表)。epoll_wait的工作實(shí)際上就是在這個(gè)就緒鏈表中查看有沒有就緒的fd(利用schedule_timeout()實(shí)現(xiàn)睡一會(huì),判斷一會(huì)的效果,和select實(shí)現(xiàn)中的第7步是類似的)。
  對(duì)于第三個(gè)缺點(diǎn),epoll沒有這個(gè)限制,它所支持的FD上限是最大可以打開文件的數(shù)目,這個(gè)數(shù)字一般遠(yuǎn)大于2048,舉個(gè)例子,在1GB內(nèi)存的機(jī)器上大約是10萬左右,一般來說這個(gè)數(shù)目和系統(tǒng)內(nèi)存關(guān)系很大。

Node中的異步網(wǎng)絡(luò)Io就是利用了epoll來實(shí)現(xiàn), 簡(jiǎn)單來說, 就是利用一個(gè)線程來管理眾多的IO請(qǐng)求, 通過事件機(jī)制實(shí)現(xiàn)消息通訊。

事件循環(huán)

理解了Node中磁盤IO和網(wǎng)絡(luò)IO的底層實(shí)現(xiàn)后, 基于上面的代碼, 可以看出Node是基于事件注冊(cè)的方式在完成Io后進(jìn)行一系列的處理, 其內(nèi)部是利用了事件循環(huán)的機(jī)制。

關(guān)于事件循環(huán), 是指JS在每次執(zhí)行完同步任務(wù)后會(huì)檢查執(zhí)行棧是否為空, 是的話就會(huì)去執(zhí)行注冊(cè)的事件列表, 不斷的循環(huán)該過程。Node中的事件循環(huán)有六個(gè)階段:

其中的每個(gè)階段都會(huì)處理相關(guān)的事件:

timers: 執(zhí)行setTimeout和setInterval中到期的callback。

pending callback: 執(zhí)行延遲到下一個(gè)循環(huán)迭代的 I/O 回調(diào)。

idle, prepare:僅系統(tǒng)內(nèi)部使用。

poll:檢索新的 I/O 事件;執(zhí)行與 I/O 相關(guān)的回調(diào)(幾乎所有情況下,除了關(guān)閉的回調(diào)函數(shù),它們由計(jì)時(shí)器和 setImmediate() 排定的之外),其余情況 node 將在此處阻塞。(即本文的內(nèi)容相關(guān)))

check: setImmediate() 回調(diào)函數(shù)在這里執(zhí)行。

close callbacks: 執(zhí)行close事件的callback,例如socket.on("close"[,fn])或者h(yuǎn)ttp.server.on("close, fn)。

ok, 這樣就解釋了Node是如何執(zhí)行我們注冊(cè)的事件, 那么還缺少一個(gè)環(huán)節(jié), Node又是怎么把事件和IO請(qǐng)求對(duì)應(yīng)起來呢? 這里涉及到了另外一種中間產(chǎn)物請(qǐng)求對(duì)象。
以打開一個(gè)文件為例子:

fs.open = function(path, flags, mode, callback){

//...

binding.open(pathModule._makeLong(path), stringToFlags(flags), mode, callback);

}

fs.open()的作用是根據(jù)指定路徑和參數(shù)去打開一個(gè)文件,從而得到一個(gè)文件描述符,這是后續(xù)所有I/O操作的初始操作。從前面的代碼中可以看到,JavaScript層面的代碼通過調(diào)用C++核心模塊進(jìn)行下層的操作。

從JavaScript調(diào)用Node的核心模塊,核心模塊調(diào)用C++內(nèi)建模塊,內(nèi)建模塊通過libuv進(jìn)行系統(tǒng)調(diào)用,這是Node里經(jīng)典的調(diào)用方式。這里libuv作為封裝層,有兩個(gè)平臺(tái)的實(shí)現(xiàn),實(shí)質(zhì)上是調(diào)用了uv_fs_open()方法。在uv_fs_open()的調(diào)用過程中,我們創(chuàng)建了一個(gè)FSReqWrap請(qǐng)求對(duì)象。從JavaScript層傳入的參數(shù)和當(dāng)前方法都被封裝在這個(gè)請(qǐng)求對(duì)象中,其中我們最為關(guān)注的回調(diào)函數(shù)則被設(shè)置在這個(gè)對(duì)象的oncomplete_sym屬性上:
req_wrap->object_->Set(oncomplete_sym, callback);
QueueUserWorkItem()方法接受3個(gè)參數(shù):第一個(gè)參數(shù)是將要執(zhí)行的方法的引用,這里引用的uv_fs_thread_proc;第二個(gè)參數(shù)是uv_fs_thread_proc方法運(yùn)行時(shí)所需要的參數(shù);第三個(gè)參數(shù)是執(zhí)行的標(biāo)志。當(dāng)線程池中有可用線程時(shí),我們會(huì)調(diào)用uv_fs_thread_proc()方法。uv_fs_thread_proc()方法會(huì)根據(jù)傳入?yún)?shù)的類型調(diào)用相應(yīng)的底層函數(shù)。以u(píng)v_fs_open()為例,實(shí)際上調(diào)用fs_open()方法。

至此,JavaScript調(diào)用立即返回,由JavaScript層面發(fā)起的異步調(diào)用的第一階段就此結(jié)束。JavaScript線程可以繼續(xù)執(zhí)行當(dāng)前任務(wù)的后續(xù)操作。當(dāng)前的I/O操作在線程池中等待執(zhí)行,不管它是否阻塞I/O,都不會(huì)影響到JavaScript線程的后續(xù)執(zhí)行,如此就達(dá)到了異步的目的。

請(qǐng)求對(duì)象是異步I/O過程中的重要中間產(chǎn)物,所有的狀態(tài)都保存在這個(gè)對(duì)象中,包括送入線程池等待執(zhí)行以及I/O操作完畢后的回調(diào)處理。
關(guān)于這一塊其實(shí)個(gè)人認(rèn)為不用過于細(xì)究, 大致上知道有這么一個(gè)請(qǐng)求對(duì)象即可, 最后總結(jié)一下整個(gè)異步IO的流程:

圖引用自深入淺出NodeJs

至此, Node的整個(gè)異步Io流程都已經(jīng)清晰了, 它是依賴于IO線程池epoll、事件循環(huán)、請(qǐng)求對(duì)象共同構(gòu)成的一個(gè)管理機(jī)制。

Node為什么更適合IO密集

Node為人津津樂道的就是它更適合IO密集型的系統(tǒng), 并且具有更好的性能, 關(guān)于這一點(diǎn)其實(shí)與它的異步IO息息相關(guān)。

對(duì)于一個(gè)request而言, 如果我們依賴io的結(jié)果, 異步io和同步阻塞io(每線程/每請(qǐng)求)都是要等到io完成才能繼續(xù)執(zhí)行. 而同步阻塞io, 一旦阻塞就不會(huì)在獲得cpu時(shí)間片, 那么為什么異步的性能更好呢?

其根本原因在于同步阻塞Io需要為每一個(gè)請(qǐng)求創(chuàng)建一個(gè)線程, 在Io的時(shí)候, 線程被block, 雖然不消耗cpu, 但是其本身具有內(nèi)存開銷, 當(dāng)大并發(fā)的請(qǐng)求到來時(shí), 內(nèi)存很快被用光, 導(dǎo)致服務(wù)器緩慢, 在加上, 切換上下文代價(jià)也會(huì)消耗cpu資源。而Node的異步Io是通過事件機(jī)制來處理的, 它不需要為每一個(gè)請(qǐng)求創(chuàng)建一個(gè)線程, 這就是為什么Node的性能更高。

特別是在Web這種IO密集型的情形下更具優(yōu)勢(shì), 除開Node之外, 其實(shí)還有另外一種事件機(jī)制的服務(wù)器Ngnix, 如果明白了Node的機(jī)制對(duì)于Ngnix應(yīng)該會(huì)很容易理解, 有興趣的話推薦看這篇文章。

總結(jié)

在真正的學(xué)習(xí)Node異步IO之前, 經(jīng)常看到一些關(guān)于Node適不適合作為服務(wù)器端的開發(fā)語(yǔ)言的爭(zhēng)論, 當(dāng)然也有很多片面的說法。
其實(shí), 關(guān)于這個(gè)問題還是取決于你的業(yè)務(wù)場(chǎng)景。

假設(shè)你的業(yè)務(wù)是cpu密集型的, 那你采用Node來開發(fā), 肯定是不適合的。 為什么不適合? 因?yàn)镹ode是單線程, 你被阻塞在計(jì)算的時(shí)候, 其他的事件就做不了, 處理不了請(qǐng)求, 也處理不了回調(diào)。

那么在IO密集型中, Node就比Java好嗎? 其實(shí)也不一定, 還是要取決于你的業(yè)務(wù)。 如果你的業(yè)務(wù)是非常大的并發(fā), 但是你的服務(wù)器資源又有限, 就好比現(xiàn)在有個(gè)入口, Node可以一次進(jìn)10個(gè)人, 而Java依次排隊(duì)進(jìn)一個(gè)人, 如果是10個(gè)人同時(shí)進(jìn), 當(dāng)然是Node更具有優(yōu)勢(shì), 但是假設(shè)有100個(gè)人(如1w個(gè)異步請(qǐng)求之類)的話, 那么Node就會(huì)因?yàn)樗漠惒綑C(jī)制導(dǎo)致應(yīng)用被掛起,內(nèi)存狂飆,IO堵塞,而且不可恢復(fù),這個(gè)時(shí)候你只能重啟了。而Java卻可以有序的處理, 雖然會(huì)慢一點(diǎn)。 而一臺(tái)服務(wù)器掛了造成的線上事故的損失更是不可衡量的。(當(dāng)然, 如果服務(wù)器資源足夠的話, Node也能處理)。

最后, 事實(shí)上Java也是具有異步IO的庫(kù), 只是相對(duì)來說, Node的語(yǔ)法更自然更貼近, 也就更適合。

參考&引用

怎樣理解阻塞非阻塞與同步異步的區(qū)別?
Linux epoll & Node.js Event Loop & I / O復(fù)用
node.js應(yīng)用高并發(fā)高性能的核心關(guān)鍵本質(zhì)是什么?
Linux IO模式及 select、poll、epoll詳解
異步IO比同步阻塞IO性能更好嗎?為什么?
深入淺出Nodejs

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/104069.html

相關(guān)文章

  • node.js的異步IO 第一篇

    摘要:給出了解決方案就是單線程,遠(yuǎn)離線程鎖,狀態(tài)同步的問題,使用異步讓單線程遠(yuǎn)離阻塞,高效利用。而實(shí)際上的異步是采用了線程池技術(shù),發(fā)起異步時(shí),把操作扔到線程池里面執(zhí)行,然后主線程繼續(xù)執(zhí)行其他操作,執(zhí)行完畢通過線程間通信通知主線程,主線程執(zhí)行回調(diào)。 異步IO,事件驅(qū)動(dòng),單線程構(gòu)成了node的基調(diào),為什么異步IO在node中如此重要呢? 我們先來說一下異步的概念,異步常見于前端開發(fā),例如ajax...

    feng409 評(píng)論0 收藏0
  • JavaScript單線程事件循環(huán)(Event Loop)那些事

    摘要:概述本篇主要介紹的運(yùn)行機(jī)制單線程事件循環(huán)結(jié)論先在中利用運(yùn)行至完成和非阻塞完成單線程下異步任務(wù)的處理就是先處理主模塊主線程上的同步任務(wù)再處理異步任務(wù)異步任務(wù)使用事件循環(huán)機(jī)制完成調(diào)度涉及的內(nèi)容有單線程事件循環(huán)同步執(zhí)行異步執(zhí)行定時(shí)器的事件循環(huán)開始 1.概述 本篇主要介紹JavaScript的運(yùn)行機(jī)制:單線程事件循環(huán)(Event Loop). 結(jié)論先: 在JavaScript中, 利用運(yùn)行至...

    Shisui 評(píng)論0 收藏0
  • node - 非阻塞的異步 IO

    摘要:而線程是進(jìn)程的一部分,二者相扶相依,其中單線程被稱為輕權(quán)進(jìn)程或輕量級(jí)進(jìn)程,執(zhí)行特性線程只有個(gè)基本狀態(tài)就緒,執(zhí)行,阻塞。以上所述證明了操作與其他函數(shù)的這種區(qū)別是由實(shí)現(xiàn),是用多線程的方式,在標(biāo)準(zhǔn)的阻塞式上模擬非阻塞異步,線程池默認(rèn)限制四線程。 node - 非阻塞的異步 IO 每當(dāng)我們提起 node.js 時(shí)總會(huì)脫口而出 事件驅(qū)動(dòng)、非阻塞I/O 和 單線程,所以我總結(jié)了以下幾點(diǎn)對(duì)這三項(xiàng)概念...

    yuxue 評(píng)論0 收藏0
  • node - 非阻塞的異步 IO

    摘要:而線程是進(jìn)程的一部分,二者相扶相依,其中單線程被稱為輕權(quán)進(jìn)程或輕量級(jí)進(jìn)程,執(zhí)行特性線程只有個(gè)基本狀態(tài)就緒,執(zhí)行,阻塞。以上所述證明了操作與其他函數(shù)的這種區(qū)別是由實(shí)現(xiàn),是用多線程的方式,在標(biāo)準(zhǔn)的阻塞式上模擬非阻塞異步,線程池默認(rèn)限制四線程。 node - 非阻塞的異步 IO 每當(dāng)我們提起 node.js 時(shí)總會(huì)脫口而出 事件驅(qū)動(dòng)、非阻塞I/O 和 單線程,所以我總結(jié)了以下幾點(diǎn)對(duì)這三項(xiàng)概念...

    keelii 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

MyFaith

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<