主頁 > 企業開發 > 最易懂的Prometheus告警原理詳解

最易懂的Prometheus告警原理詳解

2023-02-25 07:54:20 企業開發

通俗易懂的一篇文章,主要介紹了 Prometheus 什么時候告警,什么時候不會告警,同時介紹了 Prometheus 告警原理,

 

警報是監控系統中必不可少的一塊, 當然了, 也是最難搞的一塊. 我們乍一想, 警報似乎很簡單一件事:

 

假如發生了例外情況, 發送或郵件/訊息通知給某人或某頻道,

 

一把梭搞起來之后,就不免有一些小麻煩:

 

  • 這個啊…一天中總有那么幾次波動,也難修難查了,算了算了不看了;

     

  • 警報太多了,實在看不過來,屏蔽/歸檔/放生吧…

     

  • 有毒吧,這個閾值也太低了;

     

  • 臥槽,這些警報啥意思啊,發給我干嘛啊?

     

  • 臥槽臥槽臥槽,怎么一下子幾十百來條警報, 哦…原來網路出問題了全崩了,

 

玩笑歸玩笑,但至少我們能看出,警報不是一個簡單的計算+通知系統,只是,”做好警報”這件事本身是個綜合問題,代碼能解決的也只是其中的一小部分,更多的事情要在組織、人事和管理上去做,

 

從 for 引數開始

 

我們首先需要一些背景知識:Prometheus 是如何計算并產生警報的?

 

看一條簡單的警報規則:

alert: KubeAPILatencyHigh
  annotations:
    message: The API server has a 99th percentile latency of {{ $value }} seconds
      for {{ $labels.verb }} {{ $labels.resource }}.
  expr: |
    cluster_quantile:apiserver_request_latencies:histogram_quantile{job="apiserver",quantile="0.99",subresource!="log"} > 4
  for: 10m
  labels:
    severity: critical

這條警報的大致含義是,假如 kube-apiserver 的 P99 回應時間大于 4 秒,并持續 10 分鐘以上,就產生報警,

 

首先要注意的是由 for 指定的 Pending Duration,這個引數主要用于降噪,很多類似回應時間這樣的指標都是有抖動的,通過指定 Pending Duration,我們可以 過濾掉這些瞬時抖動,讓 on-call 人員能夠把注意力放在真正有持續影響的問題上,

 

那么顯然,下面這樣的狀況是不會觸發這條警報規則的,因為雖然指標已經達到了警報閾值,但持續時間并不夠長:

 

圖片

 

但偶爾我們也會碰到更奇怪的事情,

 

問題 1 為什么不報警?

 

圖片

 

類似上面這樣持續超出閾值的場景,為什么有時候會不報警呢?

 

問題 2 為什么報警?

 

圖片

 

類似上面這樣并未持續超出閾值的場景,為什么有時又會報警呢?

 

采樣間隔

 

這其實都源自于 Prometheus 的資料存盤方式與計算方式,

 

首先,Prometheus 按照配置的抓取間隔(scrape_interval)定時抓取指標資料,因此存盤的是形如 (timestamp, value) 這樣的采樣點,

 

對于警報, Prometheus 會按固定的時間間隔重復計算每條警報規則,因此警報規則計算得到的只是稀疏的采樣點,而警報持續時間是否大于 for 指定的 Pending Duration 則是由這些稀疏的采樣點決定的,

 

而在 Grafana 渲染圖表時,Grafana 發送給 Prometheus 的是一個 Range Query,其執行機制是從時間區間的起始點開始,每隔一定的時間點(由 Range Query 的 step 請求引數決定) 進行一次計算采樣,

 

這些結合在一起,就會導致警報規則計算時“看到的內容”和我們在 Grafana 圖表上觀察到的內容不一致,比如下面這張示意圖:

 

圖片

 

