主頁 > 軟體設計 > 部署前后端為獨立的 Docker 節點

部署前后端為獨立的 Docker 節點

2022-08-20 10:54:47 軟體設計

在『服務器部署 Vue 和 Django 專案的全記錄』一文中,介紹了在服務器中使用 Nginx 部署前后端專案的程序,然而,當 Web 應用流量增多時,需要考慮負載均衡、流量分發、容災等情況,原生的部署方式通常難以滿足需求,此時,引入 Docker 部署多節點,能夠在單臺高性能服務器或服務器集群中搭建更完善的部署架構,

本文主要以 Vue 和 Django 專案為例介紹 Docker 部署的流程,稍帶 Docker 簡介和基礎的 Nginx 負載均衡配置,

Docker 簡介與安裝

簡單介紹 Docker 相關概念,具體需要讀者另外學一學,推薦『Docker-從入門到實踐』

Docker 是什么

Docker 是一個開源的應用容器引擎,可以讓開發者打包應用和依賴到一個輕量級、可移植的容器中,并發布到任何流行的 Linux 機器上,也可以實作虛擬化,容器使用沙箱機制,相互之間不存在介面,其與宿主機通過埠轉發進行通信,性能開銷低,

Docker 部署 Web 應用有以下優點:

  • 容器適合持續集成和持續交付(CI/CD)流程
  • 回應式部署和擴展,其可移植性和輕量級的特性支持實時擴展或拆除服務
  • Docker 輕巧快速,支持開發者在同一機器上運行更多作業負載

Docker 作業流程

Docker 包括三個概念:

  • 鏡像(Image):相當于一個 root 檔案系統,
  • 容器(Container):鏡像和容器的關系類似于物件程式設計中的類和實體,鏡像是靜態的定義,容器是鏡像運行時的物體,容器可以被創建、啟動、停止、洗掉、暫停等,
  • 倉庫(Repository):倉庫可看成一個代碼控制中心,用來保存鏡像,

Docker 的作業流程通常為:

  1. 從倉庫中拉取(pull)官方或基準鏡像
  2. 在 Dockerfile 中描述應用和安裝依賴的指令,構建鏡像
  3. 由鏡像創建和運行容器

Docker 安裝

見『Ubuntu 安裝 Docker 環境』.

部署架構

在不考慮多節點負載均衡時,本文的部署架構如下:

前后端專案分離部署,分別部署在兩個 Nginx 節點,對應兩個域名或兩個埠,

deploy-structure

Nginx + Docker 部署前端

首先,Vue 專案打包為 dist 檔案夾,同目錄下新建 Dockerfilevhosts.conf 檔案和 logs 檔案夾,作用見下列代碼塊中的注釋,

.
├── dist            # Vue 專案打包用以部署的檔案夾
├── Dockerfile      # 用于建立 Docker 鏡像
├── vhosts.conf     # 容器中啟動 Nginx 服務的組態檔
└── logs            # 映射容器中的 Nginx 日志目錄,以便在宿主機查看日志

Dockerfile 檔案內容:

# 設定基礎鏡像
FROM nginx:latest
#設定CTS時區
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' > /etc/timezone
# 將dist檔案中的內容復制到 /usr/share/nginx/html/ 這個目錄下面
COPY ./dist /usr/share/nginx/html/
#用本地的 vhosts.conf 配置來替換 nginx 鏡像里的默認配置
COPY vhosts.conf /etc/nginx/conf.d/vhosts.conf

vhosts.conf 檔案內容:

