Kubernetes 調度約束(親和性、污點、容忍)

目錄

一、Pod啟動典型創建過程

二、調度流程

三、指定調度節點

1.使用nodeName字段指定調度節點

2.使用nodeSelector指定調度節點

2.1給對應的node節點添加標簽

2.2修改為nodeSelector調度方式

3.通過親和性來指定調度節點

3.1節點親和性

3.2Pod親和性與反親和性

3.2.1使用Pod親和性調度

?3.2.2使用Pod反親和性調度

4.使用污點(Taint) 和 容忍(Tolerations)指定調度節點

4.1污點(Taint)?

4.2容忍(Tolerations)

四、cordon 和 drain

五、Pod詳解

1.Pod啟動階段(相位 phase)

2.?Pod常見狀態

3.?如何刪除 Unknown 狀態的 Pod ?

4.?故障排除步驟


一、Pod啟動典型創建過程

Kubernetes 是通過 List-Watch 的機制進行每個組件的協作,保持數據同步的,每個組件之間的設計實現了解耦。

用戶是通過 kubectl 根據配置文件,向 APIServer 發送命令,在 Node 節點上面建立 Pod 和 Container。
APIServer 經過 API 調用,權限控制,調用資源和存儲資源的過程,實際上還沒有真正開始部署應用。這里?? ?需要 Controller Manager、Scheduler 和 kubelet 的協助才能完成整個部署過程。

在 Kubernetes 中,所有部署的信息都會寫到 etcd 中保存。實際上 etcd 在存儲部署信息的時候,會發送 Create 事件給 APIServer,而 APIServer 會通過監聽(Watch)etcd 發過來的事件。其他組件也會監聽(Watch)APIServer 發出來的事件。

Pod 是 Kubernetes 的基礎單元,Pod 啟動典型創建過程如下

  1. 這里有三個 List-Watch,分別是 Controller Manager(運行在 Master),Scheduler(運行在 Master),kubelet(運行在 Node)。 他們在進程已啟動就會監聽(Watch)APIServer 發出來的事件。
  2. 用戶通過 kubectl 或其他 API 客戶端提交請求給 APIServer 來建立一個 Pod 對象副本。
  3. APIServer 嘗試著將 Pod 對象的相關元信息存入 etcd 中,待寫入操作執行完成,APIServer 即會返回確認信息至客戶端。
  4. 當 etcd 接受創建 Pod 信息以后,會發送一個 Create 事件給 APIServer。
  5. 由于 Controller Manager 一直在監聽(Watch,通過https的6443端口)APIServer 中的事件。此時 APIServer 接受到了 Create 事件,又會發送給 Controller Manager。
  6. Controller Manager 在接到 Create 事件以后,調用其中的 Replication Controller 來保證 Node 上面需要創建的副本數量。一旦副本數量少于 RC 中定義的數量,RC 會自動創建副本。總之它是保證副本數量的 Controller(PS:擴容縮容的擔當)。
  7. 在 Controller Manager 創建 Pod 副本以后,APIServer 會在 etcd 中記錄這個 Pod 的詳細信息。例如 Pod 的副本數,Container 的內容是什么。
  8. 同樣的 etcd 會將創建 Pod 的信息通過事件發送給 APIServer。
  9. 由于 Scheduler 在監聽(Watch)APIServer,并且它在系統中起到了“承上啟下”的作用,“承上”是指它負責接收創建的 Pod 事件,為其安排 Node;“啟下”是指安置工作完成后,Node 上的 kubelet 進程會接管后繼工作,負責 Pod 生命周期中的“下半生”。 換句話說,Scheduler 的作用是將待調度的 Pod 按照調度算法和策略綁定到集群中 Node 上。
  10. Scheduler 調度完畢以后會更新 Pod 的信息,此時的信息更加豐富了。除了知道 Pod 的副本數量,副本內容。還知道部署到哪個 Node 上面了。并將上面的 Pod 信息更新至 API Server,由 APIServer 更新至 etcd 中,保存起來。
  11. etcd 將更新成功的事件發送給 APIServer,APIServer 也開始反映此 Pod 對象的調度結果。
  12. kubelet 是在 Node 上面運行的進程,它也通過 List-Watch 的方式監聽(Watch,通過https的6443端口)APIServer 發送的 Pod 更新的事件。kubelet 會嘗試在當前節點上調用 Docker 啟動容器,并將 Pod 以及容器的結果狀態回送至 APIServer。
  13. APIServer 將 Pod 狀態信息存入 etcd 中。在 etcd 確認寫入操作成功完成后,APIServer將確認信息發送至相關的 kubelet,事件將通過它被接受。