上面圖中,圓點代表原始采樣點:

 

  • 40s 時,第一次計算,低于閾值,

     

  • 80s 時,第二次計算,高于閾值,進入 Pending 狀態,

     

  • 120s 時,第三次計算,仍然高于閾值,90s 處的原始采樣點雖然低于閾值,但是警報規則計算時并沒有”看到它“,

     

  • 160s 時,第四次計算,高于閾值,Pending 達到 2 分鐘,進入 firing 狀態 持續高于閾值,

     

  • 直到 360s 時,計算得到低于閾值,警報消除,

 

由于采樣是稀疏的,部分采樣點會出現被跳過的狀況,而當 Grafana 渲染圖表時,取決于 Range Query 中采樣點的分布,圖表則有可能捕捉到 被警報規則忽略掉的”低谷“(圖三)或者也可能無法捕捉到警報規則碰到的”低谷“(圖二),如此這般,我們就被”圖表“給蒙騙過去,質疑起警報來了,

 

如何應對

 

首先嘛, Prometheus 作為一個指標系統天生就不是精確的——由于指標本身就是稀疏采樣的,事實上所有的圖表和警報都是”估算”,我們也就不必 太糾結于圖表和警報的對應性,能夠幫助我們發現問題解決問題就是一個好監控系統,當然,有時候我們也得證明這個警報確實沒問題,那可以看一眼 ALERTS 指標,ALERTS 是 Prometheus 在警報計算程序中維護的內建指標,它記錄每個警報從 Pending 到 Firing 的整個歷史程序,拉出來一看也就清楚了,

 

但有時候 ALERTS 的說服力可能還不夠,因為它本身并沒有記錄每次計算出來的值到底是啥,而在我們回頭去考證警報時,又無法選取出和警報計算程序中一模一樣的計算時間點, 因此也就無法還原警報計算時看到的計算值究竟是啥,這時候終極解決方案就是把警報所要計算的指標定義成一條 Recording Rule,計算出一個新指標來記錄計算值,然后針對這個 新指標做閾值報警,kube-prometheus 的警報規則中就大量采用了這種技術,

 

到此為止了嗎?

 

Prometheus 警報不僅包含 Prometheus 本身,還包含用于警報治理的 Alertmanager,我們可以看一看上面那張指標計算示意圖的全圖:

 

圖片

 

在警報產生后,還要經過 Alertmanager 的分組、抑制處理、靜默處理、去重處理和降噪處理最后再發送給接收者,而這個程序也有大量的因素可能會導致警報產生了卻最終 沒有進行通知,

 

為什么要 Alertmanager?

 

我們先介紹一點背景知識,Prometheus 生態中的警報是在 Prometheus Server 中計算警報規則(Alert Rule)并產生的,而所謂計算警報規則,其實就是周期性地執行一段 PromQL,得到的查詢結果就是警報,比如:

node_load5 > 20

 

這個 PromQL 會查出所有”在最近一次采樣中,5分鐘平均 Load 大于 20”的時間序列,這些序列帶上它們的標簽就被轉化為警報,

 

只是,當 Prometheus Server 計算出一些警報后,它自己并沒有能力將這些警報通知出去,只能將警報推給 Alertmanager,由 Alertmanager 進行發送,

 

這個切分,一方面是出于單一職責的考慮,讓 Prometheus “do one thing and do it well”, 另一方面則是因為警報發送確實不是一件”簡單”的事,需要一個專門的系統來做好它,可以這么說,Alertmanager 的目標不是簡單地”發出警報”,而是”發出高質量的警報”,它提供的高級功能包括但不限于:

 

Go Template 渲染警報內容;

 

  • 管理警報的重復提醒時機與消除后消除通知的發送;

     

  • 根據標簽定義警報路由,實作警報的優先級、接收人劃分,并針對不同的優先級和接收人定制不同的發送策略;

     

  • 將同型別警報打包成一條通知發送出去,降低警報通知的頻率;

     

  • 支持靜默規則: 用戶可以定義一條靜默規則,在一段時間內停止發送部分特定的警報,比如已經確認是搜索集群問題,在修復搜索集群時,先靜默掉搜索集群相關警報;

     

  • 支持”抑制”規則(Inhibition Rule): 用戶可以定義一條”抑制”規則,規定在某種警報發生時,不發送另一種警報,比如在”A 機房網路故障”這條警報發生時,不發送所有”A 機房中的警報”;

 

