050.集群管理-Prometheus+Grafana監控方案

来源:https://www.cnblogs.com/itzgr/archive/2020/03/25/12567233.html
-Advertisement-
Play Games

一 Prometheus概述 1.1 Prometheus簡介 Prometheus是由SoundCloud公司開發的開源監控系統,是繼Kubernetes之後CNCF第2個畢業的項目,在容器和微服務領域得到了廣泛應用。Prometheus的主要特點如下: 使用指標名稱及鍵值對標識的多維度數據模型。 ...


一 Prometheus概述

1.1 Prometheus簡介

Prometheus是由SoundCloud公司開發的開源監控系統,是繼Kubernetes之後CNCF第2個畢業的項目,在容器和微服務領域得到了廣泛應用。Prometheus的主要特點如下:
  • 使用指標名稱及鍵值對標識的多維度數據模型。
  • 採用靈活的查詢語言PromQL。
  • 不依賴分散式存儲,為自治的單節點服務。
  • 使用HTTP完成對監控數據的拉取。
  • 支持通過網關推送時序數據。
  • 支持多種圖形和Dashboard的展示,例如Grafana。
Prometheus生態系統由各種組件組成,用於功能的擴充。
  • Prometheus Server:負責監控數據採集和時序數據存儲,並提供數據查詢功能。
  • 客戶端SDK:對接Prometheus的開發工具包。
  • Push Gateway:推送數據的網關組件。
  • 第三方Exporter:各種外部指標收集系統,其數據可以被Prometheus採集。
  • AlertManager:告警管理器。
  • 其他輔助支持工具。
Prometheus的核心組件Prometheus Server的主要功能包括:
  • 從Kubernetes Master獲取需要監控的資源或服務信息;
  • 從各種Exporter抓取(Pull)指標數據,然後將指標數據保存在時序資料庫(TSDB)中;
  • 向其他系統提供HTTP API進行查詢;
  • 提供基於PromQL語言的數據查詢;
  • 可以將告警數據推送(Push)給AlertManager,等等。

1.2 Prometheus組件架構圖

clipboard Prometheus 直接從jobs接收或者通過中間的 Pushgateway 網關被動獲取指標數據,在本地存儲所有獲取的指標數據,並對這些數據進行一些規則整理,用來生成一些聚合數據或者報警信息,然後可以通過 Grafana 或者其他工具來可視化這些數據。 其工作流程大致如下:
  1. Prometheus 伺服器定期從配置好的 jobs 或者 exporters 中獲取度量數據;或者接收來自推送網關發送過來的度量數據。
  2. Prometheus 伺服器在本地存儲收集到的度量數據,並對這些數據進行聚合;
  3. 運行已定義好的 alert.rules,記錄新的時間序列或者向告警管理器推送警報。
  4. 告警管理器根據配置文件,對接收到的警報進行處理,並通過email等途徑發出告警。
  5. Grafana等圖形工具獲取到監控數據,並以圖形化的方式進行展示。

1.3 Prometheus監控粒度

Prometheus作為監控系統主要在以下各層面實現監控:
  • 基礎設施層:監控各個主機伺服器資源(包括Kubernetes的Node和非Kubernetes的Node),如CPU,記憶體,網路吞吐和帶寬占用,磁碟I/O和磁碟使用等指標。
  • 中間件層:監控獨立部署於Kubernetes集群之外的中間件,例如:MySQL、Redis、RabbitMQ、ElasticSearch、Nginx等。
  • Kubernetes集群:監控Kubernetes集群本身的關鍵指標
  • Kubernetes集群上部署的應用:監控部署在Kubernetes集群上的應用

二 Prometheus相關概念

2.1 數據模型

Prometheus從根本上將所有數據存儲為時間序列:屬於相同度量標準和同一組標註尺寸的時間戳值流。除了存儲的時間序列之外,Prometheus可能會生成臨時派生時間序列作為查詢的結果。
  • 度量名稱和標簽
每個時間序列都是由度量標準名稱和一組鍵值對(也稱為標簽)組成唯一標識。度量名稱指定被測量的系統的特征(例如:http_requests_total-接收到的HTTP請求的總數)。它可以包含ASCII字母和數字,以及下劃線和冒號。它必須匹配正則表達式[a-zA-Z_:][a-zA-Z0-9_:]*。 標簽啟用Prometheus的維度數據模型:對於相同度量標準名稱,任何給定的標簽組合都標識該度量標準的特定維度實例。查詢語言允許基於這些維度進行篩選和聚合。更改任何標簽值(包括添加或刪除標簽)都會創建新的時間序列。標簽名稱可能包含ASCII字母,數字以及下劃線。他們必須匹配正則表達式[a-zA-Z_][a-zA-Z0-9_]*。以__開始的標簽名稱保留給供內部使用。
  • 樣本
