精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

基于Prometheus的自動化巡檢

開發 前端
大部分企業雖然都有監控告警,但是自動化巡檢在日常的運維工作中還是必要的,它可以聚合目前系統、集群存在的問題,避免遺漏告警信息。

前言

目前,大部分公司都采用Prometheus + Grafana這一套來做指標監控,所以在Prometheus中也有大量的指標數據。為了滿足日常工作中的巡檢,可以基于Prometheus實現自動巡檢,減輕部分運維壓力。

思路

為了靈活管理巡檢任務,將整個巡檢功能進行了拆分管理,分為:

  • 數據源管理:可以管理多個Prometheus數據源,后期也可以增加其他數據源,比如ES等。
  • 巡檢項管理:目前的巡檢項就是各種Prometheus規則,之所以要單獨進行管理,是為了在多數據源、多集群等情況下進行復用。
  • 標簽管理:目前是Prometheuslabel,也是為了方便復用巡檢項,巡檢項標簽可以靈活進行組合。
  • 任務編排:編排各種巡檢任務。
  • 執行作業:配置定時的巡檢作業,它由多個編排的任務組成。
  • 巡檢報告:便于查看、導出巡檢結果。
  • 巡檢通知:巡檢結果可以通知到企業微信群,便于業務方快速知道目前整個系統有沒有問題。

圖片圖片

效果

數據源管理

(1)添加數據源

圖片

(2)數據源列表

圖片

巡檢項管理

(1)添加巡檢項

圖片

(2)巡檢項列表

圖片

標簽管理

(1)添加標簽

圖片

(2)標簽列表

圖片

任務編排

(1)創建任務編排

圖片

(2)任務列表

圖片

執行作業

(1)創建執行作業

圖片

(2)作業列表

圖片

巡檢報告

每次巡檢完成都會生成對應的巡檢報告。

圖片

點擊詳情可以看到巡檢的具體結果。

圖片

點擊導出,即可將報告導出為PDF。

圖片

如果配置了巡檢通知,則會將對應的巡檢結果發送到企業微信群。

圖片

代碼實現

大部分的代碼都是普通的CRUD,比如數據源的管理、巡檢項的管理都是基礎的CRUD,沒有什么好說的。

這里簡單說一下具體巡檢的實現。

(1)當用戶創建了執行作業且該作業處于開啟狀態,就會創建一個定時任務。

// CreateCronTask 創建定時任務

func (inspectionExecutionJobService *InspectionExecutionJobService) CreateCronTask(job *AutoInspection.InspectionExecutionJob) error {
    cronName := fmt.Sprintf("InspectionExecution_%d", job.ID)
    taskName := fmt.Sprintf("InspectionExecution_%d", job.ID)
    // 檢查是否已存在相同的定時任務
    if _, found := global.GVA_Timer.FindTask(cronName, taskName); found {
        // 如果已存在,先清除舊的定時任務
        global.GVA_Timer.Clear(cronName)
    }
    // 創建定時任務
    var option []cron.Option
    option = append(option, cron.WithSeconds())
    // 添加定時任務
    if _, err := global.GVA_Timer.AddTaskByFunc(cronName, job.CronExpr, func() {
        // 執行巡檢任務
        inspectionExecutionJobService.ExecuteInspectionJob(job)
    }, taskName, option...); err != nil {
        global.GVA_LOG.Error("創建定時任務失敗", zap.Error(err), zap.Uint("jobID", job.ID))
        return err
    }
    // 更新下次執行時間
    nextTime := inspectionExecutionJobService.calculateNextRunTime(job.CronExpr)
    job.NextRunTime = &nextTime
    // 更新數據庫中的記錄
    return global.GVA_DB.Model(job).Updates(map[string]interface{}{
        "next_run_time": job.NextRunTime,
    }).Error
}


Tips:因為是采用的gin-vue-admin框架,所以直接使用框架自帶的timer定時器。

(2)當執行時間到了,就會執行ExecuteInspectionJob巡檢任務。