server {
    listen       80;
    server_name  localhost;
    access_log  /var/log/nginx/host.access.log  main;
    error_log  /var/log/nginx/error.log  error;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

構建 Docker 鏡像

在終端中輸入以下命令,根據 Dockerfile 構建鏡像,

docker build -f Dockerfile -t nginx/hsheng-mall:v1.0.0 .
# 鏡像名稱:nginx/hsheng-mall
# 版本號:v1.0.0

運行 Docker 容器

依據創建的鏡像 nginx/hsheng-mall:v1.0.0 運行容器,

docker run -d -p 8081:80 --name=hsheng-mall -v /home/hsheng/www/hsheng-mall/logs:/var/log/nginx nginx/hsheng-mall:v1.0.0
# 宿主機 8081 埠映射容器 80 埠
# 容器名稱:hsheng-mall
# 宿主機 /home/hsheng/www/hsheng-mall/logs 目錄映射容器 /var/log/nginx 目錄
# 鏡像名稱:nginx/hsheng-mall:v1.0.0

宿主機 Nginx 轉發

與原生 Nginx 部署類似,在 /etc/nginx/conf.d 目錄下創建組態檔 hsheng-mall.conf,內容如下:

server {
    listen 443 ssl; # 埠,若部署 https 域名則為 443
    server_name aaa.abc.com; # 域名或 IP

    location / {
        proxy_pass http://127.0.0.1:8081;   # 轉發本機(宿主機) 8081 埠,已與 Docker 埠建立映射
        proxy_redirect default;
    }

    ssl_certificate   /home/hsheng/www/hsheng-mall/ssl_certs/aaa.abc.com_bundle.crt;    # ssl證書絕對路徑
    ssl_certificate_key  /home/hsheng/www/hsheng-mall/ssl_certs/aaa.abc.com.key;    # ssl證書私鑰絕對路徑
    ssl_session_timeout 5m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
}

server {
    listen 80;
    server_name aaa.abc.com;
    # 把http的域名請求轉成https
    return 301 https://$host$request_uri;
}

而后重啟 Nginx 服務,即可通過 server_name 訪問 Docker 的應用服務,

sudo nginx -s reload

Nginx + Docker 部署 uWSGI 后端

專案部署目錄結構如下:

.
├── src                     # Django 專案原始碼
│   ├── manage.py
│   ├── requirements.txt    # Python 專案依賴包
│   ├── uwsgi.ini           # uWSGI 組態檔
│   ├── start.sh            # Django 服務啟動腳本
|   └── ...
├── Dockerfile              # 用于建立 Docker 鏡像
└── logs                    # 映射容器中的 uWSGI 日志目錄,以便在宿主機查看日志

Dockerfile 檔案內容:

FROM python:3.8
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' > /etc/timezone
RUN mkdir -p /var/www/html/backend
COPY ./src /var/www/html/backend/
WORKDIR /var/www/html/backend

RUN pip install -i https://pypi.doubanio.com/simple uwsgi
RUN pip install -i https://pypi.doubanio.com/simple/ -r requirements.txt

# Windows環境下撰寫的start.sh每行命令結尾有多余的\r字符,需移除
RUN sed -i 's/\r//' ./start.sh
RUN chmod +x ./start.sh

uwsgi.ini 檔案內容:

[uwsgi]
socket = 0.0.0.0:8000   # 容器內 uWSGI 服務須為 0.0.0.0,以便與宿主機建立正常連接
project = backend
base = /var/www/html
base-app = hshengmall
chdir = %(base)/%(project)
wsgi-file = %(base)/%(project)/%(base-app)/wsgi.py
master = true
processes = 8
threads = 4
enable-threads = true
buffer-size = 65536
post-buffering = 32768
vacuum = true
pidfile = %(base)/uwsgi/%(project)-master.pid
daemonize = %(base)/uwsgi/uwsgi.log
chmod-socket = 664
# 設定一個請求的超時時間(秒),如果一個請求超過了這個時間,則請求被丟棄
harakiri = 300
# 當一個請求被harakiri殺掉會,會輸出一條日志
harakiri-verbose = true

start.sh 檔案內容:

python manage.py makemigrations&&
python manage.py migrate&&
uwsgi --ini /var/www/html/backend/uwsgi.ini

構建 Docker 鏡像

在終端中輸入以下命令,根據 Dockerfile 構建鏡像,

docker build -f Dockerfile -t python/hsheng-mall-backend:v1.0.0 .

運行 Docker 容器

依據創建的鏡像 python/hsheng-mall-backend:v1.0.0 運行容器,

docker run -it -p 8001:8000 --name=hsheng-mall-backend -v /home/hsheng/www/hsheng-mall-backend/logs:/var/www/html/uwsgi -d python/hsheng-mall-backend:v1.0.0

啟動服務

進入容器:

docker exec -it <container_id> /bin/bash

運行啟動腳本:

./start.sh

這樣即成功啟動了一個后端服務容器,若想做多節點負載均衡,可以修改埠映射關系,按上述步驟多創建和啟動幾個容器,

宿主機 Nginx 轉發

/etc/nginx/conf.d 目錄下創建組態檔 hsheng-mall-backend.conf,內容如下:

server {
    listen 443 ssl;
    server_name api-aaa.abc.com;

    location / {
        include /etc/nginx/uwsgi_params;
        uwsgi_pass 127.0.0.1:8001;  # 轉發本機(宿主機) 8001 埠,已與 Docker 埠建立映射
    }

    ssl_certificate   /home/hsheng/www/hsheng-mall-backend/ssl_certs/api-aaa.abc.com_bundle.crt;
    ssl_certificate_key  /home/hsheng/www/hsheng-mall-backend/ssl_certs/api-aaa.abc.com.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
}

server {
    listen 80;
    server_name api-aaa.abc.com;
    return 301 https://$host$request_uri;
}

而后重啟 Nginx 服務,即可通過 server_name 請求后端服務,

sudo nginx -s reload

*Nginx 負載均衡

簡略描述一個負載均衡的結構:Nginx + Docker 多節點部署架構,

前端節點為靜態節點,通常只需要單個節點即可,可使用 CDN 加速優化訪問,因此,當請求流量大時,主要通過增多后端 Docker+uWSGI 節點進行負載均衡,

deploy-structure-total

為實作上圖架構,首先根據本文第四章節「Docker 部署 uWSGI 后端節點」創建和啟動 3 個 Docker 后端服務節點,分別映射至宿主機 8001 ~ 8003 埠,

而后,修改宿主機用于部署后端的 Nginx 組態檔,例如本文的 hsheng-mall-backend.conf,添加 upstream,修改后檔案內容應為:

upstream uwsgicluster {
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
    server 127.0.0.1:8003;
}
server {
    listen 443 ssl;
    server_name api-aaa.abc.com;

    location / {
        include /etc/nginx/uwsgi_params;
        uwsgi_pass uwsgicluster  # 轉發上游集群
    }

    ssl_certificate   /home/hsheng/www/hsheng-mall-backend/ssl_certs/api-aaa.abc.com_bundle.crt;
    ssl_certificate_key  /home/hsheng/www/hsheng-mall-backend/ssl_certs/api-aaa.abc.com.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
}

server {
    listen 80;
    server_name api-aaa.abc.com;
    return 301 https://$host$request_uri;
}

可以看到,與單節點不同之處在于,新增了 upstream 定義,并將 uwsgi_pass 修改為定義的 upstream 名稱,

在組態檔中,還能設定各個節點的權重分配等,此處不展開介紹,默認為輪詢方式,請求隨機派發到各節點,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/502341.html

標籤:架構設計

上一篇:經典設計原則 - SOLID

下一篇:部署前后端為獨立的 Docker 節點

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more