實際的時間序列,每個序列包括:一個 float64 的值和一個毫秒級的時間戳。
  • 格式
給定度量標準名稱和一組標簽,時間序列通常使用以下格式來標識:<metric name>{<label name>=<label value>, ...} 例如,時間序列的度量名稱為api_http_requests_total,標簽method=”POST”和handler=”/messages”,則標記為: api_http_requests_total{method="POST", handler="/messages"}

2.2 度量類型

Prometheus 客戶端庫主要提供Counter、Gauge、Histogram和Summery四種主要的 metric 類型:
  • Counter(計算器)
Counter是一種累加的度量,它的值只能增加或在重新啟動時重置為零。例如,可以使用計數器來表示提供的請求數,已完成的任務或錯誤的數量。不要使用計數器來表達可減少的值。例如,不要使用Counter來計算當前正在運行的進程的數量,而是使用Gauge。
  • Gauge(測量)
Gauge表示單個數值,表達可以任意地上升和下降的度量。Gauge通常用於測量值,例如溫度或當前的記憶體使用情況,但也可以表達上升和下降的“計數”,如正在運行的goroutines的數量。
  • Histogram(直方圖)
Histogram樣本觀測(例如:請求持續時間或響應大小),並將它們計入配置的桶中。它也提供所有觀測值的總和。具有<basename>基本度量標準名稱的histogram的在獲取數據期間會顯示多個時間序列:
    • 觀察桶的累計計數器,暴露為 <basename>_bucket{le=”<upper inclusive bound>”}
    • 所有觀察值的總和,暴露為<basename>_sum
    • 已觀察到的事件的計數,暴露為<basename>_count(等同於<basename>_bucket{le=”+Inf”})
  • Summery:類似於Histogram,Summery樣本觀察(通常是請求持續時間和響應大小)。雖然它也提供觀測總數和所有觀測值的總和,但它計算滑動時間窗內的可配置分位數。在獲取數據期間,具有<basename>基本度量標準名稱的Summery會顯示多個時間序列:
    • 流動φ分位數(0≤φ≤1)的觀察事件,暴露為<basename>{quantile=”<φ>”}
    • 所有觀察值的總和,暴露為<basename>_sum
    • 已經觀察到的事件的計數,暴露為<basename>_count

2.3 工作和實例

在Prometheus中,可以獲取數據的端點被稱為實例(instance),通常對應於一個單一的進程。具有相同目的的實例集合(例如為了可伸縮性或可靠性而複製的進程)稱為作業(job)。

2.4 標簽和時間序列

當Prometheus獲取目標時,它會自動附加一些標簽到所獲取的時間序列中,以識別獲取目標:
  • job:目標所屬的配置作業名稱。
  • instance:<host>:<port>被抓取的目標網址部分。
如果這些標簽中的任何一個已經存在於抓取的數據中,則行為取決於honor_labels配置選項。對於每個實例抓取,Prometheus會在以下時間序列中存儲一個樣本:
  • up{job=”<job-name>”, instance=”<instance-id>”}:1 如果實例健康,即可達;或者0抓取失敗。
  • scrape_duration_seconds{job=”<job-name>”, instance=”<instance-id>”}:抓取的持續時間。
  • scrape_samples_post_metric_relabeling{job=”<job-name>”, instance=”<instance-id>”}:應用度量標準重新標記後剩餘的樣本數。
  • scrape_samples_scraped{job=”<job-name>”, instance=”<instance-id>”}:目標暴露的樣本數量。
up時間序列是實例可用性的監控。

三 Prometheus部署

3.1 創建命名空間

[root@k8smaster01 study]# vi monitor-namespace.yaml
  1 apiVersion: v1
  2 kind: Namespace
  3 metadata:
  4   name: monitoring
  5 
[root@k8smaster01 study]# kubectl create -f monitor-namespace.yaml

3.2 獲取部署文件

[root@k8smaster01 study]# git clone https://github.com/prometheus/prometheus

3.3 創建RBAC

