Docker存儲捲(V18.X)

来源:https://www.cnblogs.com/wdliu/archive/2019/03/01/10456974.html
-Advertisement-
Play Games

簡介 介紹 Docker的存儲捲稱之為volume,本質上容器上的一個或者多個目錄,而這些目錄繞過了聯合文件系統,與宿主機中的目錄或者其他容器目錄進行了綁定關係,這種綁定關係可以看作Linux的mount操作,當容器中的程式對這些目錄寫入數據時,其實寫入到的是與之綁定的宿主機目錄上,這樣就實現了數據 ...


簡介

介紹

  Docker的存儲捲稱之為volume,本質上容器上的一個或者多個目錄,而這些目錄繞過了聯合文件系統,與宿主機中的目錄或者其他容器目錄進行了綁定關係,這種綁定關係可以看作Linux的mount操作,當容器中的程式對這些目錄寫入數據時,其實寫入到的是與之綁定的宿主機目錄上,這樣就實現了數據的存儲功能。特別說明:本文章所使用的docker版本基於v18.X,對於較早版本的docker並不適合,例如tmpfs類型捲是v17.06新加入的存儲捲。

作用

  預設情況下,容器不使用任何 volume時,容器的數據被保存在容器之內,它只在容器的生命周期記憶體在,會隨著容器的刪除而被刪除,而想要持久化的存儲這些數據,就得使用存儲捲。特別的,保存容器中的數據也可以使用 docker commit 命令將容器提交為一個新的鏡像,這個鏡像中會保存容器運行時的所有數據(綁定的數據捲除外),但此種方法非常不推薦,因為這樣的鏡像通常會很大,鏡像拉取以及運行容器都會變慢。當容器使用了存儲捲,即使容器被刪除了,但是與綁定的存儲捲還在,對應目錄的數據都會保存,如果想要恢復該容器,只要新建的容器綁定該存儲捲,對應目錄的數據也會隨之恢復。

分類

  Docker存儲捲可分為兩類:

  • Volumes:數據捲,這類存儲捲是被Docker Daemon管理,可使用docker volume create顯示創建,被創建出來的捲位於/var/lib/docker/volumes/下,使用時候只需指定使用捲的名稱以及對應的容器的一個目錄,刪除時候只需指定刪除捲名即可,這類數據捲是存儲數據最為推薦的方式。
  • Bind mounts :綁定掛載捲,從早版本docker提供,這類存儲捲可以是宿主機的任意目錄,也可以是來自其他容器的目錄,不受docker Daemon管理,刪除時候需要手動清理目錄。
  • tmpfs mounts:臨時掛載捲,該類存儲捲數據存放在主機記憶體中,好處在於這類存儲捲由於使用的tmpfs格式文件系統,讀寫性能好,但同時也增加了主機的記憶體開銷,Docker早期版本不支持此類存儲捲。

以下是其示意圖:

 

存儲捲使用

--volume&&--mount

  存儲捲的使用是在docker run命令時候使用-v或者--volume來指明使用的存儲捲,但是如果需要指明更多選項如捲類型、驅動等那就需要使用--mount來指明更多的選項。以下是兩種選擇的使用方法。

-v或--volume選項:[volume_name]:container_path:[options]

解釋:

由三個欄位組成,用冒號字元(:)分隔,欄位必須按正確的順序排列
volume_name:捲名,可省略,省略的時候預設會分配一個隨機目錄,在/var/lib/docker/volumes/隨機目錄/_data。還可以指定宿主機目錄。
container_path:綁定的容器中的目錄,必須。
options:其他選項,是逗號分隔的選項列表,例如讀寫模式(ro、rw),可省略。

示例:創建一個綁定掛載捲

 

--mount:該選項從V17.06加入,由多個鍵值對組成,用逗號分隔,每個鍵值由<key>=<value>組成。常用的key如下:

  • type:指明捲的類型,三種類型之一bind、volume、tmpfs
  • source:可簡寫為src,指定掛載來源通常是捲名稱,匿名捲時忽略該選項
  • destination:可簡寫為dst或target,指定容器中的使用的目錄
  • readonly:指定捲是否為只讀
  • volume-opt:其他掛載選項可以多次使用,採用volume-opt=type=nfs

示例:將上述容器使用--mount啟動(這裡換一個名稱為nginx-c2):

 

