021.掌握Pod-Pod調度策略

来源:https://www.cnblogs.com/itzgr/archive/2019/11/21/11904794.html
-Advertisement-
Play Games

一 Pod生命周期管理 1.1 Pod生命周期 Pod在整個生命周期過程中被系統定義瞭如下各種狀態。 狀態值 描述 Pending API Server已經創建該Pod,且Pod內還有一個或多個容器的鏡像沒有創建,包括正在下載鏡像的過程。 Running Pod內所有容器均已創建,且至少有一個容器處 ...


一 Pod生命周期管理

1.1 Pod生命周期

Pod在整個生命周期過程中被系統定義瞭如下各種狀態。
狀態值 描述
Pending API Server已經創建該Pod,且Pod內還有一個或多個容器的鏡像沒有創建,包括正在下載鏡像的過程。
Running Pod內所有容器均已創建,且至少有一個容器處於運行狀態、正在啟動狀態或正在重啟狀態。
Succeeded Pod內所有容器均成功執行退出,且不會重啟。
Failed Pod內所有容器均已退出,但至少有一個容器退出為失敗狀態。
Unknown 由於某種原因無法獲取該Pod狀態,可能由於網路通信不暢導致。

1.2 Pod重啟策略

Pod重啟策略(RestartPolicy)應用於Pod內的所有容器,並且僅在Pod所處的Node上由kubelet進行判斷和重啟操作。當某個容器異常退出或者健康檢查失敗時,kubelet將根據RestartPolicy的設置來進行相應操作。Pod的重啟策略包括Always、OnFailure和Never,預設值為Always。
  • Always:當容器失效時,由kubelet自動重啟該容器;
  • OnFailure:當容器終止運行且退出碼不為0時,由kubelet自動重啟該容器;
  • Never:不論容器運行狀態如何,kubelet都不會重啟該容器。

       kubelet重啟失效容器的時間間隔以sync-frequency乘以2n來計算,例如1/2/4/8倍等,最長延時5min,並且在成功重啟後的10min後重置該時間。

Pod的重啟策略與控制方式關聯,當前可用於管理Pod的控制器包括ReplicationController、Job、DaemonSet及直接管理kubelet管理(靜態Pod)。 不同控制器的重啟策略限制如下:
  • RC和DaemonSet:必須設置為Always,需要保證該容器持續運行;
  • Job:OnFailure或Never,確保容器執行完成後不再重啟;
  • kubelet:在Pod失效時重啟,不論將RestartPolicy設置為何值,也不會對Pod進行健康檢查。

Pod包含的容器數 Pod當前的狀態 發生事件 Pod的結果狀態
RestartPolicy=Always RestartPolicy=OnFailure RestartPolicy=Never
包含1個容器 Running 容器成功退出 Running Succeeded Succeeded
包含1個容器 Running 容器失敗退出 Running Running Failed
包括兩個容器 Running 1個容器失敗退出 Running Running Running
包括兩個容器 Running 容器被OOM殺掉 Running Running Failed

1.3 Pod健康檢查

對Pod的健康檢查可以通過兩類探針來檢查:LivenessProbe和ReadinessProbe。 LivenessProbe探針:用於判斷容器是否存活(running狀態),如果LivenessProbe探針探測到容器不健康,則kubelet將殺掉該容器,並根據容器的重啟策略做相應處理。若一個容器不包含LivenessProbe探針,kubelet認為該容器的LivenessProbe探針返回值用於是“Success”。 ReadineeProbe探針:用於判斷容器是否啟動完成(ready狀態)。如果ReadinessProbe探針探測到失敗,則Pod的狀態將被修改。Endpoint Controller將從Service的Endpoint中刪除包含該容器所在Pod的Eenpoint。 kubelet定期執行LivenessProbe探針來診斷容器的健康狀態,通常有以下三種方式:
  • ExecAction:在容器內執行一個命令,若返回碼為0,則表明容器健康。