假如你很忙,那么讀到這里就完全 OK 了,反正這類文章最大的作用就是讓我們”知道有 X 這回事,大概了解有啥特性,當有需求匹配時,能想到試試看 X 合不合適“,其中 X = Alertmanager,當然,假如你是個好奇寶寶,那么還可以看看下面的決議,

 

Alertmanager 內部架構

 

先看官方檔案中的架構圖:

 

圖片

 

  • 從左上開始,Prometheus 發送的警報到 Alertmanager;

     

  • 警報會被存盤到 AlertProvider 中,Alertmanager 的內置實作就是包了一個 map,也就是存放在本機記憶體中,這里可以很容易地擴展其它 Provider;

     

  • Dispatcher 是一個單獨的 goroutine,它會不斷到 AlertProvider 拉新的警報,并且根據 YAML 配置的 Routing Tree 將警報路由到一個分組中;

     

  • 分組會定時進行 flush (間隔為配置引數中的 group_interval), flush 后這組警報會走一個 Notification Pipeline 鏈式處理;

     

  • Notification Pipeline 為這組警報確定發送目標,并執行抑制邏輯,靜默邏輯,去重邏輯,發送與重試邏輯,實作警報的最終投遞;

 

下面就分開講一講核心的兩塊:

 

  • Dispatcher 中的 Routing Tree 的實作與設計意圖

     

  • Notification Pipeline 的實作與設計意圖

 

Routing Tree

 

Routing Tree 的是一顆多叉樹,節點的資料結構定義如下:


// 節點包含警報的路由邏輯
type Route struct {
    // 父節點
    parent *Route
    // 節點的配置,下文詳解
    RouteOpts RouteOpts
    // Matchers 是一組匹配規則,用于判斷 Alert 與當前節點是否匹配
    Matchers types.Matchers
    // 假如為 true, 那么 Alert 在匹配到一個節點后,還會繼續往下匹配
    Continue bool
    // 子節點
    Routes []*Route
}

 

具體的處理代碼很簡單,深度優先搜索:警報從 root 開始匹配(root 默認匹配所有警報),然后根據節點中定義的 Matchers 檢測警報與節點是否匹配,匹配則繼續往下搜索,默認情況下第一個”最深”的 match (也就是 DFS 回溯之前的最后一個節點)會被回傳,特殊情況就是節點配置了 Continue=true,這時假如這個節點匹配上了,那不會立即回傳,而是繼續搜索,用于支持警報發送給多方這種場景(比如”抄送”)

 

深度優先搜索

func (r *Route) Match(lset model.LabelSet) []*Route {
    if !r.Matchers.Match(lset) {
    return nil
    }

    var all []*Route
    for _, cr := range r.Routes {
        // 遞回呼叫子節點的 Match 方法
        matches := cr.Match(lset)

        all = append(all, matches...)

        if matches != nil && !cr.Continue {
          break
        }
    }
    // 假如沒有任何節點匹配上,那就匹配根節點
    if len(all) ==0 {
        all = append(all, r)
    }
    return all
}

 

為什么要設計一個復雜的 Routing Tree 邏輯呢?我們看看 Prometheus 官方的配置例子:為了簡化撰寫,Alertmanager 的設計是根節點的所有引數都會被子節點繼承(除非子節點重寫了這個引數)


