<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          打造云原生大型分布式監(jiān)控系統(tǒng)

          共 8232字,需瀏覽 17分鐘

           ·

          2021-04-07 11:29

          笑談監(jiān)控系統(tǒng)

          隨著時間的積累,出現(xiàn)故障的風(fēng)險越來越高,事故的發(fā)生總是出人預(yù)料,如果采用人力運(yùn)維的方式,對于故障定位、故障處理都是很大的挑戰(zhàn)。故障的時間越長,面臨的損失越大,所以在發(fā)展到一定程度的團(tuán)隊(duì)都需要一套完善的監(jiān)控系統(tǒng)

          監(jiān)控大屏

          一套完善的監(jiān)控系統(tǒng)最重要的就是本身永遠(yuǎn)不可以故障,即使平臺故障也要確保監(jiān)控可能告警出來,所以監(jiān)控系統(tǒng)本身的高可用,是我們一直在追求的,先來看看一個完備的監(jiān)控系統(tǒng)應(yīng)該考慮哪些功能

          監(jiān)控系統(tǒng)設(shè)計面臨什么問題

          監(jiān)控系統(tǒng)會對很多角色進(jìn)行監(jiān)控,我把他分為這幾個大類:服務(wù)器、容器、服務(wù)或應(yīng)用、網(wǎng)絡(luò)、存儲、中間件,根據(jù)業(yè)界的方案,不同的分類使用不同的采集器進(jìn)行采集

          在功能上要考慮哪些問題?

          • 支持標(biāo)記不同監(jiān)控指標(biāo)來源,方便理清楚業(yè)務(wù)來源
          • 支持聚合運(yùn)算,轉(zhuǎn)換指標(biāo)的含義、組合用來進(jìn)行計算、匯總、分析
          • 告警、報表、圖形化大屏展示
          • 保存歷史數(shù)據(jù)便于溯源

          在易用性上應(yīng)該考慮

          • 支持配置增減監(jiān)控項(xiàng),自定義監(jiān)控

          • 支持配置表達(dá)式進(jìn)行計算

          • 最好有自動發(fā)現(xiàn),在新增服務(wù)器或新增pod等資源時自動納入監(jiān)控

          • 支持配置告警策略定義告警范圍與閾值,支持自定義告警

          方案選型

          從以上方面考慮,應(yīng)該選用哪些開源方案呢?業(yè)界常見的有ElasticsearchNagioszabbixprometheus,其他方案比較小眾不做討論

          方案選型
          • Elasticsearch 是一個實(shí)時的分布式搜索和分析引擎,支持分片、搜索速度快,一般和LogstashKibana結(jié)合起來一起用,也就是ELK,更擅長文檔日志的搜索分析

          • Nagios: 優(yōu)點(diǎn)是出錯的服務(wù)器、應(yīng)用和設(shè)備會自動重啟,自動日志滾動;配置靈活,可以自定義 shell 腳本,通過分布式監(jiān)控模式;并支持以冗余方式進(jìn)行主機(jī)監(jiān)控,報警設(shè)置多樣,以及命令重新加載配置文件無需打擾 Nagios 的運(yùn)行。缺點(diǎn)是事件控制臺功能很弱,插件易用性差;對性能、流量等指標(biāo)的處理不給力;看不到歷史數(shù)據(jù),只能看到報警事件,很難追查故障原因;配置復(fù)雜,初學(xué)者投入的時間、精力和成本比較大。

          • zabbix入門容易、上手簡單、功能強(qiáng)大,容易配置和管理,但是深層次需求需要非常熟悉 zabbix 并進(jìn)行大量的二次定制開發(fā),二次開發(fā)太多是不可接受的

          • prometheus幾乎支撐了上面所有的需求,可視化展示可以接入grafana,可以用promSQL語言來做聚合查詢,不需要定制;可以使用打tag的方式,對每個指標(biāo)分類;強(qiáng)大的社區(qū)針對各種應(yīng)用、網(wǎng)絡(luò)、服務(wù)器等設(shè)備、角色都提供了采集方案以及無侵入式的高可用方案,這個就是今天討論的重點(diǎn)

          根據(jù)上面的種種原因,綜合來看prometheus比較合適

          prometheus與他的缺陷

          prometheus架構(gòu)圖
          • 從上面的架構(gòu)圖可以看出,prometheus是在客戶端部署采集器(exporter)的形式來采集數(shù)據(jù),服務(wù)端主動向prometheus通信來拉取數(shù)據(jù)

          • 客戶端也可以通過推送數(shù)據(jù)到PushGateway再交給prometheus拉取

          • prometheus有自動發(fā)現(xiàn)的能力,簡單配置以后就可以主動拉取平臺接口獲取監(jiān)控范圍:azure、consul、openstack等,并針對檢測角色配置tag,如果和業(yè)務(wù)強(qiáng)相關(guān),可以定制修改代碼,拉取自己平臺的接口來識別監(jiān)控角色和動態(tài)打tag

          • prometheus也有告警的能力,接入官方提供的AlertManager組件可以檢測產(chǎn)生告警,再使用webhook接入自己的告警郵件/短信通知平臺

            • 這里的問題在于無法通過頁面配置告警策略、也無法存儲告警記錄,可以在AlertManager后面加一些組件來告警收斂、靜默、分組、存儲

            • 告警策略的動態(tài)配置,可以寫程序根據(jù)策略生成告警配置、放到prometheus指定目錄下,并調(diào)用prometheus熱更新接口

          唯一要解決的就是負(fù)載量大時出現(xiàn)的性能問題以及高可用問題

          單機(jī)prometheus的部署存在的問題

          prometheus的架構(gòu)決定是他更適合單機(jī)的部署方案,單機(jī)部署在壓力過大時可以通過服務(wù)器升配的方式緩解壓力,但是依然會存在共性的問題

          單點(diǎn)prometheus的問題
          • 采集速率會因?yàn)閏pu/網(wǎng)絡(luò)通信限制導(dǎo)致卡頓,采集速度變慢,指標(biāo)在周期內(nèi)未主動拉取的時候會丟失本次的指標(biāo),這里可以把采集周期拉長,后果是粒度變粗,不建議拉太長;另一種方式就是減少無用指標(biāo)的采集

          • 查詢時也是因?yàn)橥瑯拥脑蛩俣葧艿较拗疲瑪?shù)據(jù)存儲時間范圍過多時,對磁盤會有很大的壓力

          • 單點(diǎn)故障時就完全沒有辦法了,直接服務(wù)不可用

          單點(diǎn)高負(fù)載考慮什么方案?

          參考前一次的文章,高負(fù)載的時候自動水平擴(kuò)展,并做負(fù)載均衡,首先想到的水平擴(kuò)展方式就是Prometheus提供的分組能力

          分片采集

          相應(yīng)于把prometheus分片,通過配置的方式各采集部分節(jié)點(diǎn),這種方式有三個問題

          • 數(shù)據(jù)分散運(yùn)維困難

          • 要來回切換數(shù)據(jù)源,看不到全局視圖

          解決這個問題,考慮增加一個存儲位置匯總數(shù)據(jù)(remote write)

          分片后匯總

          這里考慮使用TSDB匯總,需要支持?jǐn)U容的、支持集群保證高可用的TSDB

          但是需要在TSDB上層再加一個查詢組件來做查詢,會喪失原生的查詢語句能力,可以考慮把TSDB替換成prometheus節(jié)點(diǎn),用聯(lián)邦的形式存儲

          聯(lián)邦

          這種情況可以滿足基本的使用要求,通過prometheus自監(jiān)控來通知運(yùn)維人員手動擴(kuò)容修改分組,有沒有更自動一點(diǎn)的方式呢?

          彈性伸縮(自動水平伸縮)

          彈性伸縮的前提有三個

          • 要能監(jiān)控當(dāng)前節(jié)點(diǎn)負(fù)載狀態(tài),預(yù)判擴(kuò)容時機(jī)

          • 需要維護(hù)服務(wù)啟停方式、自動創(chuàng)建服務(wù)并放到相應(yīng)節(jié)點(diǎn)上

          • 同時要能修改prometheus各節(jié)點(diǎn)數(shù)據(jù)采集范圍

          k8s做容器編排是最直接的方案,可以解決創(chuàng)建和銷毀服務(wù)的問題,也是可以通過cpu使用率或自定義指標(biāo)完成橫向擴(kuò)容的,但解決不了的問題是修改prometheus節(jié)點(diǎn)配置,動態(tài)分配采集范圍,考慮使用以下方案

          調(diào)度器
          • prometheus注意要配置節(jié)點(diǎn)反親和性(k8s配置podAntiAffinity

          • 寫一個調(diào)度器通過k8s api檢測prometheus節(jié)點(diǎn)狀態(tài)

          • 通過k8s檢測節(jié)點(diǎn)故障以及負(fù)載情況,使用hash分?jǐn)倝毫Γ瑪U(kuò)展prometheussd自動發(fā)現(xiàn)功能,帶上自己的hostname來獲取調(diào)度器提供的數(shù)據(jù)范圍

          用這種方式就不需要修改配置文件了,因?yàn)槭?code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;border-radius: 4px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.047);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">prometheus接口端定時更新監(jiān)控范圍

          • 根據(jù)具體運(yùn)行情況伸縮prometheus,不需要再配置configmap

          到這里你可能有一個疑問,假如我監(jiān)控服務(wù)器用上面的方式,那么多接收端,再加一個redis集群的監(jiān)控,應(yīng)該放到哪個節(jié)點(diǎn)上呢?答案是可以專門創(chuàng)建獨(dú)立于此自動伸縮方案的prometheus來進(jìn)行少量數(shù)據(jù)監(jiān)控,或者直接放到所有節(jié)點(diǎn)上,在上層再考慮去重的問題,這個我們一會討論。

          到目前為止分片以后分散了壓力,但還沒有解決的問題是數(shù)據(jù)分散無法匯總查詢、單點(diǎn)故障數(shù)據(jù)丟失的問題。

          匯總查詢可能你會想到剛剛說的聯(lián)邦部署,但壓力又匯總到一點(diǎn)上了,不能根本的解決問題;解決單點(diǎn)故障應(yīng)該使用冗余的形式部署,給每個監(jiān)控范圍分配2個及以上監(jiān)控節(jié)點(diǎn),但會導(dǎo)致客戶端拉取次數(shù)翻倍,也不建議。

          如何保證單點(diǎn)故障數(shù)據(jù)不丟失

          為了避免無法匯總查詢、單點(diǎn)故障數(shù)據(jù)丟失的問題,這里打算接入一個高可用方案thanos,把prometheus設(shè)置為無狀態(tài)應(yīng)用,并開啟遠(yuǎn)程寫把數(shù)據(jù)推送到thanos

          推送到thanos

          這樣的話prometheus本身不存儲數(shù)據(jù),即使掛掉部分節(jié)點(diǎn),只要保證node夠多也會再自動伸縮出新的節(jié)點(diǎn),期間讀取到的采集范圍會先負(fù)載變大,然后又得到緩解,整個過程在2個周期內(nèi)解決

          PS: ,Prometheus在將采集到的指標(biāo)寫入遠(yuǎn)程存儲之前,會先緩存在內(nèi)存隊(duì)列中,然后打包發(fā)送給遠(yuǎn)端存儲,以減少連接數(shù)量,要提高寫入速率需要修改配置項(xiàng)queue_config

          簡單介紹下thanosthanos是無侵入式的高可用方案,負(fù)責(zé)對prometheus產(chǎn)生的數(shù)據(jù)進(jìn)行匯總、計算、去重、壓縮、存儲、查詢、告警,他實(shí)現(xiàn)了prometheus提供的查詢接口,對外部而言查詢prometheus還是查詢thanos的效果完全一樣,是無感知的

          一起來實(shí)現(xiàn)分布式高可用監(jiān)控系統(tǒng)

          如何讓我們來實(shí)現(xiàn)一個這樣的組件,你會怎么做呢?

          匯總存儲,上層完成其他功能

          把分片數(shù)據(jù)寫入到存儲,其他組件和存儲通信,thanos的主流方案也是這么做的

          thanos架構(gòu)圖

          如上圖所示所有的組件都會與對象存儲通信,完成數(shù)據(jù)存儲或者讀取的功能

          • 使用對象存儲做存儲引擎

          • prometheus節(jié)點(diǎn)一同部署sidecar,每個節(jié)點(diǎn)對應(yīng)一個,定期放數(shù)據(jù)推送到對象存儲

          • Ruler負(fù)責(zé)判定告警以及根據(jù)規(guī)則做指標(biāo)聚合運(yùn)算

          • Compact負(fù)責(zé)降準(zhǔn)壓縮,一份數(shù)據(jù)變?nèi)荩话闶欠譃?分鐘、5分鐘、1小時寫回存儲,查詢時間粒度越大呈現(xiàn)指標(biāo)粒度越粗,防止前端數(shù)據(jù)刷爆

          • Query與其他組件通過grpc的方式進(jìn)行通信讀取數(shù)據(jù),它不和對象存儲直接通信,而是在中間加了一層gateway網(wǎng)關(guān)

          • 上圖的方案sidecar不是我這次的架構(gòu),其他是一樣的,sidecar的原理是把采集到的數(shù)據(jù)使用緩存到本地(默認(rèn)2小時數(shù)據(jù)為熱數(shù)據(jù)),冷數(shù)據(jù)才推送,近期數(shù)據(jù)存儲本地,查詢時再做匯總會有一定的壓力,同時單點(diǎn)故障問題還是沒有解決

          如果是小規(guī)模集群無網(wǎng)絡(luò)壓力可以使用sidercar

          不要在接收端存儲

          prometheus部署在一起的sidercar違背了容器中的簡單性原則,也提高存儲壓力,把他們剝離開試試?

          匯總再轉(zhuǎn)存

          我的想法是收集數(shù)據(jù)推送,然后進(jìn)行存儲,由其他組件完成與存儲的通信

          receive方案

          如上圖,Receive組件實(shí)現(xiàn)了remote write接口,Prometheus可以將數(shù)據(jù)實(shí)時推送到Receive上;Receive本身實(shí)際上相當(dāng)于一個沒有收集功能的Prometheus,那此時Prometheus就不再需要存儲數(shù)據(jù),之前的方案就可以實(shí)施了

          • 對象存儲中的數(shù)據(jù)具有不可修改特性,也就是說一旦寫入就變成只讀了

          • Prometheus本地存儲的原理是接受到的數(shù)據(jù)寫到本地文件存儲里面組成WAL文件列表,Receive也是這么做的,然后超過一定時限后生成block,這些block會上傳到對象存儲

          • Query組件來近期數(shù)據(jù)(默認(rèn)2小時內(nèi))查詢recevie,過期后使用對象存儲

          • receive使用k8s的dnssrv功能做服務(wù)發(fā)現(xiàn),便于下游拉取數(shù)據(jù)而不要使用k8s的service:ip自帶的負(fù)載均衡

          • receive自帶了hash算法,可以把上游遠(yuǎn)程寫過來的流量均勻分布在各個節(jié)點(diǎn)上,這里可以采用k8s的service自動輪訓(xùn),recevie會把請求route到相應(yīng)節(jié)點(diǎn)上

          為防止prometheus掛掉一個導(dǎo)致的數(shù)據(jù)丟失問題,給prometheus加一個副本,然后在query時去重,主要由query--query.replica-label 參數(shù)和Prometheus配置的 prometheus_replica參數(shù)來實(shí)現(xiàn),如下圖

          概覽

          同樣的其他組件,如ruler也可以配置冗余部署rule_replica就不展開講了

          還好recevie自帶了分布式一致性算法,不然就要自己實(shí)現(xiàn)一個了,到此我們解決了

          • 數(shù)據(jù)接收端能應(yīng)對海量數(shù)據(jù)的壓力均衡

          • 解決了prometheus部署在不同集群上時查詢延遲高的問題

          • 解決了跨節(jié)點(diǎn)數(shù)據(jù)復(fù)合運(yùn)算(ruler

          • 解決了數(shù)據(jù)壓縮降準(zhǔn)

          hashring真的是分布式一致性算法嗎

          我們知道分布式一致性算法可以解決下面的問題

          • 在壓力增加時做到自動擴(kuò)容,壓力減小時自動縮容

          • 擴(kuò)縮容時必須要保障數(shù)據(jù)不丟失,單點(diǎn)故障時數(shù)據(jù)也不可以丟失

          • 擴(kuò)縮容時數(shù)據(jù)映射落點(diǎn)要一致,不然會出現(xiàn)數(shù)據(jù)斷連

          但是實(shí)際使用過程中,不難發(fā)現(xiàn),還是會發(fā)生數(shù)據(jù)丟失,這引起了我的興趣

          這一塊的官網(wǎng)介紹很少,hashring 的endpoints參考下面的代碼,你會發(fā)現(xiàn)0 1 2 的方式就是k8sstatefulsetpod 分配的name,所以recevie要以sts的方式部署,并提前把副本數(shù)與配置關(guān)系對應(yīng)起來,3節(jié)點(diǎn)已經(jīng)可以支撐很大數(shù)量的數(shù)據(jù)處理了

          thanos-receive-hashrings.json: |
              [
                {
                  "hashring": "soft-tenants",
                  "endpoints":
                  [
                    "thanos-receive-0.thanos-receive.thanos.svc.cluster.local:10901",
                    "thanos-receive-1.thanos-receive.thanos.svc.cluster.local:10901",
                    "thanos-receive-2.thanos-receive.thanos.svc.cluster.local:10901"
                  ]
                }
              ]

          在源碼里發(fā)現(xiàn),實(shí)際上這里并沒有使用分布式一致性算法!! 在hashring.go函數(shù)里可以看到,這是一個簡單的hash mod,所以hashring是有誤導(dǎo)性的

          func (s simpleHashring) GetN(tenant string, ts *prompb.TimeSeries, n uint64) (string, error) {
           if n >= uint64(len(s)) {
            return "", &insufficientNodesError{have: uint64(len(s)), want: n + 1}
           }
           return s[(hash(tenant, ts)+n)%uint64(len(s))], nil
          }

          提煉出來是這樣的hash算法

          hash(string(tenant_id) + sort(timeseries.labelset).join())
          • tenant_id是指數(shù)據(jù)源帶上租戶,可以給不同租戶分配自己的hash

          • 具體的hash算法使用xxHash 參考文末資料5

          解決的辦法也有了,可以通過配置多副本冗余的方式,把receive的數(shù)據(jù)冗余到其他位置,設(shè)置receive.replication-factor配置,然后拉取數(shù)據(jù)的時候因?yàn)槭褂玫氖欠?wù)發(fā)現(xiàn),和所有服務(wù)通信的方式,可以在一定程序上保證數(shù)據(jù)不丟失

          PS: 冗余也會有點(diǎn)問題,算法是先選hash mod后的節(jié)點(diǎn),比如是第n個,然后如果factor是2,就再選n+1n+2,然后發(fā)請求給n,這個時候如果n掛了其實(shí)會失敗,相對而言n+1或者n+2節(jié)點(diǎn)掛了的話不會對這部分的數(shù)據(jù)有影響

          當(dāng)receive出現(xiàn)故障是怎么處理的

          當(dāng)發(fā)生擴(kuò)縮容的時候,由于hashring發(fā)生變化,所有的節(jié)點(diǎn)需要將write-ahead-log的數(shù)據(jù)flushTSDB塊并上傳到OSS中(如果配置了的話),因?yàn)檫@些節(jié)點(diǎn)之后將有一個新的分配。之前已存在節(jié)點(diǎn)上的時間序列不需要作調(diào)整,只是后面過來的請求按新的分發(fā)來尋找該去的receiver節(jié)點(diǎn)。

          這個過程不需要重啟receive,代碼里有watch,可以檢測hashring的變化

          注意,這種情況發(fā)生的flush可能會產(chǎn)生較小的TSDB塊,但compactor模塊可以將它們優(yōu)化合并,因此不會有什么問題。

          當(dāng)有receiver節(jié)點(diǎn)發(fā)生故障時,prometheus的遠(yuǎn)程寫會在后端目標(biāo)無響應(yīng)或503時進(jìn)行重試,因此,receiver一定時間的服務(wù)掛掉是可以容忍的。如果這種掛機(jī)時間是不可接受的話,可以將副本數(shù)配置為 3 或以上,這樣即使有一個receiver節(jié)點(diǎn)掛掉,還有其他receiver節(jié)點(diǎn)來接收寫請求

          業(yè)務(wù)指標(biāo)計算問題

          如果有非常復(fù)雜的業(yè)務(wù)指標(biāo),需要從其他地方采集推送,最好的方式是寫成采集器exporter,在ruler進(jìn)行復(fù)合運(yùn)算,當(dāng)然也有可能出現(xiàn)表達(dá)式寫不出來的尷尬問題

          考慮寫成k8sjob定時任務(wù),把數(shù)據(jù)推送到PushGateway,再交給prometheus去拉取

          PS1: 注意按exporter的開發(fā)標(biāo)準(zhǔn),不允許出現(xiàn)重復(fù)指標(biāo)哦

          PS2:如果要刪除過期的垃圾數(shù)據(jù)可以調(diào)用PushGatewayhttp://%s/metrics/job/%s/instance/%s/host/接口進(jìn)行刪除

          告警策略動態(tài)更新/告警記錄儲存的問題

          要動態(tài)生成告警策略,可以寫一個服務(wù)接收請求,調(diào)用k8s生成configmap,并通知ruler進(jìn)行熱更新

          • 更新策略配置文件configmap(同步更新到pod里會有一定的延遲,使用subPath是無法熱更新的,注意configMapAndSecretChangeDetectionStrategy: Watch參數(shù)必須為默認(rèn)參數(shù)Watch
          • 把configmap掛載相應(yīng)的ruler上面

          全景視圖

          全景視圖

          最后

          當(dāng)然對于一個成熟的監(jiān)控系統(tǒng)來說,除了發(fā)現(xiàn)故障及時告警以外,還應(yīng)該有更多的功能,這不是本次討論的范圍,如果有時間未來會寫寫

          • 運(yùn)營故障報表和資源日報周報月報等用于趨勢分析
          • 低負(fù)載報表用于分析服務(wù)器利用率,防止資源浪費(fèi)
          • 有了故障趨勢和更多的重要指標(biāo)覆蓋,可以結(jié)合AI進(jìn)行故障預(yù)測,在故障發(fā)生前提前預(yù)測

          最后的最后

          針對全k8s的集群監(jiān)控來說,還有更簡單的方式來監(jiān)控,那就是Prometheus Operator,可以非常簡單的創(chuàng)建k8s的資源,比如收集器Prometheus、采集器的抽象ServiceMonitorAlertManager等,要監(jiān)控什么數(shù)據(jù)就變成直接操作k8s集群的資源對象了

          監(jiān)控可能為其他應(yīng)用的水平伸縮服務(wù)服務(wù),使用Prometheus Adpater來自定義監(jiān)控某些指標(biāo),來達(dá)到自動擴(kuò)縮容的目的

          監(jiān)控還可以為運(yùn)維平臺服務(wù),提供故障自動修復(fù)

          一句話,只要監(jiān)控運(yùn)維平臺做得足夠好,運(yùn)維人員都得失業(yè)

          引用與拓展資料

          • 1、7 款你不得不了解的開源云監(jiān)控工具

          • 2、Thanos在TKEStack中的實(shí)踐 - Even - A super concise theme for Hugo

          • 3、Prometheus Remote Write配置 - 時序數(shù)據(jù)庫 TSDB - 阿里云

          • 4、Thanos - Highly available Prometheus setup with long term storage capabilities

          • 5、xxHash - Extremely fast non-cryptographic hash algorithm

          瀏覽 13
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91亚洲电影 | 亚洲一线精品操逼毛片 | 亚洲网站视频在线观看 | 日本激情视频在线播放 | 中文AV字幕网 |