HIVE作業(yè)管理分析及解決方案是什么

HIVE作業(yè)管理分析及解決方案是什么,相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。

成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),椒江企業(yè)網(wǎng)站建設(shè),椒江品牌網(wǎng)站建設(shè),網(wǎng)站定制,椒江網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,椒江網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。

hive任務(wù)管理

對(duì)于hive任務(wù)展示的時(shí)候需要把id和mr id關(guān)聯(lián), 殺死任務(wù)的時(shí)候需要把所有屬于這個(gè)hive語(yǔ)句的任務(wù)都?xì)⑺馈?/p>


一 相關(guān)知識(shí)

1.1 基礎(chǔ)知識(shí)

Hive是基于Hadoop的一個(gè)數(shù)據(jù)倉(cāng)庫(kù)工具,可以將結(jié)構(gòu)化的數(shù)據(jù)文件映射為一張數(shù)據(jù)庫(kù)表,并提供類SQL查詢功能。 本質(zhì)是將SQL轉(zhuǎn)換為MapReduce程序 HIVE作業(yè)管理分析及解決方案是什么

1.2 Thrift服務(wù)

thrift是facebook開(kāi)發(fā)的一個(gè)軟件框架,它用來(lái)進(jìn)行可擴(kuò)展且跨語(yǔ)言的服務(wù)的開(kāi)發(fā),hive集成了該服務(wù),能讓不同的編程語(yǔ)言調(diào)用hive的接口。

1.3 hiveServer/HiveServer2

兩者都允許遠(yuǎn)程客戶端使用多種編程語(yǔ)言,通過(guò)HiveServer或者HiveServer2,客戶端可以在不啟動(dòng)CLI的情況下對(duì)Hive中的數(shù)據(jù)進(jìn)行操作, 允許遠(yuǎn)程客戶端使用多種編程語(yǔ)言如java,python等向hive提交請(qǐng)求,取回結(jié)果(從hive0.15起就不再支持hiveserver了)。

HiveServer或者HiveServer2都是基于Thrift的,但HiveSever有時(shí)被稱為T(mén)hrift server,而HiveServer2卻不會(huì)。

既然已經(jīng)存在HiveServer,為什么還需要HiveServer2呢?

這是因?yàn)?=HiveServer不能處理多于一個(gè)客戶端的并發(fā)請(qǐng)求==,這是由于HiveServer使用的Thrift接口所導(dǎo)致的限制,不能通過(guò)修改HiveServer的代碼修正。因此在Hive-0.11.0版本中重寫(xiě)了HiveServer代碼得到了HiveServer2,進(jìn)而解決了該問(wèn)題。

HiveServer2支持多客戶端的并發(fā)和認(rèn)證,為開(kāi)放API客戶端如JDBC、ODBC提供更好的支持。

1.4 執(zhí)行原理

HIVE作業(yè)管理分析及解決方案是什么

1.5 用戶接口

Hive 命令行模式(CLI)

命令行接口,CLI可以以兩種模式運(yùn)行,一種是單純的客戶端,直接連接driver;還有一種是連接hiveserver1;hiveserver1已經(jīng)被hiveserver2取代,并在1.0.0版本去掉。因?yàn)榘踩缘仍?,官方希望用beeline替代cli;或者直接修改cli的底層實(shí)現(xiàn)來(lái)達(dá)到無(wú)縫修改。 https://issues.apache.org/jira/browse/HIVE-10511 https://cwiki.apache.org/confluence/display/Hive/Replacing+the+Implementation+of+Hive+CLI+Using+Beeline

Hive 的 Web 模式(WUI)

hive客戶端提供了一種通過(guò)網(wǎng)頁(yè)的方式訪問(wèn)hive所提供的服務(wù)。這個(gè)接口對(duì)應(yīng)hive的hwi組件(hive web interface),使用前要啟動(dòng)hwi服務(wù)。 ==hwi因?yàn)槭褂幂^少,2.2版本后被移除。==

