Docker 快速入門實操教程(完結)

Docker 快速入門實操教程(完結)

Docker,啟動!

如果安裝好Docker不知道怎么使用,不理解各個名詞的概念,不太了解各個功能的用途,這篇文章應該會對你有幫助。

前置條件:已經安裝Docker并且Docker成功啟動。

實操內容:使用Docker容器替換本地安裝的程序并遷移數據(MySQLredis)。

最終目的:熟練使用Docker各項功能。

理解概念

Docker官方提供了一個分發平臺DockerHub,可以從上面拉取已經提供好的鏡像直接構建容器運行。

這個過程會涉及到Docker的一些概念,在剛接觸的時候比較抽象,這里以烘焙出一個蛋糕為例子說明一下:

  • Dockerfile 蛋糕的配方。配方上詳細列出了需要的材料(如面粉、糖、雞蛋)以及烘焙的步驟(如先將面粉和糖混合,然后加入雞蛋攪拌)。
  • 鏡像(Image): 按照配方做出了一個半成品蛋糕,這就是蛋糕的"鏡像" 。這個蛋糕可以被任何人復制,每一個復制品都會和原蛋糕一模一樣。
  • 容器(Container): 將半成品蛋糕烘焙后,得到一個可食用的蛋糕。可以根據同一個鏡像制作出很多個完全一樣的蛋糕,也可以在烘焙時自己加一些材料。每個蛋糕都是獨立的,和其他蛋糕沒有關聯。

所以從DockerHub拉取鏡像并且跑起來的過程就可以理解為:

  1. 鏡像提供者編寫好了配方( Dockerfile ),將其制成( 構建 )了半成品蛋糕( 鏡像 )。
  2. 用戶購買( 拉取 )這個半成品蛋糕。
  3. 烘焙( 創建 )后得到了一個可食用的蛋糕( 容器 ),食用蛋糕( 運行容器 )。
  4. 通常創建容器和運行容器都會歸攏在同一步:創建并運行。