#注意:在創建 Pod 的工作就已經完成了后,為什么 kubelet 還要一直監聽呢?原因很簡單,假設這個時候 kubectl 發命令,要擴充 Pod 副本數量,那么上面的流程又會觸發一遍,kubelet 會根據最新的 Pod 的部署情況調整 Node 的資源。又或者 Pod 副本數量沒有發生變化,但是其中的鏡像文件升級了,kubelet 也會自動獲取最新的鏡像文件并且加載。

二、調度流程

Scheduler 是 kubernetes 的調度器,主要的任務是把定義的 pod 分配到集群的節點上。其主要考慮的問題如下:

  • 公平:如何保證每個節點都能被分配資源
  • 資源高效利用:集群所有資源最大化被使用
  • 效率:調度的性能要好,能夠盡快地對大批量的 pod 完成調度工作
  • 靈活:允許用戶根據自己的需求控制調度的邏輯

Sheduler 是作為單獨的程序運行的,啟動之后會一直監聽 APIServer,獲取 spec.nodeName 為空的 pod,對每個 pod 都會創建一個 binding,表明該 pod 應該放到哪個節點上。

調度分為幾個部分:首先是過濾掉不滿足條件的節點,這個過程稱為預算策略(predicate);然后對通過的節點按照優先級排序,這個是優選策略(priorities);最后從中選擇優先級最高的節點。如果中間任何一步驟有錯誤,就直接返回錯誤。

Predicate 有一系列的常見的算法可以使用

  • PodFitsResources:節點上剩余的資源是否大于 pod 請求的資源。
  • PodFitsHost:如果 pod 指定了 NodeName,檢查節點名稱是否和 NodeName 匹配。
  • PodFitsHostPorts:節點上已經使用的 port 是否和 pod 申請的 port 沖突。
  • PodSelectorMatches:過濾掉和 pod 指定的 label 不匹配的節點。
  • NoDiskConflict:已經 mount 的 volume 和 pod 指定的 volume 不沖突,除非它們都是只讀。

如果在 predicate 過程中沒有合適的節點,pod 會一直在 pending 狀態,不斷重試調度,直到有節點滿足條件。 經過這個步驟,如果有多個節點滿足條件,就繼續 priorities 過程:按照優先級大小對節點排序。

優先級由一系列鍵值對組成,鍵是該優先級項的名稱,值是它的權重(該項的重要性)。有一系列的常見的優先級選項包括:

  • LeastRequestedPriority:通過計算CPU和Memory的使用率來決定權重,使用率越低權重越高。也就是說,這個優先級指標傾向于資源使用比例更低的節點。
  • BalancedResourceAllocation:節點上 CPU 和 Memory 使用率越接近,權重越高。這個一般和上面的一起使用,不單獨使用。比如 node01 的 CPU 和 Memory 使用率 20:60,node02 的 CPU 和 Memory 使用率 50:50,雖然 node01 的總使用率比 node02 低,但 node02 的 CPU 和 Memory 使用率更接近,從而調度時會優選 node02。
  • ImageLocalityPriority:傾向于已經有要使用鏡像的節點,鏡像總大小值越大,權重越高。

通過算法對所有的優先級項目和權重進行計算,得出最終的結果。

三、指定調度節點

1.使用nodeName字段指定調度節點

nodeName 將 Pod 直接調度到指定的 Node 節點上,會跳過 Scheduler 的調度策略,該匹配規則是強制匹配

apiVersion: apps/v1
kind: Deployment          #創建deployment控制器
metadata:name: myapp             #deployment控制器名稱:myapp
spec:                     #定義模板文件replicas: 3             #副本集為3個selector:               #標簽選擇器matchLabels:          #匹配的標簽為 app: myapp1app: myapp1template:               #定義pod模板metadata:labels:             #pod的標簽app: myapp1spec:                 nodeName: node01    #pod創建后所在的node節點名稱containers:         #定義pod中的容器- name: myapp       #pod容器中的名稱image: nginx      #容器使用的鏡像ports:            - containerPort: 80kubectl apply -f demo1.yamlkubectl get pods --show-labels -owide
#查看詳細事件(發現未經過 scheduler 調度分配)
kubectl describe pod myapp-6bc58d7775-6wlpp