Hive 的遠(yuǎn)程服務(wù)(Client)

通過(guò)Thrift協(xié)議與某個(gè)單獨(dú)的HiveServer2進(jìn)程進(jìn)行連接通信。

beeline

HiveServer2提供了一個(gè)新的命令行工具Beeline,它是基于SQLLine CLI的JDBC客戶端。

Beeline工作模式有兩種,即本地嵌入模式和遠(yuǎn)程模式。嵌入模式情況下,它返回一個(gè)嵌入式的Hive(類似于Hive CLI)。而遠(yuǎn)程模式則是通過(guò)Thrift協(xié)議與某個(gè)單獨(dú)的HiveServer2進(jìn)程進(jìn)行連接通信。

二 開(kāi)源方案

2.1 hive falcon

在開(kāi)發(fā)工作當(dāng)中,提交 Hadoop 任務(wù),任務(wù)的運(yùn)行詳情,這是我們所關(guān)心的,當(dāng)業(yè)務(wù)并不復(fù)雜的時(shí)候,我們可以使用 Hadoop 提供的命令工具去管理 YARN 中的任務(wù)。在編寫(xiě) Hive SQL 的時(shí)候,需要在 Hive 終端,編寫(xiě) SQL 語(yǔ)句,來(lái)觀察 MapReduce 的運(yùn)行情況,長(zhǎng)此以往,感覺(jué)非常的不便。另外隨著業(yè)務(wù)的復(fù)雜化,任務(wù)的數(shù)量增加,此時(shí)我們?cè)谑褂眠@套流程,已預(yù)感到力不從心,這時(shí)候 Hive 的監(jiān)控系統(tǒng)此刻便尤為顯得重要,我們需要觀察 Hive SQL 的 MapReduce 運(yùn)行詳情以及在 YARN 中的相關(guān)狀態(tài)。

Hive Falcon 用于監(jiān)控 Hadoop 集群中被提交的任務(wù),以及其運(yùn)行的狀態(tài)詳情。其中 Yarn 中任務(wù)詳情包含任務(wù) ID,提交者,任務(wù)類型,完成狀態(tài)等信息。另外,還可以編寫(xiě) Hive SQL,并運(yùn) SQL,查看 SQL 運(yùn)行詳情。也可以查看 Hive 倉(cāng)庫(kù)中所存在的表及其表結(jié)構(gòu)等信息。

==不能將HIVE的查詢和yarn任務(wù)關(guān)聯(lián)在一起,不滿足需求。==

2.2 zepplin

待確認(rèn)

2.3 ambari

待確認(rèn)

2.4 hue

采用thrift方式實(shí)現(xiàn)。具體可以下載hue源代碼,apps/beeswax, 使用python實(shí)現(xiàn)。

此實(shí)現(xiàn)方式只能管理通過(guò)hue界面執(zhí)行的查詢,其他客戶端的查詢無(wú)法管理。 查詢和mapreduce的關(guān)聯(lián)關(guān)系是通過(guò)分析日志實(shí)現(xiàn)的,thrift沒(méi)有對(duì)應(yīng)的接口。 https://groups.google.com/a/cloudera.org/forum/#!topic/hue-user/wSDcTnZJqTg

日志