func (inspectionExecutionJobService *InspectionExecutionJobService) ExecuteInspectionJob(job *AutoInspection.InspectionExecutionJob) {
    // 更新作業執行時間
    inspectionExecutionJobService.updateJobExecutionTime(job)
    // 創建執行記錄
    jobExecution := inspectionExecutionJobService.createJobExecution(job)
    if jobExecution == nil {
        return
    }
    // 執行所有關聯的巡檢任務并收集結果
    allResults := inspectionExecutionJobService.executeAllInspectionTasks(job, jobExecution)
    global.GVA_LOG.Info("執行完成", zap.Any("results", allResults))
    // 更新執行記錄狀態和結果
    inspectionExecutionJobService.updateJobExecutionResult(jobExecution, allResults)
    // 發送通知
    if *job.IsNotice {
        inspectionExecutionJobService.sendInspectionNotification(job, jobExecution, allResults)
    }
}

這里主要是executeAllInspectionTasks來執行巡檢任務。

// executeAllInspectionTasks 執行所有關聯的巡檢任務并收集結果

func (inspectionExecutionJobService *InspectionExecutionJobService) executeAllInspectionTasks(job *AutoInspection.InspectionExecutionJob, jobExecution *AutoInspection.JobExecution) []*result.ProductsResult {
    // 創建一個等待組來同步所有巡檢任務
    var wg sync.WaitGroup
    // 創建一個互斥鎖來保護結果集
    var mu sync.Mutex
    // 創建一個結果集合
    allResults := make([]*result.ProductsResult, 0)
    // 執行所有關聯的巡檢任務
    for _, jobID := range job.JobIds {
        wg.Add(1)
        gofunc(id uint) {
            defer wg.Done()
            // 執行單個巡檢任務并獲取結果
            result := inspectionExecutionJobService.executeSingleInspectionTask(id, jobExecution)
            if result != nil {
                // 將結果添加到總結果集中
                mu.Lock()
                allResults = append(allResults, result)
                mu.Unlock()
            }
        }(jobID)
    }
    // 等待所有巡檢任務完成
    wg.Wait()
    return allResults
}

它會把作業中的任務拆成單個任務,然后由executeSingleInspectionTask分別執行并收集執行結果。

// executeSingleInspectionTask 執行單個巡檢任務
func (inspectionExecutionJobService *InspectionExecutionJobService) executeSingleInspectionTask(jobID uint, jobExecution *AutoInspection.JobExecution) *result.ProductsResult {
    global.GVA_LOG.Info("執行巡檢任務", zap.Uint("jobID", jobID))
    // 獲取巡檢任務信息
    inspectionJob, _ := inspectionJobService.GetInspectionJob(fmt.Sprintf("%d", jobID))
    // 創建結果通道
    resultCh := make(chan *result.ProductsResult)
    // 創建一個用于等待結果的WaitGroup
    var resultWg sync.WaitGroup
    resultWg.Add(1)
    // 用于存儲結果的變量
    var taskResult *result.ProductsResult
    // 啟動一個goroutine來接收結果
    gofunc() {
        defer resultWg.Done()
        result := <-resultCh
        global.GVA_LOG.Info("巡檢任務執行完成",
            zap.String("jobName", inspectionJob.Name),
            zap.Any("result", result))
        // 保存結果
        taskResult = result
    }()
    // 執行巡檢任務
    inspectionExecutionJobService.ExecuteInspectionTask(&inspectionJob, jobExecution, resultCh)
    // 等待結果接收完成
    resultWg.Wait()
    return taskResult

}

ExecuteInspectionTask中是為了方便擴展數據源。

func (inspectionExecutionJobService *InspectionExecutionJobService) ExecuteInspectionTask(inspectionJob *AutoInspection.InspectionJob, jobExecution *AutoInspection.JobExecution, resultCh chan *result.ProductsResult) {

    switch inspectionJob.DataSourceType {
    case "prometheus":
        // 執行Prometheus巡檢任務
        inspectionExecutionJobService.ExecutePrometheusInspectionTask(inspectionJob, jobExecution, resultCh)
    }
}

由于目前只有Prometheus數據源,所以將直接執行ExecutePrometheusInspectionTask。在這個方法中主要是構造Prometheus規則然后進行巡檢。