示例:通過執行"cat /tmp/health"命令判斷一個容器運行是否正常。容器初始化並創建該文件,10s後刪除該文件,15s秒通過命令判斷,由於該文件已被刪除,因此判斷該容器Fail,導致kubelet殺掉該容器並重啟。
  1 [root@uk8s-m-01 study]# vi dapi-liveness.yaml
  2 apiVersion: v1
  3 kind: Pod
  4 metadata:
  5   name: dapi-liveness-pod
  6   labels:
  7     test: liveness-exec
  8 spec:
  9   containers:
 10     - name: dapi-liveness
 11       image: busybox
 12       args:
 13       - /bin/sh
 14       - -c
 15       - echo ok > /tmp/health; sleep 10; rm -rf /tmp/health; sleep 600
 16       livenessProbe:
 17         exec:
 18           command:
 19           - cat
 20           - /tmp/health
 21 
 22 [root@uk8s-m-01 study]# kubectl describe pod dapi-liveness-pod
clipboard
  • TCPSocketAction:通過容器的IP地址和埠號執行TCP檢查,若能建立TCP連接,則表明容器健康。
示例:
  1 [root@uk8s-m-01 study]# vi dapi-tcpsocket.yaml
  2 apiVersion: v1
  3 kind: Pod
  4 metadata:
  5   name: dapi-healthcheck-tcp
  6 spec:
  7   containers:
  8     - name: nginx
  9       image: nginx
 10       ports:
 11       - containerPort: 80
 12       livenessProbe:
 13         tcpSocket:
 14           port: 80
 15         initialDelaySeconds: 30
 16         timeoutSeconds: 1
 17 
 18 [root@uk8s-m-01 study]# kubectl create -f dapi-tcpsocket.yaml
提示:對於每種探測方式,都需要設置如下兩個參數,其包含的含義如下: initialDelaySeconds:啟動容器後進行首次健康檢查的等待時間,單位為s; timeoutSeconds:健康檢查發送請求後等待響應的超時時間,單位為s,當超時發生時,kubelet會認為容器已經無法提供服務,將會重啟該容器。

二 Pod調度

Kubernetes中,Pod通常是容器的載體,一般需要通過Deployment、DaemonSet、RC、Job等對象來完成一組Pod的調度與自動控制功能。

2.1 Depolyment/RC自動調度

Deployment或RC的主要功能之一就是自動部署一個容器應用的多份副本,以及持續監控副本的數量,在集群內始終維持用戶指定的副本數量。 示例:
  1 [root@uk8s-m-01 study]# vi nginx-deployment.yaml
  2 apiVersion: apps/v1beta1
  3 kind: Deployment
  4 metadata:
  5   name: nginx-deployment-01
  6 spec:
  7   replicas: 3
  8   template:
  9     metadata:
 10       labels:
 11         app: nginx
 12     spec:
 13       containers:
 14       - name: nginx
 15         image: nginx:1.7.9
 16         ports:
 17         - containerPort: 80
 18 
 19 [root@uk8s-m-01 study]# kubectl get deployments
 20 NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
 21 nginx-deployment-01   3/3     3            3           30s
 22 [root@uk8s-m-01 study]# kubectl get rs
 23 NAME                             DESIRED   CURRENT   READY   AGE
 24 nginx-deployment-01-5754944d6c   3         3         3       75s
 25 [root@uk8s-m-01 study]# kubectl get pod | grep nginx
 26 nginx-deployment-01-5754944d6c-hmcpg   1/1     Running     0          84s
 27 nginx-deployment-01-5754944d6c-mcj8q   1/1     Running     0          84s
 28 nginx-deployment-01-5754944d6c-p42mh   1/1     Running     0          84s

2.2 NodeSelector定向調度

當需要手動指定將Pod調度到特定Node上,可以通過Node的標簽(Label)和Pod的nodeSelector屬性相匹配。 # kubectl label nodes <node-name> <label-key>=<label-value> node節點創建對應的label後,可通過在定義Pod的時候加上nodeSelector的設置實現指定的調度。 示例:
  1 [root@uk8s-m-01 study]# kubectl label nodes 172.24.9.14 speed=io
  2 node/172.24.9.14 labeled
  3 [root@uk8s-m-01 study]# vi nginx-master-controller.yaml
  4 kind: ReplicationController
  5 metadata:
  6   name: nginx-master
  7   labels:
  8     name: nginx-master
  9 spec:
 10   replicas: 1
 11   selector:
 12     name: nginx-master
 13   template:
 14     metadata:
 15       labels:
 16         name: nginx-master
 17     spec:
 18       containers:
 19       - name: master
 20         image: nginx:1.7.9
 21         ports:
 22         - containerPort: 80
 23       nodeSelector:
 24         speed: io
 25 
 26 [root@uk8s-m-01 study]# kubectl create -f nginx-master-controller.yaml
 27 [root@uk8s-m-01 study]# kubectl get pods -o wide
 28 NAME                READY   STATUS    RESTARTS    AGE    IP            NODE
 29 nginx-master-7fjgj  1/1     Running   0           82s    172.24.9.71   172.24.9.14