使用建議:兩個命令能都實現數據捲的掛載,如果是老用戶可以繼續使用-v的方式來運行容器,如果是新用戶推薦使用--mount,這樣的語法比較簡介明瞭,比如人性化的各種選項src、type、dest,但是如果需要使用tmpfs類型的數據捲時候必須使用--mount。

使用Volumes

  volume類型的數據捲是比較推薦方式,它是能被Docker 管理的捲, 使用流程是先創建捲,在使用-v或--mount進行掛載。如果在docker run時候不指定其宿主機目錄,則預設也屬於volumes類型,也受Docker管理。 

創建捲

[root@app51 ~]# docker volume create data-vol    
data-vol
[root@app51 ~]# docker volume inspect data-vol
[
    {
        "CreatedAt": "2019-02-28T17:39:36+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/data-vol/_data",
        "Name": "data-vol",
        "Options": {},
        "Scope": "local"
    }
]
[root@app51 ~]# 

掛載捲並寫入數據

[root@app51 ~]# docker run -it --name  bs1 -v data-vol:/data/tmp  busybox:latest /bin/sh
/ # ls /data/tmp/
/ # echo "hello world" > /data/tmp/index.html 
/ # 

在宿主機上查看:

創建捲是還可以指定其他,列如指定大小、uid等其他選項,這些選項都是mount命令的選項,捲的管理中會介紹:

[root@app51 ~]# docker volume create --driver local  --opt type=tmpfs   --opt device=tmpfs  --opt o=size=100m,uid=1000 test-vol6
test-vol6
[root@app51 ~]# docker run -it --name  bs6 -v test-vol6:/data/tmp  busybox:latest /bin/sh                                                                 
/ # ls /data
tmp

上面的掛載命令使用等價--mount:

[root@app51 ~]# docker run -it --name  bs7 --mount type=volume,src=test-vol6,dst=/data/tmp  busybox:latest /bin/sh     
/ # 

 

容器內可以使用mount命令可以查看掛載點:

 

使用bind mounts

  綁定掛載捲使用,無非指定宿主機的具體某個目錄,可以使用-v HOST_PATH:CONTAINER_PATH 也可以使用--mount type=bind,src=HOST_PATH,dst=CONTAINER_PATH。

示例:

[root@app51 ~]#  docker run -it --name bind-vol  -v "$(pwd)":/data busybox:latest /bin/sh
/ # ls /data
Dockerfile        a.txt             anaconda-ks.cfg   dr.sh             nat.sh            nginx-bus.tar.gz  nginx.tar
/ # 

等價於使用--mount:

[root@app51 ~]#  docker run -it --name bind-vol-1 --mount type=bind,src="$(pwd)",dst=/data busybox:latest /bin/sh                             
/ # ls /data
Dockerfile        a.txt             anaconda-ks.cfg   dr.sh             nat.sh            nginx-bus.tar.gz  nginx.tar
/ # 

以只讀的方式掛載:

[root@app51 ~]#  docker run -it --name bind-vol-2 --mount type=bind,src="$(pwd)",dst=/data,readonly busybox:latest /bin/sh 
/ # ls /data/
Dockerfile        a.txt             anaconda-ks.cfg   dr.sh             nat.sh            nginx-bus.tar.gz  nginx.tar
/ # cd /data/
/data # touch 1.txt
touch: 1.txt: Read-only file system
/data # 

查看捲(新開終端):

[root@app51 ~]# docker inspect bind-vol-2

 "Mounts": [
                {
                    "Type": "bind",
                    "Source": "/root",
                    "Target": "/data",
                    "ReadOnly": true
                }
            ],

 

使用tmpfs mounts

  tmpfs類型的捲只適用於Linux系統,命令行中除了使用--mount指定外還可以使用--tmpfs指定其類型。特別註意的,與volume捲和綁定掛載捲相反,tmpfs掛載是臨時的,並且僅在主機記憶體中持久存在,當容器停止時,將刪除tmpfs掛載,並且不會保留寫在那裡的文件。

示例 使用--mount:

[root@app51 ~]# docker run -it  --name tmpfs-c1  --mount type=tmpfs,dst=/app busybox:latest /bin/sh   
/ # 
/ # mount |grep /app
tmpfs on /app type tmpfs (rw,nosuid,nodev,noexec,relatime)

等價於使用--tmpfs:

[root@app51 ~]# docker run -it  --name tmpfs-c2   --tmpfs /app busybox:latest /bin/sh                        
/ # mount |grep /app 
tmpfs on /app type tmpfs (rw,nosuid,nodev,noexec,relatime)
/ # 

查看掛載捲:

[root@app51 ~]# docker inspect tmpfs-c1 

"Mounts": [
            {
                "Type": "tmpfs",
                "Source": "",
                "Destination": "/app",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

註意--mount選項還支持指定掛載目錄的大小和許可權,選項如下:

tmpfs-size 設置tmpfs類型捲的大小,預設無限制(即由宿主機記憶體決定)
tmpfs-mode 設置tmpfs類型捲掛載的目錄許可權,如1770。預設1777

 

 

 

 指定一個大小為50m,目錄選項為1770類似為tmpfs的存儲捲:

[root@app51 ~]# docker run -it --name tmpfs-c3  --mount type=tmpfs,dst=/data/tmp,tmpfs-mode=1770,tmpfs-size=50m busybox:latest /bin/sh
/ # 
/ # 
/ # mo
modinfo     modprobe    more        mount       mountpoint
/ # mount |grep /data/tmp
tmpfs on /data/tmp type tmpfs (rw,nosuid,nodev,noexec,relatime,size=51200k,mode=1770)
/ # ls /data/ -l
total 0
drwxrwx--T    2 root     root            40 Mar  1 01:47 tmp

查看其存儲捲信息:

[root@app51 ~]# docker inspect tmpfs-c3 

"Mounts": [
            {
                "Type": "tmpfs",
                "Source": "",
                "Destination": "/data/tmp",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

使用容器數據捲 

  除了以上數據捲外,還可以直接使用容器中已經掛載的數據捲,使用--volumes-from指定,此時兩個容器的數據捲是共用的。從本質上來講,這兩數據捲共同掛載了宿主機上的同一個目錄。

示例:創建一個容器share-c1掛載當前目錄(確保不要退出)

[root@app51 ~]# docker run -it --name share-c1 -v $(pwd):/data busybox:latest /bin/sh 
/ # ls /data/
Dockerfile        a.txt             anaconda-ks.cfg   backup.tar        dr.sh             nat.sh            nginx-bus.tar.gz  nginx.tar
/ # 

在運行一個容器掛載share-c1的捲:

[root@app51 ~]# docker run -it --name share-c2 --volumes-from share-c1 busybox:latest /bin/sh 
/ # ls /data/
Dockerfile        a.txt             anaconda-ks.cfg   backup.tar        dr.sh             nat.sh            nginx-bus.tar.gz  nginx.tar
/ # 

 

存儲捲管理

  docker存儲捲管理通過docker volume命令組實現,v18.09的命令集合如下:

1.創建存儲捲

docker volume create [OPTIONS] [VOLUME_NAME]

通常這樣創建的捲會保存在宿主機目錄/var/lib/docker/volumes/VOLUME_NAME/_data如果不指名 VOLUME則會創建匿名捲,方式等同於在docker run -v不指定宿主機目錄。

常用選項:

 -o, --opt :指定存儲捲掛載選項。常用選項如下:

  • type: 掛載文件系統類型,可以是tmpfs、brtfs、甚至是nfs。
  • device:掛載的設備,
  • o:mount命令掛載選項,其選項可參考這裡

示例一:創建一個普通的捲名稱為test-vol-1。

[root@app51 test-vol-1]# docker volume create test-vol-1
test-vol-1
[root@app51 test-vol-1]# ls /var/
adm/      crash/    empty/    gopher/   lib/      lock/     mail/     opt/      run/      tmp/      yp/       
cache/    db/       games/    kerberos/ local/    log/      nis/      preserve/ spool/    .updated  
[root@app51 test-vol-1]# ls /var/lib/docker/volumes/test-vol-1/ -l
總用量 0
drwxr-xr-x 2 root root 6 3月   1 11:08 _data
[root@app51 test-vol-1]# 

示例二:創建一個tmpfs類型的存儲捲,名稱為test-vol-2

[root@app51 test-vol-1]# docker volume create --opt type=tmpfs  --opt device=tmpfs  --opt o=size=100m,uid=1000  test-vol-2
test-vol-2


###掛載test-vol-2
[root@app51 test-vol-1]# docker run -it --name bs-c10 -v test-vol-2:/data busybox:latest /bin/sh
/ # mount |grep /data
tmpfs on /data type tmpfs (rw,relatime,size=102400k,uid=1000)
/ # 

示例三:創建一個nfs類型的存儲捲,伺服器地址為10.1.210.52,許可權讀寫,目錄為/data/tmp,名稱為test-vol-3

[root@app51 test-vol-1]# docker volume create --opt type=nfs --opt o=addr=10.1.210.52,rw  --opt device=:/data/tmp test-vol-3
test-vol-3

需要註意的是:創建的捲即使創建成功了但是掛載的時候很可能出錯,docker不會在創建捲時候檢查掛載選項是否符合要求。

 2.查看存儲捲詳情

 docker volume inspect [OPTIONS] VOLUME [VOLUME...]

常用選項:

 -f, --format :輸出格式,基於go模版

示例:

[root@app51 ~]# docker inspect test-vol-1
[
    {
        "CreatedAt": "2019-03-01T11:08:00+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/test-vol-1/_data",
        "Name": "test-vol-1",
        "Options": {},
        "Scope": "local"
    }
]

使用-f:.代表以根開頭,Name是一級欄位。

[root@app51 ~]# docker inspect test-vol-1 -f {{.Name}}
test-vol-1
[root@app51 ~]# 

3.查看所有存儲捲

docker volume ls [OPTIONS]

常用選項:

-f, --filter 過濾具體存儲捲

示例:

[root@app51 ~]# docker volume ls 
DRIVER              VOLUME NAME
local               test-vol-1
local               test-vol-2
local               test-vol-3
[root@app51 ~]# 

過濾某個捲:

[root@app51 ~]# docker volume ls -f name=test-vol-1 
DRIVER              VOLUME NAME
local               test-vol-1

4.刪除一個或多個捲

  docker volume rm [OPTIONS] VOLUME [VOLUME...]

常用選項:

-f, --force 強制刪除存儲捲,即使它還在被使用

[root@app51 ~]# docker volume ls
DRIVER              VOLUME NAME
local               test-vol-1
local               test-vol-2
local               test-vol-3
[root@app51 ~]# docker volume rm test-vol-3
test-vol-3
[root@app51 ~]# docker volume ls 
DRIVER              VOLUME NAME
local               test-vol-1
local               test-vol-2
[root@app51 ~]# 

5.移除本地未使用的捲

docker volume prune [OPTIONS]

[root@app51 ~]# docker volume prune 
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
test-vol-1

Total reclaimed space: 0B
[root@app51 ~]# 

 

數據捲的備份與恢復

數據備份

  容器中的數據捲備份有兩種方式,一是你可以直接備份與之對應的宿主機目錄,二則運行一個容器掛載有數據的容器將其備份到與之對應的宿主機目錄。這裡演示下第二種數據備份方法。

方法:

1.創建備份容器並掛載需要備份的目錄,同時掛載宿主機目錄進行備份任務。

2.運行備份指令並將備份數據放到掛載的宿主機目錄,以下示例為/backup,將數據備份在來/backup就等於備份在了宿主機的$(pwd)目錄下,也就是當前目錄。

新建一個數據容器並寫入數據:

[root@app51 ~]# docker run -it --name data-c1 -v /data busybox:latest /bin/sh                    
/ # cd /data/
/data # touch 1.txt
/data # echo "hello world" > index.html
/data # ls -l
total 4
-rw-r--r--    1 root     root             0 Mar  1 07:40 1.txt
-rw-r--r--    1 root     root            12 Mar  1 07:40 index.html
/data # 

創建備份容器同時掛載兩個目錄進行數據備份:

[root@app51 ~]#  docker run --rm --volumes-from data-c1 -v $(pwd):/backup centos tar cvf /backup/backup.tar /data
/data/
/data/1.txt
/data/index.html
tar: Removing leading `/' from member names

查看備份數據:

[root@app51 ~]# ls -l
總用量 220332
-rw-------. 1 root root      1258 1月  16 00:15 anaconda-ks.cfg
-rw-r--r--  1 root root         7 2月  27 10:25 a.txt
-rw-r--r--  1 root root     10240 3月   1 15:42 backup.tar
-rw-r--r--  1 root root        76 2月  27 19:14 Dockerfile
-rw-r--r--  1 root root       578 1月  16 10:41 dr.sh
-rw-r--r--  1 root root       559 1月  16 14:53 nat.sh
-rw-------  1 root root 114356736 2月  24 10:56 nginx-bus.tar.gz
-rw-------  1 root root 111224320 2月  23 19:18 nginx.tar
[root@app51 ~]# tar tvf backup.tar 
drwxr-xr-x root/root         0 2019-03-01 15:40 data/
-rw-r--r-- root/root         0 2019-03-01 15:40 data/1.txt
-rw-r--r-- root/root        12 2019-03-01 15:40 data/index.html

 

數據恢復 

  恢複數據的原理與備份類似,也是啟動一個容器共用需要備份的目錄,同時掛載宿主機的備份目錄,最後解壓數據到備份目錄中。為了演示數據恢復,我將上述容器 data-c1中的data目錄中文件全部刪除:

[root@app51 ~]# docker run -it --name data-c1 -v /data busybox:latest /bin/sh 
/ # cd /data/
/data # rm -rf *
/data # 

創建一個恢復容器:

[root@app51 ~]# docker run --rm --volumes-from data-c1 -v $(pwd):/backup centos bash -c "cd / && tar xvf /backup/backup.tar"    
data/
data/1.txt
data/index.html
[root@app51 ~]# 

再次查看data-c1容器數據:

/data # rm -rf data
/data # 
/data # 
/data # 
/data # 
/data # ls -l
total 4
-rw-r--r--    1 root     root             0 Mar  1 07:40 1.txt
-rw-r--r--    1 root     root            12 Mar  1 07:40 index.html
/data # 

 

  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我叫王龍龍,來自河南平頂山,初中畢業就去上了技校,當時也是特別迷茫,便隨大流選擇了汽修行業,學了一年就被分配出來在工廠實習上班,後來慢慢長大了,也懂事了,覺得工廠實在無聊,然後就自己辭職找工作,在鄭州漂泊了兩年,結果依然沒有任何的收穫和存款,就決心重新學習一門技術,提升自己的能力,以在社會上更好的生 ...
  • 創建簡單模型 您可以使用 Simulink® 對系統建模,然後模擬該系統的動態行為。Simulink 允許您創建模塊圖,圖中的各個連接模塊代表系統的各個部分,信號代表這些模塊之間的輸入/輸出關係。Simulink 的主要功能是對系統各個組件隨時間流逝的行為變化進行模擬。簡單來講就是:採用一個時鐘,按 ...
  • 轉載請標明出處,維權必究:https://www.cnblogs.com/tangZH/p/10458388.html linux系統下能夠直接用命令行查看so庫的信息,但是window系統下咋辦好呢?涼拌~ 還是找到了辦法,這麼辦: 首先下載cygwin,這個工具到底是啥,其實它能夠讓我們在win ...
  • 在Linux系統中,目錄被組織成一個: 單根倒置樹結構 ,文件系統從根目錄開始,用/來表示。文件名稱 區分大小寫 ( 大小寫敏感還需要看具體的文件系統格式 ),以.開頭的為隱藏文件, 路徑用/來進行分割 (windows中使用\來分割),文件有兩個種類: 元數據與數據本身 .在操作linux系統時, ...
  • 1.在啟動的時候按住方向鍵停留在內核選項頁面,在內核選項出按e鍵 2.進入到另一個頁面後,尋找到以linux16開頭的地方,按end到行後,輸入空格,然後輸入rd.break console=tty0,並按ctrl+x組合鍵進入到GRUB引導頁面 3.進入之後,輸入掛載命令改變根分區的掛載選項,命令 ...
  • 使用命令: 說明:user 為當前用戶; 完畢! ...
  • 1.在Linux系統中的【 ~/.baserc 】文件與【 /etc/profile 】配置環境變數後(可以使任意環境變數)無效的現象,如下為解決辦法: 使用命令: 在 【# User configuration】下添加環境變數; 如圖說明: 2.也可以直接將【 ~/.baserc 】文件或【 /e ...
  • 0x00 ubuntu server 16.04 開啟root密碼登錄由於眾多VPS預設使用證書驗證登錄,雖然安全但使用十分不便,所以特提供開啟root用戶並使用密碼登錄方法。0x01 為root賬戶設置密碼$ sudo passwd root0x02 進入root賬戶$ su root0x03 編... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...