// ExecutePrometheusInspectionTask 執行Prometheus巡檢任務
func (inspectionExecutionJobService *InspectionExecutionJobService) ExecutePrometheusInspectionTask(inspectionJob *AutoInspection.InspectionJob, jobExecution *AutoInspection.JobExecution, resultCh chan *result.ProductsResult) {
// 執行Prometheus巡檢任務的邏輯
var inspectionItemsService InspectionItemsService
var inspectionTagService InspectionTagService
var dataSourceService DataSourceService

// 獲取數據源信息
 dataSource, _ := dataSourceService.GetDataSource(fmt.Sprintf("%d", inspectionJob.DataSourceId))

// 創建規則列表
 prometheusRules := make([]*product.PrometheusRule, 0, len(inspectionJob.ItemLabelMaps))

// 遍歷巡檢項與標簽映射關系
for _, itemLabelMap := range inspectionJob.ItemLabelMaps {
// 獲取巡檢項信息
  inspectionItem, _ := inspectionItemsService.GetInspectionItems(fmt.Sprintf("%d", itemLabelMap.ItemId))

// 獲取標簽信息
var inspectionTag AutoInspection.InspectionTag
if itemLabelMap.LabelId != 0 {
   inspectionTag, _ = inspectionTagService.GetInspectionTag(fmt.Sprintf("%d", itemLabelMap.LabelId))
  }

// 創建Prometheus規則
  prometheusRule := &product.PrometheusRule{
   Name:           inspectionItem.Name,
   Rule:           inspectionItem.Rule,
   LabelFilter:    inspectionTag.Label,
   Desc:           inspectionItem.Description,
   AlertInfo:      inspectionItem.OutputTemplate,
   DataSourceName: dataSource.Name,
  }

// 添加到規則列表
  prometheusRules = append(prometheusRules, prometheusRule)

 }

// 創建規則集合
 rules := product.Rules{
  Prometheus: prometheusRules,
  AliyunSafe: []*product.AliyunSafeRule{}, // 空列表,因為這里只處理Prometheus規則
 }

// 創建產品
 prod := &product.Product{
  Name:  inspectionJob.Name,
  Rules: rules,
 }

// 使用defer和recover捕獲可能的panic
deferfunc() {
if r := recover(); r != nil {
   // 記錄panic信息
   global.GVA_LOG.Error("執行巡檢任務發生panic",
    zap.Any("panic", r),
    zap.String("jobName", inspectionJob.Name))

   // 創建一個表示失敗的結果并發送到結果通道
   pr := &result.ProductsResult{ProductName: inspectionJob.Name}

   // 為每個規則創建失敗結果
   for _, rule := range prometheusRules {
    errorMsg := fmt.Sprintf("巡檢執行失敗: %v", r)
    failureResult := result.NewRuleResult(
     result.WithInspectionInfo(rule.Name),
     result.WithInspectionResult(result.ABNORMAL),
     result.WithInspectionErrorInfo(
      []map[string]string{{
       "error": errorMsg,
       "rule":  rule.Rule,
      }},
      "執行規則 {{rule}} 時發生錯誤: {{error}}",
     ),
    )
    pr.Add(failureResult)
   }

   // 發送結果
   resultCh <- pr
  }
 }()

// 執行巡檢
 err = prod.Run(resultCh)
if err != nil {
  global.GVA_LOG.Error("執行巡檢任務失敗", zap.Error(err), zap.String("jobName", inspectionJob.Name))
return
 }

 global.GVA_LOG.Info("巡檢任務已啟動", zap.String("jobName", inspectionJob.Name))
}

prod.Run中,會去做真正的指標數據查詢。

func (p *Product) Run(resultCh chan *result.ProductsResult) error {
 global.GVA_LOG.Info(fmt.Sprintf("開始巡檢, %s", p.Name))
 pr := &result.ProductsResult{ProductName: p.Name}
// prometheus巡檢規則
for _, prometheusRule := range p.Rules.Prometheus {
  ruleInspectRes, err := prometheusRule.Run()
if err != nil {
   return err
  }
  pr.Add(ruleInspectRes)
 }
 resultCh <- pr
returnnil
}

然后調用prometheusRule.Run獲取結果。

func (r *PrometheusRule) Run() (*result.RuleResult, error) {
 ds, err := datasource.GetByName(r.DataSourceName)
if err != nil {
returnnil, err
 }
 pds, ok := ds.(*datasource.PrometheusDataSource)
if !ok {
returnnil, fmt.Errorf("數據源類型錯誤: %s 不是Prometheus數據源", r.DataSourceName)
 }
if pds.Client == nil {
returnnil, fmt.Errorf("數據源為空: %s", r.DataSourceName)
 }
 res, err := pds.Run(r.Rule, r.LabelFilter)
if err != nil {
returnnil, err
 }
 ruleRes := r.buildRuleResult(res)
return ruleRes, nil
}

