[軟體概念入門系列][Workshop] Linux與後端服務 #1

Brett Yu
Brett’s dev log
Published in
9 min readNov 7, 2023

--

前置準備

一個Linux環境

Windows Terminal (非必須)

瞭解基本Linux指令

  • pwd — 列印工作路徑
  • ls — 列出工作路徑下的檔案或是目錄清單
  • cat — 印出指定文件內容
  • grep — 文字搜尋過濾
  • cd — 切換目錄的路徑
  • rm, cp, mv — 刪除/複製/移動檔案、目錄
  • chmod — 變更檔案權限
  • sudo — 提升至root權限
  • service — 控制服務
  • vim — 文字編輯器

Workshop目標

建立兩個python flask API並架設nginx以讓外部發動的http request可以存取

你會學習到

  • 如何建立API處理http request
  • 伺服器上的service以及port
  • 架設nginx處理http request導轉到伺服器上的service

建議可以複習 [軟體概念入門系列] 瀏覽器與伺服器 — Part 2

以python建立API

  1. 安裝python3

進入wsl並執行以下指令

sudo apt update
sudo apt install python3 python3-pip python3.11-venv

2. 確認python版本

python3 --version
pip3 --version

3. 建立python虛擬環境以避免python指令與虛擬化linux衝突

python3 -m venv .venv

4. 執行python虛擬環境

source .venv/bin/activate

5. 安裝flask

pip install Flask

6. 建立flask程式碼

cd {你想要的程式碼路徑}
vim app.py

在vim內貼上以下程式碼後儲存離開vim

(按i進入編輯模式, 按Esc再輸入:wq!儲存離開)

from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello, World!"

7. 執行flask

flask run

現在嘗試從你的windows瀏覽http://localhost:5000/
應要可以看到 Hello, World!
這樣第一個python API就建立完成了

8. 建立第二個flask程式碼

開第二個cmd/powershell/windows terminal tab進入wsl

cd {剛剛的程式碼路徑}
vim app2.py

在vim內貼上以下程式碼後儲存離開vim

from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "this is API No.2"

9. 執行第二個flask

flask --app app2 run -p 3000 

現在嘗試從你的windows瀏覽http://localhost:3000/
應要可以看到 this is API No.2
第二個python API也建立完成了

以nginx架設伺服器處理request

  1. 安裝nginx

開第三個cmd/powershell/windows terminal tab進入wsl

sudo apt update
sudo apt install nginx

2. 啟動nginx

先瀏覽http://localhost/
這時候還沒法顯示頁面, 因為還沒有任何服務可以接收80 port的http request

sudo service nginx status
sudo service nginx start
sudo service nginx status

確認nginx啟動後

再次瀏覽http://localhost/
可以看到nginx的歡迎畫面, 代表80 port的http request已經可以進到伺服器被nginx處理了

3. 設定nginx config以讓http request可以連到python API

切到 /etc/nginx/ 目錄下並修改nginx.conf

cd /etc/nginx/
sudo vim nginx.conf

在http區塊中加入以下nginx config

    server {
listen 80;
server_name workshop-1.com;

location / {
proxy_pass http://localhost:5000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

server {
listen 80;
server_name workshop-2.com;

location / {
proxy_pass http://localhost:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

接著執行nginx reload以讓最新的nginx config生效

sudo nginx -s reload

4. 調整windows上的host file以讓workshop-1.com, workshop-2.com這兩個domain可以被解析成localhost

以管理者權限編輯windows中的C:\Windows\System32\drivers\etc\hosts

在檔案最下方加入以下區塊並儲存

127.0.0.1 workshop-1.com
127.0.0.1 workshop-2.com

接著瀏覽以下網址, 應可以訪問到兩個python api

http://workshop-1.com/

http://workshop-2.com/

5. 設定nginx config讓同一個domain可以讓http request依據不同url連到不同的python API

切到 /etc/nginx/ 目錄下並修改nginx.conf

cd /etc/nginx/
sudo vim nginx.conf

在http區塊中加入以下nginx config

    server {
listen 80;
server_name workshop-reverse-proxy.com;

location /site1/ {
proxy_pass http://localhost:5000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

location /site2/ {
proxy_pass http://localhost:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

在windows中的C:\Windows\System32\drivers\etc\hosts加入以下區塊並儲存

127.0.0.1 workshop-reverse-proxy.com

接著瀏覽以下網址

http://workshop-reverse-proxy.com/site1/

http://workshop-reverse-proxy.com/site2/

可以看到我們用同一個domain的不同路徑導轉到不同的後端服務來回應, 也就是反向代理的概念

6. 以nginx設定load balance到兩個python API

現在假設我們建立的兩個python flask API是完全一樣的API, 為了分散壓力, 我們要做load balance將http request分配到兩個API上

在nginx的http區段中加入以下nginx config

    upstream loadbalance_backend {
server localhost:3000;
server localhost:5000;
}

server {
listen 80;
server_name workshop-load-balance.com;

location / {
proxy_pass http://loadbalance_backend/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

執行nginx config reload

sudo nginx -s reload

在windows host file加入

127.0.0.1 workshop-load-balance.com

現在瀏覽 http://workshop-load-balance.com/ 並持續重新整理
可以看到同一個URL被導轉到不同python API

Recap

回顧我們這次做過的內容

  1. 在伺服器(你的電腦)上安裝python, nginx
  2. 分別建立兩個python flask API, 並可以透過localhost的不同port號去存取
  3. 以nginx設定兩個獨立的domain, 分別導轉到兩個python flask API
  4. 以nginx設定同一個domain下的不同路徑導轉到兩個python flask API
  5. 以nginx設定同一個URL會做load balance到兩個python flask API

延伸思考

  1. 每次要設定一個新環境, 都要從安裝python, nginx開始從頭做起嗎?
    是否有更簡易, 更自動化的做法?
    - virtual machine + snapshot?
    - docker?
    - ansible?
    - docker + ansible?
  2. 升版python, nginx要做哪些事情? 可能會有哪些影響? 是否方便還原?
  3. 伺服器資源是共用的, nginx, python是否會互相影響?
  4. 承上, 如果我們想要再增加nginx或python的數量該怎麼做?

--

--