2017-04-26 13:54:24,068 INFO  ql.Driver (Driver.java:compile(411)) - Compiling command(queryId=hadoop_20170426135454_41352e71-5685-48e5-9e4d-c25819669666): select count(*) from t_function
2017-04-26 13:54:26,891 INFO  HiveMetaStore.audit (HiveMetaStore.java:logAuditEvent(388)) - ugi=hadoop  ip=unknown-ip-addr      cmd=get_table : db=default tbl=t_function       
2017-04-26 13:54:37,444 INFO  ql.Driver (Driver.java:compile(463)) - Semantic Analysis Completed
2017-04-26 13:54:37,677 INFO  ql.Driver (Driver.java:getSchema(245)) - Returning Hive schema: Schema(fieldSchemas:[FieldSchema(name:_c0, type:bigint, comment:null)], properties:null)
2017-04-26 13:54:38,331 INFO  ql.Driver (Driver.java:compile(541)) - Completed compiling command(queryId=hadoop_20170426135454_41352e71-5685-48e5-9e4d-c25819669666); Time taken: 14.712 second
s
2017-04-26 13:54:38,332 INFO  ql.Driver (Driver.java:execute(1448)) - Executing command(queryId=hadoop_20170426135454_41352e71-5685-48e5-9e4d-c25819669666): select count(*) from t_function
2017-04-26 13:54:38,334 INFO  ql.Driver (SessionState.java:printInfo(927)) - Query ID = hadoop_20170426135454_41352e71-5685-48e5-9e4d-c25819669666
2017-04-26 13:54:38,335 INFO  ql.Driver (SessionState.java:printInfo(927)) - Total jobs = 1
2017-04-26 13:54:38,516 INFO  ql.Driver (SessionState.java:printInfo(927)) - Launching Job 1 out of 1

2017-04-26 13:55:24,615 INFO  exec.Task (SessionState.java:printInfo(927)) - Starting Job = job_1493083994846_0010, Tracking URL = http://T-163:23188/proxy/application_1493083994846_0010/
2017-04-26 13:55:24,860 INFO  exec.Task (SessionState.java:printInfo(927)) - Kill Command = /opt/beh/core/hadoop/bin/hadoop job  -kill job_1493083994846_0010

三 其他方案

未發(fā)現(xiàn)完全實(shí)現(xiàn)該功能的開(kāi)源方案,接下來(lái)需要看看有沒(méi)有其他人干過(guò)類似的事,并發(fā)了相關(guān)文章。

3.1 Hive SQL運(yùn)行狀態(tài)監(jiān)控

目前數(shù)據(jù)平臺(tái)使用Hadoop構(gòu)建,為了方便數(shù)據(jù)分析師的工作,使用Hive對(duì)Hadoop MapReduce任務(wù)進(jìn)行封裝,我們面對(duì)的不再是一個(gè)個(gè)的MR任務(wù),而是一條條的SQL語(yǔ)句。數(shù)據(jù)平臺(tái)內(nèi)部通過(guò)類似JDBC的接口與HiveServer進(jìn)行交互,僅僅能夠感知到一條SQL的開(kāi)始與結(jié)束,而中間的這個(gè)過(guò)程通常是漫長(zhǎng)的(兩個(gè)因素:數(shù)據(jù)量、SQL復(fù)雜度),某些場(chǎng)景下用戶需要了解這條SQL語(yǔ)句的執(zhí)行進(jìn)度,從而為我們引入以下幾個(gè)問(wèn)題:

(1)通過(guò)JDBC接口執(zhí)行一條SQL語(yǔ)句時(shí),這條SQL語(yǔ)句被轉(zhuǎn)換成幾個(gè)MR任務(wù),每個(gè)MR任務(wù)的JobId是多少,如何維護(hù)這條SQL語(yǔ)句與MR任務(wù)的對(duì)應(yīng)關(guān)系?

(2)如何獲取MR任務(wù)的運(yùn)行狀態(tài),通過(guò)JobClient?

(3)通過(guò)HiveServer是否可以獲取到上述信息?

http://www.cnblogs.com/yurunmiao/p/4224137.html

四 匯總分析

通過(guò)之前的調(diào)研發(fā)現(xiàn),不管是開(kāi)源項(xiàng)目還是其他網(wǎng)絡(luò)資料,大多數(shù)需求只實(shí)現(xiàn)了特定情況下的hive查詢與yarn任務(wù)之間的對(duì)應(yīng), 多數(shù)還是在log上做文章,通過(guò)分析hive產(chǎn)生的日志來(lái)獲得查詢和yarn任務(wù)的關(guān)系。

種種跡象表明,情況不太樂(lè)觀,遇到硬茬了;想做一種兼容所有執(zhí)行方式的查詢管理工具,有比較大的難度,需要深入到源代碼去了解。