func (r *PrometheusRule) buildRuleResult(resultLabels []map[string]string) *result.RuleResult {
iflen(resultLabels) == 0 {
return result.NewRuleResult(result.WithInspectionInfo(fmt.Sprintf("%s", r.Name)),
   result.WithInspectionResult(result.NORMAL))
 }
return result.NewRuleResult(result.WithInspectionInfo(fmt.Sprintf("%s", r.Name)),
  result.WithInspectionResult(result.ABNORMAL),
  result.WithInspectionErrorInfo(resultLabels, r.AlertInfo))
}

具體的查詢是封裝在pds.Run中的,它會去調用Prometheus的接口去查詢數據。

func Query(client api.Client, rule string) (model.Value, []string, error) {
// 添加空指針檢查
if client == nil {
returnnil, nil, errors.New("Prometheus client is nil")
 }
 v1Api := promV1.NewAPI(client)
 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
 value, warnings, err := v1Api.Query(ctx, rule, time.Now(), promV1.WithTimeout(10*time.Second))
 global.GVA_LOG.Debug("查詢結果", zap.String("value", value.String()), zap.Any("warnings", warnings))
if err != nil {
returnnil, nil, errors.WithStack(err)
 }
return value, warnings, nil
}

(3)如果需要發送到企業微信,就會構建發送結果進行發送。

func (inspectionExecutionJobService *InspectionExecutionJobService) sendInspectionNotification(job *AutoInspection.InspectionExecutionJob, jobExecution *AutoInspection.JobExecution, results []*result.ProductsResult) {
// 獲取通知配置
var notifyService = NotifyService{}
 notify, err := notifyService.GetNotify(fmt.Sprintf("%d", job.NoticdId))
if err != nil {
  global.GVA_LOG.Error("獲取通知配置失敗", zap.Error(err))
return
 }

// 構建通知內容
// 1. 巡檢摘要
 taskCount := len(results)   // 巡檢任務數量
 itemCount := 0              // 巡檢項數量
 normalCount := 0            // 正常項數量
 abnormalCount := 0          // 異常項數量
 abnormalItems := []string{} // 異常項列表

// 統計巡檢項、正常項和異常項的數量
for _, task := range results {
  itemCount += len(task.SubRuleResults)
for _, item := range task.SubRuleResults {
   if item.InspectionResult == result.NORMAL {
    normalCount++
   } elseif item.InspectionResult == result.ABNORMAL {
    abnormalCount++
    // 收集異常項信息
    abnormalDetail := fmt.Sprintf("【%s】%s", task.ProductName, item.InspectionInfo)
    iflen(item.InspectionErrorInfo) > 0 {
     abnormalDetail += "\n" + strings.Join(item.InspectionErrorInfo, "\n")
    }
    abnormalItems = append(abnormalItems, abnormalDetail)
   }
  }
 }

// 格式化摘要信息
 summary := fmt.Sprintf("巡檢任務%d個,巡檢項%d個,正常%d個,異常%d個", taskCount, itemCount, normalCount, abnormalCount)

// 構建企業微信通知內容
var content string
if notify.TemplateType == "markdown" {
// Markdown格式
  content = fmt.Sprintf(`{
   "msgtype": "markdown",
   "markdown": {
    "content": "# 自動化巡檢結果通知\n\n> ### 執行作業:%s\n> ### 執行時間:%s\n> ### 執行結果:%s\n\n### **異常項列表:**\n%s"
   }
  }`,
   jobExecution.ExecutionJobName,
   jobExecution.EndTime.Format("2006-01-02 15:04:05"),
   summary,
   formatAbnormalItems(abnormalItems))
 } else {
// 文本格式
  content = fmt.Sprintf(`{
   "msgtype": "text",
   "text": {
    "content": "巡檢結果通知\n執行作業:%s\n執行時間:%s\n執行結果:%s\n\n異常項列表:\n%s"
   }
  }`,
   jobExecution.ExecutionJobName,
   jobExecution.EndTime.Format("2006-01-02 15:04:05"),
   summary,
   formatAbnormalItemsText(abnormalItems))
 }

// 發送通知
 ctx := context.Background()
 sendParams := sender.SendParams{
  NoticeType: notify.Type,
  NoticeId:   fmt.Sprintf("%d", notify.ID),
  NoticeName: notify.Name,
  Hook:       notify.Address,
  Content:    content,
 }

 err = sender.Sender(&ctx, sendParams)
if err != nil {
  global.GVA_LOG.Error("發送巡檢通知失敗", zap.Error(err))
return
 }

 global.GVA_LOG.Info("發送巡檢通知成功",
  zap.String("jobName", jobExecution.ExecutionJobName),
  zap.String("summary", summary))
}