[root@k8smaster01 ~]# cd prometheus/documentation/examples/ [root@k8smaster01 examples]# vi rbac-setup.yml
  1 apiVersion: rbac.authorization.k8s.io/v1beta1
  2 kind: ClusterRole
  3 metadata:
  4   name: prometheus
  5 rules:
  6 - apiGroups: [""]
  7   resources:
  8   - nodes
  9   - nodes/proxy
 10   - services
 11   - endpoints
 12   - pods
 13   verbs: ["get", "list", "watch"]
 14 - apiGroups:
 15   - extensions
 16   resources:
 17   - ingresses
 18   verbs: ["get", "list", "watch"]
 19 - nonResourceURLs: ["/metrics"]
 20   verbs: ["get"]
 21 ---
 22 apiVersion: v1
 23 kind: ServiceAccount
 24 metadata:
 25   name: prometheus
 26   namespace: monitoring               #修改命名空間
 27 ---
 28 apiVersion: rbac.authorization.k8s.io/v1beta1
 29 kind: ClusterRoleBinding
 30 metadata:
 31   name: prometheus
 32 roleRef:
 33   apiGroup: rbac.authorization.k8s.io
 34   kind: ClusterRole
 35   name: prometheus
 36 subjects:
 37 - kind: ServiceAccount
 38   name: prometheus
 39   namespace: monitoring               #修改命名空間
 40 
[root@k8smaster01 examples]# kubectl create -f rbac-setup.yml

3.4 創建Prometheus ConfigMap

[root@k8smaster01 examples]# cat prometheus-kubernetes.yml | grep -v ^$ | grep -v "#" >> prometheus-config.yaml [root@k8smaster01 examples]# vi prometheus-config.yaml
  1 apiVersion: v1
  2 kind: ConfigMap
  3 metadata:
  4   name: prometheus-server-conf
  5   labels:
  6     name: prometheus-server-conf
  7   namespace: monitoring               #修改命名空間
  8 data:
  9   prometheus.yml: |-
 10     global:
 11       scrape_interval: 10s
 12       evaluation_interval: 10s
 13 
 14     scrape_configs:
 15       - job_name: 'kubernetes-apiservers'
 16         kubernetes_sd_configs:
 17         - role: endpoints
 18         scheme: https
 19         tls_config:
 20           ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
 21         bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
 22         relabel_configs:
 23         - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
 24           action: keep
 25           regex: default;kubernetes;https
 26 
 27       - job_name: 'kubernetes-nodes'
 28         scheme: https
 29         tls_config:
 30           ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
 31         bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
 32         kubernetes_sd_configs:
 33         - role: node
 34         relabel_configs:
 35         - action: labelmap
 36           regex: __meta_kubernetes_node_label_(.+)
 37         - target_label: __address__
 38           replacement: kubernetes.default.svc:443
 39         - source_labels: [__meta_kubernetes_node_name]
 40           regex: (.+)
 41           target_label: __metrics_path__
 42           replacement: /api/v1/nodes/${1}/proxy/metrics
 43 
 44       - job_name: 'kubernetes-cadvisor'
 45         scheme: https
 46         tls_config:
 47           ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
 48         bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
 49         kubernetes_sd_configs:
 50         - role: node
 51         relabel_configs:
 52         - action: labelmap
 53           regex: __meta_kubernetes_node_label_(.+)
 54         - target_label: __address__
 55           replacement: kubernetes.default.svc:443
 56         - source_labels: [__meta_kubernetes_node_name]
 57           regex: (.+)
 58           target_label: __metrics_path__
 59           replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
 60 
 61       - job_name: 'kubernetes-service-endpoints'
 62         kubernetes_sd_configs:
 63         - role: endpoints
 64         relabel_configs:
 65         - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
 66           action: keep
 67           regex: true
 68         - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
 69           action: replace
 70           target_label: __scheme__
 71           regex: (https?)
 72         - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
 73           action: replace
 74           target_label: __metrics_path__
 75           regex: (.+)
 76         - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
 77           action: replace
 78           target_label: __address__
 79           regex: ([^:]+)(?::\d+)?;(\d+)
 80           replacement: $1:$2
 81         - action: labelmap
 82           regex: __meta_kubernetes_service_label_(.+)
 83         - source_labels: [__meta_kubernetes_namespace]
 84           action: replace
 85           target_label: kubernetes_namespace
 86         - source_labels: [__meta_kubernetes_service_name]
 87           action: replace
 88           target_label: kubernetes_name
 89 
 90       - job_name: 'kubernetes-services'
 91         metrics_path: /probe
 92         params:
 93           module: [http_2xx]
 94         kubernetes_sd_configs:
 95         - role: service
 96         relabel_configs:
 97         - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]
 98           action: keep
 99           regex: true
