package prefetch import ( "bytes" "encoding/json" "fmt" "io" "net" "net/http" "sync" "time" "91porn-server/common/log" "91porn-server/models/v/sourcemod" "91porn-server/models/v/vidmod" ) var exit = make(chan int) var wg sync.WaitGroup var client = &http.Client{ Transport: &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, }).DialContext, MaxIdleConns: 20, MaxIdleConnsPerHost: 20, IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: time.Second, }, Timeout: 30 * time.Second, } const prefetchSubmitUrl = "https://prefetch.csrrz.com/master/submit" func StartSubmitPrefetch() { wg.Add(1) go prefetchLoop() } func StopSubmitPrefetch() { close(exit) wg.Wait() } func prefetchLoop() { log.Info("cdn预热提交协程启动....") ticker := time.NewTicker(time.Hour * 12) temp := make(chan int) time.AfterFunc(time.Minute*5, func() { temp <- 1 }) for { select { case <-exit: goto exit case <-ticker.C: execute() case <-temp: execute() } } exit: log.Info("cdn预热提交协程退出....") ticker.Stop() close(temp) wg.Done() } func execute() { videoCdn, imgCdn := sourcemod.GetVideoAndImgCdn() if len(videoCdn) == 0 || len(imgCdn) == 0 { log.Error("视频或者图片cdn为空,不执行推送") return } page, pageSize := int64(1), int64(1000) for { data, err := vidmod.GetManyPrefetchVideos(page, pageSize) if err != nil { log.Error("查询预热视频出错", log.Any("page", page), log.Any("pageSize", pageSize), log.E(err)) return } fmt.Println("page:", page) page++ dataLen := len(data) submitData := &SubmitPrefetch{ M3u8List: make([]string, dataLen), VideoCdnDomains: videoCdn, ImageList: make([]string, 0), ImgCdnDomains: imgCdn, } for i, v := range data { submitData.ImageList = append(submitData.ImageList, v.Images...) submitData.M3u8List[i] = v.M3u8Url } if len(submitData.M3u8List) == 0 && len(submitData.ImageList) == 0 { return } //提交需要缓存的数据到预热中心节点 submit(submitData) //分页查询到最后数据 if int64(len(data)) < pageSize { fmt.Println("======end=========") return } } } func submit(sp *SubmitPrefetch) { data, _ := json.Marshal(sp) url := prefetchSubmitUrl req, err := http.NewRequest("POST", url, bytes.NewBuffer(data)) if err != nil { log.Error("new http post request failed", log.Any("url", url), log.E(err)) return } req.Header.Add("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { log.Error("submit prefetch httpClient do failed", log.Any("url", url), log.E(err)) return } defer resp.Body.Close() buf, err := io.ReadAll(resp.Body) if err != nil { log.Error("submit prefetch read response body failed", log.Any("url", url), log.E(err)) return } var result SubmitPrefetchResp if err = json.Unmarshal(buf, &result); err != nil { log.Error("submit prefetch Unmarshal failed", log.Any("url", url), log.E(err)) return } if result.Code != 200 { log.Error("submit prefetch response failed", log.Any("url", url), log.Any("response's Code", result.Code), log.E(err)) } } type SubmitPrefetch struct { M3u8List []string `json:"m3u8List"` VideoCdnDomains []string `json:"videoCdnDomains"` ImageList []string `json:"imageList"` ImgCdnDomains []string `json:"imgCdnDomains"` } type SubmitPrefetchResp struct { Code int `json:"code"` Msg string `json:"msg"` }