隨筆 - 59, 文章 - 4, 評論 - 184, 引用 - 7
          數據加載中……

          【ESB專題】之五 - Message Endpoint及其相關模式


          ESB中另外一個重要的課題就是Message Endpoint,這是關于一個應用程序如何連接到一個消息系統,并通過它來發送和接收消息。如果你在面向一個消息API編程,則你就正在開發一個endpoint代碼。商業中間件通常都提供了這些工具。

           

          l         Messaging Gateway

          l         Messaging Mapper

          l         Transactional Client

          l         Polling Consumer

          l         Event-Driven Consumer

          l         Competing Consumers

          l         Message Dispatcher

          l         Selective Consumer

          l         Durable Subscriber

          l         Idempotent Receiver

          l         Service Activator

           

          發送和接收模式

           

          有些endpoint模式既可以使用在發送方也可以使用在接受方。它們描述一個應用連接一個消息系統的一般情況。

           

          包裝消息代碼 一個應用不應該意識到正在使用消息同另外一個應用程序通訊,大多數應用代碼應該在不知道message的情況下被編寫。在應用集成的地方,應該有一個薄薄的一層代碼來執行應用的集成部分。當集成是由消息實現的,這層將應用連接到消息系統的代碼稱為一個Message Gateway

           

          數據轉換 當發送者和接受者使用不同的數據格式,或者不同的消息格式(支持不同的發送和接收者),在這種情況下,使用一個Message Mapper來在應用格式和消息格式之間轉換數據。

           

          外部控制的事務 消息系統在內部和外部使用事務,默認的,每個發送和接收方法在他們自己的事務中運行。Message生產者和消費者應可選的使用一個Transactional Client來控制事務,當你需要將幾個消息一起發送伙通過其他事務服務整理消息時是很有用的。

           

          消息消費者模式

           

          其他endpoint模式只適用于消息消費者,發送消息是簡單的。棘手的問題是決定一個消息應該何時發送,它應包含什么,以及怎樣將它送到接受者 這是為什么我們有很多消息結構模式 但是一旦消息被構建,發送它是很容易的。另一方面,接收消息 很麻煩。因此許多endpoint模式是關于接收消息的。

           

          接收消息的一個最重要的主題就是流量控制:一個應用控制,或者調節它消費消息的速度。一個潛在的問題是任何server都面臨著大量的客戶端請求會使其超載。通過遠程過程調用(RPI),server幾乎受到客戶端調用的支配。同樣的,通過消息,server不能控制客戶端發送請求的速度 但是server可是控制它處理這些請求的速度。應用不必像消息系統傳送消息那么快的接收并處理消息;使用一個Message Channel可以使它在一個可接收的速率上處理消息。然而,當消息積累太多,而server還有資源可以處理的更快,它可以使用同步message消費者來加快速度。所以使用這些消息消費者模式可以讓你的應用將速度控制在它可以承受的范圍。

           

          許多消息消費者模式都是成對出現的,你可以任選一個使用。

           

          同步或異步接受者 可以使用輪詢消費者或一個事件驅動消費者。輪詢提供最好的流量控制,因為如果server忙,則它不再繼續輪詢消息,所以message將阻塞在隊列。事件驅動的消費者傾向于消息到達便觸發處理,所以有可能會使server超載,但是每個消費者每次只處理一個消息,所以限制消費者的數量可以有效的控制消費速度。

           

          消息分派 vs 消息獲取 另外一個二選一的模式是一堆消費者如何處理一堆消息。如果每個消費者獲得一個消息,他們可以并行的處理消息。最簡單的方法是Competing Consumers,也就是一個點對點的channel有多個消費者。每個都可能獲得任何消息;消息系統的實現決定那個消費者獲得消息。如果你想控制消息到消費者的匹配過程,使用Message Dispatcher這時只有一個消費者接收消息,但是將委派消息到一個執行者去處理。一個應用程序可以通過限制消費者或執行者的數量來控制流量。當然,分派者Message Dispatcher也可以實現一個流量控制行為。

           

          接收所有消息或者過濾 默認的,任何到達一個Message Channel的消息對于監聽著這個channelMessage Endpoint都是可用的。然而有些消費者并不打算處理channel上的任何消息,而是希望只處理其中幾種。這樣一個識別的消費者可以使用一個Selective Consumer來描述它將接收什么類型的消息。然后消息系統將只將匹配的消息對該接受者描述為可用。

           

          當斷開連接的時候訂閱消息 Publish-Subscribe Channels帶來的問題是,如果一個消費者感興趣一個channel,但是現在網絡是斷開的怎么辦?是不是一個未連接的應用將錯過發布的消息,即使它已經訂閱過該消息?默認的,是的,訂閱只對連接的訂閱者有效,為了使應用不會因為連接而錯過訂閱的消息,要使用Durable Subscriber

           

          等冪 有時一個消息可能被傳輸不只一次,可能因為消息系統不確定該消息是否已經被成功的傳遞過,或者可能因為Message ChannelQoS被設置較低來提高效率。另一面的,消息接受者認為每個消息只會被傳輸一次,并且當它們重復處理相同的消息,它們會出錯。一個Idempotent Receiver可以優雅的處理重復的消息,并且阻止它們引起接收者應用的發生錯誤。

           

          同步或異步服務 另外一個選擇是一個應用應該暴露它的service為同步(RPI)還是異步的(Messaging)。不同的客戶端可能喜歡不同的方式;不同的環境可能需要不同的方式。既然很難選擇,就一起使用。一個Service Activator連接一個Message Channel到一個應用的同步服務以便當一個消息被接收,service就被調用。同步客戶端可以簡單的直接調用service;異步客戶端可以通過發送消息調用service

           

          Message Endpoint的相關主題

           

          Message Endpoint的另外一個重要主題是很難同其他模式共同應用Transactional ClientEvent-Driven Consumer通常不能適當的在外部控制事務,Message Dispatcher也必須小心的設計這個問題,Competing Consumers的事務也是個重大問題。最安全的使用Transactional Client是使用一個單獨的Polling Consumer,但是這不會是一個令人滿意的解決方案。

           

          這里特別要提到應該會保證成功的JMS風格的MDBEJB的一種。一個MDB是一個消息消費者,它即使一個Event-Driven Consumer又是一個支持J2EE分布式事務的Transactional Client,并且它可以作為Competing Consumers動態的池化,甚至作為一個Publish-Subscribe Channel。這是在一個自由的應用中實現這些是一個困難且乏味的組合,但是這個功能作為一個EJB容器的內建的功能被提供。(MDB框架如何實現的?本質上,容器通過一個動態改變大小的可重用的執行者的線程池來實現了一個Message Dispatcher,在那里每個執行者自己使用自己的session和事務來消費消息。)

           

          最后,緊記一個單獨的Message Endpoint可以很好結合幾個不同的模式。一組Competing Consumers可以被作為Polling Consumers實現,同時也可以是一個Selective Consumers并且可以作為一個Service Activator調用一個應用的service

          一個Message Dispatcher可以是一個Event-Driven Consumer和一個使用Messaging Mapper的一個Durable Subscriber。無論一個endpoint實現什么模式,它總是一個Messaging Gateway。所以,不要考慮使用哪種模式 而要考慮如何結合他們。這是使用模式解決問題的魅力所在。

           

          要實現一個Message Endpoint有很多選擇。Message Endpoint模式用于解釋這些選擇是什么以及如何最好的使用它們。

           

           

          posted @ 2005-11-22 21:40 fisher 閱讀(2089) | 評論 (2)編輯 收藏

          【ESB專題】之四 - Message Transformation及其相關模式

           

           

           

          通常,通過消息系統集成的應用很少有同樣的消息格式。比如說,一個帳務系統同一個CRM系統對客戶對象是有著不同的概念的。基于這個,一個系統可能將消息存儲在關系表中,另一個可能存儲在文件中。集成已存在的系統通常意味著我們沒有修改系統以便使他們更好的一起工作的自由。然而,集成方案不得不協調和解決各種系統之間的不同。Message Translator模式提供了一個通用的解決方案。這里解釋幾種特定的Message Translator

           

          Message Transformation包含以下幾種模式:

          l         Envelope Wrapper

          l         Content Enricher

          l         Content Filter

          l         Claim Check

          l         Normalizer

          l         Canonical Data Model

           

          大多數消息系統放置特定的需求在消息頭的格式和內容中。我們包裝有效數據到一個Envelope Wrapper中以適應消息基礎設施的需求。如果消息需要穿過不同的消息基礎設施,可以結合多個Envelope Wrapper

          如果原始系統不能提供目標系統需要的數據域,可以使用一個Content Enricher。它可以查找缺少的信息并從已有數據中計算出它。Content Filter正好相反,它從消息中刪除不需要的數據。Claim Check也從消息中刪除數據,但是它將存儲他們以便以后取回。Normalizer將多個不同格式的消息翻譯成統一格式。

           

          消除依賴

           

          消息轉換在集成中是一個很深的話題。Message ChannelsMessage Routers可以通過消除應用必須知道另外一個應用的位置的需求從而解除應用間的基本依賴。

          一個應用可以發送一個消息到Message Channel而不必擔心誰來取出消息。然而消息格式增加了另外一種依賴。如果一個應用不得不將消息格式化成另外一個應用的數據格式,通過Message Channel解耦的說法就像一個幻想。接收系統的任何改變或切換到另外一個接收系統都需要對發送應用進行改變。Message Translators可以幫助除去這種依賴。

           

          元數據管理

           

          將消息從一個消息格式轉換到另一個格式需要操作元數據 描述數據格式的數據。

          元數據在兩個并行系統之間的集成中扮演著非常重要的角色。一個處理實際的消息數據,另外一個處理元數據。許多用于處理消息數據的模式也同樣可以管理元數據。比如說,Channel Adapter不僅可以從一個系統中移進和移出消息,還可以從一個外部應用中獲取元數據,并將其加載到一個元數據倉庫中。使用這個倉庫,集成開發者可以定義應用元數據與Canonical Data Model.之間的轉換。

           

           

          元數據集成

           

          o_MT1.JPG

          舉例來說,上面的圖描述了兩個需要交換客戶信息的應用的集成。每個系統的客戶數據的定義稍有不同。從
          AB的消息需要轉換一下才能被B接收。如果Channel Adapters可以抽取元數據的話,創建一個轉換將非常簡單。然后這個元數據可以被放入一個倉庫,大大的簡化了Message Translator的配置和驗證。元數據可以被存儲成不同的格式。通常XML消息使用XSD格式。其他EAI工具實現所有元數據格式,但是允許管理員導入或導出到其他格式。

           

          消息系統外的數據轉換

           

          這些轉換模式組成的很多原則可以被應用于非消息集成。比如說,File Transfer可以執行系統間的轉換工作。類似的,Remote Procedure Invocation必須使請求使用要調用的service的格式,即使應用本身的格式可能不同。典型的,需要調用程序來執行轉換。一些最成熟的轉換引擎組成了ETL工具,比如Informatica或者DataMirror。這些工具一般都一次轉換大量的數據,而不是轉換單個消息。

          Message System應專注于幾種基本的Message Translator模式。而不應該關心實體間結構轉換的細節(不同的數據模型之間的轉換,比如ER模型不支持多對多關系而其他的支持這種)。關于這個主題最老也使最相關的書是Kent的《Data and Reality》。

           

          posted @ 2005-11-21 21:40 fisher 閱讀(1614) | 評論 (1)編輯 收藏

          【ESB專題】之三 - Message Construction及其相關模式


          在前面的關鍵組件中我們提到了Messages。當兩個應用想要交換數據,他們將數據包裝在一個message中。但是一個Message Channel不能傳輸原始數據,它只能傳輸包含在一個message中的數據(即傳輸特定格式的數據)。

           

          Message在消息系統中處于信息載體的位置,而在ESB中,還消息識別、序列以及生存周期等職責。

           

          Message的結構涉及以下幾個模式:

          l         Command Message      

          l         Document Message      

          l         Event Message

          l         Request-Reply

          l         Return Address

          l         Correlation Identifier

          l         Message Sequence

          l         Message Expiration

          l         Format Indicator

           

          創建和發送一個Message產生以下幾個問題:

           

          消息意圖 Message最終是為了運送一些數據,但是發送者可能有其他目的,比如它希望接受者使用消息做些事情。它可以發送一個Command Message,指定它希望調用的接受者上的函數或方法。發送者告訴接受者運行那些代碼。發送者可以發送一個Document Message來傳送它的數據結構到接受者。發送者發送數據到接受者,但是不指定接受者應該做什么。

          或者它可以發送一個Event Message,通知接受者發送者那里有一個改變。發送者不應告訴接受者應該怎樣適應這個改變,而只應提供通知。

           

          返回一個應答 當一個應用發送一個消息,它通常期望得到一個回應來確定消息被處理并提供一個結果。這是一個Request-Reply場景。Request通常是一個Command Message,而應答是一個包含返回值或異常的Document Message。請求者應該在請求中指定一個Return Address來告訴應答者使用哪個通道來傳回應答。請求者可能在一個處理過程中發送多個請求,所以應答應該包含一個Correlation Identifier來指出這個應答對應哪個請求。

          有兩個Request-Reply場景需要注意;它們都包含了一個Command Message請求和一個對應的Document Message應答。在第一個場景中,Message RPC,請求不但要調用應答者的函數,而且期望一個返回值。這是RPC。另一個場景中,Message Query,請求者執行一個查詢;應答者執行查詢并在應答中返回結果。這是遠程查詢。

           

          大量的數據 有時應用想要傳送大量的數據結構,放入一個單獨的message里面不是很合適。在這種情況下,將他們分解成可管理的消息塊并將他們作為Message Sequence發送。這些消息必須按順序發送,以便接受者能夠充足原始數據結構。

           

          慢速消息 消息系統的一個問題是發送者通常不知道接受者要多久才能接受到消息。然而,消息的內容可能是時間敏感的,所以如果消息在某一時間內沒有被接受,它將被忽略并取消。在這種情況下,sender應該使用Message Expiration來指定一個到期時間。如果消息系統在規定時間內無法傳輸一個消息,應該將它取消并刪除到Dead Letter Channel中。同樣的一個receiver接受到一個超出該時間點的消息,也要取消該消息。

           

          總之,只選擇使用消息是不夠的。使一個消息工作的其他決定性因素來自于消息所要完成的任務。

           

          posted @ 2005-11-19 20:31 fisher 閱讀(1415) | 評論 (6)編輯 收藏

          【ESB專題】之二 - Message Channel及其相關模式

           

           

          在前面一個專題中,我們列出了一個ESB系統所需要關心的所有方面的關鍵組件,這里介紹其中的Message Channels所關注的問題及相關的模式。

           

          Message Channel主題之下包含以下模式,分別用于解決channel中不同方面的問題:

           

          l         Point-to-Point Channel  

          l         Publish-Subscribe Channel   

          l         Datatype Channel  

          l         Invalid Message Channel      

          l         Dead Letter Channel     

          l         Guaranteed Delivery     

          l         Channel Adapter    

          l         Messaging Bridge  

          l         Message Bus  

           

           

          當兩個應用需要交換數據,它們通過連接兩端的channel來發送數據。發送的應用可能不知道哪個應用將接受數據。然而,通過選擇特定的channel來發送,發送者知道接受者將是守候在channel另一端等待數據的應用之一。通過這種方式,生產數據的應用有了一個同數據消費者通訊的途徑。

           

          Message Channels面對的各個主要問題:

           

          如果一個應用要傳輸或接受數據,它一定會用到一個channel。問題是你的應用要知道要使用什么樣的channel,以及用它來做什么。

           

          固定的channel集合 Channel中討論的一個主題是,一個應用可用的Message Channel集合一般是固定的。設計一個應用時,一個開發者必須知道將某種類型的數據放到哪里可以同其他應用共享該數據,以及從什么地方可以找到其他應用的特定數據。這些通訊路徑不會在運行期動態的創建和發現;它們需要在設計期間就確定下來,以便應用知道它的數據從哪里來以及數據將去哪里。( 雖然大多數channel必須被靜態定義使正確的,但是也有例外,有些情況下動態channel是很好用的。一個例外就是Request-Reply模式中的reply channel。請求者可以創建或者獲得一個應答者不知道的新的channel,并在請求消息中指定該channelReturn Address,應答者就可以使用它。另外一個例外是支持集成channels的消息系統實現。一個接受者可以訂閱一個集成體系的根channel,然后發送者可以發布消息到一個子channel,而接受者不需要知道子channel,仍然會收到消息。這些都是不常見的情況,channel通常仍然是在部署之前被定義,并且應用被設計連接到一個已知的channel集合 )。

           

          決定channel的集合 一個相關的主題是,誰決定那些Message Channel是可用的 message系統還是應用程序?換句話說,是由消息系統確定一些channel,然后要求應用程序使用它們?還是應用決定它們需要什么channel,然后要求消息系統提供它們?這個問題沒有一個簡單的答案,設計必須的channel集合是迭代的。首先,應用要決定消息系統提供哪些channel。然后應用將圍繞這些channel設計它們的通訊,但是如果這樣是不可行的,它們將需要添加額外的channel。當一些應用已經使用了一個確定的channel集合,當加入新的應用,它們將使用已存在的channel。當為應用添加新的功能,它們需要新的channel

           

          單向channel 另外一個經常引起混淆的是一個Message channel是單向的還是雙向的。技術上來說,兩者都不是,一個channel更像是一個桶,一個應用放入數據,另外一個應用從中取出數據。但是由于數據是放在消息中從一個應用傳到另一個,這使得channel具有方向性,使它變成單向的。如果一個channel是雙向的,應用將從中發送和接受數據,雖然技術上是可行的,但是會有小小的問題,應用將有可能持續的取出自己放進去的希望發送給其他應用的消息。所以,為了實踐性的目的,channel是單向的。作為結論,兩個應用如果有雙向通訊,它們需要兩個channel,每個方向一個

           

          如何使用Message channels

           

          現在我們來討論以下如何使用channel

           

          一對一或者一對多 當你的應用共享一些數據,你希望只將它共享給一個應用還是對它感興趣的所有應用?要傳送數據到一個單獨的應用,使用Point-to-Point Channel。這并不意味著發送到這個channel的每個數據都發送給同樣的接受者,因為一個channel可能有多個接受者。它意味著,實際上,保證每個數據都被同一個應用接收。如果你想讓所有接收應用都能接收數據,使用Publish-Subscribe Channel。當你通過這種方式發送數據,channel將高效的復制數據到每一個接收者。

           

          什么類型的數據 任何內存中的數據都有一個類型。另一方面,所有數據都是一些bytes集合。消息系統工作同這類似,消息內容必須符合某些類型以便接受者了解數據的結構。Datatype Channel認為在一個channel中的數據必須擁有同樣的類型。這也是為什么消息系統需要很多channel的主要原因(每個channel一種格式)。如果數據可以是任意的格式,那么消息系統在兩個應用之間只需要兩條channel

           

          無效的和過期的消息 消息系統可以確定消息被正確的傳輸,但是它不能保證接受者知道如何處理它。接收者對數據格式和意義存在期望。當它接收到一個不符合期望的消息,它什么也不能做。它們能作的,就是將這個陌生的消息放入到一個特別設計的Invalid Message Channel并希望某些監控這個channel的工具能夠取出這個消息,并指出該如何處置它們。許多消息系統有一個類似的內建特征,一個Dead Letter Channel,用來存放成功送出但卻無法成功投遞的消息。另外,一個系統管理工具應該監視Dead Letter Channel并且決定如何處置這些無法投遞的消息。

           

          故障檢測 如果一個消息系統發生故障或停機維護,它的消息會怎樣?當它重啟并重新運行,它的消息能否還在它的channel中?默認的:不會;channel將消息存儲在內存中。然而,Guaranteed Deliverychannel持久化以便將它們的消息存儲到硬盤上。這會影響效率,但會使消息更加可靠,即使消息系統是不可靠的。

           

          非消息客戶端 如果一個應用不能連接到一個消息系統但是仍然想要參與消息怎么辦?通常它只能自認倒霉了,但是如果消息系統可以通過某種方式連接到應用系統 通過它的用戶界面,它的service API,它的數據庫,或者一個TCP/IPHTTP這樣的網絡連接 那么消息系統可以使用一個Channel Adapter。這允許你連接到一個或多個連接到應用的channel而不必改變應用或者可能也不需要一個同應用運行在同一個機器上的消息客戶端。有時‘非消息客戶端’真的是一個消息客戶端,但是只有連接的是其他消息系統的時候。

           

          通訊中樞 隨著越來越多的企業應用系統連接到消息系統以便通過消息暴露他們的功能,消息系統變成了企業中一站式功能的集散地。一個應用只需簡單的知道用哪個channel來請求功能,以及從哪個監聽結果。消息系統本質上變成一個消息總線,一個提供所有企業應用甚至變化中的應用和功能的中樞。你可以更快速的集成。

           

          如你所見,使用消息構建應用不僅僅是將他們連接到消息系統并發送消息。消息必須使用Message Channel來發送。Channel必須被設計為某個目的服務,比如基于被共享的數據類型,共享數據的應用類型,和接收數據的應用。

           

          posted @ 2005-11-17 22:56 fisher 閱讀(1293) | 評論 (1)編輯 收藏

          【ESB專題】-面向消息的EAI的關鍵組件

           

          企業集成有很多種模式,隨著技術的發展,實時的、面向消息的企業集成越來越成為主流,面向消息的企業集成的穩定性和兼容性要求其基礎件,也就是message系統必須提供足夠強壯和可擴展的設計,下面幾種是作為面向消息的企業集成的基礎件所必須提供的幾個關鍵性組件。

           

          消息集成使得message系統負責轉換兩個應用之間的數據格式,從而使得應用可以專注于他們需要共享什么數據而不是如何共享它們。

           

          以下這些組件,在著名的ESB系統Mule中都可以見到,有興趣的同學可以去看看Mule的源代碼,雖然Mule對ESB的實現有很多不成熟的地方,以至于讓我不敢在生產系統中使用(唉...可恨的Mule),但是畢竟是一個大而全的系統,值得借鑒一下。
           

          Channels — Messaging應用通過一個Message Channel傳送數據,一個senderreceiver的虛擬管道。一個新安裝的消息系統默認不包含任何channel;你必須知道你的應用需要怎樣通訊,然后才能建立channel來完成它。

           

          Messages — Message是在channel上傳輸的不可分割的包。因此,為了傳輸數據,應用必須將數據打包成一個或多個packets,將每個packet包裝成一個message,然后將其傳輸到一個channel。同樣的,一個receiver應用在接受到message后必須從message中提取出數據才能使用。Message系統應該能重復的傳輸message,直到它成功為止。

           

          Pipes and Filters 最簡單的情況下,message系統將一個消息直接從sender計算機傳送到receiver計算機。然而,通常在消息從sender中發出后,receiver接受到之前,有一些動作需要對message執行。舉例來說,message也許需要驗證或者轉換。Pipes and Filters架構使用channel將多個處理步驟連接起來。

           

          Routing 在一個大型的、擁有許多不同的應用和channel連接的企業應用中,一個message可能需要穿過多個channel才能到達最終目的地。Message的路由如此復雜以至于最初的發送者無法知道那些channel能將message傳送給最終的receiver。因此,最初的發送者將message發送給一個Message Router,一個以Pipes and Filters架構中的filter形式存在的應用組件。Router將決定如何將message發送到最終receiver或者至少是下一個Router

           

          Transformation 不同的應用的數據格式可能不同。為了調節senderreceiver之間的數據格式不同的問題,message必須經過一個中介的filter,一個Message Translator,它將message從一個格式轉換成另外一個格式,或轉換成一個公共的格式。

           

          Endpoints 大多數的應用程序沒有內建的能力來同一個message系統交互。因此他們必須包含一個中間層,它知道應用系統如何工作,也知道message系統如何工作,并橋接兩個系統。這個系統是一組并列的Message Endpoints,它能夠使得應用發送和接受message

           

          System manager 作為一個大型的消息集成系統,其面向消息的、異步、低耦合的本質使得系統更加難以調試,運行期的狀態也難以跟蹤,所以,我們必須有強有力的手段進行系統的運行期管理和監控,同時最好能夠在運行進行動態更新,以保障系統的強壯性。


          企業應用集成是一個巨大而復雜的系統,作為其基礎件ESB系統,必須能夠提供對其完全的支撐以及足夠強壯的系統,這正是ESB系統建設的難度所在。

          posted @ 2005-11-16 20:56 fisher 閱讀(2333) | 評論 (6)編輯 收藏

          僅列出標題
          共12頁: 上一頁 1 2 3 4 5 6 7 8 9 下一頁 Last 
          主站蜘蛛池模板: 敦煌市| 江都市| 五常市| 山阴县| 常熟市| 广德县| 浏阳市| 阳谷县| 綦江县| 湟源县| 贡觉县| 普定县| 齐齐哈尔市| 阳曲县| 尚志市| 巧家县| 高碑店市| 巴里| 长沙市| 建德市| 涟源市| 西贡区| 宁蒗| 衡阳市| 林周县| 南木林县| 成安县| 棋牌| 明星| 大宁县| 祁连县| 合水县| 两当县| 钦州市| 兴仁县| 永春县| 山阳县| 肥西县| 运城市| 黑水县| 建湖县|