1. Kafka概述
1.1 定義
Kafka 是由 Apache 軟件基金會(huì)開發(fā)的一個(gè)開源流處理平臺(tái)。
Kafka 是一個(gè)分布式的基于發(fā)布/訂閱模式的消息隊(duì)列(Message Queue),主要應(yīng)用于大數(shù)據(jù)實(shí)時(shí)處理領(lǐng)域。
1.2 消息隊(duì)列
1.2.1 傳統(tǒng)消息隊(duì)列的應(yīng)用場(chǎng)景
1.2.2 為什么需要消息隊(duì)列
解耦:允許你獨(dú)立的擴(kuò)展或修改兩邊的處理過程,只要確保它們遵守同樣的接口約束。
冗余:消息隊(duì)列把數(shù)據(jù)進(jìn)行持久化直到它們已經(jīng)被完全處理,通過這一方式規(guī)避了數(shù)據(jù)丟失風(fēng)險(xiǎn)。許多消息隊(duì)列所采用的"插入-獲取-刪除"范式中,在把一個(gè)消息從隊(duì)列中刪除之前,需要你的處理系統(tǒng)明確的指出該消息已經(jīng)被處理完畢,從而確保你的數(shù)據(jù)被安全的保存直到你使用完畢。
擴(kuò)展性:因?yàn)橄㈥?duì)列解耦了你的處理過程,所以增大消息入隊(duì)和處理的頻率是很容易的,只要另外增加處理過程即可。
靈活性 & 峰值處理能力:在訪問量劇增的情況下,應(yīng)用仍然需要繼續(xù)發(fā)揮作用,但是這樣的突發(fā)流量并不常見。如果以能處理這類峰值訪問為標(biāo)準(zhǔn)來(lái)投入資源隨時(shí)待命無(wú)疑是巨大的浪費(fèi)。使用消息隊(duì)列能夠使關(guān)鍵組件頂住突發(fā)的訪問壓力,而不會(huì)因?yàn)橥话l(fā)的超負(fù)荷的請(qǐng)求而完全崩潰。
可恢復(fù)性:系統(tǒng)的一部分組件失效時(shí),不會(huì)影響到整個(gè)系統(tǒng)。消息隊(duì)列降低了進(jìn)程間的耦合度,所以即使一個(gè)處理消息的進(jìn)程掛掉,加入隊(duì)列中的消息仍然可以在系統(tǒng)恢復(fù)后被處理。
順序保證:在大多使用場(chǎng)景下,數(shù)據(jù)處理的順序都很重要。大部分消息隊(duì)列本來(lái)就是排序的,并且能保證數(shù)據(jù)會(huì)按照特定的順序來(lái)處理。(Kafka 保證一個(gè) Partition 內(nèi)的消息的有序性)
緩沖:有助于控制和優(yōu)化數(shù)據(jù)流經(jīng)過系統(tǒng)的速度, 解決生產(chǎn)消息和消費(fèi)消息的處理速度不一致的情況。
異步通信:很多時(shí)候,用戶不想也不需要立即處理消息。消息隊(duì)列提供了異步處理機(jī)制,允許用戶把一個(gè)消息放入隊(duì)列,但并不立即處理它。想向隊(duì)列中放入多少消息就放多少,然后在需要的時(shí)候再去處理它們。
1.2.3 消息隊(duì)列的兩種模式
點(diǎn)對(duì)點(diǎn)模式(一對(duì)一,消費(fèi)者主動(dòng)拉取數(shù)據(jù),收到后消息清除)
消息生產(chǎn)者生產(chǎn)消息發(fā)送到 Queue 中,然后消費(fèi)者從 Queue 中取出并且消費(fèi)消息。消息被消費(fèi)以后,queue 中不再有存儲(chǔ),所以消息消費(fèi)者不可能消費(fèi)到已經(jīng)被消費(fèi)的消息。Queue 支持存在多個(gè)消費(fèi)者,但是對(duì)一個(gè)消息而言,只會(huì)有一個(gè)消費(fèi)者可以消費(fèi)。
發(fā)布/訂閱模式(一對(duì)多,數(shù)據(jù)生產(chǎn)后,推送給所有訂閱者)
消息生產(chǎn)者(發(fā)布)將消息發(fā)布到 topic 中,同時(shí)有多個(gè)消息消費(fèi)者(訂閱)消費(fèi)該消息。和點(diǎn)對(duì)點(diǎn)方式不同,發(fā)布到 topic 的消息會(huì)被所有訂閱者消費(fèi)。
1.3 Kafka 基礎(chǔ)架構(gòu)圖
Producer :消息生產(chǎn)者,就是向 kafka broker 發(fā)消息的客戶端;
Consumer :消息消費(fèi)者,向 kafka broker 取消息的客戶端;
Consumer Group (CG):消費(fèi)者組,由多個(gè) consumer 組成。消費(fèi)者組內(nèi)每個(gè)消費(fèi)者負(fù)責(zé)消費(fèi)不同分區(qū)的數(shù)據(jù),一個(gè)分區(qū)只能由一個(gè)組內(nèi)消費(fèi)者消費(fèi);消費(fèi)者組之間互不影響。所有的消費(fèi)者都屬于某個(gè)消費(fèi)者組,即消費(fèi)者組是邏輯上的一個(gè)訂閱者。
Broker :一臺(tái) kafka 服務(wù)器就是一個(gè) broker(雖然多個(gè) Broker 進(jìn)程能夠運(yùn)行在同一臺(tái)機(jī)器上,但更常見的做法是將不同的 Broker 分散運(yùn)行在不同的機(jī)器上)。一個(gè)集群由多個(gè) broker 組成。一個(gè) broker 可以容納多個(gè) topic;
Topic :可以理解為一個(gè)隊(duì)列,Kafka 的消息通過 Topics(主題) 進(jìn)行分類,生產(chǎn)者和消費(fèi)者面向的都是一個(gè) topic;
Partition:為了實(shí)現(xiàn)擴(kuò)展性,一個(gè)非常大的 topic 可以分布到多個(gè) broker(即服務(wù)器)上, 一個(gè) topic 可以分為多個(gè) partition,每個(gè) partition 是一個(gè)有序的隊(duì)列;partition 中的每條消息都會(huì)被分配一個(gè)有序的 id( offset)。kafka 只保證按一個(gè) partition 中的順序?qū)⑾l(fā)給 consumer,不保證一個(gè) topic 的整體(多個(gè) partition 間)的順序;
Replica:副本,為保證集群中的某個(gè)節(jié)點(diǎn)發(fā)生故障時(shí),該節(jié)點(diǎn)上的 partition 數(shù)據(jù)不丟失,且 kafka 仍然能夠繼續(xù)工作,kafka 提供了副本機(jī)制,一個(gè) topic 的每個(gè)分區(qū)都有若干個(gè)副本, 一個(gè) leader 和若干個(gè) follower;
leader:每個(gè)分區(qū)多個(gè)副本的“主”,生產(chǎn)者發(fā)送數(shù)據(jù)的對(duì)象,以及消費(fèi)者消費(fèi)數(shù)據(jù)的對(duì)象都是 leader;
follower:每個(gè)分區(qū)多個(gè)副本中的“從”,實(shí)時(shí)從 leader 中同步數(shù)據(jù),保持和 leader 數(shù)據(jù)的同步。leader 發(fā)生故障時(shí),某個(gè) follower 會(huì)成為新的 follower;
offset:kafka 的存儲(chǔ)文件都是按照offset.kafka來(lái)命名,用 offset 做名字的好處是方便查找。例如你想找位于 2049 的位置,只要找到 2048.kafka 的文件即可。當(dāng)然 the first offset 就是 00000000000.kafka。
2. Hello Kafka
2.1 動(dòng)起手來(lái)
Quickstart
中文版入門指南
2.2 基本概念(官方介紹翻譯)
Kafka 是一個(gè)分布式的流處理平臺(tái)。是支持分區(qū)的(partition)、多副本的(replica),基于 ZooKeeper 協(xié)調(diào)的分布式消息系統(tǒng),它的最大的特性就是可以實(shí)時(shí)的處理大量數(shù)據(jù)以滿足各種需求場(chǎng)景:比如基于 hadoop 的批處理系統(tǒng)、低延遲的實(shí)時(shí)系統(tǒng)、storm/Spark 流式處理引擎,web/nginx 日志、訪問日志,消息服務(wù)等等
有三個(gè)關(guān)鍵能力
它可以讓你發(fā)布和訂閱記錄流。在這方面,它類似于一個(gè)消息隊(duì)列或企業(yè)消息系統(tǒng)
它可以讓你持久化收到的記錄流,從而具有容錯(cuò)能力
它可以讓你處理收到的記錄流
應(yīng)用于兩大類應(yīng)用
構(gòu)建實(shí)時(shí)的流數(shù)據(jù)管道,可靠地獲取系統(tǒng)和應(yīng)用程序之間的數(shù)據(jù)。
構(gòu)建實(shí)時(shí)流的應(yīng)用程序,對(duì)數(shù)據(jù)流進(jìn)行轉(zhuǎn)換或反應(yīng)。
想要了解 Kafka 如何具有這些能力,首先,明確幾個(gè)概念:
Kafka 作為一個(gè)集群運(yùn)行在一個(gè)或多個(gè)服務(wù)器上
Kafka 集群存儲(chǔ)的消息是以主題(topics)為類別記錄的
每個(gè)消息記錄包含一個(gè)鍵,一個(gè)值和時(shí)間戳
Kafka有五個(gè)核心API:
Producer API允許應(yīng)用程序發(fā)布記錄流至一個(gè)或多個(gè) Kafka 的話題(Topics)
Consumer API允許應(yīng)用程序訂閱一個(gè)或多個(gè)主題,并處理這些主題接收到的記錄流
Streams API允許應(yīng)用程序充當(dāng)流處理器(stream processor),從一個(gè)或多個(gè)主題獲取輸入流,并生產(chǎn)一個(gè)輸出流至一個(gè)或多個(gè)的主題,能夠有效地變換輸入流為輸出流
Connector API允許構(gòu)建和運(yùn)行可重用的生產(chǎn)者或消費(fèi)者,能夠把 Kafka 主題連接到現(xiàn)有的應(yīng)用程序或數(shù)據(jù)系統(tǒng)。例如,一個(gè)連接到關(guān)系數(shù)據(jù)庫(kù)的連接器(connector)可能會(huì)獲取每個(gè)表的變化
Admin API允許管理和檢查主題、brokes 和其他 Kafka 對(duì)象。(這個(gè)是新版本才有的)
Kafka 的客戶端和服務(wù)器之間的通信是靠一個(gè)簡(jiǎn)單的,高性能的,與語(yǔ)言無(wú)關(guān)的 TCP 協(xié)議完成的。這個(gè)協(xié)議有不同的版本,并保持向后兼容舊版本。Kafka 不光提供了一個(gè) Java 客戶端,還有許多語(yǔ)言版本的客戶端。
主題和日志
主題是同一類別的消息記錄(record)的集合。Kafka 的主題支持多用戶訂閱,也就是說(shuō),一個(gè)主題可以有零個(gè),一個(gè)或多個(gè)消費(fèi)者訂閱寫入的數(shù)據(jù)。對(duì)于每個(gè)主題,Kafka 集群都會(huì)維護(hù)一個(gè)分區(qū)日志,如下所示:
每個(gè)分區(qū)是一個(gè)有序的,不可變的消息序列,新的消息不斷追加到 partition 的末尾。在每個(gè) partition 中,每條消息都會(huì)被分配一個(gè)順序的唯一標(biāo)識(shí),這個(gè)標(biāo)識(shí)被稱為offset,即偏移量。kafka 不能保證全局有序,只能保證分區(qū)內(nèi)有序。
Kafka 集群保留所有發(fā)布的記錄,不管這個(gè)記錄有沒有被消費(fèi)過,Kafka 提供可配置的保留策略去刪除舊數(shù)據(jù)(還有一種策略根據(jù)分區(qū)大小刪除數(shù)據(jù))。例如,如果將保留策略設(shè)置為兩天,在數(shù)據(jù)發(fā)布后兩天,它可用于消費(fèi),之后它將被丟棄以騰出空間。Kafka 的性能跟存儲(chǔ)的數(shù)據(jù)量的大小無(wú)關(guān)(會(huì)持久化到硬盤), 所以將數(shù)據(jù)存儲(chǔ)很長(zhǎng)一段時(shí)間是沒有問題的。
事實(shí)上,在單個(gè)消費(fèi)者層面上,每個(gè)消費(fèi)者保存的唯一的元數(shù)據(jù)就是它所消費(fèi)的數(shù)據(jù)日志文件的偏移量。偏移量是由消費(fèi)者來(lái)控制的,通常情況下,消費(fèi)者會(huì)在讀取記錄時(shí)線性的提高其偏移量。不過由于偏移量是由消費(fèi)者控制,所以消費(fèi)者可以將偏移量設(shè)置到任何位置,比如設(shè)置到以前的位置對(duì)數(shù)據(jù)進(jìn)行重復(fù)消費(fèi),或者設(shè)置到最新位置來(lái)跳過一些數(shù)據(jù)。
分布式
日志的分區(qū)會(huì)跨服務(wù)器的分布在 Kafka 集群中,每個(gè)服務(wù)器會(huì)共享分區(qū)進(jìn)行數(shù)據(jù)請(qǐng)求的處理。每個(gè)分區(qū)可以配置一定數(shù)量的副本分區(qū)提供容錯(cuò)能力。
每個(gè)分區(qū)都有一個(gè)服務(wù)器充當(dāng)“l(fā)eader”和零個(gè)或多個(gè)服務(wù)器充當(dāng)“followers”。leader 處理所有的讀取和寫入分區(qū)的請(qǐng)求,而 followers 被動(dòng)的從領(lǐng)導(dǎo)者拷貝數(shù)據(jù)。如果 leader 失敗了,followers 之一將自動(dòng)成為新的領(lǐng)導(dǎo)者。每個(gè)服務(wù)器可能充當(dāng)一些分區(qū)的 leader 和其他分區(qū)的 follower,所以 Kafka 集群內(nèi)的負(fù)載會(huì)比較均衡。
生產(chǎn)者
生產(chǎn)者發(fā)布數(shù)據(jù)到他們所選擇的主題。生產(chǎn)者負(fù)責(zé)選擇把記錄分配到主題中的哪個(gè)分區(qū)。這可以使用輪詢算法( round-robin)進(jìn)行簡(jiǎn)單地平衡負(fù)載,也可以根據(jù)一些更復(fù)雜的語(yǔ)義分區(qū)算法(比如基于記錄一些鍵值)來(lái)完成。
消費(fèi)者
消費(fèi)者以消費(fèi)群(consumer group)的名稱來(lái)標(biāo)識(shí)自己,每個(gè)發(fā)布到主題的消息都會(huì)發(fā)送給訂閱了這個(gè)主題的消費(fèi)群里面的一個(gè)消費(fèi)者的一個(gè)實(shí)例。消費(fèi)者的實(shí)例可以在單獨(dú)的進(jìn)程或單獨(dú)的機(jī)器上。
如果所有的消費(fèi)者實(shí)例都屬于相同的消費(fèi)群,那么記錄將有效地被均衡到每個(gè)消費(fèi)者實(shí)例。
如果所有的消費(fèi)者實(shí)例有不同的消費(fèi)群,那么每個(gè)消息將被廣播到所有的消費(fèi)者進(jìn)程。
這是 kafka 用來(lái)實(shí)現(xiàn)一個(gè) topic 消息的廣播(發(fā)給所有的 consumer) 和單播(發(fā)給任意一個(gè) consumer)的手段。一個(gè) topic 可以有多個(gè) CG。topic 的消息會(huì)復(fù)制 (不是真的復(fù)制,是概念上的)到所有的 CG,但每個(gè) partion 只會(huì)把消息發(fā)給該 CG 中的一 個(gè) consumer。如果需要實(shí)現(xiàn)廣播,只要每個(gè) consumer 有一個(gè)獨(dú)立的 CG 就可以了。要實(shí)現(xiàn)單播只要所有的 consumer 在同一個(gè) CG。用 CG 還可以將 consumer 進(jìn)行自由的分組而不需要多次發(fā)送消息到不同的 topic;
舉個(gè)栗子:
如上圖所示,一個(gè)兩個(gè)節(jié)點(diǎn)的 Kafka 集群上擁有一個(gè)四個(gè) partition(P0-P3)的 topic。有兩個(gè)消費(fèi)者組都在消費(fèi)這個(gè) topic 中的數(shù)據(jù),消費(fèi)者組 A 有兩個(gè)消費(fèi)者實(shí)例,消費(fèi)者組 B 有四個(gè)消費(fèi)者實(shí)例。
從圖中我們可以看到,在同一個(gè)消費(fèi)者組中,每個(gè)消費(fèi)者實(shí)例可以消費(fèi)多個(gè)分區(qū),但是每個(gè)分區(qū)最多只能被消費(fèi)者組中的一個(gè)實(shí)例消費(fèi)。也就是說(shuō),如果有一個(gè) 4 個(gè)分區(qū)的主題,那么消費(fèi)者組中最多只能有 4 個(gè)消費(fèi)者實(shí)例去消費(fèi),多出來(lái)的都不會(huì)被分配到分區(qū)。其實(shí)這也很好理解,如果允許兩個(gè)消費(fèi)者實(shí)例同時(shí)消費(fèi)同一個(gè)分區(qū),那么就無(wú)法記錄這個(gè)分區(qū)被這個(gè)消費(fèi)者組消費(fèi)的 offset 了。如果在消費(fèi)者組中動(dòng)態(tài)的上線或下線消費(fèi)者,那么 Kafka 集群會(huì)自動(dòng)調(diào)整分區(qū)與消費(fèi)者實(shí)例間的對(duì)應(yīng)關(guān)系。
Kafka消費(fèi)群的實(shí)現(xiàn)方式是通過分割日志的分區(qū),分給每個(gè) Consumer 實(shí)例,使每個(gè)實(shí)例在任何時(shí)間點(diǎn)的都可以“公平分享”獨(dú)占的分區(qū)。維持消費(fèi)群中的成員關(guān)系的這個(gè)過程是通過 Kafka 動(dòng)態(tài)協(xié)議處理。如果新的實(shí)例加入該組,他將接管該組的其他成員的一些分區(qū);如果一個(gè)實(shí)例死亡,其分區(qū)將被分配到剩余的實(shí)例。
Kafka 只保證一個(gè)分區(qū)內(nèi)的消息有序,不能保證一個(gè)主題的不同分區(qū)之間的消息有序。分區(qū)的消息有序與依靠主鍵進(jìn)行數(shù)據(jù)分區(qū)的能力相結(jié)合足以滿足大多數(shù)應(yīng)用的要求。但是,如果你想要保證所有的消息都絕對(duì)有序可以只為一個(gè)主題分配一個(gè)分區(qū),雖然這將意味著每個(gè)消費(fèi)群同時(shí)只能有一個(gè)消費(fèi)進(jìn)程在消費(fèi)。
保證
Kafka 提供了以下一些高級(jí)別的保證:
由生產(chǎn)者發(fā)送到一個(gè)特定的主題分區(qū)的消息將被以他們被發(fā)送的順序來(lái)追加。也就是說(shuō),如果一個(gè)消息 M1 和消息 M2 都來(lái)自同一個(gè)生產(chǎn)者,M1 先發(fā),那么 M1 將有一個(gè)低于 M2 的偏移,會(huì)更早在日志中出現(xiàn)。
消費(fèi)者看到的記錄排序就是記錄被存儲(chǔ)在日志中的順序。
對(duì)于副本因子 N 的主題,我們將承受最多 N-1 次服務(wù)器故障切換而不會(huì)損失任何的已經(jīng)保存的記錄。
2.3 Kafka的使用場(chǎng)景
消息
Kafka 被當(dāng)作傳統(tǒng)消息中間件的替代品。消息中間件的使用原因有多種(從數(shù)據(jù)生產(chǎn)者解耦處理,緩存未處理的消息等)。與大多數(shù)消息系統(tǒng)相比,Kafka 具有更好的吞吐量,內(nèi)置的分區(qū),多副本和容錯(cuò)功能,這使其成為大規(guī)模消息處理應(yīng)用程序的良好解決方案。
網(wǎng)站行為跟蹤
Kafka 的初衷就是能夠?qū)⒂脩粜袨楦櫣艿乐貥?gòu)為一組實(shí)時(shí)發(fā)布-訂閱數(shù)據(jù)源。這意味著網(wǎng)站活動(dòng)(頁(yè)面瀏覽量,搜索或其他用戶行為)將被發(fā)布到中心主題,這些中心主題是每個(gè)用戶行為類型對(duì)應(yīng)一個(gè)主題的。這些數(shù)據(jù)源可被訂閱者獲取并用于一系列的場(chǎng)景,包括實(shí)時(shí)處理,實(shí)時(shí)監(jiān)控和加載到 Hadoop 或離線數(shù)據(jù)倉(cāng)庫(kù)系統(tǒng)中進(jìn)行離線處理和報(bào)告。用戶行為跟蹤通常會(huì)產(chǎn)生巨大的數(shù)據(jù)量,因?yàn)橛脩裘總€(gè)頁(yè)面的瀏覽都會(huì)生成許多行為活動(dòng)消息。
測(cè)量
Kafka 通常用于監(jiān)測(cè)數(shù)據(jù)的處理。這涉及從分布式應(yīng)用程序聚集統(tǒng)計(jì)數(shù)據(jù),生產(chǎn)出集中的運(yùn)行數(shù)據(jù)源 feeds(以便訂閱)。
日志聚合
許多人用 Kafka 作為日志聚合解決方案的替代品。日志聚合通常從服務(wù)器收集物理日志文件,并將它們集中放置(可能是文件服務(wù)器或HDFS),以便后續(xù)處理。kafka 抽象出文件的細(xì)節(jié),并將日志或事件數(shù)據(jù)作為消息流清晰地抽象出來(lái)。這為低時(shí)延的處理提供支持,而且更容易支持多個(gè)數(shù)據(jù)源和分布式的數(shù)據(jù)消費(fèi)。相比集中式的日志處理系統(tǒng)(如 Scribe 或 Flume),Kafka 性能同樣出色,而且因?yàn)楦北緜浞萏峁┝烁鼜?qiáng)的可靠性保證和更低的端到端延遲。
流處理
Kafka 的流數(shù)據(jù)管道在處理數(shù)據(jù)的時(shí)候包含多個(gè)階段,其中原始輸入數(shù)據(jù)從 Kafka 主題被消費(fèi)然后匯總,加工,或轉(zhuǎn)化成新主題用于進(jìn)一步的消費(fèi)或后續(xù)處理。例如,用于推薦新聞文章的數(shù)據(jù)流處理管道可能從 RSS 源抓取文章內(nèi)容,并將其發(fā)布到“文章”主題; 進(jìn)一步的處理可能是標(biāo)準(zhǔn)化或刪除重復(fù)數(shù)據(jù),然后發(fā)布處理過的文章內(nèi)容到一個(gè)新的主題, 最后的處理階段可能會(huì)嘗試推薦這個(gè)內(nèi)容給用戶。這種處理管道根據(jù)各個(gè)主題創(chuàng)建實(shí)時(shí)數(shù)據(jù)流圖。從版本 0.10.0.0 開始,Apache Kafka 加入了輕量級(jí)的但功能強(qiáng)大的流處理庫(kù)Kafka Streams,Kafka Streams 支持如上所述的數(shù)據(jù)處理。除了Kafka Streams,可以選擇的開源流處理工具包括Apache Storm and Apache Samza。
事件源
事件源是一種應(yīng)用程序設(shè)計(jì)風(fēng)格,是按照時(shí)間順序記錄的狀態(tài)變化的序列。Kafka 的非常強(qiáng)大的存儲(chǔ)日志數(shù)據(jù)的能力使它成為構(gòu)建這種應(yīng)用程序的極好的后端選擇。
提交日志
Kafka 可以為分布式系統(tǒng)提供一種外部提交日志(commit-log)服務(wù)。日志有助于節(jié)點(diǎn)之間復(fù)制數(shù)據(jù),并作為一種數(shù)據(jù)重新同步機(jī)制用來(lái)恢復(fù)故障節(jié)點(diǎn)的數(shù)據(jù)。Kafka 的 log compaction 功能有助于支持這種用法。Kafka 在這種用法中類似于 Apache BookKeeper 項(xiàng)目。
-
大數(shù)據(jù)
+關(guān)注
關(guān)注
64文章
8908瀏覽量
137692 -
消息隊(duì)列
+關(guān)注
關(guān)注
0文章
33瀏覽量
3012 -
kafka
+關(guān)注
關(guān)注
0文章
52瀏覽量
5238
原文標(biāo)題:程序員必須了解的消息隊(duì)列之王-Kafka
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論