提示:可以將集群中具有不同特點的Node貼上不同的標簽,實現在部署時就可以根據應用的需求設置NodeSelector來進行指定Node範圍的調度。 註意:若在定義Pod中指定了NodeSelector條件,但集群中不存在符合該標簽的Node,即使集群有其他可供使用的Node,Pod也無法被成功調度。

2.3 NodeAffinity親和性調度

親和性調度機制極大的擴展了Pod的調度能力,主要增強功能如下:
  1. 更具表達力,即更精細的力度控制;
  2. 可以使用軟限制、優先採用等限制方式,即調度器在無法滿足優先需求的情況下,會使用其他次條件進行滿足;
  3. 可以依據節點上正在運行的其他Pod的標簽來進行限制,而非節點本身的標簽,從而實現Pod之間的親和或互斥關係。
目前有兩種節點親和力表達: requiredDuringSchedulingIgnoredDuringExecution:硬規則,必須滿足指定的規則,調度器才可以調度Pod至Node上(類似nodeSelector,語法不同)。 preferredDuringSchedulingIgnoredDuringExecution:軟規則,優先調度至滿足的Node的節點,但不強求,多個優先順序規則還可以設置權重值。 IgnoredDuringExecution指:如果一個Pod所在的節點在Pod運行期間標簽發生了變化,不再符合該Pod的節點親和性需求,則系統將忽略Node上Label的變化,該Pod能繼續在該節點運行。 示例: 條件1:只運行在amd64的節點上;儘量運行在ssd節點上。
  1 [root@uk8s-m-01 study]# vi nodeaffinity-pod.yaml
  2 apiVersion: v1
  3 kind: Pod
  4 metadata:
  5   name: with-node-affinity
  6 spec:
  7   affinity:
  8     nodeAffinity:
  9       requiredDuringSchedulingIgnoredDuringExecution:
 10         nodeSelectorTerms:
 11         - matchExpressions:
 12           - key: kubernetes.io/arch
 13             operator: In
 14             values:
 15             - amd64
 16       preferredDuringSchedulingIgnoredDuringExecution:
 17       - weight: 1
 18         preference:
 19           matchExpressions:
 20           - key: disk-type
 21             operator: In
 22             values:
 23             - ssd
 24   containers:
 25   - name: with-node-affinity
 26     image: gcr.azk8s.cn/google_containers/pause:2.0
NodeAffinity操作語法;In、NotIn、Exists、DoesNotExist、Gt、Lt。NotIn和DoesNotExist可以實現互斥功能。 NodeAffinity規則設置註意事項:
  • 若同時定義nodeSelector和nodeAffinity,則必須兩個條件都滿足,Pod才能最終運行指定在Node上;;
  • 若nodeAffinity指定多個nodeSelectorTerms,則只需要其中一個能夠匹配成功即可;
  • 若nodeSelectorTerms中有多個matchExpressions,則一個節點必須滿足所有matchExpressions才能運行該Pod。

2.4 PodAffinity親和性調度

PodAffinity根據節點上正在運行的Pod標簽而不是Node標簽來判斷和調度,要求對節點和Pod兩個條件進行匹配。 規則描述為:若在具有標簽X的Node上運行了一個或多個符合條件Y的Pod,則Pod應該(或者不應該)運行在這個Node上。 X通常為Node節點的機架、區域等概念,Pod是屬於某個命名空間,所以條件Y表達的是一個或全部命名空間中的一個Label Selector。 Pod親和性定義與PodSpec的affinity欄位下的podAffinity欄位里,互斥性定義於同一層次的podAntiAffinity子欄位中。 舉例:
  1 [root@uk8s-m-01 study]# vi nginx-flag.yaml	#創建名為pod-flag,帶有兩個標簽的Pod
  2 apiVersion: v1
  3 kind: Pod
  4 metadata:
  5   name: pod-affinity
  6 spec:
  7   affinity:
  8     podAffinity:
  9       requiredDuringSchedulingIgnoredDuringExecution:
 10       - labelSelector:
 11           matchExpressions:
 12           - key: security
 13             operator: In
 14             values:
 15             - S1
 16         topologyKey: kubernetes.io/hostname
 17   containers:
 18   - name: with-pod-affinity
 19     image: gcr.azk8s.cn/google_containers/pause:2.0
  1 [root@uk8s-m-01 study]# vi nginx-affinity-in.yaml	#創建定義標簽security=S1,對應如上Pod “Pod-flag”。
  2 apiVersion: v1
  3 kind: Pod
  4 metadata:
  5   name: pod-affinity
  6 spec:
  7   affinity:
  8     podAffinity:
  9       requiredDuringSchedulingIgnoredDuringExecution:
 10       - labelSelector:
 11           matchExpressions:
 12           - key: security
 13             operator: In
 14             values:
 15             - S1
 16         topologyKey: kubernetes.io/hostname
 17   containers:
 18   - name: with-pod-affinity
 19     image: gcr.azk8s.cn/google_containers/pause:2.0
 20 
 21 [root@uk8s-m-01 study]# kubectl create -f nginx-affinity-in.yaml
 22 [root@uk8s-m-01 study]# kubectl get pods -o wide
