精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

欧美sm一区| 小泽玛利亚一区| 久久久久免费精品国产| 一区二区三区在线视频免费 | 欧美特级特黄aaaaaa在线看| 欧美日一区二区在线观看 | 欧美成人黄色小视频| 天堂va欧美va亚洲va老司机| 一区一区三区| 亚洲人成精品久久久久久 | 日本少妇一区二区三区| 国产99在线观看| 国产日本一区二区| 91精品国产一区二区三区动漫| 亚洲国产精一区二区三区性色| 国内成人自拍| 精品国产3级a| 中文字幕亚洲欧洲| 精品国产第一福利网站| 一区二区三区在线不卡| 亚洲激情一区二区| 欧美色视频免费| 国产成人午夜精品5599| 国产精品日韩一区| 香蕉免费毛片视频| 91成人精品| 在线播放国产一区中文字幕剧情欧美 | 欧美人妻一区二区三区| 久久久精品国产**网站| 欧美日韩在线三区| 日本中文字幕片| 爱情岛亚洲播放路线| 亚洲色图视频网站| 小说区图片区图片区另类灬| 五月天婷婷激情网| 国产成人精品亚洲午夜麻豆| 国产在线精品自拍| 久久久999久久久| 久久最新视频| 欧美亚洲成人免费| xxxx 国产| 国产一区二区中文| 欧美日韩第一视频| 国产精品免费区二区三区观看| 国产精品96久久久久久| 国产三级在线观看完整版| 噜噜噜天天躁狠狠躁夜夜精品| 欧美日韩国产综合视频在线观看| 91免费视频网站在线观看| 91制片在线观看| 亚洲午夜一区二区三区| 性做久久久久久久免费看| 五月天婷婷综合| 精品少妇人妻av一区二区| 成人高清免费在线播放| 久久久久国产一区二区三区四区| 九色91国产| 香蕉视频黄色片| 91视频一区二区三区| 欧美日韩一区二区在线观看| 日本在线观看不卡| 精品无人乱码| 国产日产精品1区| 午夜精品区一区二区三| 91精品国产91久久久久游泳池 | 日本黄色特级片| 亚欧日韩另类中文欧美| 亚洲无线码在线一区观看| 成人免费无遮挡无码黄漫视频| 国产欧美一区二区精品久久久| 亚洲欧美资源在线| 久久久久久成人网| 999视频精品| 欧美高清在线观看| 成年人免费看毛片| 性色一区二区| 国产在线观看不卡| 国产福利第一视频| 99久久精品国产导航| 欧美黄色直播| 黄色网页在线免费看| 一级精品视频在线观看宜春院| 福利视频一区二区三区四区| 亚洲第一av| 欧美日产国产精品| 中文字幕在线视频播放| 禁果av一区二区三区| 久久亚洲电影天堂| 日韩美女视频网站| 欧美aⅴ一区二区三区视频| 成人激情黄色网| 天天射天天色天天干| 96av麻豆蜜桃一区二区| 伊人久久av导航| 99热成人精品热久久66| 国产91色在线|| 能看的毛片网站| 欧美大片网站| 精品国产一区二区三区不卡 | 日韩第二十一页| 黑人操日本美女| 日韩精品一区二区三区av| 欧美日韩免费高清一区色橹橹| 国产成人强伦免费视频网站| 欧美特黄一级片| 91精品国产闺蜜国产在线闺蜜| 日韩一区网站| 亚洲精品中文字幕有码专区| 色偷偷男人天堂| 亚洲激情社区| 成人中心免费视频| 你懂的视频在线观看| 亚洲视频一区二区在线| 久久精品国产99国产精品| 伊人色**天天综合婷婷| 欧美精品一区二区三区蜜桃 | 国产精品一区二区91| 麻豆av一区二区| www在线视频| 色婷婷久久久综合中文字幕| 午夜精品久久久久久久白皮肤 | 超碰caoprom| 色综合久久网| 日韩av黄色在线观看| 亚洲精品久久久久久无码色欲四季 | 亚洲图片欧洲图片日韩av| 97在线视频免费观看完整版| 51久久夜色精品国产麻豆| 久久午夜福利电影| 国产深夜精品| 国产精品免费在线播放| a毛片在线播放| 欧美蜜桃一区二区三区| 亚洲av成人无码久久精品 | 亚洲高清免费观看| 日韩精品在线播放视频| 日韩电影二区| 国产精品久久久久久久久久 | 91丝袜呻吟高潮美腿白嫩在线观看| 亚洲国产精品女人| 亚洲欧美专区| 日韩一中文字幕| 中文字幕黄色av| 中文文精品字幕一区二区| 欧美在线观看视频网站| 国产精品一区二区三区av麻 | 国产一区二区高清在线| www亚洲精品| 一二三四区视频| 中文字幕在线一区二区三区| 日本888xxxx| 日本不卡电影| 成人国产精品一区二区| 国产人成网在线播放va免费| 欧美男人的天堂一二区| 成人在线观看高清| 国产精品一区二区在线观看不卡| 欧美性受黑人性爽| 日本一区二区乱| 久久久国产一区二区| 国产一区二区三区三区在线观看| 国产日本欧美视频| 亚洲卡一卡二卡三| 亚洲午夜一二三区视频| 亚洲一区二区三区免费看| 一区二区三区日| 欧美另类亚洲| 91观看网站| av伦理在线| 亚洲国产精品成人一区二区| 精品91久久久| 久久久久久久电影| 超碰在线公开97| 亚洲综合专区| 国内一区在线| 精品成人av| 久久亚洲电影天堂| 天天干天天草天天射| 色婷婷综合久久久| 国产三级aaa| 国产成人av在线影院| 精品视频免费在线播放| 欧美人妖在线| 成人免费视频网址| mm视频在线视频| 亚洲人成电影网站色xx| 国产精品久久久久久久久毛片| 一区二区三区四区国产精品| 一出一进一爽一粗一大视频| 蜜臀av亚洲一区中文字幕| 欧美在线观看视频免费| 亚洲免费专区| 亚洲综合日韩在线| 日韩精品av| 久久成人亚洲精品| 免费在线视频一级不卡| 欧美一区三区四区| 国产精品100| 中文字幕一区二区三区视频| 无码一区二区精品| 国产在线精品一区二区| 黄色一级视频片| **女人18毛片一区二区| 乱色588欧美| 欧美三级一区| 国产999精品久久久| 182tv在线播放| 伊人久久男人天堂| 天天操天天插天天射| 欧美日韩久久一区二区| 日本午夜视频在线观看| 亚洲色欲色欲www| 日韩免费成人av| 99v久久综合狠狠综合久久| 国产乱叫456| 日韩成人伦理电影在线观看| 91免费黄视频| 欧美jizzhd精品欧美巨大免费| 日本精品一区二区三区高清 久久 日本精品一区二区三区不卡无字幕 | 日韩黄色片在线观看| 婷婷视频在线播放| 综合综合综合综合综合网| 99久久自偷自偷国产精品不卡| 成人看片网站| 欧美亚洲国产精品| 成人三级小说| 不用播放器成人网| 少妇人妻丰满做爰xxx| 免费在线一级片| 激情小视频在线| 亚洲电影在线免费观看| 色婷婷粉嫩av| 国产欧美综合色| 人妻少妇精品视频一区二区三区| 国产高清在线观看免费不卡| 日韩一区二区三区不卡视频| 免费亚洲婷婷| 91高清视频在线免费观看| 五月天婷婷激情网| 亚洲成人免费网站| 午夜免费福利视频| 欧美一区二区久久久| 国产又黄又大又粗的视频| 欧美性做爰猛烈叫床潮| 老熟妇一区二区三区| 欧美视频在线观看免费| 日韩色图在线观看| 天天爽夜夜爽夜夜爽精品视频 | 亚洲女与黑人做爰| 美国黄色片视频| 18欧美亚洲精品| 亚洲精品久久久久久国| 国产精品卡一卡二卡三| 国产又粗又猛又爽又黄的视频四季 | 在线不卡一区二区| 一二三四区视频| 91精品国产综合久久福利软件| 国产精品欧美激情在线| 91精品在线观看入口| 国产女人高潮毛片| 日韩免费一区二区| 狠狠人妻久久久久久综合麻豆| 亚洲精品一区二区三区在线观看| 性生交生活影碟片| 亚洲国产欧美精品| 六十路在线观看| 中文字幕在线看视频国产欧美| 国产69精品久久app免费版| 中文字幕亚洲一区二区三区五十路| freemovies性欧美| 深夜福利一区二区| 超碰在线观看免费版| 色综合色综合久久综合频道88| 啦啦啦中文在线观看日本| 97av视频在线| 成人亚洲综合| 国产99视频精品免费视频36| 日韩精品社区| 亚洲一区高清| 亚洲性图久久| 国产一区视频免费观看| 精品亚洲porn| 国产美女视频免费观看下载软件| 26uuu亚洲| 日本 欧美 国产| 亚洲h在线观看| 五月天中文字幕| 日韩视频免费观看高清完整版 | 亚洲不卡免费视频| 亚洲男人天堂九九视频| 秋霞午夜理伦电影在线观看| 欧美—级a级欧美特级ar全黄| 依依综合在线| 亚洲iv一区二区三区| 日韩精品欧美大片| 日韩中文在线字幕| 亚洲一区一卡| 亚洲色图15p| 97碰在线视频| 雨宫琴音一区二区三区| 老太脱裤子让老头玩xxxxx| 日本不卡不码高清免费观看 | 国内久久精品视频| 亚洲一区二区乱码| 亚洲四区在线观看| 男人午夜免费视频| 欧美一级生活片| 久草福利资源在线观看| caopeng在线| 国产视频欧美| 欧美专区在线播放| 97成人超碰| 精品国产日本| 68国产成人综合久久精品| 啊啊啊一区二区| 国产精品一级黄| 黑人と日本人の交わりビデオ| 五月天激情小说综合| 天美传媒免费在线观看| 久久超级碰视频| 无遮挡aaaaa大片免费看| 亚洲女人的天堂| 中文字幕一区2区3区| 日韩精品在线观看一区二区| caopen在线视频| 91精品国产综合久久香蕉922| 五月国产精品| www插插插无码视频网站| 狠狠网亚洲精品| 欧美三级视频网站| 色婷婷综合久色| 天天操天天干天天干| 欧美日韩电影在线观看| 国产精品18| 伊人久久大香线蕉av一区| 免费成人在线视频观看| 久久久久久亚洲精品不卡| 在线国产情侣| 国产精品成人一区二区三区吃奶| 青青草久久爱| 日本在线xxx| www.亚洲激情.com| 国产无遮挡免费视频| 日韩欧美的一区| 四虎影视国产在线视频| 亚洲xxx视频| 欧美女激情福利| 被黑人猛躁10次高潮视频| 亚洲欧美日韩在线播放| 国产又粗又大又黄| 久久久国产精彩视频美女艺术照福利| 欧美高清免费| 91社在线播放| 国产精品一区二区黑丝| 免费在线观看一级片| 日韩久久免费av| 国产盗摄在线视频网站| 精品国产_亚洲人成在线| 99成人免费视频| 草草影院第一页| 欧洲亚洲国产日韩| 欧美激情二区| 俄罗斯精品一区二区| 亚洲激情女人| 午夜时刻免费入口| 欧美高清激情brazzers| 在线免费观看污| 精品无人区一区二区三区| 久久国产精品久久久久久电车 | 久久精品亚洲精品| 亚洲精品午夜| 日韩av一二三四区| 国产精品视频在线看| 国产三级视频在线播放| 高清欧美性猛交xxxx| 久久av资源| 欧美性受xxxx黒人xyx性爽| 亚洲国产另类av| 免费国产在线视频| 国产欧美一区二区三区四区| 欧美日韩调教| wwwwww日本| 91精品婷婷国产综合久久| av福利导福航大全在线| 日韩欧美视频第二区| 国产精品综合在线视频| 亚洲 欧美 日韩 综合| 在线性视频日韩欧美| 亚洲大奶少妇| 91久久在线播放| 亚洲男人第一av| 精品污污网站免费看| 免费观看久久久久| 国产精品乱码| 蜜桃一区二区三区在线观看| 久久免费播放视频| 亚洲天堂网站在线观看视频| 日韩精品视频中文字幕| 99久久国产宗和精品1上映| 亚洲四区在线观看|