(4)PDF導出是用wkhtmltopdf實現,該包依賴服務器上的wkhtmltopdf命令。

func (jobExecutionService *JobExecutionService) GeneratePDF(jobExecution *AutoInspection.JobExecution) (string, error) {

 pdf, err := wkhtmltopdf.NewPDFGenerator()
if err != nil {
  global.GVA_LOG.Error("PDF生成器初始化失敗", zap.Error(err))
return"", err
 }

// 設置全局選項
 pdf.Dpi.Set(300)
 pdf.Orientation.Set(wkhtmltopdf.OrientationPortrait)
 pdf.PageSize.Set(wkhtmltopdf.PageSizeA4)
 pdf.MarginTop.Set(20)
 pdf.MarginBottom.Set(20)
 pdf.MarginLeft.Set(20)
 pdf.MarginRight.Set(20)

// 渲染HTML模板
 htmlContent, err := jobExecutionService.renderHTMLTemplate(jobExecution)
if err != nil {
  global.GVA_LOG.Error("HTML模板渲染失敗", zap.Error(err))
return"", err
 }

// 創建一個頁面并添加到生成器
 page := wkhtmltopdf.NewPageReader(bytes.NewBufferString(htmlContent))
 pdf.AddPage(page)

// 生成PDF
 err = pdf.Create()
if err != nil {
return"", err
 }

 basePath := "uploads/pdf"
// 創建目錄(如果不存在)
if err = os.MkdirAll(basePath, 0755); err != nil {
  global.GVA_LOG.Error("創建PDF保存目錄失敗", zap.Error(err))
return"", err
 }

 filename := generatePDFFileName(jobExecution)
 filePath := filepath.Join(basePath, filename)

// 3. 保存PDF到文件
if err = os.WriteFile(filePath, pdf.Bytes(), 0644); err != nil {
  global.GVA_LOG.Error("保存PDF文件失敗", zap.Error(err))
return"", err
 }

    ....
    
return downloadURL, nil
}

以上就是實現巡檢的主要代碼。

最后

大部分企業雖然都有監控告警,但是自動化巡檢在日常的運維工作中還是必要的,它可以聚合目前系統、集群存在的問題,避免遺漏告警信息。另外,在AI發展迅猛的今天,可以把AI也結合到自動化巡檢中,比如在巡檢中增加一些AI預測,AI故障診斷、AI根因分析等功能。

責任編輯:武曉燕 來源: 運維開發故事
相關推薦

2017-06-14 08:08:40

運維監控自動化

2015-05-25 19:34:06

KickstartCentOS

2015-10-08 10:55:23

云服務自動化運維 ANSIBLE

2017-12-17 21:58:18

2025-09-26 08:36:43

2024-11-28 09:26:46

網絡網絡設備

2022-02-18 13:12:49

人工智能自動化技術

2022-02-17 17:37:17

超級自動化人工智能AI

2020-04-29 11:28:54

智能自動化機器人流程自動化AI

2010-12-06 09:59:58

2019-02-19 15:37:18

自動化測試數據

2012-02-27 17:34:12

Facebook自動化

2020-12-08 06:20:49

前端重構Vue

2023-11-15 18:02:52

2015-10-20 17:12:58

SuSE自動化運維運維

2017-06-23 13:51:38

ShutItPythonshell

2018-07-13 06:46:35

數據中心自動化微服務

2023-06-30 09:46:00

服務物理機自動化

2022-04-14 08:21:48

微服務項目多模塊

2022-02-17 10:37:16

自動化開發團隊預測
點贊
收藏