所有查詢方式

graph LR
Hue-->Thrift
Thrift-->Driver
CLI-->Driver
HWI-->Driver
Beeline-->Driver
Beeline-->Thrift
  • HWI方式官方將在2.2版本后去掉,且使用率不高,暫不支持。

  • Thrift方式支持多客戶端的并發(fā)和認(rèn)證,官方建議采用這種方式,故Beeline只支持Thrift使用方式。

  • CLI雖然不通過(guò)Thrift,但因?yàn)楝F(xiàn)在的項(xiàng)目用的比較多,考慮支持。

    通過(guò)以上分析,我們要支持的訪問(wèn)方式如下。

支持查詢方式

graph LR
Hue-->Thrift
Thrift-->Driver
CLI-->Driver
Beeline-->Thrift

五 源碼分析

通過(guò)上述分析,我們得出我們的研究方向,并確定了研究方案。 主要分兩部分,CLI模式任務(wù)管理和Thrift模式任務(wù)管理。

6.1 CLI模式任務(wù)管理

我們知道,cli模式下,我們一次只能執(zhí)行一條查詢,查詢執(zhí)行過(guò)程中,我們可以通過(guò)ctrl+c來(lái)終止查詢。 ctrl+c是給進(jìn)程發(fā)送sig_int中斷信號(hào)。

通過(guò)閱讀源碼我們發(fā)現(xiàn),中斷信號(hào)的處理在processLine函數(shù)中觸發(fā),該函數(shù)為處理單條命令。 http://blog.csdn.net/lpxuan151009/article/details/7956518 注: 源碼為hive1.1分支,其中hive-cli工程即為CLI的對(duì)應(yīng)工程。 入口類為org.apache.hadoop.hive.cli.CliDriver。

 if (allowInterrupting) {
      // Remember all threads that were running at the time we started line processing.
      // Hook up the custom Ctrl+C handler while processing this line
      interruptSignal = new Signal("INT");
      oldSignal = Signal.handle(interruptSignal, new SignalHandler() {
        private final Thread cliThread = Thread.currentThread();
        private boolean interruptRequested;

        @Override
        public void handle(Signal signal) {
          boolean initialRequest = !interruptRequested;
          interruptRequested = true;

          // Kill the VM on second ctrl+c
          if (!initialRequest) {
            console.printInfo("Exiting the JVM");
            System.exit(127);
          }

          // Interrupt the CLI thread to stop the current statement and return
          // to prompt
          console.printInfo("Interrupting... Be patient, this might take some time.");
          console.printInfo("Press Ctrl+C again to kill JVM");

          // First, kill any running MR jobs
          HadoopJobExecHelper.killRunningJobs();
          TezJobExecHelper.killRunningJobs();
          HiveInterruptUtils.interrupt();
        }
      });
    }

至此,CLI查詢的終止操作我們已經(jīng)通過(guò)進(jìn)程和源代碼兩種方式獲取到, 此種任務(wù)管理的任務(wù)解決方案見(jiàn)六。

執(zhí)行流程

graph LR
processCmd-->processLocalCmd
processLine-->processCmd
executeDriver-->processLine
run-->executeDriver
main-->run

processLocalCmd

            Driver qp = (Driver) proc;
            PrintStream out = ss.out;
            long start = System.currentTimeMillis();
            if (ss.getIsVerbose()) {
              out.println(cmd);
            }

            qp.setTryCount(tryCount);
            ret = qp.run(cmd).getResponseCode();
            if (ret != 0) {
              qp.close();
              return ret;
            }

查詢實(shí)際執(zhí)行的地方,可以在此處將執(zhí)行相關(guān)信息輸出,輸出方式可選擇log方式或者數(shù)據(jù)庫(kù),也可選擇rpc(rpc方式)

6.2 Thrift模式任務(wù)管理