2.使用nodeSelector指定調度節點

通過 kubernetes 的 label-selector 機制選擇節點,由調度器調度策略匹配 label,然后調度 Pod 到目標節點,該匹配規則屬于強制約束

2.1給對應的node節點添加標簽

kubectl label nodes node01 app=akubectl label nodes node02 app=b#查看標簽
kubectl get nodes --show-labels注:
#修改一個 label 的值,需要加上 --overwrite 參數
kubectl label nodes node02 app=a --overwrite#刪除一個 label,只需在命令行最后指定 label 的 key 名并與一個減號相連即可:
kubectl label nodes node02 app-
或
kubectl label nodes node02 app=b-#指定標簽查詢 node 節點
kubectl get node -l app=a

2.2修改為nodeSelector調度方式

vim myapp1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: myapp1
spec:replicas: 3selector:matchLabels:run: myapp1template:metadata:labels:run: myapp1spec:nodeSelector:app: acontainers:- name: myapp1image: nginx:1.14ports:- containerPort: 80kubectl apply -f myapp1.yaml
kubectl get pods -owide
#查看詳細事件(通過事件可以發現要先經過 scheduler 調度分配)
kubectl describe pod myapp1-7cc594f786-jfs97

3.通過親和性來指定調度節點

將 Pod 指派給節點 | Kubernetes

3.1節點親和性

pod.spec.nodeAffinity

  • preferredDuringSchedulingIgnoredDuringExecution:軟策略
  • requiredDuringSchedulingIgnoredDuringExecution:硬策略

注:

  • 硬策略就是Pod必須要去指定條件的node節點,不去不行
  • 軟策略表示Pod最優先去指定node節點,如果沒有符合條件的node節點,也可以選擇其它node節點

鍵值運算關系

  • In:label 的值在某個列表中
  • NotIn:label 的值不在某個列表中
  • Gt:label 的值大于某個值
  • Lt:label 的值小于某個值
  • Exists:某個 label 存在
  • DoesNotExist:某個 label 不存在?

nodeAffinity硬策略和軟策略示例

apiVersion: v1
kind: Pod
metadata:name: affinitylabels:app: node-affinity-pod
spec:containers:- name: with-node-affinityimage: soscscs/myapp:v1affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:   #先滿足硬策略,排除有kubernetes.io/hostname=node02標簽的節點nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: NotInvalues:- node02preferredDuringSchedulingIgnoredDuringExecution:  #再滿足軟策略,優先選擇有app=a標簽的節點- weight: 1        #如果有多個軟策略,權重越大,優先級越大preference:matchExpressions:- key: appoperator: Invalues:- a只有硬策略的情況下,如果硬策略不滿足條件,Pod 狀態一直會處于 Pending 狀態。
如果把硬策略和軟策略合在一起使用,則要先滿足硬策略之后才會滿足軟策略

3.2Pod親和性與反親和性

pod.spec.affinity.podAffinity/podAntiAffinity

  • preferredDuringSchedulingIgnoredDuringExecution:軟策略
  • requiredDuringSchedulingIgnoredDuringExecution:硬策略?
調度策略匹配標簽操作符拓撲域支持調度目標
nodeAffinity主機In, NotIn, Exists,DoesNotExist, Gt, Lt?指定主機
podAffinityPodIn, NotIn, Exists,DoesNotExistPod與指定Pod同一拓撲域
podAntiAffinityPodIn, NotIn, Exists,DoesNotExistPod與指定Pod不在同一拓撲域

3.2.1使用Pod親和性調度

apiVersion: v1
kind: Pod
metadata:name: myapplabels:                         #定義該Pod的標簽app: myapp
spec:containers:- name: myapp01image: nginxaffinity:podAffinity:                  #定義pod親和性requiredDuringSchedulingIgnoredDuringExecution:    #pod親和性的硬策略- labelSelector:            #定義硬策略標簽選擇器的信息matchExpressions:       #定義標簽選擇器選擇的信息- key: app              #定義鍵名operator: In          #定義鍵值之間的運算關系values:               #定義鍵值- myapptopologyKey: run          #定義節點標簽的鍵,判斷是否在同一拓撲域中topologykey: run表示如果node節點都包含有標簽為run=鍵值,
當node節點的鍵值相同時,則表示node節點在同一拓撲域中;
當run鍵的值不相同時,則表示node節點不在同一拓撲域中。