route:
  # 根節點的警報會發送給默認的接收組
  # 該節點中的警報會按’cluster’和’alertname’做 Group,每個分組中最多每5分鐘發送一條警報,同樣的警報最多4小時發送一次
  receiver:’default-receiver’
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  group_by: [cluster, alertname]
  # 沒有匹配到子節點的警報,會默認匹配到根節點上
  # 接下來是子節點的配置:
  routes:
    # 所有 service 欄位為 mysql 或 cassandra 的警報,會發送到’database-pager’這個接收組
    # 由于繼承邏輯,這個節點中的警報仍然是按’cluster’和’alertname’做 Group 的
  - receiver:’database-pager’
    group_wait: 10s
    match_re:
    service: mysql|cassandra
    # 所有 team 欄位為 fronted 的警報,會發送到’frontend-pager’這個接收組
    # 很重要的一點是,這個組中的警報是按’product’和’environment’做分組的,因為’frontend’面向用戶,更關心哪個’產品’的什么’環境’出問題了
  - receiver:’frontend-pager’
    group_by: [product, environment]
    match:
    team: frontend

 

總結一下,Routing Tree 的設計意圖是讓用戶能夠非常自由地給警報歸類,然后根據歸類后的類別來配置要發送給誰以及怎么發送:

 

發送給誰?上面已經做了很好的示例,’資料庫警報’和’前端警報’都有特定的接收組,都沒有匹配上那么就是’默認警報’, 發送給默認接收組

 

怎么發送?對于一類警報,有個多個欄位來配置發送行為:

 

  • group_by

 

決定了警報怎么分組,每個 group 只會定時產生一次通知,這就達到了降噪的效果,而不同的警報類別分組方式顯然是不一樣的,舉個例子:配置中的 ‘資料庫警報’ 是按 ‘集群’ 和 ‘規則名’ 分組的,這表明對于資料庫警報,我們關心的是“哪個集群的哪個規則出問題了”,比如一個時間段內,’華東’集群產生了10條 ‘API回應時間過長’ 警報,這些警報就會聚合在一個通知里發出來;配置中的 ‘前端警報’ 是按 ‘產品’ 和 ‘環境’ 分組的, 這表明對于前端警報,我們關心的是“哪個產品的哪個環境出問題了”,

 

  • group_interval 和 group_wait

 

控制分組的細節,不細談,其中 group_interval 控制了這個分組最快多久執行一次 Notification Pipeline,

 

  • repeat_interval

 

假如一個相同的警報一直 FIRING,Alertmanager 并不會一直發送警報,而會等待一段時間,這個等待時間就是 repeat_interval,顯然,不同型別警報的發送頻率也是不一樣的,

 

group_interval 和 repeat_interval 的區別會在下文中詳述,

 

Notification Pipeline

 

由 Routing Tree 分組后的警報會觸發 Notification Pipeline:

 

當一個 AlertGroup 新建后,它會等待一段時間(group_wait 引數),再觸發第一次 Notification Pipeline 假如這個 AlertGroup 持續存在,那么之后每隔一段時間(group_interval 引數),都會觸發一次 Notification Pipeline 每次觸發 Notification Pipeline,AlertGroup 都會將組內所有的 Alert 作為一個串列傳進 Pipeline, Notification Pipeline 本身是一個按照責任鏈模式設計的介面,MultiStage 這個實作會鏈式執行所有的 Stage:

// A Stage processes alerts under the constraints of the given context.
type Stage interface {
    Exec(ctx context.Context, l log.Logger, alerts …*types.Alert) (context.Context, []*types.Alert, error)
}

// A MultiStage executes a series of stages sequencially.
type MultiStage []Stage
// Exec implements the Stage interface.
func (ms MultiStage) Exec(ctx context.Context, l log.Logger, alerts …*types.Alert) (context.Context, []*types.Alert, error) {
    var err error
    for _, s := range ms {
        if len(alerts) ==0{
            return ctx, nil, nil
        }

        ctx, alerts, err = s.Exec(ctx, l, alerts…)
        if err != nil {
            return ctx, nil, err
        }
    }
    return ctx, alerts, nil
}

 