相比較而言,CLI的任務(wù)管理相對(duì)簡(jiǎn)單,因?yàn)槊總€(gè)CLI只能執(zhí)行一個(gè)查詢; 而Thrift模式則支持并發(fā),這里的Thrift模式我們指的是hiveserver2的實(shí)現(xiàn)方式。 通過(guò)Thrift模式,Hue,Beeline,Ambari等等客戶端均可以連接到hive執(zhí)行查詢?nèi)蝿?wù), 需要把這些查詢?nèi)蝿?wù)都統(tǒng)一管理起來(lái)。

Thrift連接

graph LR
Hue-->hiveserver2
Beeline-->hiveserver2
Ambari-->hiveserver2
other-->hiveserver2

我們發(fā)現(xiàn),官方提供的thrift包主要實(shí)現(xiàn)的是一個(gè)連接所對(duì)應(yīng)的各種操作, 但并不包括連接間的信息;即連接間的信息并未提供外部接口。

下面為一段Thrift示例代碼,主要功能為建立一個(gè)連接后查詢hive的數(shù)據(jù)數(shù)據(jù)。

thrift示例代碼

        TSocket tSocket = new TSocket("T-162", 10000);
        tSocket.setTimeout(20000);
        TTransport transport = tSocket;

        TBinaryProtocol protocol = new TBinaryProtocol(transport);
        TCLIService.Client client = new TCLIService.Client(protocol);

        transport.open();
        TOpenSessionReq openReq = new TOpenSessionReq();
        TOpenSessionResp openResp = client.OpenSession(openReq);
        TSessionHandle sessHandle = openResp.getSessionHandle();

        TExecuteStatementReq execReq = new TExecuteStatementReq(sessHandle, "show databases");
        TExecuteStatementResp execResp = client.ExecuteStatement(execReq);
        TOperationHandle stmtHandle = execResp.getOperationHandle();

        TFetchResultsReq fetchReq = new TFetchResultsReq(stmtHandle, TFetchOrientation.FETCH_FIRST, 100);
        TFetchResultsResp resultsResp = client.FetchResults(fetchReq);
        List<TColumn> res=resultsResp.getResults().getColumns();
        for(TColumn tCol: res){
            Iterator<String> it = tCol.getStringVal().getValuesIterator();
            while (it.hasNext()){
                System.out.println(it.next());
            }
        }

        TCloseOperationReq closeReq = new TCloseOperationReq();
        closeReq.setOperationHandle(stmtHandle);
        client.CloseOperation(closeReq);
        TCloseSessionReq closeConnectionReq = new TCloseSessionReq(sessHandle);
        client.CloseSession(closeConnectionReq);

        transport.close();

通過(guò)查看源代碼我們發(fā)現(xiàn), 注: 源碼為hive1.1分支,其中hive-service工程即為hiveserver2的對(duì)應(yīng)工程。 Thrift類主要在org.apache.hive.service.cli.thrift包下。

session&operation管理

graph LR
HiveServer2-->CLIService
CLIService-->SessionManager
SessionManager-->handleToSession
SessionManager-->OperationManager
OperationManager-->handleToOperation

SessionManager

  private final Map<SessionHandle, HiveSession> handleToSession =
      new ConcurrentHashMap<SessionHandle, HiveSession>();
  private final OperationManager operationManager = new OperationManager();

OperationManager

    private final Map<OperationHandle, Operation> handleToOperation =
      new HashMap<OperationHandle, Operation>();

CLIService.cancelOperation

  @Override
  public void cancelOperation(OperationHandle opHandle)
      throws HiveSQLException {
    sessionManager.getOperationManager().getOperation(opHandle)
    .getParentSession().cancelOperation(opHandle);
    LOG.debug(opHandle + ": cancelOperation()");
  }

通過(guò)上述接口可知,只需要找到對(duì)應(yīng)操作的OperationHandle, 然后調(diào)用CLIService.cancelOperation即可。

operation&handler

graph LR
SQLOperation-->ExecuteStatementOperation
ExecuteStatementOperation-->Operation
OperationHandle-->Handle
public abstract class Handle {