注:

  • 僅當節點上至少包含一個已運行且 app=myapp 的標簽 的 Pod 處于拓撲域 a 時,才可以將該 Pod 調度到拓撲域 a 上的節點。 (更確切的說,新建pod分配node節點,會選擇有標簽為app=myapp的pod運行的node節點或該node節點所處拓撲域上其它node節點。)
  • topologyKey 是節點標簽的鍵。如果兩個節點使用此鍵標記并且具有相同的標簽值,則調度器會將這兩個節點視為處于同一拓撲域中。 調度器試圖在每個拓撲域中放置數量均衡的 Pod。
  • 如果 app 對應的值不一樣就是不同的拓撲域。比如 Pod1 在 app=a?的 Node 上,Pod2 在 app=b?的 Node 上,Pod3 在 app=a?的 Node 上,則 Pod2 和 Pod1、Pod3 不在同一個拓撲域,而Pod1 和 Pod3在同一個拓撲域。

?3.2.2使用Pod反親和性調度

apiVersion: v1
kind: Pod
metadata:name: myapplabels:app: myapp
spec:containers:- name: myappimage: nginxaffinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- atopologyKey: run如果節點處于 Pod 所在的同一拓撲域且具有鍵“app”和值“a”的標簽, 則該 pod 不能將其調度到該節點上。 
(如果 topologyKey 為 run,則意味著當節點和具有鍵 “app”和值“a”的 Pod 處于相同的拓撲域,Pod 不能被調度到該節點上。)

4.使用污點(Taint) 和 容忍(Tolerations)指定調度節點

4.1污點(Taint)?

節點親和性,是Pod的一種屬性(偏好或硬性要求),它使Pod被吸引到一類特定的節點。Taint 則相反,它使節點能夠排斥一類特定的 Pod。
Taint 和 Toleration 相互配合,可以用來避免 Pod 被分配到不合適的節點上。每個節點上都可以應用一個或多個 taint ,這表示對于那些不能容忍這些 taint 的 Pod,是不會被該節點接受的。如果將 toleration 應用于 Pod 上,則表示這些 Pod 可以(但不一定)被調度到具有匹配 taint 的節點上。

使用 kubectl taint 命令可以給某個 Node 節點設置污點,Node 被設置上污點之后就和 Pod 之間存在了一種相斥的關系,可以讓 Node 拒絕 Pod 的調度執行,甚至將 Node 已經存在的 Pod 驅逐出去。污點的組成格式如下:
key=value:effect每個污點有一個 key 和 value 作為污點的標簽,其中 value 可以為空,effect 描述污點的作用。當前 taint effect 支持如下三個選項:
●NoSchedule:表示 k8s 將不會將 Pod 調度到具有該污點的 Node 上
●PreferNoSchedule:表示 k8s 將盡量避免將 Pod 調度到具有該污點的 Node 上
●NoExecute:表示 k8s 將不會將 Pod 調度到具有該污點的 Node 上,同時會將 Node 上已經存在的 Pod 驅逐出去#設置污點
kubectl taint node node01 key1=value1:NoSchedule#節點說明中,查找 Taints 字段
kubectl describe node node01  #去除污點
kubectl taint node node01 key1:NoSchedule-

4.2容忍(Tolerations)

設置了污點的 Node 將根據 taint 的 effect:NoSchedule、PreferNoSchedule、NoExecute 和 Pod 之間產生互斥的關系,Pod 將在一定程度上不會被調度到 Node 上。但我們可以在 Pod 上設置容忍(Tolerations),意思是設置了容忍的 Pod 將可以容忍污點的存在,可以被調度到存在污點的 Node 上。

apiVersion: v1
kind: Pod
metadata:name: myapp01labels:app: myapp01
spec:containers:- name: with-node-affinityimage: soscscs/myapp:v1tolerations:- key: "check"                    #定義污點鍵名operator: "Equal"           value: "mycheck"                #定義污點鍵值effect: "NoExecute"             #定義污點的作用tolerationSeconds: 3600#其中的 key、vaule、effect 都要與 Node 上設置的 taint 保持一致
#operator 的值為 Exists 將會忽略 value 值,即存在即可
#tolerationSeconds 用于描述當 Pod 需要被驅逐時可以在 Node 上繼續保留運行的時間

注意事項:

(1)當不指定 key 值時,表示容忍所有的污點 keytolerations:- operator: "Exists"(2)當不指定 effect 值時,表示容忍所有的污點作用tolerations:- key: "key"operator: "Exists"(3)有多個 Master 存在時,防止資源浪費,可以如下設置
kubectl taint node Master-Name node-role.kubernetes.io/master=:PreferNoSchedule//如果某個 Node 更新升級系統組件,為了防止業務長時間中斷,可以先在該 Node 設置 NoExecute 污點,把該 Node 上的 Pod 都驅逐出去
kubectl taint node node01 check=mycheck:NoExecute//此時如果別的 Node 資源不夠用,可臨時給 Master 設置 PreferNoSchedule 污點,讓 Pod 可在 Master 上臨時創建
kubectl taint node master node-role.kubernetes.io/master=:PreferNoSchedule//待所有 Node 的更新操作都完成后,再去除污點
kubectl taint node node01 check=mycheck:NoExecute-

四、cordon 和 drain

對節點執行維護操作:
kubectl get nodes//將 Node 標記為不可調度的狀態,這樣就不會讓新創建的 Pod 在此 Node 上運行
kubectl cordon <NODE_NAME> 		 #該node將會變為SchedulingDisabled狀態//kubectl drain 可以讓 Node 節點開始釋放所有 pod,并且不接收新的 pod 進程。drain 本意排水,意思是將出問題的 Node 下的 Pod 轉移到其它 Node 下運行
kubectl drain <NODE_NAME> --ignore-daemonsets --delete-emptydir-data --force--ignore-daemonsets:無視 DaemonSet 管理下的 Pod。
--delete-emptydir-data:如果有 mount local volume 的 pod,會強制殺掉該 pod。
--force:強制釋放不是控制器管理的 Pod。注:執行 drain 命令,會自動做了兩件事情:
(1)設定此 node 為不可調度狀態(cordon)
(2)evict(驅逐)了 Pod//kubectl uncordon 將 Node 標記為可調度的狀態
kubectl uncordon <NODE_NAME>

五、Pod詳解

1.Pod啟動階段(相位 phase)

Pod 創建完之后,一直到持久運行起來,中間有很多步驟,也就有很多出錯的可能,因此會有很多不同的狀態。
一般來說,pod 這個過程包含以下幾個步驟:

  1. 調度到某臺 node 上。kubernetes 根據一定的優先級算法選擇一臺 node 節點將其作為 Pod 運行的 node
  2. 拉取鏡像
  3. 掛載存儲配置等
  4. 容器運行起來。如果有健康檢查,會根據檢查的結果來設置其狀態。

2.?Pod常見狀態

  • Pending:表示APIServer創建了Pod資源對象并已經存入了etcd中,但是它并未被調度完成(比如還沒有調度到某臺node上),或者仍然處于從倉庫下載鏡像的過程中。
  • Running:Pod已經被調度到某節點之上,并且Pod中所有容器都已經被kubelet創建。至少有一個容器正在運行,或者正處于啟動或者重啟狀態(也就是說Running狀態下的Pod不一定能被正常訪問)。
  • Succeeded:有些pod不是長久運行的,比如job、cronjob,一段時間后Pod中的所有容器都被成功終止,并且不會再重啟。需要反饋任務執行的結果。
  • Failed:Pod中的所有容器都已終止了,并且至少有一個容器是因為失敗終止。也就是說,容器以非0狀態退出或者被系統終止,比如 command 寫的有問題。
  • Unknown:表示無法讀取 Pod 狀態,通常是 kube-controller-manager 無法與 Pod 通信。Pod 所在的 Node 出了問題或失聯,從而導致 Pod 的狀態為 Unknow

3.?如何刪除 Unknown 狀態的 Pod ?

  • 從集群中刪除有問題的 Node。使用公有云時,kube-controller-manager 會在 VM 刪除后自動刪除對應的 Node。 而在物理機部署的集群中,需要管理員手動刪除 Node(kubectl delete node <node_name>)。
  • 被動等待 Node 恢復正常,Kubelet 會重新跟 kube-apiserver 通信確認這些 Pod 的期待狀態,進而再決定刪除或者繼續運行這些 Pod。
  • 主動刪除 Pod,通過執行 kubectl delete pod <pod_name> --grace-period=0 --force 強制刪除 Pod。但是這里需要注意的是,除非明確知道 Pod 的確處于停止狀態(比如 Node 所在 VM 或物理機已經關機),否則不建議使用該方法。特別是 StatefulSet 管理的 Pod,強制刪除容易導致腦裂或者數據丟失等問題。