還有另外兩個比較重要的概念: 層(Layers緩存(Cache ,目前不會接觸到,可以在看 構建/推送鏡像 這一節時再去深入理解。

創建/運行容器

每一步都提供了Docker desktop(簡稱桌面版)的操作截圖和終端命令(桌面版界面友好但局限較大,僅適合初步上手)。

拉取鏡像

DockerHub拉取MySQL鏡像到本地,這一步可能會因為網絡原因失敗,可以配置其他鏡像源或者使用代理,網上教程很多。

image-20240128210738711

終端命令

docker pull 倉庫地址/命名空間/鏡像名稱:標簽
  • 倉庫地址: 沒有顯式指定倉庫地址時,默認會從DockerHub查找鏡像;拉取私有倉庫的鏡像,需要指定倉庫地址。
  • 命名空間: 截圖最后有一個名為 ubuntu/mysql 的鏡像,其中 ubuntu 是命名空間,用以區分不同的個人或組織發布的鏡像。沒有顯式指定命名空間時,默認會查找官方團隊發布的鏡像。
  • 鏡像名稱: 需要拉取的鏡像的名稱。
  • 標簽: 沒有顯式指定標簽時,默認會拉取 latest 標簽, latest 表示這是最新的版本。

通過 docker pull 拉取鏡像并不是必須的,在 docker run 時,如果本地不存在指定鏡像,Docker會自動拉取。

創建并運行容器

拉取完成后,通過 docker run 創建容器并運行前進行一些配置:

image-20240128213738553

終端命令

# 截圖對應命令
docker run -d --name mysql_8.3.0 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:latest# 完整命令
docker run [選項參數] 倉庫地址/命名空間/鏡像名稱:標簽 [命令行] [命令行參數]
  • 選項參數:

    --name :設置容器名稱,不能重復,這里使用的是 鏡像名_版本號 的方式。

    -p :設置端口映射,將宿主機的 3306 端口映射到容器的 3306 端口,宿主機上的其他進程通過該端口才能訪問到容器內的服務。如果不配置端口映射,則只能在容器內部訪問服務或通過虛擬網絡讓容器可以相互通信。

    -e :設置環境變量,配置 MYSQL_ROOT_PASSWORD=root 用以指定root用戶密碼,這是由鏡像創建者約定的,不同的鏡像配置項會有所不同。

    -v :設置目錄掛載,用法參考 目錄掛載 章節。

    -d :讓容器在后臺運行

  • 命令行: 在容器啟動時執行命令(如 ls ),可以省略。

  • 命令行參數: 傳給 命令行 的額外參數(如 /etc ,這樣在容器啟動時就會執行 ls /etc ),可以省略。

常用命令

容器已經創建好后就不再適用于 docker run 命令了, docker run 命令主要是用于創建新的容器并運行,如果需要啟動已經存在的容器,則使用 docker start 命令。

# 列出所有容器
docker ps -a# 列出所有鏡像
docker image ls
docker images# 啟動容器
docker start 容器名稱/容器ID# 停止容器
docker stop 容器名稱/容器ID# 強制停止容器
docker kill 容器名稱/容器ID# 重啟容器
docker restart 容器名稱/容器ID# 刪除容器
docker rm 容器名稱/容器ID# 刪除鏡像
docker rmi 容器名稱/容器ID

目錄掛載

現存問題:

  • 數據沒有保存到宿主機中,當容器刪除后,數據就丟失了。
  • 宿主機和容器之間的文件傳遞比較麻煩。
  • 多個容器需要共享數據。

目錄掛載可以解決以上問題,Docker為目錄掛載提供了三種方式:

  • bind mount: 把宿主機目錄映射到容器內,雙向文件傳遞。適合變動比較頻繁的場景,比如代碼目錄、配置文件等。

  • volume: 由容器創建和管理,存儲在宿主機中,官方推薦,Linux 文件系統。適合存儲不需要關心的數據,如數據庫數據。

  • tmpfs mount: 適合存儲臨時文件,存儲在宿主機內存中。不可多容器共享。

以MySQL鏡像為例,其 Dockerfile 中寫了創建 volume 用于持久化保存數據的命令(其他鏡像也可以通過這種方式查看需要持久化的目錄)。

image-20240128224015528

雖然 Dockerfile 中有創建 volume 的命令,但是如果創建容器時沒有主動為 volume 命名,其就是匿名 volume Docker會為匿名 volume 隨機生成一個名稱,當掛載該 volume 的容器被刪除后,該 volume 也會被刪除。

當創建容器時主動指定的 volume 路徑和 Dockerfile 約定的路徑一致,則該鏡像創建的 volume 就不會被掛載為匿名 volume 了,容器刪除后該 volume 也會保留,這也是最方便的一種命名方式。

image-20240128220629652

終端命令

docker run -d --name mysql_8.3.0 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -v=mysql_volume:/var/lib/mysql -v D:\mount:/pc_mount mysql:latest

掛載目錄時,如果只賦予了名稱則是 volume 方式,如果指定了具體目錄就是 bind mount 方式。

所以在這個容器中:

  1. 將容器內的 /var/lib/mysql 目錄掛載為 volume 并且命名為 mysql_volume
  2. 將宿主機的 D:\mount目錄映射至容器中的 /pc_mount

在掛載目錄時,如果你指定的目錄不存在于容器中,則會自動創建,這里的 /pc_mount 目錄就會自動被創建。

遷移實操

現在需要將宿主機中MySQL數據遷移到容器中,打算采用navicat的數據遷移工具,那么就需要同時運行兩個數據庫,端口同為 3306 會沖突,宿主機上MySQL端口改起來并不方便,容器創建后端口也不能修改,那么就可以使用數據掛載的方式。

遷移方案:

  1. 停止運行端口為 3306 MySQL容器。
  2. 新創建一個MySQL容器,端口指定為 3305 (或其他任意未被占用的端口),指定 volume 的名稱和端口 3306 的容器一致。
  3. 遷移數據,刪除端口為 3305 的容器,運行端口為 3306 的容器,數據遷移成功。

當數據庫文件較大時,使用navicat遷移則會顯得有些性能不足了,這時候就需要通過命令行導入:

  1. 將需要導入的SQL文件放在宿主機掛載的目錄下(宿主機: D:\mount ;容器: /pc_mount )。

  2. 打開容器的終端

    docker exec -it mysql_8.3.0 bash
    

  3. 登入MySQL并選擇需要導入的數據庫

    mysql -u root -proot
    use test-base;
    source /pc_mount/001.sql;
    

從容器中導出SQL文件到宿主機同理,將SQL文件導出至掛載的 /pc_mount 目錄下,在宿主機的 D:\mount 就可以看到。

虛擬網絡

每個Docker容器都運行在自己的環境中,互不干擾,所以上述內容中都依賴宿主機的端口映射進行容器通信。但是有些時候我們只要讓這個項目能在宿主機上訪問到,并不在意其所依賴的服務是否能夠被宿主機操作和管理。就可以通過Docker提供的虛擬網絡實現容器之間的通信,再映射項目入口到宿主機即可。

桌面版并沒有為虛擬網絡提供較好的GUI支持,需要終端執行。

# 查看已存在的虛擬網絡
docker network ls

默認已經存在了三個虛擬網絡,這是由Docker創建的,對應著不同的網絡驅動類型,驅動類型的區別如下:

  • Bridge網絡: 默認值。容器在獨立的網絡空間運行,可以相互通信并訪問外部網絡。容器內服務能通過端口映射被外部訪問。
  • Host網絡: 容器共享宿主機的網絡空間,不再需要端口映射,直接使用宿主機的端口。這種模式提供了最高的網絡性能,但是失去了隔離性。
  • None網絡: 容器擁有自己的網絡空間,但不配置任何網絡接口。它只有本地回環接口,沒有任何外部網絡訪問能力,提供了最高的網絡隔離性。
# 創建名為 test_net 的網絡
docker network create test_net# 在該網絡下創建兩個容器
docker run --name redis_temp --network=test_net -d redis:latest
docker run --name redisinsight -p 8001:8001 --network test_net -d redislabs/redisinsight:latest

創建了redis容器,但是并沒有為其映射端口。所以現在在宿主機中并不能訪問到這個redis容器。

創建了redisInsight容器并且映射了8001端口,這是一個redisGUI工具,用于測試是否可以通過虛擬網絡訪問到redis容器。

訪問 http://localhost:8001/ 進入redisInsight的主頁,添加一個redis數據庫。

Docker內部的DNS服務會自動將容器名稱解析為容器對應的IP地址(即容器名稱就是域名),所以主機地址填寫容器名稱即可。

image-20240129172212539

連接成功,這樣既可以操作容器內的redis數據,又不會占用宿主機自身的redis應用搶占端口。同理,部署其他項目時,如果項目容器需要連接數據庫容器,也可以通過虛擬網絡實現。

如果容器已經被創建,可以更改已存在的容器的連接的網絡

docker network connect 網絡名稱 容器名稱

使用技巧

查看軟件版本

部分鏡像的 Tag latest ,并沒有明確指出具體的版本號,想要查看版本號就只能手動查看。

桌面版點擊容器右側 ··· 打開更多選項,選擇 Open in terminal 進入容器的終端,執行該軟件查看版本的命令。

終端命令

docker exec mysql_8.3.0 mysql -V

但是問題就來了,如果需要版本號是為了給容器命名,這種方案需要先運行容器,將容器刪除,再重新創建容器,很麻煩。

通常鏡像的環境變量中會指明版本號,可以直接點開鏡像查看

image-20240128220336815

終端命令

docker inspect mysql:latest

這個方式雖然比較方便,但是需要進行推測,并非一定正確。

保持容器運行

當在桌面版運行ubuntu等容器時,會發現容器啟動后就停止了,進入 Exited 狀態,如果想要容器持續運行,就需要需要在容器內部執行一個持續運行的進程。

桌面版已經不能滿足需求了,需要終端執行

docker run -it --name ubuntu_22.04 ubuntu:latest

-t 指令分配一個虛擬的終端或控制臺,可以讓容器持續運行不會關閉。

-i 指令可以讓打開的控制臺能夠接受用戶輸入。

構建/推送鏡像

想要通過Docker將項目部署到服務器上或是分發項目供他人使用,就需要將項目構建為鏡像,官方主要推薦通過 Dockerfile 構建鏡像。 Dockerfile 是一個文本文件(無文件后綴),由一系列的命令和參數構成,這些命令對應了在構建鏡像時的操作步驟。

編寫Dockerfile文件

Dockerfile常用指令:

  • FROM: 指定基礎鏡像。所有后續的操作都是基于這個基礎鏡像進行的。
  • WORKDIR: 設定后續命令的執行目錄。
  • COPY: 復制文件、指定目錄中的所有內容(不含目錄本身)到鏡像中。
  • ADD: 復制文件、指定目錄中的所有內容(不含目錄本身)到鏡像中。對tar格式的壓縮文件會自動解壓。
  • RUN: 構建過程中執行命令。比如安裝一些軟件,創建一些文件等。
  • CMD: 為容器提供默認的執行命令,會被 docker run 的命令行參數覆蓋。
  • ENTRYPOINT: 為容器提供默認的執行命令,不會被 docker run 的命令行參數覆蓋。
  • EXPOSE: 公開容器的一個端口供外部訪問。

通過maven執行 package 手動將項目打包,命名為 output-dem.jar ,在項目根目錄下新建一個 Dockerfile 文件:

# 使用JDK17基礎鏡像
FROM openjdk:17-jdk-slim# 設置工作目錄,容器也會使用該目錄作為工作目錄
WORKDIR /app# 將jar包復制到/app路徑下
COPY target/output-demo.jar app.jar# 設置在運行此鏡像后默認執行的命令,讓它運行剛才的jar包
ENTRYPOINT ["java", "-jar", "app.jar"]# 暴露端口,取決于項目實際使用的端口號
EXPOSE 8080

如果不是Java開發,設備上并沒有安裝 JDK maven 等構建需要的環境(其他語言同理),但是又有打包項目的需求,則可以通過多階段構建的方式,在鏡像中完成編譯等操作:

# 使用包含JDK17和Maven3.8.5的基礎鏡像
# 將本構建階段命名為 build ,以便在后面的階段中引用
FROM maven:3.8.5-openjdk-17-slim AS build# 設置工作目錄,容器也會使用該目錄作為工作目錄
WORKDIR /app# 將當前目錄下的所有文件添加到工作目錄下(.和./都可以表示當前目錄)
ADD . .# 使用Maven構建項目為jar包
RUN mvn clean package
# 使用Maven構建項目為jar包(跳過測試階段)
# RUN mvn clean package -DskipTests=true# 新的構建階段
# 引入JDK17的基礎鏡像
FROM openjdk:17-jdk-slim# 設置工作目錄,容器也會使用該目錄作為工作目錄
WORKDIR /app# 將 build 階段構建jar包復制到新階段的/app路徑下
COPY --from=build /app/target/output-demo.jar app.jar# 設置在運行此鏡像后默認執行的命令,讓它運行剛才的jar包
ENTRYPOINT ["java", "-jar", "app.jar"]# 暴露端口,取決于項目實際使用的端口號
EXPOSE 8080

Docker的多階段構建中,每次使用新的 FROM 指令,都會開始一個新的構建階段,上一階段的指令會創建為一個臨時的鏡像。在新階段中,前一階段的層和設置都被丟棄,只有 --from 指定的之前階段的內容被保留,就像是開始了一個全新的 Dockerfile 一樣。

構建鏡像

寫好 Dockerfile 后,就可以通過該文件構建鏡像了

 docker build -t 倉庫地址/命名空間/鏡像名:標簽 .docker build -t 倉庫地址/命名空間/鏡像名:標簽 -f /path/myDockerfile .

-t 指定鏡像名稱(如果不推送到私有倉庫,僅本地使用, 倉庫地址/命名空間/ 可以省略)。

-f 指定 Dockerfile 所在的目錄,也可以指定 自定義名稱的Dockerfile -f 參數可省略)。

. 使用當前目錄下作為上下文環境, COPY 等命令會從該目錄查找文件。未指定 -f 參數時,則使用上下文環境中名為 Dockerfile 的文件。

推送鏡像

每次發布更改內容都需要打包鏡像后上傳到生產環境再部署很麻煩,將鏡像推送至私有倉庫中,在生產環境直接從倉庫中拉取鏡像則更加高效。

# 登錄倉庫
docker login 倉庫地址# 推送鏡像
docker push 倉庫地址/命名空間/鏡像名:標簽

沒有顯式指定倉庫地址時,默認會將DockerHub作為倉庫地址。

層與緩存

層(Layers): 根據 Dockerfile 構建鏡像時,每一個會改變文件系統狀態的指令( RUNCOPY ADD 等)都會新建一個層 ,每個層都是前一層的改動的結果,并且每個層都只保留改動的部分,共享未改動的部分。依次將所有的層合并起來就是完成的鏡像。

根據這個例子可以方便理解層的概念:

# Dockerfile A
RUN apt-get install -y software-package # 第一層
RUN rm -rf /var/lib/apt/lists/* # 第二層

在這個片段中,第一層中安裝了一個軟件包,第二層中刪除了軟件包。

因為 每個層都是前一層的改動的結果 ,所以第二層的刪除文件并不能影響到第一層,只是會在第二層中對該文件打上一個 刪除 的標記,這個文件會作為一個無用的文件存在于最終構建的鏡像中,增加了鏡像的體積。

# Dockerfile B
RUN apt-get install -y software-package && rm -rf /var/lib/apt/lists/*

在這個片段中,安裝和刪除軟件包是在同一個指令下執行的,所以他們是處于同一層的操作,當這一層的構建結束時,這些文件就會被清理掉,它們也就不會存在于最終的鏡像中了。


緩存: 緩存多個鏡像之間可以共享層,如果多鏡像都是基于同一個基礎鏡像進行構建的。那么,這個基礎鏡像的所有層都只需要存儲一次,就能在所有的鏡像中共享。如果一個鏡像的大部分層已經在本地存在,那么在拉取這個鏡像時,只有不存在的層需要被下載,這可以極大地節省時間和網絡帶寬。

Docker Compose

當項目依賴的服務較多時,每個容器都要單獨配置運行,指定網絡。使用Docker Compose,可以通過一個YAML文件定義服務,并同時運行它們。

Docker Compose將所管理的容器分為三層:工程(Project)、服務(Service)、容器(Container)。

通過一個例子來理解三層結構:

  1. 工程: 一個工程可以被視為一家公司,它為所有服務提供了整體的工作環境和資源配置。
  2. 服務: 公司內設有各種部門,如財務和行政等,每個部門有自己特定的職責和任務。每個部門都可以被看作一個服務。
  3. 容器: 每個部門由一個或多個員工組成。盡管每個員工都是獨立的,但他們共享同樣的環境。一個員工相當于一個容器。

所有部門都在同一家公司工作并使用該公司的資源,所以所有服務在工程中共享同樣的網絡、卷等資源

各個部門之間還是會進行交流和協作,所以各個服務之間可以互相通信

同一部門的所有員工都具有相同的工作環境,所以屬于同一服務的所有容器都有統一的配置。員工各自做自己的項目,所以容器間有一定的隔離性

在要部署項目的目錄創建一個 docker-compose.yml 文件:

# 指定Docker Compose配置文件的版本
version: '3.8'services: # 定義應用服務,名為 appapp:image: '倉庫地址/命名空間/鏡像名稱:標簽'# 將容器的8080端口映射到宿主機的8080端口ports: - 8080:8080 volumes:# 將 docker-compose.yml 所在目錄映射到容器中的 /app 目錄(在 Dockerfile 中給定的工作目錄) - ./:/app # 定義啟動依賴,會先啟動 mysqldb 和 redisdb,再啟動 appdepends_on:- mysqldb- redisdb# 指定容器啟動后執行的命令command: ["java", "-jar", "app.jar"]   # 如果服務非手動停止,Docker會自動嘗試重啟服務restart: always# 定義一個MySQL服務,名為 mysqldb # 其他服務連接MySQL數據庫時,主機地址就是 mysqldb:3306mysqldb:image: mysql:8.0.30environment:- MYSQL_ROOT_PASSWORD=rootvolumes:- db_data:/var/lib/mysql# 定義一個Redis服務,名為 redisdb# 其他服務連接Redis數據庫時,主機地址就是 redisdb:6379redisdb:image: redis:7.2.4volumes:- redis_data:/datavolumes:db_data:redis_data:

docker-compose.yml 文件所在的目錄執行

docker compose up -d

docker compose up 根據 docker-compose.yml 文件內容啟動、創建、連接服務。

-d 參數表示以后臺方式運行。

-f 如果文件名稱不是 docker-compose.yml ,可以通過 -f 命令指定,使用方法與 構建鏡像 章節一致。

每次更改了 docker-compose.yml 文件,都需要重新運行 docker-compose up -d 命令以應用更改。

結語

任何技術都有其深度與復雜性,難以通過一篇文章詳盡闡述。本文的初衷是為你在遭遇問題時,提供一個尋找解答的方向指引。

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

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

相關文章

【Hadoop】在spark讀取clickhouse中數據

讀取clickhouse數據庫數據 import scala.collection.mutable.ArrayBuffer import java.util.Properties import org.apache.spark.sql.SaveMode import org.apache.spark.sql.SparkSessiondef getCKJdbcProperties(batchSize: String "100000",socketTimeout: Strin…

IOS 發布遇到“Unable to authenticate with App Store Connect”錯誤咋解決?

問題: 在開發ios app后,先發布adhoc版本,測試通過后,再發布testflight版本測試,但是可能會遇到一下問題。 解決辦法: 在Signing &Capabilities中,在ios下邊要指定有發布權限的Team賬號&a…

PAT (Basic Level) Practice | 判斷題

判斷題的評判很簡單,本題就要求你寫個簡單的程序幫助老師判題并統計學生們判斷題的得分。 輸入格式 輸入在第一行給出兩個不超過 100 的正整數 N 和 M,分別是學生人數和判斷題數量。第二行給出 M 個不超過 5 的正整數,是每道題的滿分值。第…

pytorch基礎2-數據集與歸一化

專題鏈接:https://blog.csdn.net/qq_33345365/category_12591348.html 本教程翻譯自微軟教程:https://learn.microsoft.com/en-us/training/paths/pytorch-fundamentals/ 初次編輯:2024/3/2;最后編輯:2024/3/2 本教程…

迪杰斯特拉算法的具體應用

fill與memset的區別介紹 例一 #include <iostream> #include <algorithm> using namespace std; const int maxn500; const int INF1000000000; bool isin[maxn]{false}; int G[maxn][maxn]; int path[maxn],rescue[maxn],num[maxn]; int weight[maxn]; int cityn…

【深度學習數學基礎】Hebbian圖(Hebbian Graph)

Hebbian圖&#xff08;Hebbian Graph&#xff09;是一種基于神經科學原理的網絡結構&#xff0c;它受到唐納德赫布&#xff08;Donald Hebb&#xff09;提出的赫布學習規則&#xff08;Hebb’s rule&#xff09;的啟發。赫布學習規則是神經科學中描述神經元之間突觸連接如何通過…

模板方法模式 詳解 設計模式

模板方法模式 模板方法模式是一種行為型設計模式&#xff0c;它定義了一個算法的骨架&#xff0c;將一些步驟延遲到子類中實現。這種模式允許子類在不改變算法結構的情況下重新定義算法的某些步驟。 結構 抽象類&#xff08;Abstract Class&#xff09;&#xff1a;負責給出一…

JavaWeb老杜視頻筆記總結,Servlet-JSP

關于直播 什么時間直播&#xff1f; 晚上8:00到10:00 每周直播幾天&#xff1f; 3天&#xff08;周一、周三、周五&#xff09; 本周比較特殊&#xff1a;周四周五周六三天直播&#xff0c;從下周開始就是一三五直播。 直播什么內容&#xff1f; 從JavaWEB開始。&#xff08…

《深入淺出紅黑樹:一起動手實現自平衡的二叉搜索樹》

一、分析 1. 紅黑樹的性質 紅黑樹是一種自平衡的二叉搜索樹&#xff0c;它具有以下五個性質&#xff1a; &#xff08;1&#xff09;節點是紅色或黑色。 &#xff08;2&#xff09;根節點是黑色。 &#xff08;3&#xff09;所有葉子節點&#xff08;NIL節點&#xff09;是…

探索數據宇宙:深入解析大數據分析與管理技術

?? 歡迎大家來訪Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭?&#xff5e;?? &#x1f31f;&#x1f31f; 歡迎各位親愛的讀者&#xff0c;感謝你們抽出寶貴的時間來閱讀我的文章。 我是Srlua&#xff0c;在這里我會分享我的知識和經驗。&#x…

第六課:NIO簡介

一、傳統BIO的缺點 BIO屬于同步阻塞行IO,在服務器的實現模型為&#xff0c;每一個連接都要對應一個線程。當客戶端有連接請求的時候&#xff0c;服務器端需要啟動一個新的線程與之對應處理&#xff0c;這個模型有很多缺陷。當客戶端不做出進一步IO請求的時候&#xff0c;服務器…

《Spring Security 簡易速速上手小冊》第4章 授權與角色管理(2024 最新版)

文章目錄 4.1 理解授權4.1.1 基礎知識詳解授權的核心授權策略方法級安全動態權限檢查 4.1.2 主要案例&#xff1a;基于角色的頁面訪問控制案例 Demo 4.1.3 拓展案例 1&#xff1a;自定義投票策略案例 Demo測試自定義投票策略 4.1.4 拓展案例 2&#xff1a;使用方法級安全進行細…

【flutter】加載指示器(loading indicator)阻止用戶在某個操作執行期間操作頁面

在Flutter中&#xff0c;通過顯示一個加載指示器&#xff08;loading indicator&#xff09;來阻止用戶在某個操作執行期間操作頁面。以下是一個簡單的示例代碼&#xff0c;演示了按鈕被點擊后執行某操作&#xff0c;在操作完成前顯示加載指示器&#xff0c;阻止用戶操作頁面&a…

c語言數據結構(5)——棧

歡迎來到博主的專欄——C語言數據結構 博主id&#xff1a;代碼小豪 文章目錄 棧棧的順序存儲結構棧的插入空棧的初始化棧的刪除判斷空棧讀取棧頂元素數據 實現順序棧的所有代碼棧的鏈式存儲結構鏈式棧的初始化鏈式棧的入棧操作鏈式棧的出棧操作 實現鏈式棧的所有代碼 棧 棧是…

學習網絡編程No.11【傳輸層協議之UDP】

引言&#xff1a; 北京時間&#xff1a;2023/11/20/9:17&#xff0c;昨天成功更文&#xff0c;上周實現了更文兩篇&#xff0c;所以這周再接再厲。當然做題任在繼續&#xff0c;而目前做題給我的感覺以套路和技巧偏多&#xff0c;還是那句話很多東西不經歷你就是不懂&#xff…

測試人員如何向開發人員準確清晰地描述問題?

測試人員向開發人員準確清晰地描述問題可以采取以下方法&#xff1a; 提供詳細的背景和上下文信息&#xff1a;描述問題發生的環境、前提條件和操作步驟&#xff0c;讓開發人員能夠了解問題出現的場景。明確問題的癥狀和表現&#xff1a;清楚地說明問題的具體表現&#xff0c;…

【Python】2. 基礎語法

常量和表達式 我們可以把 Python 當成一個計算器, 來進行一些算術運算. 注意: print 是一個 Python 內置的 函數, 這個稍后詳細介紹. 可以使用 - * / ( ) 等運算符進行算術運算. 先算乘除, 后算加減. 運算符和數字之間, 可以沒有空格, 也可以有多個空格. 但是一般習慣上寫一…

LDR6328芯片:智能家居時代的小家電充電革新者

在當今的智能家居時代&#xff0c;小家電的供電方式正變得越來越智能化和高效化。 利用PD&#xff08;Power Delivery&#xff09;芯片進行誘騙取電&#xff0c;為后端小家電提供穩定電壓的技術&#xff0c;正逐漸成為行業的新寵。在這一領域&#xff0c;LDR6328芯片以其出色的…

Qt下使用modbus-c庫實現PLC線圈/保持寄存器的讀寫

系列文章目錄 提示&#xff1a;這里是該系列文章的所有文章的目錄 第一章&#xff1a;Qt下使用ModbusTcp通信協議進行PLC線圈/保持寄存器的讀寫&#xff08;32位有符號數&#xff09; 第二章&#xff1a;Qt下使用modbus-c庫實現PLC線圈/保持寄存器的讀寫 文章目錄 系列文章目錄…

前端Vue3項目如何打包成Docker鏡像運行

將前端Vue3項目打包成Docker鏡像并運行包括幾個主要步驟&#xff1a;項目打包、編寫Dockerfile、構建鏡像和運行容器。下面是一個基本的流程&#xff1a; 1. 項目打包 首先&#xff0c;確保你的Vue3項目可以正常運行和打包。在項目根目錄下執行以下命令來打包你的Vue3項目&am…