乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Dubbo系列-揚(yáng)帆起航

       鷹兔牛熊眼 2020-08-18

      前言

      接下來(lái)一段時(shí)間敖丙將帶大家開(kāi)啟緊張刺激的 Dubbo 之旅!是的要開(kāi)始寫(xiě) Dubbo 系列的文章了,之前我已經(jīng)寫(xiě)過(guò)一篇架構(gòu)演進(jìn)的文章,也說(shuō)明了微服務(wù)的普及化以及重要性,服務(wù)化場(chǎng)景下隨之而來(lái)的就是服務(wù)之間的通信問(wèn)題,那服務(wù)間的通信腦海中想到的就是 RPC,說(shuō)到 RPC 就離不開(kāi)咱們的 Dubbo。

      這篇文章敖丙先帶著大家來(lái)總覽全局,一般而言熟悉一個(gè)框架你要先知道這玩意是做什么的,能解決什么痛點(diǎn),核心的模塊是什么,大致運(yùn)轉(zhuǎn)流程是怎樣的。

      你要一來(lái)就扎入細(xì)節(jié)之中無(wú)法自拔,一波 DFS 直接被勸退的可能性高達(dá)99.99%,所以本暖男敖丙將帶大家先過(guò)一遍 Dubbo 的簡(jiǎn)介、總體分層、核心組件以及大致調(diào)用流程

      不僅如此我還會(huì)帶著大家過(guò)一遍如果要讓你設(shè)計(jì)一個(gè) RPC 框架你看看都需要什么功能?這波操作之后你會(huì)發(fā)現(xiàn)嘿嘿 Dubbo 怎么設(shè)計(jì)的和我想的一樣呢?真是英雄所見(jiàn)略同??!

      而且我還會(huì)寫(xiě)一個(gè)簡(jiǎn)單版 RPC 框架實(shí)現(xiàn),讓大家明白 RPC 到底是如何工作的。

      如果看了這篇文章你要還是不知道 Dubbo 是啥,我可以要?jiǎng)裢肆恕?/p>

      我們先來(lái)談一談什么叫 RPC ,我發(fā)現(xiàn)有很多同學(xué)不太了解這個(gè)概念,還有人把 RPC 和 HTTP 來(lái)進(jìn)行對(duì)比。所以咱們先來(lái)說(shuō)說(shuō)什么是 RPC。

      什么是 RPC

      RPC,Remote Procedure Call 即遠(yuǎn)程過(guò)程調(diào)用,遠(yuǎn)程過(guò)程調(diào)用其實(shí)對(duì)標(biāo)的是本地過(guò)程調(diào)用,本地過(guò)程調(diào)用你熟悉吧?

      想想那青蔥歲月,你在大學(xué)趕著期末大作業(yè),正在攻克圖書(shū)管理系統(tǒng),你奮筆疾書(shū)瘋狂地敲擊鍵盤(pán),實(shí)現(xiàn)了圖書(shū)借閱、圖書(shū)歸還等等模塊,你實(shí)現(xiàn)的一個(gè)個(gè)方法之間的調(diào)用就叫本地過(guò)程調(diào)用。

      你要是和我說(shuō)你實(shí)現(xiàn)圖書(shū)館里系統(tǒng)已經(jīng)用了服務(wù)化,搞了遠(yuǎn)程調(diào)用了,我只能和你說(shuō)你有點(diǎn)東西。

      簡(jiǎn)單的說(shuō)本機(jī)上內(nèi)部的方法調(diào)用都可以稱(chēng)為本地過(guò)程調(diào)用,而遠(yuǎn)程過(guò)程調(diào)用實(shí)際上就指的是你本地調(diào)用了遠(yuǎn)程機(jī)子上的某個(gè)方法,這就是遠(yuǎn)程過(guò)程調(diào)用。

      所以說(shuō) RPC 對(duì)標(biāo)的是本地過(guò)程調(diào)用,至于 RPC 要如何調(diào)用遠(yuǎn)程的方法可以走 HTTP、也可以是基于 TCP 自定義協(xié)議。

      所以說(shuō)你討論 RPC 和 HTTP 就不是一個(gè)層級(jí)的東西。

      RPC 框架就是要實(shí)現(xiàn)像那小助手一樣的東西,目的就是讓我們使用遠(yuǎn)程調(diào)用像本地調(diào)用一樣簡(jiǎn)單方便,并且解決一些遠(yuǎn)程調(diào)用會(huì)發(fā)生的一些問(wèn)題,使用戶用的無(wú)感知、舒心、放心、順心,它好我也好,快樂(lè)沒(méi)煩惱。

      如何設(shè)計(jì)一個(gè) RPC 框架

      在明確了什么是 RPC,以及 RPC 框架的目的之后,咱們想想如果讓你做一款 RPC 框架你該如何設(shè)計(jì)?

      服務(wù)消費(fèi)者

      我們先從消費(fèi)者方(也就是調(diào)用方)來(lái)看需要些什么,首先消費(fèi)者面向接口編程,所以需要得知有哪些接口可以調(diào)用,可以通過(guò)公用 jar 包的方式來(lái)維護(hù)接口。

      現(xiàn)在知道有哪些接口可以調(diào)用了,但是只有接口啊,具體的實(shí)現(xiàn)怎么來(lái)?這事必須框架給處理了!所以還需要來(lái)個(gè)代理類(lèi),讓消費(fèi)者只管調(diào),啥事都別管了,我代理幫你搞定。

      對(duì)了,還需要告訴代理,你調(diào)用的是哪個(gè)方法,并且參數(shù)的值是什么。

      雖說(shuō)代理幫你搞定但是代理也需要知道它到底要調(diào)哪個(gè)機(jī)子上的遠(yuǎn)程方法,所以需要有個(gè)注冊(cè)中心,這樣調(diào)用方從注冊(cè)中心可以知曉可以調(diào)用哪些服務(wù)提供方,一般而言提供方不止一個(gè),畢竟只有一個(gè)掛了那不就沒(méi)了。

      所以提供方一般都是集群部署,那調(diào)用方需要通過(guò)負(fù)載均衡來(lái)選擇一個(gè)調(diào)用,可以通過(guò)某些策略例如同機(jī)房?jī)?yōu)先調(diào)用啊啥的。

      當(dāng)然還需要有容錯(cuò)機(jī)制,畢竟這是遠(yuǎn)程調(diào)用,網(wǎng)絡(luò)是不可靠的,所以可能需要重試什么的。

      還要和服務(wù)提供方約定一個(gè)協(xié)議,例如我們就用 HTTP 來(lái)通信就好啦,也就是大家要講一樣的話,不然可能聽(tīng)不懂了。

      當(dāng)然序列化必不可少,畢竟我們本地的結(jié)構(gòu)是“立體”的,需要序列化之后才能傳輸,因此還需要約定序列化格式。

      并且這過(guò)程中間可能還需要摻入一些 Filter,來(lái)作一波統(tǒng)一的處理,例如調(diào)用計(jì)數(shù)啊等等。

      這些都是框架需要做的,讓消費(fèi)者像在調(diào)用本地方法一樣,無(wú)感知。

      服務(wù)提供者

      服務(wù)提供者肯定要實(shí)現(xiàn)對(duì)應(yīng)的接口這是毋庸置疑的。

      然后需要把自己的接口暴露出去,向注冊(cè)中心注冊(cè)自己,暴露自己所能提供的服務(wù)。

      然后有消費(fèi)者請(qǐng)求過(guò)來(lái)需要處理,提供者需要用和消費(fèi)者協(xié)商好的協(xié)議來(lái)處理這個(gè)請(qǐng)求,然后做反序列化。

      序列化完的請(qǐng)求應(yīng)該扔到線程池里面做處理,某個(gè)線程接受到這個(gè)請(qǐng)求之后找到對(duì)應(yīng)的實(shí)現(xiàn)調(diào)用,然后再將結(jié)果原路返回

      注冊(cè)中心

      上面其實(shí)我們都提到了注冊(cè)中心,這東西就相當(dāng)于一個(gè)平臺(tái),大家在上面暴露自己的服務(wù),也在上面得知自己能調(diào)用哪些服務(wù)。

      當(dāng)然還能做配置中心,將配置集中化處理,動(dòng)態(tài)變更通知訂閱者。

      監(jiān)控運(yùn)維

      面對(duì)眾多的服務(wù),精細(xì)化的監(jiān)控和方便的運(yùn)維必不可少。

      這點(diǎn)很多開(kāi)發(fā)者在開(kāi)發(fā)的時(shí)候察覺(jué)不到,到你真正上線開(kāi)始運(yùn)行維護(hù)的時(shí)候,如果沒(méi)有良好的監(jiān)控措施,快速的運(yùn)維手段,到時(shí)候就是睜眼瞎!手足無(wú)措,等著挨批把!

      那種痛苦不要問(wèn)我為什么知道,我就是知道!

      小結(jié)一下

      讓我們小結(jié)一下,大致上一個(gè) RPC 框架需要做的就是約定要通信協(xié)議,序列化的格式、一些容錯(cuò)機(jī)制、負(fù)載均衡策略、監(jiān)控運(yùn)維和一個(gè)注冊(cè)中心!

      簡(jiǎn)單實(shí)現(xiàn)一個(gè) RPC 框架

      沒(méi)錯(cuò)就是簡(jiǎn)單的實(shí)現(xiàn),上面我們?cè)谒伎既绾卧O(shè)計(jì)一個(gè) RPC 框架的時(shí)候想了很多,那算是生產(chǎn)環(huán)境使用級(jí)別的功能需求了,我們這是 Demo,目的是突出 RPC框架重點(diǎn)功能 - 實(shí)現(xiàn)遠(yuǎn)程調(diào)用

      所以啥七七八八的都沒(méi),并且我用偽代碼來(lái)展示,其實(shí)也就是刪除了一些保護(hù)性和約束性的代碼,因?yàn)榭雌饋?lái)太多了不太直觀,需要一堆 try-catch 啥的,因此我刪減了一些,直擊重點(diǎn)。

      Let's Do It!

      首先我們定義一個(gè)接口和一個(gè)簡(jiǎn)單實(shí)現(xiàn)。

      public interface AobingService {  
          String hello(String name);  


      public class AobingServiceImpl implements AobingService {  
          public String hello(String name) {  
              return 'Yo man Hello,I am' + name;  
          }  
      }  

      然后我們?cè)賮?lái)實(shí)現(xiàn)服務(wù)提供者暴露服務(wù)的功能。

      public class AobingRpcFramework 
           public static void export(Object service, int port) throws Exception 
                ServerSocket server = new ServerSocket(port);
                while(true) {
                    Socket socket = server.accept();
                    new Thread(new Runnable() {
                        //反序列化
                        ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); 
                        String methodName = input.read(); //讀取方法名
                        Class<?>[] parameterTypes = (Class<?>[]) input.readObject(); //參數(shù)類(lèi)型
                        Object[] arguments = (Object[]) input.readObject(); //參數(shù)
                        Method method = service.getClass().getMethod(methodName, parameterTypes);  //找到方法
                        Object result = method.invoke(service, arguments); //調(diào)用方法
                        // 返回結(jié)果
                        ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
                        output.writeObject(result);
                    }).start();
                }
           }
          public static <T> refer (Class<T> interfaceClass, String host, int port) throws Exception {
             return  (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] {interfaceClass}, 
                  new InvocationHandler() {  
                      public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable {  
                          Socket socket = new Socket(host, port);  //指定 provider 的 ip 和端口
                          ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); 
                          output.write(method.getName());  //傳方法名
                          output.writeObject(method.getParameterTypes());  //傳參數(shù)類(lèi)型
                          output.writeObject(arguments);  //傳參數(shù)值
                          ObjectInputStream input = new ObjectInputStream(socket.getInputStream());  
                          Object result = input.readObject();  //讀取結(jié)果
                          return result;  
                     }
              });  
          }  
      }

      好了,這個(gè) RPC 框架就這樣好了,是不是很簡(jiǎn)單?就是調(diào)用者傳遞了方法名、參數(shù)類(lèi)型和參數(shù)值,提供者接收到這樣參數(shù)之后調(diào)用對(duì)于的方法返回結(jié)果就好了!這就是遠(yuǎn)程過(guò)程調(diào)用。

      我們來(lái)看看如何使用

              //服務(wù)提供者只需要暴露出接口
             AobingService service = new AobingServiceImpl ();  
             AobingRpcFramework.export(service, 2333);  

             //服務(wù)調(diào)用者只需要設(shè)置依賴
             AobingService service = AobingRpcFramework.refer(AobingService.class, '127.0.0.1'2333);  
             service.hello(); 

      看起來(lái)好像好不錯(cuò)喲,不過(guò)這很是簡(jiǎn)陋,用作 demo 有助理解還是極好的!

      接下來(lái)就來(lái)看看 Dubbo 吧!上正菜!

      Dubbo 簡(jiǎn)介

      Dubbo 是阿里巴巴 2011年開(kāi)源的一個(gè)基于 Java 的 RPC 框架,中間沉寂了一段時(shí)間,不過(guò)其他一些企業(yè)還在用 Dubbo 并自己做了擴(kuò)展,比如當(dāng)當(dāng)網(wǎng)的 Dubbox,還有網(wǎng)易考拉的 Dubbok。

      但是在 2017 年阿里巴巴又重啟了對(duì) Dubbo 維護(hù)。在 2017 年榮獲了開(kāi)源中國(guó) 2017 最受歡迎的中國(guó)開(kāi)源軟件 Top 3。

      在 2018 年和 Dubbox 進(jìn)行了合并,并且進(jìn)入 Apache 孵化器,在 2019 年畢業(yè)正式成為 Apache 頂級(jí)項(xiàng)目。

      目前 Dubbo 社區(qū)主力維護(hù)的是 2.6.x 和 2.7.x 兩大版本,2.6.x 版本主要是 bug 修復(fù)和少量功能增強(qiáng)為準(zhǔn),是穩(wěn)定版本。

      而 2.7.x 是主要開(kāi)發(fā)版本,更新和新增新的 feature 和優(yōu)化,并且 2.7.5 版本的發(fā)布被 Dubbo 認(rèn)為是里程碑式的版本發(fā)布,之后我們?cè)僮龇治觥?/p>

      它實(shí)現(xiàn)了面向接口的代理 RPC 調(diào)用,并且可以配合 ZooKeeper 等組件實(shí)現(xiàn)服務(wù)注冊(cè)和發(fā)現(xiàn)功能,并且擁有負(fù)載均衡、容錯(cuò)機(jī)制等。

      Dubbo 總體架構(gòu)

      我們先來(lái)看下官網(wǎng)的一張圖。

      本丙再暖心的給上圖內(nèi)每個(gè)節(jié)點(diǎn)的角色說(shuō)明一下。

      節(jié)點(diǎn)角色說(shuō)明
      Consumer需要調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方
      Registry注冊(cè)中心
      Provider服務(wù)提供方
      Container服務(wù)運(yùn)行的容器
      Monitor監(jiān)控中心

      我再來(lái)大致說(shuō)一下整體的流程,首先服務(wù)提供者 Provider 啟動(dòng)然后向注冊(cè)中心注冊(cè)自己所能提供的服務(wù)。

      服務(wù)消費(fèi)者 Consumer 啟動(dòng)向注冊(cè)中心訂閱自己所需的服務(wù)。然后注冊(cè)中心將提供者元信息通知給 Consumer, 之后 Consumer 因?yàn)橐呀?jīng)從注冊(cè)中心獲取提供者的地址,因此可以通過(guò)負(fù)載均衡選擇一個(gè) Provider 直接調(diào)用

      之后服務(wù)提供方元數(shù)據(jù)變更的話注冊(cè)中心會(huì)把變更推送給服務(wù)消費(fèi)者。

      服務(wù)提供者和消費(fèi)者都會(huì)在內(nèi)存中記錄著調(diào)用的次數(shù)和時(shí)間,然后定時(shí)的發(fā)送統(tǒng)計(jì)數(shù)據(jù)到監(jiān)控中心。

      一些注意點(diǎn)

      首先注冊(cè)中心和監(jiān)控中心是可選的,你可以不要監(jiān)控,也不要注冊(cè)中心,直接在配置文件里面寫(xiě)然后提供方和消費(fèi)方直連。

      然后注冊(cè)中心、提供方和消費(fèi)方之間都是長(zhǎng)連接,和監(jiān)控方不是長(zhǎng)連接,并且消費(fèi)方是直接調(diào)用提供方,不經(jīng)過(guò)注冊(cè)中心。

      就算注冊(cè)中心和監(jiān)控中心宕機(jī)了也不會(huì)影響到已經(jīng)正常運(yùn)行的提供者和消費(fèi)者,因?yàn)橄M(fèi)者有本地緩存提供者的信息。

      Dubbo 分層架構(gòu)

      總的而言 Dubbo 分為三層,如果每一層再細(xì)分下去,一共有十層。別怕也就十層,本丙帶大家過(guò)一遍,大家先有個(gè)大致的印象,之后的文章丙會(huì)帶著大家再深入。

      大的三層分別為 Business(業(yè)務(wù)層)、RPC 層、Remoting,并且還分為 API 層和 SPI 層。

      分為大三層其實(shí)就是和我們知道的網(wǎng)絡(luò)分層一樣的意思,只有層次分明,職責(zé)邊界清晰才能更好的擴(kuò)展。

      而分 API 層和 SPI 層這是 Dubbo 成功的一點(diǎn),采用微內(nèi)核設(shè)計(jì)+SPI擴(kuò)展,使得有特殊需求的接入方可以自定義擴(kuò)展,做定制的二次開(kāi)發(fā)。

      接下來(lái)咱們?cè)賮?lái)看看每一層都是干嘛的。

      • Service,業(yè)務(wù)層,就是咱們開(kāi)發(fā)的業(yè)務(wù)邏輯層。

      • Config,配置層,主要圍繞 ServiceConfig 和 ReferenceConfig,初始化配置信息。

      • Proxy,代理層,服務(wù)提供者還是消費(fèi)者都會(huì)生成一個(gè)代理類(lèi),使得服務(wù)接口透明化,代理層做遠(yuǎn)程調(diào)用和返回結(jié)果。

      • Register,注冊(cè)層,封裝了服務(wù)注冊(cè)和發(fā)現(xiàn)。

      • Cluster,路由和集群容錯(cuò)層,負(fù)責(zé)選取具體調(diào)用的節(jié)點(diǎn),處理特殊的調(diào)用要求和負(fù)責(zé)遠(yuǎn)程調(diào)用失敗的容錯(cuò)措施。

      • Monitor,監(jiān)控層,負(fù)責(zé)監(jiān)控統(tǒng)計(jì)調(diào)用時(shí)間和次數(shù)。

      • Portocol,遠(yuǎn)程調(diào)用層,主要是封裝 RPC 調(diào)用,主要負(fù)責(zé)管理 Invoker,Invoker代表一個(gè)抽象封裝了的執(zhí)行體,之后再做詳解。

      • Exchange,信息交換層,用來(lái)封裝請(qǐng)求響應(yīng)模型,同步轉(zhuǎn)異步。

      • Transport,網(wǎng)絡(luò)傳輸層,抽象了網(wǎng)絡(luò)傳輸?shù)慕y(tǒng)一接口,這樣用戶想用 Netty 就用 Netty,想用 Mina 就用 Mina。

      • Serialize,序列化層,將數(shù)據(jù)序列化成二進(jìn)制流,當(dāng)然也做反序列化。

      SPI

      我再稍微提一下 SPI(Service Provider Interface),是 JDK 內(nèi)置的一個(gè)服務(wù)發(fā)現(xiàn)機(jī)制,它使得接口和具體實(shí)現(xiàn)完全解耦。我們只聲明接口,具體的實(shí)現(xiàn)類(lèi)在配置中選擇。

      具體的就是你定義了一個(gè)接口,然后在META-INF/services目錄下放置一個(gè)與接口同名的文本文件,文件的內(nèi)容為接口的實(shí)現(xiàn)類(lèi),多個(gè)實(shí)現(xiàn)類(lèi)用換行符分隔。

      這樣就通過(guò)配置來(lái)決定具體用哪個(gè)實(shí)現(xiàn)!

      而 Dubbo SPI 還做了一些改進(jìn),篇幅有限留在之后再談。

      Dubbo 調(diào)用過(guò)程

      上面我已經(jīng)介紹了每個(gè)層到底是干嘛的,我們現(xiàn)在再來(lái)串起來(lái)走一遍調(diào)用的過(guò)程,加深你對(duì) Dubbo 的理解,讓知識(shí)點(diǎn)串起來(lái),由點(diǎn)及面來(lái)一波連連看。

      我們先從服務(wù)提供者開(kāi)始,看看它是如何工作的。

      服務(wù)暴露過(guò)程

      首先 Provider 啟動(dòng),通過(guò) Proxy 組件根據(jù)具體的協(xié)議Protocol 將需要暴露出去的接口封裝成 Invoker,Invoker 是 Dubbo 一個(gè)很核心的組件,代表一個(gè)可執(zhí)行體。

      然后再通過(guò) Exporter 包裝一下,這是為了在注冊(cè)中心暴露自己套的一層,然后將 Exporter 通過(guò) Registry 注冊(cè)到注冊(cè)中心。這就是整體服務(wù)暴露過(guò)程。

      消費(fèi)過(guò)程

      接著我們來(lái)看消費(fèi)者調(diào)用流程(把服務(wù)者暴露的過(guò)程也在圖里展示出來(lái)了,這個(gè)圖其實(shí)算一個(gè)挺完整的流程圖了)。

      首先消費(fèi)者啟動(dòng)會(huì)向注冊(cè)中心拉取服務(wù)提供者的元信息,然后調(diào)用流程也是從 Proxy 開(kāi)始,畢竟都需要代理才能無(wú)感知。

      Proxy 持有一個(gè) Invoker 對(duì)象,調(diào)用 invoke 之后需要通過(guò) Cluster 先從 Directory 獲取所有可調(diào)用的遠(yuǎn)程服務(wù)的 Invoker 列表,如果配置了某些路由規(guī)則,比如某個(gè)接口只能調(diào)用某個(gè)節(jié)點(diǎn)的那就再過(guò)濾一遍 Invoker 列表。

      剩下的 Invoker 再通過(guò) LoadBalance 做負(fù)載均衡選取一個(gè)。然后再經(jīng)過(guò) Filter 做一些統(tǒng)計(jì)什么的,再通過(guò) Client 做數(shù)據(jù)傳輸,比如用 Netty 來(lái)傳輸。

      傳輸需要經(jīng)過(guò) Codec 接口做協(xié)議構(gòu)造,再序列化。最終發(fā)往對(duì)應(yīng)的服務(wù)提供者。

      服務(wù)提供者接收到之后也會(huì)進(jìn)行 Codec 協(xié)議處理,然后反序列化后將請(qǐng)求扔到線程池處理。某個(gè)線程會(huì)根據(jù)請(qǐng)求找到對(duì)應(yīng)的 Exporter ,而找到 Exporter 其實(shí)就是找到了 Invoker,但是還會(huì)有一層層 Filter,經(jīng)過(guò)一層層過(guò)濾鏈之后最終調(diào)用實(shí)現(xiàn)類(lèi)然后原路返回結(jié)果。

      完成整個(gè)調(diào)用過(guò)程!

      總結(jié)

      這次敖丙帶著大家先了解了下什么是 RPC,然后規(guī)劃了一波 RPC 框架需要哪些組件,然后再用代碼實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的 RPC 框架。

      然后帶著大家了解了下 Dubbo 的發(fā)展歷史、總體架構(gòu)、分層設(shè)計(jì)架構(gòu)以及每個(gè)組件是干嘛的,再帶著大伙走了一遍整體調(diào)用過(guò)程。

      我真的是太暖了??!

      dubbo近期我會(huì)安排幾個(gè)章節(jié)繼續(xù)展開(kāi),最后會(huì)出一個(gè)面試版本的dubbo,我們拭目以待吧。

      我是敖丙,你知道的越多,你不知道的越多,我們下期見(jiàn)!

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類(lèi)似文章 更多