100         - source_labels: [__address__]
101           target_label: __param_target
102         - target_label: __address__
103           replacement: blackbox-exporter.example.com:9115
104         - source_labels: [__param_target]
105           target_label: instance
106         - action: labelmap
107           regex: __meta_kubernetes_service_label_(.+)
108         - source_labels: [__meta_kubernetes_namespace]
109           target_label: kubernetes_namespace
110         - source_labels: [__meta_kubernetes_service_name]
111           target_label: kubernetes_name
112 
113       - job_name: 'kubernetes-ingresses'
114         kubernetes_sd_configs:
115         - role: ingress
116         relabel_configs:
117         - source_labels: [__meta_kubernetes_ingress_annotation_prometheus_io_probe]
118           action: keep
119           regex: true
120         - source_labels: [__meta_kubernetes_ingress_scheme,__address__,__meta_kubernetes_ingress_path]
121           regex: (.+);(.+);(.+)
122           replacement: ${1}://${2}${3}
123           target_label: __param_target
124         - target_label: __address__
125           replacement: blackbox-exporter.example.com:9115
126         - source_labels: [__param_target]
127           target_label: instance
128         - action: labelmap
129           regex: __meta_kubernetes_ingress_label_(.+)
130         - source_labels: [__meta_kubernetes_namespace]
131           target_label: kubernetes_namespace
132         - source_labels: [__meta_kubernetes_ingress_name]
133           target_label: kubernetes_name
134 
135       - job_name: 'kubernetes-pods'
136         kubernetes_sd_configs:
137         - role: pod
138         relabel_configs:
139         - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
140           action: keep
141           regex: true
142         - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
143           action: replace
144           target_label: __metrics_path__
145           regex: (.+)
146         - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
147           action: replace
148           regex: ([^:]+)(?::\d+)?;(\d+)
149           replacement: $1:$2
150           target_label: __address__
151         - action: labelmap
152           regex: __meta_kubernetes_pod_label_(.+)
153         - source_labels: [__meta_kubernetes_namespace]
154           action: replace
155           target_label: kubernetes_namespace
156         - source_labels: [__meta_kubernetes_pod_name]
157           action: replace
158           target_label: kubernetes_pod_name
159 
[root@k8smaster01 examples]# kubectl create -f prometheus-config.yaml

3.5 創建Prometheus Deployment

[root@k8smaster01 examples]# vi prometheus-deployment.yml
  1 apiVersion: apps/v1beta2
  2 kind: Deployment
  3 metadata:
  4   labels:
  5     name: prometheus-deployment
  6   name: prometheus-server
  7   namespace: monitoring
  8 spec:
  9   replicas: 1
 10   selector:
 11     matchLabels:
 12       app: prometheus-server
 13   template:
 14     metadata:
 15       labels:
 16         app: prometheus-server
 17     spec:
 18       containers:
 19         - name: prometheus-server
 20           image: prom/prometheus:v2.14.0
 21           command:
 22           - "/bin/prometheus"
 23           args:
 24             - "--config.file=/etc/prometheus/prometheus.yml"
 25             - "--storage.tsdb.path=/prometheus/"
 26             - "--storage.tsdb.retention=72h"
 27           ports:
 28             - containerPort: 9090
 29               protocol: TCP
 30           volumeMounts:
 31             - name: prometheus-config-volume
 32               mountPath: /etc/prometheus/
 33             - name: prometheus-storage-volume
 34               mountPath: /prometheus/
 35       serviceAccountName: prometheus
 36       imagePullSecrets:
 37         - name: regsecret
 38       volumes:
 39         - name: prometheus-config-volume
 40           configMap:
 41             defaultMode: 420
 42             name: prometheus-server-conf
 43         - name: prometheus-storage-volume
 44           emptyDir: {}
 45 
[root@k8smaster01 examples]# kubectl create -f prometheus-deployment.yml 提示:若需要持久存儲Prometheus,可提前創建相應sc和pvc,sc《044.集群存儲-StorageClass》,PVC可參考如下: [root@k8smaster01 examples]# vi prometheus-pvc.yaml
  1 apiVersion: v1
  2 kind: PersistentVolumeClaim
  3 metadata:
  4   name: prometheus-pvc
  5   namespace: monitoring
  6   annotations:
  7     volume.beta.kubernetes.io/storage-class: ghstorageclass
  8 spec:
  9   accessModes:
 10   - ReadWriteMany
 11   resources:
 12     requests:
 13       storage: 5Gi
