【華為云專家原創(chuàng)】微服務(wù)架構(gòu)中使用 ELK 進(jìn)行日志采集以及統(tǒng)一處理

      網(wǎng)友投稿 1338 2025-04-03

      微服務(wù)各個(gè)組件的相關(guān)實(shí)踐會涉及到工具,本文將會介紹微服務(wù)日常開發(fā)的一些利器,這些工具幫助我們構(gòu)建更加健壯的微服務(wù)系統(tǒng),并幫助排查解決微服務(wù)系統(tǒng)中的問題與性能瓶頸等。

      我們將重點(diǎn)介紹微服務(wù)架構(gòu)中的日志收集方案 ELK(ELK 是 elasticsearch、Logstash、Kibana 的簡稱),準(zhǔn)確的說是 ELKB,即 ELK + Filebeat,其中 Filebeat 是用于轉(zhuǎn)發(fā)和集中日志數(shù)據(jù)的輕量級傳送工具。

      一、為什么需要分布式日志系統(tǒng)

      在以前的項(xiàng)目中,如果想要在生產(chǎn)環(huán)境需要通過日志定位業(yè)務(wù)服務(wù)的 bug 或者性能問題,則需要運(yùn)維人員使用命令挨個(gè)服務(wù)實(shí)例去查詢?nèi)罩疚募瑢?dǎo)致的結(jié)果是排查問題的效率非常低。

      微服務(wù)架構(gòu)下,服務(wù)多實(shí)例部署在不同的物理機(jī)上,各個(gè)微服務(wù)的日志被分散儲存不同的物理機(jī)。集群足夠大的話,使用上述傳統(tǒng)的方式查閱日志變得非常不合適。因此需要集中化管理分布式系統(tǒng)中的日志,其中有開源的組件如 syslog,用于將所有服務(wù)器上的日志收集匯總。

      然而集中化日志文件之后,我們面臨的是對這些日志文件進(jìn)行統(tǒng)計(jì)和檢索,哪些服務(wù)有報(bào)警和異常,這些需要有詳細(xì)的統(tǒng)計(jì)。所以在之前出現(xiàn)線上故障時(shí),經(jīng)常會看到開發(fā)和運(yùn)維人員下載了服務(wù)的日志,基于 Linux 下的一些命令,如 grep、awk 和 wc 等,進(jìn)行檢索和統(tǒng)計(jì)。這樣的方式效率低,工作量大,且對于要求更高的查詢、排序和統(tǒng)計(jì)等要求和龐大的機(jī)器數(shù)量依然使用這樣的方法難免有點(diǎn)力不從心。

      二、ELKB 分布式日志系統(tǒng)

      ELKB 是一個(gè)完整的分布式日志收集系統(tǒng),很好地解決了上述提到的日志收集難,檢索和分析難的問題。ELKB 分別是指 elasticsearch、Logstash、Kibana 和 Filebeat。elastic 提供的一整套組件可以看作為 MVC 模型,logstash 對應(yīng)邏輯控制 controller 層,Elasticsearch 是一個(gè)數(shù)據(jù)模型 model 層,而 Kibana 則是視圖 view 層。logstash 和 Elasticsearch 基于 Java 編寫實(shí)現(xiàn),Kibana 則使用的是 node.js 框架。

      下面依次介紹這幾個(gè)組件的功能,以及在日志采集系統(tǒng)中的作用。

      三、Elasticsearch 的安裝與使用

      Elasticsearch 是實(shí)時(shí)全文搜索和分析引擎,提供搜集、分析、存儲數(shù)據(jù)三大功能;是一套開放 REST 和 JAVA API 等結(jié)構(gòu)提供高效搜索功能,可擴(kuò)展的分布式系統(tǒng)。它構(gòu)建于 Apache Lucene 搜索引擎庫之上。

      Elasticsearch可以用于搜索各種文檔。它提供可擴(kuò)展的搜索,具有接近實(shí)時(shí)的搜索,并支持多租戶,能勝任上百個(gè)服務(wù)節(jié)點(diǎn)的擴(kuò)展,并支持 PB 級別的結(jié)構(gòu)化或者非結(jié)構(gòu)化數(shù)據(jù)。

      Elasticsearch是分布式的,這意味著索引可以被分成分片,每個(gè)分片可以有0個(gè)或多個(gè)副本。每個(gè)節(jié)點(diǎn)托管一個(gè)或多個(gè)分片,并充當(dāng)協(xié)調(diào)器將操作委托給正確的分片。再平衡和路由是自動(dòng)完成的。相關(guān)數(shù)據(jù)通常存儲在同一個(gè)索引中,該索引由一個(gè)或多個(gè)主分片和零個(gè)或多個(gè)復(fù)制分片組成。一旦創(chuàng)建了索引,就不能更改主分片的數(shù)量。

      Elasticsearch 是一個(gè)實(shí)時(shí)的分布式搜索分析引擎,它被用作全文檢索、結(jié)構(gòu)化搜索、分析以及這三個(gè)功能的組合,它是面向文檔 的,意味著它存儲整個(gè)對象或 文檔。Elasticsearch 不僅存儲文檔,而且 索引每個(gè)文檔的內(nèi)容使之可以被檢索。在 Elasticsearch 中,你 對文檔進(jìn)行索引、檢索、排序和過濾--而不是對行列數(shù)據(jù)。

      為了方便,我們直接使用使用 docker 安裝 Elasticsearch:

      $?docker?run???-d?--name?elasticsearch??docker.elastic.co/elasticsearch/elasticsearch:5.4.0

      需要注意的是,Elasticsearch 啟動(dòng)之后需要進(jìn)行簡單的設(shè)置,xpack.security.enabled 默認(rèn)是開啟的,為了方便,取消登錄認(rèn)證。我們登入到容器內(nèi)部,執(zhí)行如下的命令:

      #?進(jìn)入啟動(dòng)好的容器

      $?docker?exec?-it?elasticsearch?bash

      #?編輯配置文件

      $?vim?config/elasticsearch.yml

      cluster.name:?"docker-cluster"

      network.host:?0.0.0.0

      http.cors.enabled:?true

      http.cors.allow-origin:?"*"

      xpack.security.enabled:?false

      #?minimum_master_nodes?need?to?be?explicitly?set?when?bound?on?a?public?IP

      #?set?to?1?to?allow?single?node?clusters

      #?Details:?https://github.com/elastic/elasticsearch/pull/17288

      discovery.zen.minimum_master_nodes:?1

      修改好配置文件之后,退出容器,重啟容器即可。我們?yōu)榱撕竺媸褂脮r(shí)能夠保留配置,需要從該容器創(chuàng)建一個(gè)新的鏡像。首先獲取到該容器對應(yīng)的 ContainerId。然后基于該容器提交成一個(gè)新的鏡像。

      $?docker?commit?-a?"add?config"?-m?"dev"?a404c6c174a2??es:latest

      sha256:5cb8c995ca819765323e76cccea8f55b423a6fa2eecd9c1048b2787818c1a994

      這樣我們得到了一個(gè)新的鏡像 es:latest。我們運(yùn)行新的鏡像:

      docker?run?-d?--name?es?-p?9200:9200?-p?9300:9300???-e?"discovery.type=single-node"?es:latest

      通過訪問 Elasticsearch 提供的內(nèi)置端點(diǎn),我們檢查是否安裝成功。

      [root@VM_1_14_centos?~]#?curl?'http://localhost:9200/_nodes/http?pretty'

      {

      "_nodes"?:?{

      "total"?:?1,

      "successful"?:?1,

      "failed"?:?0

      },

      "cluster_name"?:?"docker-cluster",

      "nodes"?:?{

      "8iH5v9C-Q9GA3aSupm4caw"?:?{

      "name"?:?"8iH5v9C",

      "transport_address"?:?"10.0.1.14:9300",

      "host"?:?"10.0.1.14",

      "ip"?:?"10.0.1.14",

      "version"?:?"5.4.0",

      "build_hash"?:?"780f8c4",

      "roles"?:?[

      "master",

      "data",

      "ingest"

      ],

      "attributes"?:?{

      "ml.enabled"?:?"true"

      },

      "http"?:?{

      "bound_address"?:?[

      "[::]:9200"

      ],

      "publish_address"?:?"10.0.1.14:9200",

      "max_content_length_in_bytes"?:?104857600

      }

      }

      }

      }

      可以看到,我們成功安裝了 Elasticsearch,Elasticsearch 作為日志數(shù)據(jù)信息的存儲源,為我們提供了高效的搜索性能。

      我們另外還安裝了 Elasticsearch 的可視化工具:elasticsearch-head。安裝方法很簡答:

      $?docker?run?-p?9100:9100?mobz/elasticsearch-head:5

      elasticsearch-head 用于監(jiān)控 Elasticsearch 狀態(tài)的客戶端插件,包括數(shù)據(jù)可視化、執(zhí)行增刪改查操作等。

      安裝之后的界面如下所示:

      四、logstash 的安裝與使用

      logstash 是一個(gè)數(shù)據(jù)分析軟件,主要目的是分析 log 日志。其使用的原理如下所示:

      數(shù)據(jù)源首先將數(shù)據(jù)傳給 logstash,我們這里使用的是 Filebeat 傳輸日志數(shù)據(jù)。它主要的組成部分有 Input 數(shù)據(jù)輸入、Filter 數(shù)據(jù)源過濾和 Output 數(shù)據(jù)輸出三部分。

      logstash 將數(shù)據(jù)進(jìn)行過濾和格式化(轉(zhuǎn)成 JSON 格式),然后發(fā)送到 Elasticsearch 進(jìn)行存儲,并建搜索的索引,Kibana 提供前端的頁面視圖,可以在頁面進(jìn)行搜索,使得結(jié)果變成圖表可視化。

      下面我們開始安裝使用 logstash。首先下載解壓 logstash:

      #?下載?logstash

      $?wget?https://artifacts.elastic.co/downloads/logstash/logstash-5.4.3.tar.gz

      #?解壓?logstash

      $?tar?-zxvf?logstash-5.4.3.tar.gz

      下載速度可能比較慢,可以選擇國內(nèi)的鏡像源。解壓成功之后,我們需要配置 logstash,主要就是我們所提到的輸入、輸出和過濾。

      [root@VM_1_14_centos?elk]#?cat?logstash-5.4.3/client.conf

      input?{

      beats?{

      port?=>?5044

      codec?=>?"json"

      }

      }

      output?{

      elasticsearch?{

      hosts?=>?["127.0.0.1:9200"]

      index?=>?"logstash-app-error-%{+YYYY.MM.dd}"

      }

      stdout?{codec?=>?rubydebug}

      }

      輸入支持文件、syslog、beats,我們在配置時(shí)只能選擇其中一種。這里我們配置了 filebeats 方式。

      過濾則用于處理一些特定的行為來,處理匹配特定規(guī)則的事件流。常見的 filters 有 grok 解析無規(guī)則的文字并轉(zhuǎn)化為有結(jié)構(gòu)的格式、 geoip 添加地理信息、drop 丟棄部分事件 和 mutate 修改文檔等。如下是一個(gè) filter 使用的示例:

      filter?{

      #定義客戶端的?IP?是哪個(gè)字段

      geoip?{

      source?=>?"clientIp"

      }

      }

      輸出支持 Elasticsearch、file、graphite 和 statsd,默認(rèn)情況下將過濾扣的數(shù)據(jù)輸出到 Elasticsearch,當(dāng)我們不需要輸出到ES時(shí)需要特別聲明輸出的方式是哪一種,同時(shí)支持配置多個(gè)輸出源。

      一個(gè) event 可以在處理過程中經(jīng)過多重輸出,但是一旦所有的 outputs 都執(zhí)行結(jié)束,這個(gè) event 也就完成生命周期。

      我們在配置中,將日志信息輸出到 Elasticsearch。配置文件搞定之后,我們開始啟動(dòng) logstash:

      $?bin/logstash??-f?client.conf

      Sending?Logstash's?logs?to?/elk/logstash-5.4.3/logs?which?is?now?configured?via?log4j2.properties

      [2020-10-30T14:12:26,056][INFO?][logstash.outputs.elasticsearch]?Elasticsearch?pool?URLs?updated?{:changes=>{:removed=>[],?:added=>[http://127.0.0.1:9200/]}}

      [2020-10-30T14:12:26,062][INFO?][logstash.outputs.elasticsearch]?Running?health?check?to?see?if?an?Elasticsearch?connection?is?working?{:healthcheck_url=>http://127.0.0.1:9200/,?:path=>"/"}

      log4j:WARN?No?appenders?could?be?found?for?logger?(org.apache.http.client.protocol.RequestAuthCache).

      log4j:WARN?Please?initialize?the?log4j?system?properly.

      log4j:WARN?See?http://logging.apache.org/log4j/1.2/faq.html#noconfig?for?more?info.

      [2020-10-30T14:12:26,209][WARN?][logstash.outputs.elasticsearch]?Restored?connection?to?ES?instance?{:url=>#}[2020-10-30T14:12:26,225][INFO?][logstash.outputs.elasticsearch]?Using?mapping?template?from?{:path=>nil}

      [2020-10-30T14:12:26,288][INFO?][logstash.outputs.elasticsearch]?Attempting?to?install?template?{:manage_template=>{"template"=>"logstash-*",?"version"=>50001,?"settings"=>{"index.refresh_interval"=>"5s"},?"mappings"=>{"_default_"=>{"_all"=>{"enabled"=>true,?"norms"=>false},?"dynamic_templates"=>[{"message_field"=>{"path_match"=>"message",?"match_mapping_type"=>"string",?"mapping"=>{"type"=>"text",?"norms"=>false}}},?{"string_fields"=>{"match"=>"*",?"match_mapping_type"=>"string",?"mapping"=>{"type"=>"text",?"norms"=>false,?"fields"=>{"keyword"=>{"type"=>"keyword"}}}}}],?"properties"=>{"@timestamp"=>{"type"=>"date",?"include_in_all"=>false},?"@version"=>{"type"=>"keyword",?"include_in_all"=>false},?"geoip"=>{"dynamic"=>true,?"properties"=>{"ip"=>{"type"=>"ip"},?"location"=>{"type"=>"geo_point"},?"latitude"=>{"type"=>"half_float"},?"longitude"=>{"type"=>"half_float"}}}}}}}}

      [2020-10-30T14:12:26,304][INFO?][logstash.outputs.elasticsearch]?New?Elasticsearch?output?{:class=>"LogStash::Outputs::ElasticSearch",?:hosts=>[#]}

      [2020-10-30T14:12:26,312][INFO?][logstash.pipeline????????]?Starting?pipeline?{"id"=>"main",?"pipeline.workers"=>4,?"pipeline.batch.size"=>125,?"pipeline.batch.delay"=>5,?"pipeline.max_inflight"=>500}

      [2020-10-30T14:12:27,226][INFO?][logstash.inputs.beats????]?Beats?inputs:?Starting?input?listener?{:address=>"0.0.0.0:5044"}

      [2020-10-30T14:12:27,319][INFO?][logstash.pipeline????????]?Pipeline?main?started

      [2020-10-30T14:12:27,422][INFO?][logstash.agent???????????]?Successfully?started?Logstash?API?endpoint?{:port=>9600}

      根據(jù)控制臺輸出的日志,我們知道 logstash 已經(jīng)正常啟動(dòng)。

      五、Kibana 的安裝與使用

      Kibana 是一個(gè)基于 Web 的圖形界面,用于搜索、分析和可視化存儲在 ?Elasticsearch 指標(biāo)中的日志數(shù)據(jù)。Kibana 調(diào)用 Elasticsearch 的接口返回的數(shù)據(jù)進(jìn)行可視化。它利用 Elasticsearch 的 REST 接口來檢索數(shù)據(jù),不僅允許用戶創(chuàng)建他們自己的數(shù)據(jù)的定制儀表板視圖,還允許他們以特殊的方式查詢和過濾數(shù)據(jù)。

      Kibana 的安裝比較簡單,我們基于 docker 安裝即可:

      docker?run?--name?kibana?-e?ELASTICSEARCH_URL=http://127.0.0.1:9200?-p?5601:5601?-d?kibana:5.6.9

      我們在啟動(dòng)命令中指定了 ELASTICSEARCH 的環(huán)境變量,就是本地的 127.0.0.1:9200。

      六、Filebeat 的安裝與使用

      Filebeat 用于轉(zhuǎn)發(fā)和集中日志數(shù)據(jù)的輕量級傳送工具。Filebeat 監(jiān)視指定的日志文件或位置,收集日志事件,并將它們轉(zhuǎn)發(fā)到 Logstash、Kafka、Redis 等,或直接轉(zhuǎn)發(fā)到 Elasticsearch 進(jìn)行索引。

      下面我們開始安裝配置 Filebeat:

      #?下載?filebeat

      $?wget?https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-5.4.3-linux-x86_64.tar.gz

      $?tar?-zxvf?filebeat-5.4.3-linux-x86_64.tar.gz

      $?mv?filebeat-5.4.3-linux-x86_64?filebeat

      #?進(jìn)入目錄

      $?cd?filebeat

      #?配置?filebeat

      $?vi?filebeat/client.yml

      filebeat.prospectors:

      -?input_type:?log

      paths:

      -?/var/log/*.log

      output.logstash:

      hosts:?["localhost:5044"]

      在 filebeat 的配置中,input_type 支持從Log、Syslog、Stdin、Redis、UDP、Docker、TCP、NetFlow 輸入。上述配置了從 log 中讀取日志信息。并且配置了只輸入 /var/log/ 目錄下的日志文件。output 將 Filebeat 配置為使用 logstash,并且使用 logstash 對 Filebeat 收集的數(shù)據(jù)執(zhí)行額外的處理。

      配置好之后,我們啟動(dòng) Filebeat:

      $?./filebeat??-e??-c?client.yml

      2020/10/30?06:46:31.764391?beat.go:285:?INFO?Home?path:?[/elk/filebeat]?Config?path:?[/elk/filebeat]?Data?path:?[/elk/filebeat/data]?Logs?path:?[/elk/filebeat/logs]

      2020/10/30?06:46:31.764426?beat.go:186:?INFO?Setup?Beat:?filebeat;?Version:?5.4.3

      2020/10/30?06:46:31.764522?logstash.go:90:?INFO?Max?Retries?set?to:?3

      2020/10/30?06:46:31.764588?outputs.go:108:?INFO?Activated?logstash?as?output?plugin.

      2020/10/30?06:46:31.764586?metrics.go:23:?INFO?Metrics?logging?every?30s

      2020/10/30?06:46:31.764664?publish.go:295:?INFO?Publisher?name:?VM_1_14_centos

      2020/10/30?06:46:31.765299?async.go:63:?INFO?Flush?Interval?set?to:?1s

      2020/10/30?06:46:31.765315?async.go:64:?INFO?Max?Bulk?Size?set?to:?2048

      2020/10/30?06:46:31.765563?beat.go:221:?INFO?filebeat?start?running.

      2020/10/30?06:46:31.765592?registrar.go:85:?INFO?Registry?file?set?to:?/elk/filebeat/data/registry

      2020/10/30?06:46:31.765630?registrar.go:106:?INFO?Loading?registrar?data?from?/elk/filebeat/data/registry

      2020/10/30?06:46:31.766100?registrar.go:123:?INFO?States?Loaded?from?registrar:?6

      2020/10/30?06:46:31.766136?crawler.go:38:?INFO?Loading?Prospectors:?1

      2020/10/30?06:46:31.766209?registrar.go:236:?INFO?Starting?Registrar

      2020/10/30?06:46:31.766256?sync.go:41:?INFO?Start?sending?events?to?output

      2020/10/30?06:46:31.766291?prospector_log.go:65:?INFO?Prospector?with?previous?states?loaded:?0

      2020/10/30?06:46:31.766390?prospector.go:124:?INFO?Starting?prospector?of?type:?log;?id:?2536729917787673381

      2020/10/30?06:46:31.766422?crawler.go:58:?INFO?Loading?and?starting?Prospectors?completed.?Enabled?prospectors:?1

      2020/10/30?06:46:31.766430?spooler.go:63:?INFO?Starting?spooler:?spool_size:?2048;?idle_timeout:?5s

      2020/10/30?06:47:01.764888?metrics.go:34:?INFO?No?non-zero?metrics?in?the?last?30s

      2020/10/30?06:47:31.764929?metrics.go:34:?INFO?No?non-zero?metrics?in?the?last?30s

      2020/10/30?06:48:01.765134?metrics.go:34:?INFO?No?non-zero?metrics?in?the?last?30s

      啟動(dòng) Filebeat 時(shí),它將啟動(dòng)一個(gè)或多個(gè)輸入,這些輸入將在為日志數(shù)據(jù)指定的位置中查找。對于 Filebeat 所找到的每個(gè)日志,F(xiàn)ilebeat 都會啟動(dòng)收集器。每個(gè)收集器都讀取單個(gè)日志以獲取新內(nèi)容,并將新日志數(shù)據(jù)發(fā)送到 libbeat,libbeat 將聚集事件,并將聚集的數(shù)據(jù)發(fā)送到為 Filebeat 配置的輸出。

      七、ELKB 的使用實(shí)踐

      安裝好 ELKB 組件之后,我們開始整合這些組件。首先看下 ELKB 收集日志的流程。

      Filebeat 監(jiān)聽?wèi)?yīng)用的日志文件,隨后將數(shù)據(jù)發(fā)送給 logstash,logstash 則對數(shù)據(jù)進(jìn)行過濾和格式化,如 JSON 格式化;之后 logstash 將處理好的日志數(shù)據(jù)發(fā)送給 Elasticsearch,Elasticsearch 存儲并建立搜索的索引;Kibana 提供可視化的視圖頁面。

      我們運(yùn)行所有的組件之后,首先看下 elasticsearch-head 中的索引變化:

      可以看到多了一個(gè) filebeat-2020.10.12 的索引,說明 ELKB 分布式日志收集框架搭建成功。訪問 http://localhost:9100,我們來具體看下索引的數(shù)據(jù):

      從上面兩幅截圖可以看到,/var/log/ 目錄下的 mysqld.log 文件中產(chǎn)生了新的日志數(shù)據(jù),這些數(shù)據(jù)非常多,我們在生產(chǎn)環(huán)境需要根據(jù)實(shí)際的業(yè)務(wù)進(jìn)行過濾,并處理相應(yīng)的日志格式。

      elasticsearch-head 是一個(gè)簡單的 Elasticsearch 客戶端,更加完整的統(tǒng)計(jì)和搜索需求,需要借助于 Kibana,Kibana 提升了 Elasticsearch 分析能力,能夠更加智能地分析數(shù)據(jù),執(zhí)行數(shù)學(xué)轉(zhuǎn)換并且根據(jù)要求對數(shù)據(jù)切割分塊。

      訪問 http://localhost:5601,得到了上圖中的日志信息。Filebeat 監(jiān)聽到了 mysql 日志,并在 Kibana 上展示。Kibana 能夠更好地處理海量數(shù)據(jù),并據(jù)此創(chuàng)建柱形圖、折線圖、散點(diǎn)圖、直方圖、餅圖和地圖,這里就不一一展示了。

      八、小結(jié)

      本文主要介紹了分布式日志采集系統(tǒng) ELKB。日志主要用來記錄離散的事件,包含程序執(zhí)行到某一點(diǎn)或某一階段的詳細(xì)信息。ELKB 很好地解決了微服務(wù)架構(gòu)下,服務(wù)實(shí)例眾多且分散,日志難以收集和分析的問題。限于篇幅,本課時(shí)只介紹了 ELKB 的安裝使用,Go 微服務(wù)中一般使用日志框架如 logrus、zap 等,按照一定的格式將日志輸出到指定的位置,讀者可以自行構(gòu)建一個(gè)微服務(wù)進(jìn)行實(shí)踐。

      微服務(wù)各個(gè)組件的相關(guān)實(shí)踐會涉及到工具,本文將會介紹微服務(wù)日常開發(fā)的一些利器,這些工具幫助我們構(gòu)建更加健壯的微服務(wù)系統(tǒng),并幫助排查解決微服務(wù)系統(tǒng)中的問題與性能瓶頸等。

      我們將重點(diǎn)介紹微服務(wù)架構(gòu)中的日志收集方案 ELK(ELK 是 Elasticsearch、Logstash、Kibana 的簡稱),準(zhǔn)確的說是 ELKB,即 ELK + Filebeat,其中 Filebeat 是用于轉(zhuǎn)發(fā)和集中日志數(shù)據(jù)的輕量級傳送工具。

      一、為什么需要分布式日志系統(tǒng)

      在以前的項(xiàng)目中,如果想要在生產(chǎn)環(huán)境需要通過日志定位業(yè)務(wù)服務(wù)的 bug 或者性能問題,則需要運(yùn)維人員使用命令挨個(gè)服務(wù)實(shí)例去查詢?nèi)罩疚募瑢?dǎo)致的結(jié)果是排查問題的效率非常低。

      微服務(wù)架構(gòu)下,服務(wù)多實(shí)例部署在不同的物理機(jī)上,各個(gè)微服務(wù)的日志被分散儲存不同的物理機(jī)。集群足夠大的話,使用上述傳統(tǒng)的方式查閱日志變得非常不合適。因此需要集中化管理分布式系統(tǒng)中的日志,其中有開源的組件如 syslog,用于將所有服務(wù)器上的日志收集匯總。

      然而集中化日志文件之后,我們面臨的是對這些日志文件進(jìn)行統(tǒng)計(jì)和檢索,哪些服務(wù)有報(bào)警和異常,這些需要有詳細(xì)的統(tǒng)計(jì)。所以在之前出現(xiàn)線上故障時(shí),經(jīng)常會看到開發(fā)和運(yùn)維人員下載了服務(wù)的日志,基于 Linux 下的一些命令,如 grep、awk 和 wc 等,進(jìn)行檢索和統(tǒng)計(jì)。這樣的方式效率低,工作量大,且對于要求更高的查詢、排序和統(tǒng)計(jì)等要求和龐大的機(jī)器數(shù)量依然使用這樣的方法難免有點(diǎn)力不從心。

      二、ELKB 分布式日志系統(tǒng)

      ELKB 是一個(gè)完整的分布式日志收集系統(tǒng),很好地解決了上述提到的日志收集難,檢索和分析難的問題。ELKB 分別是指 Elasticsearch、Logstash、Kibana 和 Filebeat。elastic 提供的一整套組件可以看作為 MVC 模型,logstash 對應(yīng)邏輯控制 controller 層,Elasticsearch 是一個(gè)數(shù)據(jù)模型 model 層,而 Kibana 則是視圖 view 層。logstash 和 Elasticsearch 基于 Java 編寫實(shí)現(xiàn),Kibana 則使用的是 node.js 框架。

      下面依次介紹這幾個(gè)組件的功能,以及在日志采集系統(tǒng)中的作用。

      三、Elasticsearch 的安裝與使用

      Elasticsearch 是實(shí)時(shí)全文搜索和分析引擎,提供搜集、分析、存儲數(shù)據(jù)三大功能;是一套開放 REST 和 JAVA API 等結(jié)構(gòu)提供高效搜索功能,可擴(kuò)展的分布式系統(tǒng)。它構(gòu)建于 Apache Lucene 搜索引擎庫之上。

      Elasticsearch可以用于搜索各種文檔。它提供可擴(kuò)展的搜索,具有接近實(shí)時(shí)的搜索,并支持多租戶,能勝任上百個(gè)服務(wù)節(jié)點(diǎn)的擴(kuò)展,并支持 PB 級別的結(jié)構(gòu)化或者非結(jié)構(gòu)化數(shù)據(jù)。

      Elasticsearch是分布式的,這意味著索引可以被分成分片,每個(gè)分片可以有0個(gè)或多個(gè)副本。每個(gè)節(jié)點(diǎn)托管一個(gè)或多個(gè)分片,并充當(dāng)協(xié)調(diào)器將操作委托給正確的分片。再平衡和路由是自動(dòng)完成的。相關(guān)數(shù)據(jù)通常存儲在同一個(gè)索引中,該索引由一個(gè)或多個(gè)主分片和零個(gè)或多個(gè)復(fù)制分片組成。一旦創(chuàng)建了索引,就不能更改主分片的數(shù)量。

      Elasticsearch 是一個(gè)實(shí)時(shí)的分布式搜索分析引擎,它被用作全文檢索、結(jié)構(gòu)化搜索、分析以及這三個(gè)功能的組合,它是面向文檔 的,意味著它存儲整個(gè)對象或 文檔。Elasticsearch 不僅存儲文檔,而且 索引每個(gè)文檔的內(nèi)容使之可以被檢索。在 Elasticsearch 中,你 對文檔進(jìn)行索引、檢索、排序和過濾--而不是對行列數(shù)據(jù)。

      為了方便,我們直接使用使用 docker 安裝 Elasticsearch:

      $?docker?run???-d?--name?elasticsearch??docker.elastic.co/elasticsearch/elasticsearch:5.4.0

      需要注意的是,Elasticsearch 啟動(dòng)之后需要進(jìn)行簡單的設(shè)置,xpack.security.enabled 默認(rèn)是開啟的,為了方便,取消登錄認(rèn)證。我們登入到容器內(nèi)部,執(zhí)行如下的命令:

      #?進(jìn)入啟動(dòng)好的容器

      $?docker?exec?-it?elasticsearch?bash

      #?編輯配置文件

      $?vim?config/elasticsearch.yml

      cluster.name:?"docker-cluster"

      network.host:?0.0.0.0

      http.cors.enabled:?true

      http.cors.allow-origin:?"*"

      xpack.security.enabled:?false

      #?minimum_master_nodes?need?to?be?explicitly?set?when?bound?on?a?public?IP

      #?set?to?1?to?allow?single?node?clusters

      #?Details:?https://github.com/elastic/elasticsearch/pull/17288

      discovery.zen.minimum_master_nodes:?1

      修改好配置文件之后,退出容器,重啟容器即可。我們?yōu)榱撕竺媸褂脮r(shí)能夠保留配置,需要從該容器創(chuàng)建一個(gè)新的鏡像。首先獲取到該容器對應(yīng)的 ContainerId。然后基于該容器提交成一個(gè)新的鏡像。

      $?docker?commit?-a?"add?config"?-m?"dev"?a404c6c174a2??es:latest

      sha256:5cb8c995ca819765323e76cccea8f55b423a6fa2eecd9c1048b2787818c1a994

      這樣我們得到了一個(gè)新的鏡像 es:latest。我們運(yùn)行新的鏡像:

      docker?run?-d?--name?es?-p?9200:9200?-p?9300:9300???-e?"discovery.type=single-node"?es:latest

      通過訪問 Elasticsearch 提供的內(nèi)置端點(diǎn),我們檢查是否安裝成功。

      [root@VM_1_14_centos?~]#?curl?'http://localhost:9200/_nodes/http?pretty'

      {

      "_nodes"?:?{

      "total"?:?1,

      "successful"?:?1,

      "failed"?:?0

      },

      "cluster_name"?:?"docker-cluster",

      "nodes"?:?{

      "8iH5v9C-Q9GA3aSupm4caw"?:?{

      "name"?:?"8iH5v9C",

      "transport_address"?:?"10.0.1.14:9300",

      "host"?:?"10.0.1.14",

      "ip"?:?"10.0.1.14",

      "version"?:?"5.4.0",

      "build_hash"?:?"780f8c4",

      "roles"?:?[

      "master",

      "data",

      "ingest"

      ],

      "attributes"?:?{

      "ml.enabled"?:?"true"

      },

      "http"?:?{

      "bound_address"?:?[

      "[::]:9200"

      ],

      "publish_address"?:?"10.0.1.14:9200",

      "max_content_length_in_bytes"?:?104857600

      }

      }

      }

      }

      可以看到,我們成功安裝了 Elasticsearch,Elasticsearch 作為日志數(shù)據(jù)信息的存儲源,為我們提供了高效的搜索性能。

      我們另外還安裝了 Elasticsearch 的可視化工具:elasticsearch-head。安裝方法很簡答:

      $?docker?run?-p?9100:9100?mobz/elasticsearch-head:5

      elasticsearch-head 用于監(jiān)控 Elasticsearch 狀態(tài)的客戶端插件,包括數(shù)據(jù)可視化、執(zhí)行增刪改查操作等。

      安裝之后的界面如下所示:

      四、logstash 的安裝與使用

      logstash 是一個(gè)數(shù)據(jù)分析軟件,主要目的是分析 log 日志。其使用的原理如下所示:

      數(shù)據(jù)源首先將數(shù)據(jù)傳給 logstash,我們這里使用的是 Filebeat 傳輸日志數(shù)據(jù)。它主要的組成部分有 Input 數(shù)據(jù)輸入、Filter 數(shù)據(jù)源過濾和 Output 數(shù)據(jù)輸出三部分。

      logstash 將數(shù)據(jù)進(jìn)行過濾和格式化(轉(zhuǎn)成 JSON 格式),然后發(fā)送到 Elasticsearch 進(jìn)行存儲,并建搜索的索引,Kibana 提供前端的頁面視圖,可以在頁面進(jìn)行搜索,使得結(jié)果變成圖表可視化。

      下面我們開始安裝使用 logstash。首先下載解壓 logstash:

      #?下載?logstash

      $?wget?https://artifacts.elastic.co/downloads/logstash/logstash-5.4.3.tar.gz

      #?解壓?logstash

      $?tar?-zxvf?logstash-5.4.3.tar.gz

      下載速度可能比較慢,可以選擇國內(nèi)的鏡像源。解壓成功之后,我們需要配置 logstash,主要就是我們所提到的輸入、輸出和過濾。

      [root@VM_1_14_centos?elk]#?cat?logstash-5.4.3/client.conf

      input?{

      beats?{

      port?=>?5044

      codec?=>?"json"

      }

      }

      output?{

      elasticsearch?{

      hosts?=>?["127.0.0.1:9200"]

      index?=>?"logstash-app-error-%{+YYYY.MM.dd}"

      }

      stdout?{codec?=>?rubydebug}

      }

      輸入支持文件、syslog、beats,我們在配置時(shí)只能選擇其中一種。這里我們配置了 filebeats 方式。

      過濾則用于處理一些特定的行為來,處理匹配特定規(guī)則的事件流。常見的 filters 有 grok 解析無規(guī)則的文字并轉(zhuǎn)化為有結(jié)構(gòu)的格式、 geoip 添加地理信息、drop 丟棄部分事件 和 mutate 修改文檔等。如下是一個(gè) filter 使用的示例:

      filter?{

      #定義客戶端的?IP?是哪個(gè)字段

      geoip?{

      source?=>?"clientIp"

      }

      }

      輸出支持 Elasticsearch、file、graphite 和 statsd,默認(rèn)情況下將過濾扣的數(shù)據(jù)輸出到 Elasticsearch,當(dāng)我們不需要輸出到ES時(shí)需要特別聲明輸出的方式是哪一種,同時(shí)支持配置多個(gè)輸出源。

      一個(gè) event 可以在處理過程中經(jīng)過多重輸出,但是一旦所有的 outputs 都執(zhí)行結(jié)束,這個(gè) event 也就完成生命周期。

      我們在配置中,將日志信息輸出到 Elasticsearch。配置文件搞定之后,我們開始啟動(dòng) logstash:

      $?bin/logstash??-f?client.conf

      Sending?Logstash's?logs?to?/elk/logstash-5.4.3/logs?which?is?now?configured?via?log4j2.properties

      [2020-10-30T14:12:26,056][INFO?][logstash.outputs.elasticsearch]?Elasticsearch?pool?URLs?updated?{:changes=>{:removed=>[],?:added=>[http://127.0.0.1:9200/]}}

      [2020-10-30T14:12:26,062][INFO?][logstash.outputs.elasticsearch]?Running?health?check?to?see?if?an?Elasticsearch?connection?is?working?{:healthcheck_url=>http://127.0.0.1:9200/,?:path=>"/"}

      log4j:WARN?No?appenders?could?be?found?for?logger?(org.apache.http.client.protocol.RequestAuthCache).

      log4j:WARN?Please?initialize?the?log4j?system?properly.

      log4j:WARN?See?http://logging.apache.org/log4j/1.2/faq.html#noconfig?for?more?info.

      [2020-10-30T14:12:26,209][WARN?][logstash.outputs.elasticsearch]?Restored?connection?to?ES?instance?{:url=>#}[2020-10-30T14:12:26,225][INFO?][logstash.outputs.elasticsearch]?Using?mapping?template?from?{:path=>nil}

      [2020-10-30T14:12:26,288][INFO?][logstash.outputs.elasticsearch]?Attempting?to?install?template?{:manage_template=>{"template"=>"logstash-*",?"version"=>50001,?"settings"=>{"index.refresh_interval"=>"5s"},?"mappings"=>{"_default_"=>{"_all"=>{"enabled"=>true,?"norms"=>false},?"dynamic_templates"=>[{"message_field"=>{"path_match"=>"message",?"match_mapping_type"=>"string",?"mapping"=>{"type"=>"text",?"norms"=>false}}},?{"string_fields"=>{"match"=>"*",?"match_mapping_type"=>"string",?"mapping"=>{"type"=>"text",?"norms"=>false,?"fields"=>{"keyword"=>{"type"=>"keyword"}}}}}],?"properties"=>{"@timestamp"=>{"type"=>"date",?"include_in_all"=>false},?"@version"=>{"type"=>"keyword",?"include_in_all"=>false},?"geoip"=>{"dynamic"=>true,?"properties"=>{"ip"=>{"type"=>"ip"},?"location"=>{"type"=>"geo_point"},?"latitude"=>{"type"=>"half_float"},?"longitude"=>{"type"=>"half_float"}}}}}}}}

      [2020-10-30T14:12:26,304][INFO?][logstash.outputs.elasticsearch]?New?Elasticsearch?output?{:class=>"LogStash::Outputs::ElasticSearch",?:hosts=>[#]}

      [2020-10-30T14:12:26,312][INFO?][logstash.pipeline????????]?Starting?pipeline?{"id"=>"main",?"pipeline.workers"=>4,?"pipeline.batch.size"=>125,?"pipeline.batch.delay"=>5,?"pipeline.max_inflight"=>500}

      [2020-10-30T14:12:27,226][INFO?][logstash.inputs.beats????]?Beats?inputs:?Starting?input?listener?{:address=>"0.0.0.0:5044"}

      [2020-10-30T14:12:27,319][INFO?][logstash.pipeline????????]?Pipeline?main?started

      [2020-10-30T14:12:27,422][INFO?][logstash.agent???????????]?Successfully?started?Logstash?API?endpoint?{:port=>9600}

      根據(jù)控制臺輸出的日志,我們知道 logstash 已經(jīng)正常啟動(dòng)。

      五、Kibana 的安裝與使用

      Kibana 是一個(gè)基于 Web 的圖形界面,用于搜索、分析和可視化存儲在 ?Elasticsearch 指標(biāo)中的日志數(shù)據(jù)。Kibana 調(diào)用 Elasticsearch 的接口返回的數(shù)據(jù)進(jìn)行可視化。它利用 Elasticsearch 的 REST 接口來檢索數(shù)據(jù),不僅允許用戶創(chuàng)建他們自己的數(shù)據(jù)的定制儀表板視圖,還允許他們以特殊的方式查詢和過濾數(shù)據(jù)。

      Kibana 的安裝比較簡單,我們基于 docker 安裝即可:

      docker?run?--name?kibana?-e?ELASTICSEARCH_URL=http://127.0.0.1:9200?-p?5601:5601?-d?kibana:5.6.9

      我們在啟動(dòng)命令中指定了 ELASTICSEARCH 的環(huán)境變量,就是本地的 127.0.0.1:9200。

      六、Filebeat 的安裝與使用

      Filebeat 用于轉(zhuǎn)發(fā)和集中日志數(shù)據(jù)的輕量級傳送工具。Filebeat 監(jiān)視指定的日志文件或位置,收集日志事件,并將它們轉(zhuǎn)發(fā)到 Logstash、Kafka、Redis 等,或直接轉(zhuǎn)發(fā)到 Elasticsearch 進(jìn)行索引。

      下面我們開始安裝配置 Filebeat:

      #?下載?filebeat

      $?wget?https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-5.4.3-linux-x86_64.tar.gz

      $?tar?-zxvf?filebeat-5.4.3-linux-x86_64.tar.gz

      $?mv?filebeat-5.4.3-linux-x86_64?filebeat

      #?進(jìn)入目錄

      $?cd?filebeat

      #?配置?filebeat

      $?vi?filebeat/client.yml

      filebeat.prospectors:

      -?input_type:?log

      paths:

      -?/var/log/*.log

      output.logstash:

      hosts:?["localhost:5044"]

      在 filebeat 的配置中,input_type 支持從Log、Syslog、Stdin、Redis、UDP、Docker、TCP、NetFlow 輸入。上述配置了從 log 中讀取日志信息。并且配置了只輸入 /var/log/ 目錄下的日志文件。output 將 Filebeat 配置為使用 logstash,并且使用 logstash 對 Filebeat 收集的數(shù)據(jù)執(zhí)行額外的處理。

      配置好之后,我們啟動(dòng) Filebeat:

      $?./filebeat??-e??-c?client.yml

      2020/10/30?06:46:31.764391?beat.go:285:?INFO?Home?path:?[/elk/filebeat]?Config?path:?[/elk/filebeat]?Data?path:?[/elk/filebeat/data]?Logs?path:?[/elk/filebeat/logs]

      2020/10/30?06:46:31.764426?beat.go:186:?INFO?Setup?Beat:?filebeat;?Version:?5.4.3

      2020/10/30?06:46:31.764522?logstash.go:90:?INFO?Max?Retries?set?to:?3

      2020/10/30?06:46:31.764588?outputs.go:108:?INFO?Activated?logstash?as?output?plugin.

      2020/10/30?06:46:31.764586?metrics.go:23:?INFO?Metrics?logging?every?30s

      2020/10/30?06:46:31.764664?publish.go:295:?INFO?Publisher?name:?VM_1_14_centos

      2020/10/30?06:46:31.765299?async.go:63:?INFO?Flush?Interval?set?to:?1s

      2020/10/30?06:46:31.765315?async.go:64:?INFO?Max?Bulk?Size?set?to:?2048

      2020/10/30?06:46:31.765563?beat.go:221:?INFO?filebeat?start?running.

      2020/10/30?06:46:31.765592?registrar.go:85:?INFO?Registry?file?set?to:?/elk/filebeat/data/registry

      2020/10/30?06:46:31.765630?registrar.go:106:?INFO?Loading?registrar?data?from?/elk/filebeat/data/registry

      2020/10/30?06:46:31.766100?registrar.go:123:?INFO?States?Loaded?from?registrar:?6

      2020/10/30?06:46:31.766136?crawler.go:38:?INFO?Loading?Prospectors:?1

      2020/10/30?06:46:31.766209?registrar.go:236:?INFO?Starting?Registrar

      2020/10/30?06:46:31.766256?sync.go:41:?INFO?Start?sending?events?to?output

      2020/10/30?06:46:31.766291?prospector_log.go:65:?INFO?Prospector?with?previous?states?loaded:?0

      2020/10/30?06:46:31.766390?prospector.go:124:?INFO?Starting?prospector?of?type:?log;?id:?2536729917787673381

      【華為云專家原創(chuàng)】微服務(wù)架構(gòu)中使用 ELK 進(jìn)行日志采集以及統(tǒng)一處理

      2020/10/30?06:46:31.766422?crawler.go:58:?INFO?Loading?and?starting?Prospectors?completed.?Enabled?prospectors:?1

      2020/10/30?06:46:31.766430?spooler.go:63:?INFO?Starting?spooler:?spool_size:?2048;?idle_timeout:?5s

      2020/10/30?06:47:01.764888?metrics.go:34:?INFO?No?non-zero?metrics?in?the?last?30s

      2020/10/30?06:47:31.764929?metrics.go:34:?INFO?No?non-zero?metrics?in?the?last?30s

      2020/10/30?06:48:01.765134?metrics.go:34:?INFO?No?non-zero?metrics?in?the?last?30s

      啟動(dòng) Filebeat 時(shí),它將啟動(dòng)一個(gè)或多個(gè)輸入,這些輸入將在為日志數(shù)據(jù)指定的位置中查找。對于 Filebeat 所找到的每個(gè)日志,F(xiàn)ilebeat 都會啟動(dòng)收集器。每個(gè)收集器都讀取單個(gè)日志以獲取新內(nèi)容,并將新日志數(shù)據(jù)發(fā)送到 libbeat,libbeat 將聚集事件,并將聚集的數(shù)據(jù)發(fā)送到為 Filebeat 配置的輸出。

      七、ELKB 的使用實(shí)踐

      安裝好 ELKB 組件之后,我們開始整合這些組件。首先看下 ELKB 收集日志的流程。

      Filebeat 監(jiān)聽?wèi)?yīng)用的日志文件,隨后將數(shù)據(jù)發(fā)送給 logstash,logstash 則對數(shù)據(jù)進(jìn)行過濾和格式化,如 JSON 格式化;之后 logstash 將處理好的日志數(shù)據(jù)發(fā)送給 Elasticsearch,Elasticsearch 存儲并建立搜索的索引;Kibana 提供可視化的視圖頁面。

      我們運(yùn)行所有的組件之后,首先看下 elasticsearch-head 中的索引變化:

      可以看到多了一個(gè) filebeat-2020.10.12 的索引,說明 ELKB 分布式日志收集框架搭建成功。訪問 http://localhost:9100,我們來具體看下索引的數(shù)據(jù):

      從上面兩幅截圖可以看到,/var/log/ 目錄下的 mysqld.log 文件中產(chǎn)生了新的日志數(shù)據(jù),這些數(shù)據(jù)非常多,我們在生產(chǎn)環(huán)境需要根據(jù)實(shí)際的業(yè)務(wù)進(jìn)行過濾,并處理相應(yīng)的日志格式。

      elasticsearch-head 是一個(gè)簡單的 Elasticsearch 客戶端,更加完整的統(tǒng)計(jì)和搜索需求,需要借助于 Kibana,Kibana 提升了 Elasticsearch 分析能力,能夠更加智能地分析數(shù)據(jù),執(zhí)行數(shù)學(xué)轉(zhuǎn)換并且根據(jù)要求對數(shù)據(jù)切割分塊。

      訪問 http://localhost:5601,得到了上圖中的日志信息。Filebeat 監(jiān)聽到了 mysql 日志,并在 Kibana 上展示。Kibana 能夠更好地處理海量數(shù)據(jù),并據(jù)此創(chuàng)建柱形圖、折線圖、散點(diǎn)圖、直方圖、餅圖和地圖,這里就不一一展示了。

      八、小結(jié)

      本文主要介紹了分布式日志采集系統(tǒng) ELKB。日志主要用來記錄離散的事件,包含程序執(zhí)行到某一點(diǎn)或某一階段的詳細(xì)信息。ELKB 很好地解決了微服務(wù)架構(gòu)下,服務(wù)實(shí)例眾多且分散,日志難以收集和分析的問題。限于篇幅,本課時(shí)只介紹了 ELKB 的安裝使用,Go 微服務(wù)中一般使用日志框架如 logrus、zap 等,按照一定的格式將日志輸出到指定的位置,讀者可以自行構(gòu)建一個(gè)微服務(wù)進(jìn)行實(shí)踐。

      微服務(wù) 云原生

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:excel怎么把單元格合并拆分
      下一篇:垃圾回收機(jī)制介紹
      相關(guān)文章
      亚洲人成网网址在线看| 亚洲深深色噜噜狠狠爱网站| 国产aⅴ无码专区亚洲av麻豆| 色综合久久精品亚洲国产| 国产99在线|亚洲| 亚洲国产精品综合久久久| 亚洲视频精品在线观看| 久久亚洲AV成人无码国产| 久久精品国产亚洲av四虎| 亚洲AV无码AV男人的天堂| 亚洲综合国产精品| 亚洲国产精品久久| 亚洲一区二区在线免费观看| 337p日本欧洲亚洲大胆色噜噜| 亚洲国产综合91精品麻豆| 久久久久亚洲Av无码专| 亚洲黄色在线观看视频| 亚洲性一级理论片在线观看| 亚洲人成777在线播放| 亚洲香蕉在线观看| 亚洲日韩精品无码AV海量| 亚洲Av无码国产一区二区| 在线观看亚洲视频| 国产成人亚洲影院在线观看| 亚洲精品午夜国产VA久久成人| 亚洲国产精品无码久久久秋霞2 | 亚洲高清一区二区三区电影| 天天综合亚洲色在线精品| 亚洲一级特黄无码片| 亚洲人成亚洲人成在线观看 | 亚洲熟妇AV一区二区三区浪潮| 亚洲高清毛片一区二区| 亚洲А∨精品天堂在线| 国产亚洲精品线观看动态图| 亚洲国产精华液网站w| 精品日韩亚洲AV无码 | 亚洲无线码在线一区观看| 久久久久亚洲AV片无码| 亚洲第一区视频在线观看| 中文有码亚洲制服av片| 亚洲成人影院在线观看|