4.?故障排除步驟

//查看Pod事件
kubectl describe TYPE NAME_PREFIX  //查看Pod日志(Failed狀態下)
kubectl logs <POD_NAME> [-c Container_NAME]//進入Pod(狀態為running,但是服務沒有提供)
kubectl exec –it <POD_NAME> bash//查看集群信息
kubectl get nodes//發現集群狀態正常
kubectl cluster-info//查看kubelet日志發現
journalctl -xefu kubelet

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/40621.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/40621.shtml
英文地址,請注明出處:http://en.pswp.cn/news/40621.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue CLI創建Vue項目詳細步驟

&#x1f680; 一、安裝Node環境&#xff08;建議使用LTS版本&#xff09; 在開始之前&#xff0c;請確保您已經安裝了Node.js環境。您可以從Node.js官方網站下載LTS版本&#xff0c;以確保穩定性和兼容性。 中文官網下載 確認已安裝 Node.js。可以在終端中運行 node -v 命令…

基于STM32設計的中藥分裝系統

一、設計需求 基于STM32設計的中藥分裝系統 【1】項目背景 中藥文化是我國文化瑰寶之一,它具有療效好、副作用小的優點,而且相對于西藥,全天然的中藥還具有標本兼治的特點,不僅可以用來治病,更可以對患者身體進行調理,所以格外受到當今一直追求生活質量的人們的追捧&quo…

在Spring Boot和Vue中實現請求過濾器以驗證請求頭中的Token

在Spring Boot應用程序中創建一個過濾器類&#xff0c;用于處理請求&#xff1a; Component public class AuthenticationFilter implements Filter {Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException,…

FastAPI入門

目錄 FastAPI FastAPI 是什么 為什么要用 FastAPI FastAPI 入門 安裝 用 FastAPI 寫個接口 調試接口 創建快捷請求 保存為快捷請求 發送請求 總結 FastAPI FastAPI 是什么 什么是 FastAPI 呢&#xff1f; FastAPI 是 Python 的一個框架&#xff0c;如果要類比的話…

ros編譯catkin_make/catkin build 報錯“string no output variable specified”

文章目錄 問題描述問題分析問題描述 CMake Error at /opt/ros/melodic/share/catkin/cmake/platform/lsb.cmake:8 (string):string no output variable specified Call Stack (most recent call first):/opt/ros/melodic/share/catkin/cmake/all.cmake:164 (include)/opt/ros/…

Django的簡介安裝與配置及兩大設計模式

一.Djang的介紹 1.Django是什么 Django 是使用 Python 語言開發的一款免費而且開源的 Web 應用框架。 由于 Python 語言的跨平臺性&#xff0c;所以 Django 同樣支持 Windows、Linux 和 Mac 系統。 在 Python 語言熾手可熱的當下&#xff0c;Django 也迅速的崛起&#xff0c;在…

javaScript:一分鐘看懂數組排序以及冒泡排序(重點)

目錄 一.前言 二.數組排序 sort&#xff08;&#xff09; 字符串大小的比較原則 字符編碼排序規則 如果使用sort從小到大排列 &#xff08;重點&#xff09; 函數的返回值 規則&#xff1a; 代碼 案例 數組打亂 sort相關代碼 三.冒泡排序&#xff08;重點&#xff…

【RocketMQ】NameServer總結

NameServer是一個注冊中心&#xff0c;提供服務注冊和服務發現的功能。NameServer可以集群部署&#xff0c;集群中每個節點都是對等的關系&#xff08;沒有像ZooKeeper那樣在集群中選舉出一個Master節點&#xff09;&#xff0c;節點之間互不通信。 服務注冊 Broker啟動的時候會…

【通俗易懂】如何使用GitHub上傳文件,如何用git在github上傳文件

目錄 創建 GitHub 倉庫 使用 Git 進行操作 步驟 1&#xff1a;初始化本地倉庫 步驟 2&#xff1a;切換默認分支 步驟 3&#xff1a;連接到遠程倉庫 步驟 4&#xff1a;獲取遠程更改 步驟 5&#xff1a;添加文件到暫存區 步驟 6&#xff1a;提交更改 步驟 7&#xff1a…

Chrome 手動代理設置 HTTP/Socks5