[root@k8smaster01 examples]# kubectl create -f prometheus-pvc.yaml
將prometheus-deployment.yml存儲部分修改為:
  1 ……
  2         - name: prometheus-storage-volume
  3           persistentVolumeClaim:
  4             claimName: prometheus-pvc
  5 ……
  6 

3.6 創建Prometheus Service

[root@k8smaster01 examples]# vi prometheus-service.yaml apiVersion: v1 kind: Service metadata: labels: app: prometheus-service name: prometheus-service namespace: monitoring spec: type: NodePort selector: app: prometheus-server ports: - port: 9090 targetPort: 9090 nodePort: 30909 [root@k8smaster01 examples]# kubectl create -f prometheus-service.yaml [root@k8smaster01 examples]# kubectl get all -n monitoring NAME READY STATUS RESTARTS AGE pod/prometheus-server-fd5479489-q584s 1/1 Running 0 92s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/prometheus-service NodePort 10.107.69.147 <none> 9090:30909/TCP 29s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/prometheus-server 1/1 1 1 92s NAME DESIRED CURRENT READY AGE replicaset.apps/prometheus-server-fd5479489 1 1 1 92s

3.7 測試Prometheus

瀏覽器直接訪問:http://172.24.8.71:30909/ clipboard 查看所有Kubernetes集群上的Endpoint通過服務發現的方式自動連接到了Prometheus。 clipboard 通過圖形化界面查看記憶體。 clipboard Prometheus更多配置參考官網:https://prometheus.io/docs/prometheus/latest/configuration/configuration/

四 部署Grafana

4.1 獲取部署文件

[root@uhost ~]# git clone https://github.com/liukuan73/kubernetes-addons

4.2 部署grafana

[root@uhost ~]# cd
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • npm config set registry https://registry.npm.taobao.org npm config set disturl https://npm.taobao.org/dist npm -g install typescript ...
  • 淺談操作系統的用戶態和內核態 我們經常會聽到程式的用戶態和內核態,一個程式從用戶態進入了內核態。。。 什麼是用戶態和內核態 內核態和用戶態到底指的是什麼呢?我們這就解開其神秘面紗 所謂的用戶態、內核態,實際上是處理器(cpu)的一種狀態,在 cpu 狀態字裡面用 1bit 表示 什麼是用戶態 也叫普 ...
  • VMware Tools是一個實現主機與虛擬機文件分享,具有可支持自由拖拽的功能的工具,如果沒有VM tools,那麼沒有了複製粘貼切換的虛擬機是很不方便的。 長時間未開的虛擬機,一次嘗試拖拽Windows桌面文件到虛擬機,離奇得失敗了,後來重裝了VMware Tools還是不行,在嘗試了很多的方法 ...
  • d 輸入 ,就會列出你在這個終端會話中訪問的目錄(命令),輸入前面的序號,就可以直接跳轉。只記錄最新訪問的9個目錄地址。 省略cd 需要進行跳轉目錄時,可以省略輸入 ,直接輸入 、`... ~`或者當前屬於當前目錄內的文件夾名稱都可以直接跳轉過去。 ...
  • 聽煩了windows系統自帶音效,是不是想要換掉它的衝動呢? 如果是的,請跟我一起把windows系統音效換成科技感十足的鋼鐵俠賈維斯音效。 點擊此處獲取賈維斯音效 //1.打開運行界面 win + R //2.打開控制面板,在運行界面輸入control control 3.點擊 外觀和個性化 4. ...
  • vim成為神級編輯器,雖然本人用的不怎麼滴,但是仍然對他愛不釋手。我堅信隨著時間的積累,我會慢慢掌握它的,下麵給大家介紹一下本人簡陋的vimrc文件,大神勿噴,小白可拿去用用,見笑了#1.Ubuntu新的系統沒有vim只有vi(這哥倆兒的關係就不廢話了),因此在換源之後,首先安裝vim sudo a ...
  • 前面提到了換系統的軟體源,Python安裝第三方庫時,也是遇到網速受限問題,這裡需要換pip源,鏡像站供選擇的有很多,這裡就簡單介紹一下: 1 阿裡雲 http://mirrors.aliyun.com/pypi/simple/ 2 豆瓣 http://pypi.douban.com/simple/ ...
  • ``` # 打開或新建一個文件 $ nano tmp.txt # 常用組合按鍵 ^G:獲取幫助 ^X:退出,如果文件有改定會提示是否保存 ^O:保存文件內容 ^R:讀取其他文件的內容,放入到當前文件中 ^W:查找字元串 ^C:顯示游標所在的行和列 ^_:跳轉到指定行 M-G:同 ^_,跳轉到指定行 ... ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...