MultiStage 里塞的就是開頭架構圖里畫的 InhibitStage、SilenceStage…這么一條鏈式處理的流程,這里要提一下,官方的架構圖畫錯了,RoutingStage 其實處在整個 Pipeline 的首位,不過這個順序并不影響邏輯,要重點說的是DedupStage和NotifySetStage它倆協同負責去重作業,具體做法是:

 

  • NotifySetStage 會為發送成功的警報記錄一條發送通知,key 是’接收組名字’+’GroupKey 的 key 值’,value 是當前 Stage 收到的 []Alert (這個串列和最開始進入 Notification Pipeline 的警報串列有可能是不同的,因為其中有些 Alert 可能在前置 Stage 中已經被過濾掉了)

     

  • DedupStage 中會以’接收組名字’+’GroupKey 的 key 值’為 key 查詢通知記錄,假如:

 

查詢無結果,那么這條通知沒發過,為這組警報發送一條通知;

 

查詢有結果,那么查詢得到已經發送過的一組警報 S,判斷當前的這組警報 A 是否為 S 的子集:

 

假如 A 是 S 的子集,那么表明 A 和 S 重復,這時候要根據 repeat_interval 來決定是否再次發送:

 

距離 S 的發送時間已經過去了足夠久(repeat_interval),那么我們要再發送一遍;

 

距離 S 的發送時間還沒有達到 repeat_interval,那么為了降低警報頻率,觸發去重邏輯,這次我們就不發了;

 

假如 A 不是 S 的子集,那么 A 和 S 不重復,需要再發送一次;上面的表述可能有些抽象,最后表現出來的結果是:

 

  • 假如一個 AlertGroup 里的警報一直發生變化,那么雖然每次都是新警報,不會被去重,但是由于 group_interval (假設是5分鐘)存在,這個 AlertGroup 最多 5 分鐘觸發一次 Notification Pipeline,因此最多也只會 5 分鐘發送一條通知;

 

  • 假如一個 AlertGroup 里的警報一直不變化,就是那么幾條一直 FIRING 著,那么雖然每個 group_interval 都會觸發 Notification Pipeline,但是由于 repeate_interval(假設是1小時)存在,因此最多也只會每 1 小時為這個重復的警報發送一條通知;再說一下 Silence 和 Inhibit,兩者都是基于用戶主動定義的規則的:

 

  • Silence Rule:靜默規則用來關閉掉部分警報的通知,比如某個性能問題已經修復了,但需要排期上線,那么在上線前就可以把對應的警報靜默掉來減少噪音;

 

  • Inhibit Rule:抑制規則用于在某類警報發生時,抑制掉另一類警報,比如某個機房宕機了,那么會影響所有上層服務,產生級聯的警報洪流,反而會掩蓋掉根本原因,這時候抑制規則就有用了;因此 Notification Pipeline 的設計意圖就很明確了:通過一系列邏輯(如抑制、靜默、去重)來獲得更高的警報質量,由于警報質量的維度很多(剔除重復、類似的警報,靜默暫時無用的警報,抑制級聯警報),因此 Notification Pipeline 設計成了責任鏈模式,以便于隨時添加新的環節來優化警報質量,

 

結語

 

Alertmanager 整體的設計意圖就是奔著治理警報(通知)去的,首先它用 Routing Tree 來幫助用戶定義警報的歸類與發送邏輯,然后再用 Notification Pipeline 來做抑制、靜默、去重以提升警報質量,這些功能雖然不能解決”警報”這件事中所有令人頭疼的問題,但確實為我們著手去解決”警報質量”相關問題提供了趁手的工具,

 

作者丨alei

來源丨網址:

https://aleiwu.com/post/alertmanager/  

https://aleiwu.com/post/prometheus-alert-why/

本文來自博客園,作者:古道輕風,轉載請注明原文鏈接:https://www.cnblogs.com/88223100/p/The-easiest-to-understand-Prometheus-alarm-principle.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/544990.html

標籤:其他

上一篇:最易懂的Prometheus告警原理詳解

下一篇:理解JS函式之call,apply,bind

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more