Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 499, comments - 13, trackbacks - 0, articles - 1

          學(xué)習(xí)交流

          - 即時(shí)通訊開發(fā)交流群: 215891622 [推薦]

          一、前言

          IM發(fā)展至今,已是非常重要的互聯(lián)網(wǎng)應(yīng)用形態(tài)之一,尤其移動(dòng)互聯(lián)網(wǎng)時(shí)代,它正以無與論比的優(yōu)勢(shì)降低了溝通成本和溝通代價(jià),對(duì)各種應(yīng)用形態(tài)產(chǎn)生了深遠(yuǎn)影響。

          做為IM開發(fā)者或即將成為IM開發(fā)者的技術(shù)人員,IM的價(jià)值和重要性不言自明。但從技術(shù)實(shí)現(xiàn)來說,IM系統(tǒng)的開發(fā)(尤其是移動(dòng)端IM)還是存在許多技術(shù)難點(diǎn)和坑點(diǎn)的。也正因如此,優(yōu)質(zhì)的IM開發(fā)相關(guān)的資料、實(shí)踐性成果,對(duì)于沒有太多技術(shù)儲(chǔ)備的新手來說,尤其難以獲得。

          本文將以新手的視角引導(dǎo)你閱讀相關(guān)文章,以便為從零開發(fā)一個(gè)移動(dòng)端IM做好方方面面的知識(shí)準(zhǔn)備:包括但不限于網(wǎng)絡(luò)編程基礎(chǔ)、通信協(xié)議的選型、IM的架構(gòu)設(shè)計(jì)等等。文筆有限,如有不妥之處還請(qǐng)批評(píng)指正,希望對(duì)你有用。(本文同步發(fā)布于:http://www.52im.net/thread-464-1-1.html

          二、讀完本文的收獲 

          [1] 您將獲得

          本文將假設(shè)你是毫無技術(shù)準(zhǔn)備的新手,引導(dǎo)你通過一篇篇精選的文章,了解如何開始從零開發(fā)一個(gè)移動(dòng)端IM所需要的各種技術(shù)、資料和實(shí)踐性代碼。

          [2] 您無法獲得

          鑒于IM技術(shù)的復(fù)雜性,IM開發(fā)相關(guān)的技術(shù)不是一篇文章所能展現(xiàn)的了,限于篇幅原因本文將不包含任何實(shí)踐性代碼、也盡量不對(duì)某項(xiàng)技術(shù)作深入的展開,相關(guān)的實(shí)踐性代碼、資料、技術(shù)詳解等請(qǐng)依據(jù)本文作者準(zhǔn)備的文章逐個(gè)深入閱讀和學(xué)習(xí),而這也恰恰是本文想達(dá)到的目的。

          三、題外話

          隨著近兩年IM云服務(wù)的發(fā)展,很多團(tuán)隊(duì)基于種種原因,直接選擇了短平快的云IM接入APP中。然而,考慮到云IM無論從商業(yè)模式還是運(yùn)營模式上,還需經(jīng)過多年的沉淀,才可能真正實(shí)現(xiàn)客戶與服務(wù)商的運(yùn)營和服務(wù)良性循環(huán)的雙贏局面。因則,如何選擇云IM服務(wù)商,這就是個(gè)頭疼的問題了,不過這不是本文將要討論的重點(diǎn),如果需要,你也可以加入本文提到的討論交流群,與大家一起交流群: 215891622。 

          好了,以下是正文內(nèi)容。

          四、網(wǎng)絡(luò)編程理論準(zhǔn)備

          [1] UDP、TCP協(xié)議理論

          我們都知道,IM系統(tǒng)的業(yè)務(wù)本質(zhì)就是客戶端與客戶端進(jìn)行消息的實(shí)時(shí)傳遞,而技術(shù)基礎(chǔ)就是基于Socket連接的實(shí)時(shí)數(shù)據(jù)讀寫,那么基本的網(wǎng)絡(luò)編程理論基礎(chǔ)是作為新手的你必須掌握的知識(shí)點(diǎn)。當(dāng)然,作為IM開發(fā)來說,基礎(chǔ)的網(wǎng)絡(luò)理論就夠用了,也沒有必要像網(wǎng)絡(luò)工程師一樣精通所謂的OSI七層參考模型。

          如果你還不知道什么是UDP、TCP協(xié)議,請(qǐng)閱讀以下文章:


          這幾篇文章有助于對(duì)UDP、TCP協(xié)議建立基本的認(rèn)識(shí),當(dāng)然如果時(shí)間允許,能全書閱讀網(wǎng)絡(luò)編程理論經(jīng)典《TCP/IP詳解 卷1:協(xié)議》則再好不過了。另外,UDP、TCP作為基礎(chǔ)計(jì)算機(jī)數(shù)據(jù)傳輸協(xié)議,在其之上衍生了很多應(yīng)用層協(xié)議,相關(guān)的協(xié)議族關(guān)系圖可以在此文中找到:《計(jì)算機(jī)網(wǎng)絡(luò)通訊協(xié)議關(guān)系圖(中文珍藏版)》,可作為您日常的備查手冊(cè)使用。

          [2] 深入理解TCP傳輸協(xié)議

          透徹理解TCP傳輸協(xié)議的連接和斷開過程非常有助于您日后IM算法的優(yōu)化和實(shí)現(xiàn),這個(gè)過程被形象的總結(jié)為“3次握手與4次揮手”。

          以下文章有助于您深入理解之:

           

          [3] 深入理解UDP傳輸協(xié)議

          相比TCP協(xié)議,UDP數(shù)據(jù)傳輸協(xié)議就顯得非常輕量和易于理解,UDP通常被用于需要快速響應(yīng)的數(shù)據(jù)傳輸場(chǎng)景下,對(duì)應(yīng)于IM中的應(yīng)用形態(tài)有:P2P通信、實(shí)時(shí)音視頻等。另外,通常的IM都會(huì)被應(yīng)用于互聯(lián)網(wǎng)上(而非局域網(wǎng)),那么了解所謂的NAT路由技術(shù)原理等,也將有助于您對(duì)P2P打洞、UDP端口老化等概念有一個(gè)清楚的認(rèn)知。

          以下文章有助于您在接下來開發(fā)IM的實(shí)際應(yīng)用中提供一定的實(shí)踐依據(jù):


          當(dāng)然,現(xiàn)時(shí)的網(wǎng)絡(luò)編程,為了解決高性能問題,有很多成型的Socket應(yīng)用層模式存在,比如:NIO、AIO等,文章《Java新一代網(wǎng)絡(luò)編程模型AIO原理及Linux系統(tǒng)AIO介紹》簡(jiǎn)單介紹了傳統(tǒng)的阻塞式IO、NIO,并著重介紹了最新的AIO技術(shù),如有時(shí)間您很有必要予以了解。(更多同類文章:點(diǎn)此進(jìn)入…

          五、網(wǎng)絡(luò)編程基礎(chǔ)實(shí)踐

          如果你認(rèn)真讀完了上一層的文章,是時(shí)候?qū)懶┐a,來理論聯(lián)系實(shí)際理解Socket通信的原理和實(shí)踐了。

          有關(guān)TCP的Socket通信Demo文章和代碼:


          當(dāng)然,以是只是隨手找的Demo代碼,網(wǎng)絡(luò)上有關(guān)TCP數(shù)據(jù)通信的演示性代碼很容易找到,在此就不過多舉例了。

          本文作者專門編寫的有關(guān)跨移動(dòng)端平臺(tái)的UDP Socket通信Demo:

          六、IM到底該用UDP還是TCP協(xié)議?

          好了,上面的網(wǎng)絡(luò)編程基礎(chǔ)掌握后,就要開始為你的IM進(jìn)行傳輸協(xié)議選型了。說到IM該用UDP還是TCP作為傳輸協(xié)議,這是個(gè)頗有爭(zhēng)議的話題,各大社區(qū)每當(dāng)此問題的出現(xiàn)必定是大片的不同聲音。

          當(dāng)然,UDP和TCP各有各的應(yīng)用場(chǎng)景,作為IM來說,早期的IM因?yàn)榉?wù)端資源(服務(wù)器硬件、網(wǎng)絡(luò)帶寬等)比較昂貴且沒有更好的辦法來分擔(dān)性能負(fù)載,所以很多時(shí)候會(huì)考慮使用UDP,這其中主要是早期的QQ為代表。

          時(shí)至今日,TCP的服務(wù)端負(fù)載已經(jīng)有了很好的解決方案,加之服務(wù)器資源成本的下降,目前很多IM、消息推送解決方案也都在使用TCP作為傳輸層協(xié)議。不過,UDP也并未排除在IM、消息推送的解決方案之外,比如:弱網(wǎng)絡(luò)通信(包括跨國的高延遲網(wǎng)絡(luò)環(huán)境)、物聯(lián)網(wǎng)通信、IM中的實(shí)時(shí)音視頻通信等等場(chǎng)景下,UDP依然是首選項(xiàng)。

          以下文章或許有助于您對(duì)傳輸層協(xié)議的選型:


          當(dāng)然,關(guān)于IM到底該選擇UDP還是TCP,這是個(gè)仁者見仁智者見智的問題,沒有必要過于糾結(jié),請(qǐng)從您的IM整體應(yīng)用場(chǎng)景、開發(fā)代價(jià)、部署和運(yùn)營成本等方面綜合考慮,相信能找到你要的答案。

          七、IM的數(shù)據(jù)通信格式選型

          IM應(yīng)用開發(fā)的前期技術(shù)選型時(shí),關(guān)于數(shù)據(jù)通信格式的選擇,在同行的眼里,是同樣是個(gè)極富爭(zhēng)議話題。

          精略分析一下,究其原因,大概在于以下幾點(diǎn):

          • 可選擇的協(xié)議或封裝格式多種多樣:
            可選擇的余地大:XMPP、Protobuf、JSON、私有2進(jìn)制、MQTT、定格化XML、Plain text等等;
          • 同一種格式并不能適用于大多數(shù)的場(chǎng)景:
            不同的場(chǎng)景有同的考慮而協(xié)議的選擇往往跟這掛鉤在一起的,如:移動(dòng)端IM或推送用XMPP協(xié)議時(shí),多數(shù)情況下都會(huì)被噴;
          • 開發(fā)者對(duì)所選格式有各自的偏好:
            有的人或團(tuán)隊(duì)對(duì)某種或某幾種格式有不一樣的經(jīng)驗(yàn)和技術(shù)積累,也促成了他們對(duì)某種或某幾種協(xié)議的偏好。


          該選什么樣的數(shù)據(jù)通信格式,同樣是跟你的應(yīng)用場(chǎng)景和使用的架構(gòu)方案相關(guān)聯(lián)。不過,目前以作者掌握的信息看來,作為需要運(yùn)行在移動(dòng)設(shè)備的IM,幾乎目前所有主流討論里都不建議使用XMPP協(xié)議,具體原因就不在此展開了,下面推薦的文章里會(huì)詳細(xì)為你解答原因。

          以下文章會(huì)對(duì)你的IM的數(shù)據(jù)通信格式選型有所幫助:


          (更多同類文章:點(diǎn)此查看…

          八、移動(dòng)端IM的心跳保活和后臺(tái)消息推送

          [1] 為什么需要心跳保活?

          由于移動(dòng)網(wǎng)絡(luò)的復(fù)雜性,心跳保活對(duì)于移動(dòng)端IM來說顯的尤為重要,加之手機(jī)省電、省流量策略的設(shè)計(jì),如何實(shí)現(xiàn)心跳保活則也非常重要,文章《基于TCP協(xié)議的移動(dòng)端IM仍然需要心跳保活機(jī)制》或許可以解答你的疑問。

          [2] iOS端的后臺(tái)消息推送

          因?yàn)閕OS平臺(tái)的特殊性,iOS應(yīng)用一旦退到后臺(tái),應(yīng)用本身是無法用代碼來實(shí)現(xiàn)網(wǎng)絡(luò)保活的,也就無法自行實(shí)現(xiàn)后臺(tái)消息推送了。

          以下文章將有助于你理解iOS平臺(tái)的后臺(tái)消息推送原理:

           

          [3] Android端的心跳保活和后臺(tái)消息推送

          鑒于Android平臺(tái)眾所周之的分化和互不兼容問題,Android端IM在處理心跳保活和后臺(tái)消息推送時(shí),遇到了不少的麻煩。而且,由于Android應(yīng)用的生命周期管理是由系統(tǒng)控制,因而如何保證您的IM所在進(jìn)程或后臺(tái)服務(wù)不被系統(tǒng)殺死,是實(shí)現(xiàn)心跳保活和后臺(tái)消息推送的實(shí)現(xiàn)基礎(chǔ)。

          以下文章可為你的Android端IM的心跳保活和后臺(tái)推送方案的設(shè)計(jì)提供參考:


          (更多同類文章:此進(jìn)入…

          九、移動(dòng)端IM系統(tǒng)的架構(gòu)設(shè)計(jì)

          IM其本質(zhì)是一套消息發(fā)送與投遞系統(tǒng),或者說是一套網(wǎng)絡(luò)通信系統(tǒng),歸根結(jié)底就是兩個(gè)詞:存儲(chǔ)與轉(zhuǎn)發(fā)。但一個(gè)成熟的移動(dòng)端IM系統(tǒng)要想正常運(yùn)轉(zhuǎn),涉及的內(nèi)容則遠(yuǎn)不止這些,而最考驗(yàn)技術(shù)功底的就是服務(wù)端架構(gòu)的設(shè)計(jì)與實(shí)現(xiàn)。

          沒有過IM系統(tǒng)開發(fā)經(jīng)驗(yàn)的人,可能對(duì)以上觀點(diǎn)嗤之以鼻,在此借用TeamTalk的設(shè)計(jì)者的一段話:“IM服務(wù)器開發(fā),從功能抽象的角度看可能非常簡(jiǎn)單,可以認(rèn)為是管理大量的客戶端連接和在不同的客戶端之間傳遞消息,但具體到實(shí)現(xiàn)細(xì)節(jié)就比較復(fù)雜了。打個(gè)不恰當(dāng)?shù)谋扔鳎琌S的功能抽象也非常簡(jiǎn)單,無非是進(jìn)程間的調(diào)度和硬件資源的管理,但要是自己去實(shí)現(xiàn)一個(gè),一般人也就只能呵呵了。”

          我們以一個(gè)典型方案為例,首先來提煉一下一個(gè)IM系統(tǒng)的主要需求:包括賬號(hào)、關(guān)系鏈、在線狀態(tài)顯示、消息交互(文本、圖片、語音)、實(shí)時(shí)視頻電話......。

          要處理好上述需求,我們通常需要從以下方面進(jìn)行考量從而設(shè)計(jì)出合適的架構(gòu):

          • 如果采用可靠傳輸協(xié)議TCP,需要考慮到負(fù)載問題:短連接實(shí)現(xiàn)賬號(hào)、關(guān)系鏈相關(guān)業(yè)務(wù),長(zhǎng)連接實(shí)現(xiàn)上線、信息推送;
          • 后臺(tái)架構(gòu)的靈活性、可擴(kuò)展性:支持分布式部署——把網(wǎng)絡(luò)層、業(yè)務(wù)邏輯層、數(shù)據(jù)層分離,網(wǎng)絡(luò)層和業(yè)務(wù)層支持負(fù)載均衡策略、數(shù)據(jù)層支持分布式存儲(chǔ);
          • 客戶端SDK的易用性:把網(wǎng)絡(luò)層、數(shù)據(jù)層分離、業(yè)務(wù)邏輯層分離。


          另外,一個(gè)典型的IM系統(tǒng)架構(gòu)設(shè)計(jì),還有以下性能方面的熱點(diǎn)問題需要設(shè)計(jì)者重點(diǎn)關(guān)注:

          • 編碼角度:采用高效的網(wǎng)絡(luò)模型,線程模型,I/O處理模型,合理的數(shù)據(jù)庫設(shè)計(jì)和操作語句的優(yōu)化;
          • 垂直擴(kuò)展:通過提高單服務(wù)器的硬件資源或者網(wǎng)絡(luò)資源來提高性能;
          • 水平擴(kuò)展:通過合理的架構(gòu)設(shè)計(jì)和運(yùn)維方面的負(fù)載均衡策略將負(fù)載分擔(dān),有效提高性能;后期甚至可以考慮加入數(shù)據(jù)緩存層,突破IO瓶頸;
          • 系統(tǒng)的高可用性:防止單點(diǎn)故障;
          • 在架構(gòu)設(shè)計(jì)時(shí)做到業(yè)務(wù)處理和數(shù)據(jù)的分離,從而依賴分布式的部署使得在單點(diǎn)故障時(shí)能保證系統(tǒng)可用。
          • 對(duì)于關(guān)鍵獨(dú)立節(jié)點(diǎn)可以采用雙機(jī)熱備技術(shù)進(jìn)行切換。
          • 數(shù)據(jù)庫數(shù)據(jù)的安全性可以通過磁盤陣列的冗余配置和主備數(shù)據(jù)庫來解決。


          鑒于篇幅有限,架構(gòu)設(shè)計(jì)方面的內(nèi)容本文就不深入展開了。

          以下文章將為你的移動(dòng)端IM的架構(gòu)設(shè)計(jì)帶來一定的參考意義:


          (更多同類文章: 點(diǎn)此進(jìn)入…

          十、移動(dòng)端IM的通信安全

          IM(尤其移動(dòng)端IM)的安全性一直是開發(fā)者需要優(yōu)先考慮的基礎(chǔ)問題,如何正確地理解和使用加密技術(shù)則顯的尤其重要。IM系統(tǒng)大都采用C/S、B/S、P2P等技術(shù)來實(shí)現(xiàn)即時(shí)通信的功能,軟件編制沒有統(tǒng)一的標(biāo)準(zhǔn),使得IM系統(tǒng)本身存有多種安全漏洞,加上用戶缺乏安全意識(shí),導(dǎo)致在使用即時(shí)通信系統(tǒng)時(shí)出現(xiàn)各種安全問題。

          當(dāng)今的計(jì)算機(jī)密碼學(xué)的主要作用有:加密( Encryption)、認(rèn)證(Authentication),鑒定(Identification) 。

          加密:防止壞人獲取你的數(shù)據(jù)。 
          認(rèn)證:防止壞人修改了你的數(shù)據(jù)而你卻并沒有發(fā)現(xiàn)。 
          鑒權(quán):防止壞人假冒你的身份。

          這些基本概念和加密算法原理就不在此展開敘述了。

          以下文章或許有助于您設(shè)計(jì)出安全的移動(dòng)端IM系統(tǒng):


          (更多同類文章:點(diǎn)此進(jìn)入…

          十一、有關(guān)IM中的實(shí)時(shí)音視頻技術(shù)

          IM應(yīng)用中的實(shí)時(shí)音視頻技術(shù),幾乎是IM開發(fā)中的最后一道高墻。原因在于:實(shí)時(shí)音視頻技術(shù) = 音視頻處理技術(shù) + 網(wǎng)絡(luò)傳輸技術(shù) 的橫向技術(shù)應(yīng)用集合體,而公共互聯(lián)網(wǎng)不是為了實(shí)時(shí)通信設(shè)計(jì)的。實(shí)時(shí)音視頻技術(shù)上的實(shí)現(xiàn)內(nèi)容主要包括:音視頻的采集、編碼、網(wǎng)絡(luò)傳輸、解碼、播放等環(huán)節(jié)。這么多項(xiàng)并不簡(jiǎn)單的技術(shù)應(yīng)用,如果把握不當(dāng),將會(huì)在在實(shí)際開發(fā)過程中遇到一個(gè)又一個(gè)的坑。

          以下文章有助于您從零理解IM的實(shí)時(shí)音視頻開發(fā)的方方面面:


          (更多同類文章: 點(diǎn)此進(jìn)入…

          十二、移動(dòng)端IM開發(fā)的其它熱點(diǎn)問題

          移動(dòng)端IM開發(fā)中還會(huì)遇到上述內(nèi)容未提及的內(nèi)容,以下文章或許您用的上:
          移動(dòng)端IM開發(fā)需要面對(duì)的技術(shù)問題
          開發(fā)IM是自己設(shè)計(jì)協(xié)議用字節(jié)流好還是字符流好?
          請(qǐng)問有人知道語音留言聊天的主流實(shí)現(xiàn)方式嗎?
          IM系統(tǒng)中如何保證消息的可靠投遞(即QoS機(jī)制)
          談?wù)勔苿?dòng)端 IM 開發(fā)中登錄請(qǐng)求的優(yōu)化
          完全自已開發(fā)的IM該如何設(shè)計(jì)“失敗重試”機(jī)制?
          微信對(duì)網(wǎng)絡(luò)影響的技術(shù)試驗(yàn)及分析(論文全文)
          即時(shí)通訊系統(tǒng)的原理、技術(shù)和應(yīng)用(技術(shù)論文)
          開源IM工程“蘑菇街TeamTalk”的現(xiàn)狀:一場(chǎng)有始無終的開源秀
          >> 更多同類文章 …… 

          附錄:其它即時(shí)通訊文章

          [1] 有關(guān)WEB端即時(shí)通訊開發(fā):
          新手入門貼:史上最全Web端即時(shí)通訊技術(shù)原理詳解
          Web端即時(shí)通訊技術(shù)盤點(diǎn):短輪詢、Comet、Websocket、SSE
          SSE技術(shù)詳解:一種全新的HTML5服務(wù)器推送事件技術(shù)
          Comet技術(shù)詳解:基于HTTP長(zhǎng)連接的Web端實(shí)時(shí)通信技術(shù)
          WebSocket詳解(一):初步認(rèn)識(shí)WebSocket技術(shù)
          socket.io實(shí)現(xiàn)消息推送的一點(diǎn)實(shí)踐及思路
          >> 更多同類文章 ……

          [2] 有關(guān)推送技術(shù)的文章:
          iOS的推送服務(wù)APNs詳解:設(shè)計(jì)思路、技術(shù)原理及缺陷等
          Android端消息推送總結(jié):實(shí)現(xiàn)原理、心跳保活、遇到的問題等
          掃盲貼:認(rèn)識(shí)MQTT通信協(xié)議
          一個(gè)基于MQTT通信協(xié)議的完整Android推送Demo
          求教android消息推送:GCM、XMPP、MQTT三種方案的優(yōu)劣
          移動(dòng)端實(shí)時(shí)消息推送技術(shù)淺析
          掃盲貼:淺談iOS和Android后臺(tái)實(shí)時(shí)消息推送的原理和區(qū)別
          絕對(duì)干貨:基于Netty實(shí)現(xiàn)海量接入的推送服務(wù)技術(shù)要點(diǎn)
          移動(dòng)端IM實(shí)踐:谷歌消息推送服務(wù)(GCM)研究(來自微信)
          為何微信、QQ這樣的IM工具不使用GCM服務(wù)推送消息?
          >> 更多同類文章 ……

          [3] 更多即時(shí)通訊技術(shù)好文分類:
          http://www.52im.net/forum.php?mod=collection&op=all

          (本文同步發(fā)布于:http://www.52im.net/thread-464-1-1.html

          作者:Jack Jiang (點(diǎn)擊作者姓名進(jìn)入Github) 
          出處:http://www.52im.net/space-uid-1.html 
          交流:歡迎加入即時(shí)通訊開發(fā)交流群 215891622 
          討論:http://www.52im.net/ 
          Jack Jiang同時(shí)是【原創(chuàng)Java Swing外觀工程BeautyEye】【輕量級(jí)移動(dòng)端即時(shí)通訊框架MobileIMSDK】的作者,可前往下載交流。



          作者:Jack Jiang (點(diǎn)擊作者姓名進(jìn)入Github)
          出處:http://www.52im.net/space-uid-1.html
          交流:歡迎加入即時(shí)通訊開發(fā)交流群 215891622
          討論:http://www.52im.net/
          Jack Jiang同時(shí)是【原創(chuàng)Java Swing外觀工程BeautyEye】【輕量級(jí)移動(dòng)端即時(shí)通訊框架MobileIMSDK】的作者,可前往下載交流。
          本博文 歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處(也可前往 我的52im.net 找到我)。


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          Jack Jiang的 Mail: jb2011@163.com, 聯(lián)系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 枝江市| 红桥区| 三亚市| 鹤峰县| 德庆县| 甘泉县| 信阳市| 贺州市| 常德市| 宣化县| 天峨县| 托里县| 大化| 怀远县| 宁阳县| 孟州市| 铅山县| 保康县| 临邑县| 兴和县| 塔城市| 凤翔县| 凯里市| 福建省| 左云县| 宜兰县| 大理市| 邵东县| 通化市| 云林县| 牡丹江市| 额敏县| 太和县| 邯郸市| 贵溪市| 德格县| 冷水江市| 蓝山县| 井陉县| 江油市| 新源县|