clipboard 提示:由上Pod親和力可知,兩個Pod處於同一個Node上。
  1 [root@uk8s-m-01 study]# vi nginx-affinity-out.yaml	#創建不能與參照目標Pod運行在同一個Node上的調度策略
  2 apiVersion: v1
  3 kind: Pod
  4 metadata:
  5   name: anti-affinity
  6 spec:
  7   affinity:
  8     podAffinity:
  9       requiredDuringSchedulingIgnoredDuringExecution:
 10       - labelSelector:
 11           matchExpressions:
 12           - key: security
 13             operator: In
 14             values:
 15             - S1
 16         topologyKey: failure-domain.beta.kubernetes.io/zone
 17     podAntiAffinity:
 18       requiredDuringSchedulingIgnoredDuringExecution:
 19       - labelSelector:
 20           matchExpressions:
 21           - key: security
 22             operator: In
 23             values:
 24             - nginx
 25         topologyKey: kubernetes.io/hostname
 26   containers:
 27   - name: anti-affinity
 28     image: gcr.azk8s.cn/google_containers/pause:2.0
 29 
 30 [root@uk8s-m-01 study]# kubectl get pods -o wide	#驗證

2.5 Taints和Tolerations(污點和容忍)

Taint:使Node拒絕特定Pod運行; Toleration:為Pod的屬性,表示Pod能容忍(運行)標註了Taint的Node。 Taint語法:$ kubectl taint node node1 key=value:NoSchedule 解釋:為node1加上一個Taint,該Taint的鍵為key,值為value,Taint的效果為NoSchedule。即除非特定聲明可以容忍此Taint,否則不會調度至node1上。 Toleration示例:
  1 tolerations:
  2 - key: "key"
  3   operator: "Equal"
  4   value: "value"
  5   effect: "NoSchedule"
  1 tolerations:
  2 - key: "key"
  3   operator: "Exists"
  4   effect: "NoSchedule"
註意:Pod的Toleration聲明中的key和effect需要與Taint的設置保持一致,並且滿足以下條件:
  • operator的值是Exists(無須指定value);
  • operator的值是Equal並且value相等;
  • 空的key配合Exists操作符能夠匹配所有的鍵和值;
  • 空的effect匹配所有的effect。
若不指定operator,則預設值為Equal。 taint說明:系統允許在同一個Node上設置多個taint,也可以在Pod上設置多個toleration。Kubernetes調度器處理多個taint和toleration的邏輯順序:首先列出節點中所有的taint,然後忽略pod的toleration能夠匹配的部分,剩下的沒有忽略掉的taint就是對pod的效果。以下是幾種特殊情況: 若剩餘的taint中存在effect=NoSchedule,則調度器不會把該Pod調度到這一節點上; 若剩餘的taint中沒有NoSchedule效果,但有PreferNoSchedule效果,則調度器會嘗試不把這個Pod指派到此節點; 若剩餘taint的效果有NoSchedule,並且這個Pod已經在該節點上運行,則會被驅逐,若沒有在該節點上運行,也不會再被調度到該節點上。 示例:
  1 $ kubectl taint node node1 key=value1:NoSchedule
  2 $ kubectl taint node node1 key=value1:NoExecute
  3 $ kubectl taint node node1 key=value2:NoSchedule
  4 tolerations:
  5 - key: "key1"
  6   operator: "Equal"
  7   value: "value"
  8   effect: "NoSchedule"
  9 tolerations:
 10 - key: "key1"
 11   operator: "Equal"
 12   value: "value1"
 13   effect: "NoExecute"