  private final HandleIdentifier handleId;

  public Handle() {
    handleId = new HandleIdentifier();
  }

  public Handle(HandleIdentifier handleId) {
    this.handleId = handleId;
  }

  public Handle(THandleIdentifier tHandleIdentifier) {
    this.handleId = new HandleIdentifier(tHandleIdentifier);
  }

  public HandleIdentifier getHandleIdentifier() {
    return handleId;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((handleId == null) ? 0 : handleId.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (!(obj instanceof Handle)) {
      return false;
    }
    Handle other = (Handle) obj;
    if (handleId == null) {
      if (other.handleId != null) {
        return false;
      }
    } else if (!handleId.equals(other.handleId)) {
      return false;
    }
    return true;
  }

  @Override
  public abstract String toString();

}

可以通過(guò)handle id 進(jìn)行查找。 需要通過(guò)thrift接口放出根據(jù)handle id停止operation的接口。

// CancelOperation()
//
// Cancels processing on the specified operation handle and
// frees any resources which were allocated.
struct TCancelOperationReq {
  // Operation to cancel
  1: required TOperationHandle op_handle
}

thrift cancle接口已有; 現(xiàn)在需要thrift的獲取所有operation的接口;用于展示 現(xiàn)在需要thrift的獲取所有session的接口;用于展示

六 最終解決方案

6.1 CLI方式

cli程序沒(méi)有通信模塊,如果增加通信模塊修改較大,選擇定位進(jìn)程并對(duì)進(jìn)程發(fā)送中斷信號(hào)的方式取消查詢。

通過(guò)修改配置,將查詢log根據(jù)進(jìn)程號(hào)進(jìn)行細(xì)分,這樣就可以獲得查詢和進(jìn)程號(hào)的關(guān)系。

當(dāng)想要?dú)⑺酪粋€(gè)進(jìn)程是,通過(guò)ssh給對(duì)應(yīng)主機(jī)的指定進(jìn)程發(fā)送中斷信息即可。不能通過(guò)發(fā)送中斷信號(hào)來(lái)執(zhí)行,因?yàn)閳?zhí)行查詢的用戶可能有很多,==只有root才能保證中斷發(fā)送成功==, 但是使用root權(quán)限會(huì)有安全問(wèn)題,所有此處只能采用rpc方式進(jìn)行。

具體rpc方案目前可選的為hadoop rpc形式或者thrift方式,輪詢心跳方式或者cs合集模式。

暫定輪詢心跳方式,IPC定時(shí)查詢命令,心跳間隔1分鐘。

工作量: 4-8工作日

因?yàn)閏li方案的問(wèn)題,所以最佳方案可能還是修改driver層。

日志格式

hive-hadoop-hive-T-162.log.2621@T-162
hive-hadoop-hive-T-162.log.28632@T-162
hive-hadoop-hive-T-162.log.362@T-162
hive-hadoop-hive-T-162.log.5762@T-162

6.2 THRIFT方式

增加thrift的獲取所有operation的接口,展示所有查詢;調(diào)用取消查詢接口殺死查詢。

工作量:4-8工作日

6.3 DRIVER one for all

因?yàn)椴还躢li還是thrift方式,最終都要經(jīng)過(guò)driver層,所以在driver層修改,可以一站式解決所有問(wèn)題。 但和上面兩種不同的是,上面兩種都只是在原有代碼上加了一層殼,基本沒(méi)有動(dòng)核心代碼; 而driver層,則需要改動(dòng)一定程度邏輯的代碼,難度有所增加。

看完上述內(nèi)容,你們掌握HIVE作業(yè)管理分析及解決方案是什么的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

當(dāng)前名稱:HIVE作業(yè)管理分析及解決方案是什么
本文地址:http://bm7419.com/article16/jjsjgg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航電子商務(wù)、網(wǎng)站設(shè)計(jì)企業(yè)建站、用戶體驗(yàn)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名