51CTO技術棧公眾號

国产aaaaa毛片| 日本免费一区二区三区| 国产精品美女毛片真酒店| 国产精品2023| 在线中文字幕不卡| 在线观看成人一级片| 亚洲h视频在线观看| av不卡在线看| 日韩中文字幕在线| 国产吃瓜黑料一区二区| 欧美电影免费观看网站| 亚洲免费视频中文字幕| 欧美日韩在线一区二区三区| 国产美女永久免费| 欧美专区在线| 欧美激情视频给我| 天美传媒免费在线观看| 欧美一级三级| 欧美一级xxx| 黄色高清无遮挡| 欧美午夜大胆人体| 中日韩av电影| 九九热久久66| av中文字幕第一页| 人人精品人人爱| 97福利一区二区| 国产精品成人69xxx免费视频| 欧美毛片免费观看| 日韩欧美精品在线视频| 天天插天天操天天射| 爱情岛论坛亚洲品质自拍视频网站| 欧美激情中文字幕一区二区| 国产偷国产偷亚洲高清97cao| 伊人色综合久久久| 麻豆精品网站| 国产做受高潮69| 欧美日韩在线国产| 欧美激情理论| 怡红院精品视频| 变态另类丨国产精品| 97久久亚洲| 日韩午夜电影av| 亚洲天堂av一区二区三区| 国产精品字幕| 色噜噜狠狠成人网p站| 免费看一级大黄情大片| 爱情岛亚洲播放路线| 一区二区三区四区在线播放 | 做爰无遮挡三级| 亚洲影视综合| 欧美尤物巨大精品爽| 日本五十熟hd丰满| 亚洲高清网站| 韩国三级电影久久久久久| 久久亚洲国产成人精品性色| 欧美.www| 久久99精品久久久久久青青91 | 97国产精品| 一道本无吗dⅴd在线播放一区| 亚洲精品理论片| 青青草久久爱| 亚洲人成电影网站色www| a级在线观看视频| 亚洲香蕉视频| 亚洲欧美日韩天堂| 1024在线看片| 国产精品99一区二区三区| 俺也去精品视频在线观看| 四虎地址8848| 中文字幕免费一区二区| 欧美风情在线观看| 日韩 欧美 综合| 亚洲一卡久久| 国产精品美女免费视频| ,一级淫片a看免费| 国产精品亚洲一区二区三区在线 | 午夜精品三级视频福利| 国产成人精品av久久| 99精品国产99久久久久久福利| 欧美一区二区大胆人体摄影专业网站| 免费视频网站在线观看入口| 九九久久精品视频| 不卡一卡2卡3卡4卡精品在| 污视频软件在线观看| 久久久99免费| 国产系列第一页| 国产www视频在线观看| 狠狠色香婷婷久久亚洲精品| 蜜臀av免费观看| 视频在线亚洲| 亚洲男人的天堂在线| av资源在线免费观看| 国内一区二区三区| 国产成人一区二| 99热这里只有精品3| 91丨国产丨九色丨pron| 一区二区三区四区五区视频| 日本大片在线播放| 色综合久久综合网欧美综合网| av中文字幕网址| 丝袜连裤袜欧美激情日韩| 日日狠狠久久偷偷四色综合免费 | 92看片淫黄大片看国产片| 日本精品久久久久| 国产精品麻豆一区二区| 欧美精品久久久久久久自慰| 成人黄页网站视频| 亚洲国产精品久久久久| 貂蝉被到爽流白浆在线观看| 日韩天天综合| 91最新国产视频| a视频网址在线观看| 午夜私人影院久久久久| 911福利视频| 一道在线中文一区二区三区| 欧美激情奇米色| 国产又爽又黄又嫩又猛又粗| 久久综合九色综合欧美亚洲| 992tv快乐视频| 国产成人免费精品| 日韩精品视频在线| 免费看一级一片| 久久se这里有精品| 日本欧美精品久久久| 操人在线观看| 日韩欧美黄色影院| 亚洲欧美精品aaaaaa片| 日本欧美在线看| 欧美日韩国产高清视频| av资源中文在线天堂| 欧美一级二级三级蜜桃| 四虎地址8848| 老司机精品视频导航| 欧洲亚洲一区二区| 9i看片成人免费高清| 亚洲精品美女在线观看播放| 免费人成在线观看| 国产精品一区二区久久精品爱涩 | 99中文字幕一区| 91久久香蕉国产日韩欧美9色| 亚洲色偷偷色噜噜狠狠99网| 欧美特黄a级高清免费大片a级| 成人国产在线激情| 18免费在线视频| 色88888久久久久久影院野外| 中出视频在线观看| 亚洲一区观看| 欧美不卡在线一区二区三区| 中国字幕a在线看韩国电影| 亚洲精品福利视频| 久草视频在线观| 久久嫩草精品久久久久| 日韩免费毛片视频| av中文字幕一区二区| 国产精品海角社区在线观看| 国产区视频在线| 91国偷自产一区二区开放时间 | 91肉色超薄丝袜脚交一区二区| 中文字幕二三区不卡| 中文字幕av专区| 天天久久综合| 亚洲自拍欧美色图| 国产乱码在线| 日韩精品中文字幕在线| 亚洲精品成人在线视频| 国产欧美日韩不卡| 99九九99九九九99九他书对| 欧美69视频| 国产视频一区二区三区四区| 亚洲欧美一区二区三区| 夜夜嗨av色综合久久久综合网| 最近中文字幕在线观看| 最新欧美精品一区二区三区| 国模大尺度视频| 国产日韩欧美一区二区三区在线观看| 久久久久久一区| av久久网站| 久久久久国产视频| 精品亚洲成a人片在线观看| 欧美系列亚洲系列| 真实国产乱子伦对白在线| a级高清视频欧美日韩| 国产aaa一级片| 欧美mv日韩| 国产精品一区二区三区四区五区| 一区一区三区| 成年人精品视频| 性xxxx搡xxxxx搡欧美| 欧美色视频在线| 九九九国产视频| 国产欧美va欧美不卡在线| 日本55丰满熟妇厨房伦| 翔田千里一区二区| 国产精品12p| 婷婷综合一区| 亚洲一区二区免费| 伊人久久综合一区二区| 欧美大奶子在线| 日韩a级作爱片一二三区免费观看| 欧美日韩久久一区| 国产精品一区二区6| 亚洲青青青在线视频| 亚洲专区区免费| 国产美女一区二区| 少妇高清精品毛片在线视频 | 亚洲网站在线免费观看| 亚洲第一主播视频| 国产又黄又粗又猛又爽的| 91香蕉视频mp4| 免费不卡av网站| 麻豆视频观看网址久久| 免费看国产曰批40分钟| 亚洲色图88| 亚洲 国产 日韩 综合一区| 成人动态视频| 91日本在线观看| 91国内外精品自在线播放| 97超级碰碰碰久久久| 永久免费网站在线| 精品国偷自产在线| 成人福利在线| 亚洲精品资源美女情侣酒店| 懂色av成人一区二区三区| 91精品蜜臀在线一区尤物| 波多野结衣绝顶大高潮| 欧美日韩中文字幕在线| 精品一区免费观看| 亚洲精品综合在线| 色老板免费视频| 中文字幕色av一区二区三区| 国产传媒国产传媒| 久久午夜电影网| 国产精品无码在线| 成人av电影在线网| 激情小说欧美色图| 国产成人免费在线观看不卡| 亚洲一二区在线观看| 欧美aaaaa成人免费观看视频| 国产成人久久777777| 午夜在线视频观看日韩17c| 99精品在线免费视频| 亚洲日韩成人| 欧美,日韩,国产在线| 亚洲午夜在线| 国产精品va在线观看无码| 国产精品www.| 91免费黄视频| 99国产精品| 大肉大捧一进一出好爽视频| 国产一区二区你懂的| 18禁免费无码无遮挡不卡网站| 亚洲精品1234| 91传媒久久久| 日本美女视频一区二区| 国产又大又黄又猛| 麻豆91小视频| 四虎成人在线播放| 国产精品99久久久久久似苏梦涵| 老女人性生活视频| 成人av电影在线| 欧美 日本 国产| 国产精品日产欧美久久久久| 国产传媒免费在线观看| 亚洲精品乱码久久久久久日本蜜臀| 男人的天堂久久久| 黄色一区二区三区| 狠狠人妻久久久久久综合| 欧美亚洲综合色| 国产一区二区小视频| 日韩精品中文字幕一区| 日本人妻丰满熟妇久久久久久| 亚洲第一区在线| 黑人与亚洲人色ⅹvideos| 在线亚洲欧美视频| 91精品久久久久久粉嫩| 98精品国产自产在线观看| 亚洲播播91| 91在线观看欧美日韩| 久久99精品国产自在现线| 任我爽在线视频精品一| 久久久久久久久久久9不雅视频| 屁屁影院ccyy国产第一页| 蜜乳av另类精品一区二区| 免费网站在线观看黄| 成人av电影在线| 卡一卡二卡三在线观看| 亚洲日穴在线视频| 欧美另类一区二区| 欧美久久一二区| 免费看黄色一级视频| 国产亚洲视频在线| 欧美24videosex性欧美| 国产精品成人av性教育| 香蕉大人久久国产成人av| 久久综合九九| 88av在线播放| 精品人妻伦九区久久aaa片| 91女神在线视频| 艳妇荡乳欲伦69影片| 偷拍亚洲欧洲综合| 91亚洲一区二区| 欧美高清不卡| 国产裸体舞一区二区三区| 国精产品一区一区三区mba视频| 中文字幕精品视频在线| 中文字幕在线视频一区| 九九九在线观看| 欧美一区二区在线播放| 你懂的视频在线播放| 免费av一区二区| 另类中文字幕国产精品| 国产伦视频一区二区三区| 日韩精品诱惑一区?区三区| 999在线观看视频| 久久99精品久久久| 欧美老熟妇乱大交xxxxx| 亚洲视频香蕉人妖| 亚洲男人天堂网址| 日韩精品999| 黑人精品视频| 91在线视频导航| 成人免费在线观看av| 亚洲午夜精品久久久久久人妖| 国产精品一区二区久激情瑜伽| 日本人亚洲人jjzzjjz| 日韩欧美精品在线观看| 天天射天天操天天干| 欧美国产日韩xxxxx| 国产一区二区三区国产精品| 五月天亚洲综合| 日韩专区欧美专区| 国产在线观看无码免费视频| 一区二区三区在线视频播放 | 欧美日韩午夜剧场| 亚洲精品.www| 九九久久综合网站| 精品999日本久久久影院| 人人妻人人澡人人爽精品欧美一区| 久久在线精品| 自拍偷拍亚洲天堂| 懂色av影视一区二区三区| 特黄aaaaaaaaa真人毛片| 久久久久久久网站| www.豆豆成人网.com| 蜜臀精品一区二区| www.66久久| 国产成人精品网| 亚洲女人天堂视频| 3d欧美精品动漫xxxx无尽| 日本免费一区二区三区| 青青草精品视频| 天天舔天天操天天干| 欧美日韩一区二区三区在线看| 成人精品一区二区三区免费| 国产精品亚洲第一区| 久久美女视频| 99九九99九九九99九他书对| 亚洲欧美偷拍三级| 亚洲精品综合网| 7777kkkk成人观看| 国产一区二区三区四区| 日韩肉感妇bbwbbwbbw| 自拍偷在线精品自拍偷无码专区| 国产精品高潮呻吟av| 欧美成人免费在线观看| 风间由美性色一区二区三区四区| 僵尸世界大战2 在线播放| www激情久久| 日韩免费av网站| www.亚洲成人| 88久久精品| 黄色片一级视频| 国产精品你懂的在线| 亚洲av无码专区在线| 欧洲日本亚洲国产区| 手机在线电影一区| 亚洲精品乱码久久久久久蜜桃欧美| 欧美日韩国产专区| 999在线视频| 不卡一区二区三区视频| 蜜乳av另类精品一区二区| 欧美肥妇bbwbbw| 亚洲成人精品视频在线观看| 日韩免费va| 玖玖精品在线视频| 91色porny| 99久久99久久久精品棕色圆| 91精品国产色综合久久不卡98口| 北条麻妃国产九九九精品小说| 久久无码专区国产精品s| 日韩欧美中文字幕在线观看 | 26uuu另类亚洲欧美日本一| 精品国产一区探花在线观看 | 最好看的2019年中文视频| 免费一级欧美在线大片| 国产综合免费视频| 一区二区三区在线观看动漫| 国产一级片在线播放| www 成人av com| 免费观看30秒视频久久|