釋義:此Pod聲明瞭兩個容忍,且能匹配Node1的taint,但是由於沒有能匹配第三個taint的toleration,因此此Pod依舊不能調度至此Node。若該Pod已經在node1上運行了,那麼在運行時設置了第3個taint,它還能繼續在node1上運行,這是因為Pod可以容忍前兩個taint。 通常,若node加上effect=NoExecute的taint,那麼該Node上正在運行的所有無對應toleration的Pod都會被立刻驅逐,而具有相應toleration的Pod則永遠不會被驅逐。同時,系統可以給具有NoExecute效果的toleration加入一個可選的tolerationSeconds欄位,表明Pod可以在taint添加到Node之後還能在此Node運行多久。
  1 tolerations:
  2 - key: "key1"
  3   operator: "Equal"
  4   value: "value"
  5   effect: "NoSchedule"
  6   tolerationSeconds: 3600
釋義:若Pod正在運行,所在節點被加入一個匹配的taint,則這個pod會持續在該節點運行3600s後被驅逐。若在此期限內,taint被移除,則不會觸發驅逐事件。 Taints和Tolerations常用場景:
  • 獨占節點:
給特定的節點運行特定應用。 $ kubectl taint nodes 【nodename】 dedicated=groupName:NoSchedule 同時在Pod中設置對應的toleration配合,帶有合適toleration的Pod允許同時使用其他節點一樣使用有taint的節點。
  • 具有特殊硬體設備的節點
集群中部分特殊硬體(如安裝了GPU),則可以把不需要占用GPU的Pod禁止在此Node上
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • "點我查看秘籍連載" 進程表和進程數據結構 內核負責管理維護所有進程,為了管理進程,內核在內核空間維護了一個稱為 進程表 (Process Table)的數據結構,這個數據結構中記錄了所有進程,每個進程在數據結構中都稱為一個 進程表項 (Process Table Entry),如圖。 從圖中可知, ...
  • 版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。本文鏈接:https://blog.csdn.net/wzt_007/article/details/78622698通信分為四大步驟,握手、數據交換、準備結束、正式結束 如以下場景: 兩個陌生人 ...
  • 使用man手冊的方式,能大大加快開發速度,可能安裝的時候有些安裝不完整,下麵結合網路上搜索信息進行補充: $ sudo apt-get install manpages $ sudo apt-get install manpages-dev $ sudo apt-get install manpag ...
  • 軟鏈接的創建,刪除,修改 創建軟鏈接:ln -s【目標文件或目錄】【軟鏈接地址】 解釋:軟鏈接地址相當於快捷方式,目標文件或目錄才是真正的內容。【軟鏈接地址】指“快捷鍵”文件名稱,該文件是被指令創建的。【目標目錄】指軟連接指向的目標目錄。 [root@localhost ~]# ln -s /usr ...
  • 常操作linux系統的都會用到:ps -ef 命令,是一個非常強大的進程查看命令。 在使用Nginx時,那麼我想要看這個Nginx相關的進程,可以使用如下命令”: ps -ef | fgrep nginx 可以看到其安裝位置和配置文件。 讓你對當前應用的進程有詳細的瞭解,你可以經常使用該命令進行查看 ...
  • 1、ifconfig命令臨時配置IP地址 2、setup工具永久配置IP地址 3、修改網路配置文件 4、圖形界面配置IP地址 ifconfig命令臨時配置IP地址 主要的作用是查看網路信息,也可以臨時設置網卡IP地址 輸出的第一行信息: 首先標明瞭是乙太網和當前電腦的網卡的MAC地址 第二行信息: ...
  • OSI/ISO七層模型和TCP/IP四層模型 網路層協議和IP劃分 OSI的七層框架 物理層:設備之間的比特流的傳輸、物理介面、電氣特性等。 數據鏈路層:成幀、用MAC地址訪問媒介、錯誤檢測與修正。 網路層:提供邏輯地址、選路。 傳輸層:可靠與不可靠的傳輸、傳輸前的錯誤檢測、流量控。 會話層:對應用 ...
  • Ctrl + Alt + Fx Linux多用戶、多任務切換 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...