1、安裝代理插件&#xff1a;SwitchyOmega 在線安裝 從 Chrome 應用商店 安裝&#xff0c;如果您無法從該鏈接安裝&#xff0c;請使用下面的離線安裝。 離線安裝 ①、去 Github 下載 最新版安裝包 &#xff0c;或者直接 本地下載 文件進行安裝。 ②、下載安裝文件后&#xf…

[Vue warn]: Error in render: “SyntaxError: “undefined“ is not valid JSON“

[Vue warn]: Error in render: “SyntaxError: “undefined” is not valid JSON” 這說明出現了undefined這個變量類型&#xff0c;比如JSON.parse()時候會出現&#xff0c;可以先嘗試打印JSON.parse()括號中的內容是否是undefined&#xff0c;如果是&#xff0c;那問題的根源…

RenderDoc 導出Cubemap到UE

找到使用了Cubemap的模型,再Output里會顯示該模型使用的所有貼圖 ,選中Cubemap導出 選擇導出格式為HDR 導出的Cubemap是豎著的,需要再PS里逆時針旋轉&#xff19;&#xff10;度 還有&#xff0c;導出的的Cubemap方向是錯的,需要把3,4 跟1,2 對換,6旋轉180度 UE 文檔里的方向參…

Spring Boot @Validated 驗證注解的使用

1、引入依賴 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId> </dependency> 2、使用 2.1、非對象參數 參數如果是非對象格式&#xff0c;需要在controller類上面添…

JVM——HotSpot的算法細節實現

一、根節點枚舉 固定可作為GC Roots的節點主要在全局性的引用&#xff08;如常量或類靜態屬性&#xff09;與執行上下文&#xff08;如棧幀中的本地變量表&#xff09;中&#xff0c;盡管目標明確&#xff0c;但查找要做到高效很難。現在java應用越來越龐大&#xff0c;光方法區…

Code interpreter生成無聊的APP:病理圖像切割和提取

一、寫在前面 機器學習100步不夠分配了&#xff0c;所以開個新專欄&#xff0c;就叫做《Code interpreter生成無聊的APP》&#xff0c;旨在探索GPT-4官方插件Code interpreter的使用心路歷程。 主要靈感來源&#xff1a;聽戶主說&#xff0c;她們在做病理組學圖像標注和分割的…

如何用Apipost實現sign簽名?

我們平常對外的接口都會用到sign簽名&#xff0c;對不同的用戶提供不同的apikey ,這樣可以提高接口請求的安全性&#xff0c;避免被人抓包后亂請求。 如何用Apipost實現sign簽名&#xff1f; 可以在Apipost中通過預執行腳本調用內置的JS庫去實現預執行腳本是在發送請求之前自…

Wordcloud | 風中有朵雨做的‘詞云‘哦!~

1寫在前面 今天可算把key搞好了&#xff0c;不得不說&#x1f3e5;里手握生殺大權的人&#xff0c;都在自己的能力范圍內盡可能的難為你。&#x1f602; 我等小大夫也是很無奈&#xff0c;畢竟奔波霸、霸波奔是要去抓唐僧的。 &#x1f910; 好吧&#xff0c;今天是詞云&#x…

【C++精華鋪】8.C++模板初階

目錄 1. 泛型編程 2. 函數模板 2.1 函數模板的概念及格式 2.2 函數模板的原理 2.3 模板的實例化 2.4 模板參數的匹配原則 3. 類模板 3.1 類模板格式 3.2 類模板的實例化 1. 泛型編程 什么是泛型編程&#xff1f;泛型編程是避免使用某種具體類型而去使用某種通用類型來進行…

mysql中INSERT INTO ... ON DUPLICATE KEY UPDATE的用法,以及與REPLACE INTO 語句用法的異同

INSERT INTO ... ON DUPLICATE KEY UPDATE 是 MySQL 中一種用于插入數據并處理重復鍵沖突的語法。與之相似的還有 REPLACE INTO 語句。以下是它們的用法和異同點的詳細說明&#xff1a; 一、INSERT INTO ... ON DUPLICATE KEY UPDATE INSERT INTO ... ON DUPLICATE KEY UPDAT…

NET域名的優勢

NET域名是互聯網上最常見的頂級域名之一&#xff0c;其開放使用日期遠比其他主要頂級域名早&#xff0c;始于1985年。其作為商業網絡服務提供者的域名&#xff0c;主要用于企業、組織和個人等在網絡上建立自己的網站。本文將從以下三個方面介紹NET域名。 一、NET域名的歷史 N…