# 1131 Web Server
- Book mode: https://hackmd.io/@ncnu-opensource/book
[TOC]
:::info
#### Server 是什麼?
- 在網路上為客戶提供服務的就是 **Server**
- 任何電腦都可當 Server
- 多種種類
- Database server、Email server、**Web Server** 等等
:::
## Web Server 在幹麻
- 提供 Web 相關服務的 Server
- 讓自己的網頁可以被世界各地任何連上網路的人在瀏覽器上顯示出來
### client & server
- **client**
- 主動發送請求(request)給 server 端,並開始等待直到收到回應
- 任何可以呈現 server 端所傳來的資訊,並提供使用者本地服務的程式,都能稱之為 client
- 如 Chrome、Firefox 等瀏覽器。
- **Server**
- 被動等 client 端發送 request 來,接收後開始處理,並回傳一個回應(response)給 client 端。

[資料來源](https://medium.com/@justinlee_78563/%E9%97%9C%E6%96%BCweb%E5%BE%8C%E7%AB%AF-1-%E4%BB%80%E9%BA%BC%E6%98%AFweb-server-83ee32bc7d3e)
## HTTP
- **H**yper**t**ext **T**ransfer **P**rotocol
- 應用層的協定
- 在 client 端跟 server 端 respond & request 的標準
- 預設 port 號:80 port
## Port
- 用來提供給不同的服務使用,每個 port 提供特定的服務
- 為什麼需要分 port?
- 假設所有 data 傳輸到電腦上,電腦需要分辨不同的 data 需要給不同的服務處理
- 在 transport 層 (第四層)
- 常用的協定及 port 會記錄在 `/etc/services` 裡面
- `cat /etc/services`

[圖片來源](https://en.wikipedia.org/wiki/Port_(computer_networking) )
- 查看現在開啟的 port
- `netstat -ntupl`
- -a :顯示出目前所有的網路連線狀態
- -t :顯示 tcp 連線
- -u :顯示 udp 連線
- -p :顯示此連線的 PID
- -l :顯示 LISTEN 的內容
- -n :host 跟 port 都以數字顯示
- >看有 -n 跟沒有 -n 的差異

- Proto:協定類型,表示使用的網路協定
- Recv-Q:當前等待應用程式處理資料量(單位:byte)。
- Send-Q:待傳輸到對端資料量(單位:byte)。
- 封包 過來/過去 的時候會先放到一個 buffer 裡面
:::spoiler Recv-Q、Send-Q
- >Recv-Q、Send-Q Q是佇列
封包過來的時候會先放到一個 buffer 裡面 (os socket)
:::
- Local Address:本地 ip 和 port
- 0.0.0.0 表示可以接受來自任何地址的請求(綁定到所有可用的網卡)。
- Foreign Addres:另一邊的地址和端口
- 0.0.0.0:* 表示尚未建立具體的連接(例如,正在監聽的狀態)。
如果有特定地址,則表示已建立的連接。
- State:連接的當前狀態
- LISTEN:服務正在監聽 port ,等待客戶端連接。
- ESTABLISHED:連接已建立並正在通訊。
- PID/Program name:使用該端口的 process ID 和程序名稱
- 用 root 權限可顯示詳細信息
:::info
**DEMO**
1. 打開 firefox
2. 用 sudo netstat -antupl
3. 看看本機到 Local Address 接收 Foreign Address 傳過來的封包
:::
:::info
### 操作 Web Server 的指令
`sudo service <service_name> <<操作>>`
<<操作>>
- status 查看狀態
- start 開啟服務
- stop 關閉服務
- reload 不停止服務,重載設定檔
- restart 停止服務重新開啟
:::
# 常見的 Web Server
## Lighttpd
- 安裝: `sudo apt install lighttpd`
- 占用系統資源少,運作輕量
- 低記憶體佔用、低 CPU 負載、速度最佳化
- 在提供**靜態**內容方面高效,但動態內容可能會消耗較多資源
- 靜態內容 : 預先建立的檔案,例如 HTML,CSS 和 JavaScript
- 動態內容 : 像是 php,需要的 client 傳送才會有內容
- 適合提供靜態內容
- Demo 用 -> 小貓兩三隻
- 非直播、Youtube
- 支援 CGI、FastCGI、SCGI,允許使用任何程式語言撰寫 Web 應用程式
- >CGI:有偵測到.php->丟給其他人(像reverse proxy)

- >FIXME: 這邊要搞懂 (lighttpd 一樣)
>FIXME: 單一 process,設計就是高校處理靜態檔
nginx:很能撐,相較不快
apache:什麼都支援,功能多->肥又效率低,有小破綻
### Lighttpd 實作
1. 安裝: `sudo apt install lighttpd`
2. 查看狀態: `sudo service lighttpd status`
3. 看一下 run 在哪個 port:`sudo netstat -ntupl`
4. 至 url 輸入 http://127.0.0.1:80
:::warning
**猜猜樂**
大家猜猜下載後 Lighttpd 的資料夾在哪裡
:::spoiler 提示
關於**系統設定**
:::
-> 看一下 Lighttpd 設定檔資料夾裡面有啥
>FIXME: dpkg -L lighttpd 看建在哪些地方


- lighttpd.conf:主要設定檔
#### 基本伺服器模組設定
```bash
server.modules = (
"mod_indexfile", # 處理首頁檔案 (如 index.html 或 index.php)
"mod_access", # 控制對特定資源的訪問權限
"mod_alias", # 設定 URL 路徑的對應別名
"mod_redirect", # 設定 URL 重新定向
)
```
#### 伺服器基本設定
```bash
server.document-root = "/var/www/html" # 存放網站檔案的目錄
server.upload-dirs = ( "/var/cache/lighttpd/uploads" ) # 檔案上傳的暫存目錄
server.errorlog = "/var/log/lighttpd/error.log" # 錯誤日誌的存放位置
server.pid-file = "/run/lighttpd.pid" # 伺服器程緒 ID (PID)
server.username = "www-data" # lighttpd process 以 www-data 這個角色執行
server.groupname = "www-data" # lighttpd process 以 www-data 這個群組執行
server.port = 80 # 伺服器監聽的端口 (HTTP 預設是 80)
```
- server.username & server.groupname:指定來伺服器的 client 名稱
- 可用`sudo cat /etc/passwd | grep www` 看
- 專門給 web server 使用的特定 user/group
- 管理讓使用者在 web server 的權限
- 只能讀取特定的目錄或檔案
#### 預設首頁檔案和訪問控制
```bash
index-file.names = ( "index.php", "index.html" ) # 預設首頁檔案名稱
url.access-deny = ( "~", ".inc" ) # 禁止訪問的檔案類型 (如隱藏檔案或設定檔案)
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" ) # 排除靜態檔案處理的檔案類型
```
- index-file.names : 紀錄有哪些預設的頁面
::: info
- 我們連上 google.com 的時候,後面就直接 / 結尾,此時沒有接其他東西,對方要怎麼知道要傳甚麼網頁給我看 ?
- `/` 是目錄的意思,我們總不希望連到 google.com 他給我看底下有那些目錄跟檔案,希望他給我們看漂漂亮的頁面
- 當 web server 發現我們要存取一個目錄時,能有預設的檔案可以顯示
- >如果沒有指定路徑 -> 到 document-root 下的 index-file.names
- index-file.names 就是紀錄有哪些預設的頁面可以顯示
::: info
**小 Lab**
- `sudo service lighttpd stop`
- `sudo vim /etc/lighttpd/conf-available/99-unconfigured.conf`
- 在 index-file.names 最前面加一個 test.html
- 到 document-root 的路徑(/var/www/html)底下新增 test.html
- `sudo vim /var/www/html/test.html`
```html=
Today is 11/21 LSA Class!
```
- `sudo service lighttpd restart`
:::danger
為什麼不改 lighttpd.conf 裡面的 index-file.names?
- lighttpd.conf 是主設定檔 -> 通常不動
讀取順序:主設定檔 -> enabled 資料夾 -> 資料夾中的 modules 數字(從小讀到大->後面的會蓋掉前面的)
:::
- access-deny:讓使用者無法存取特定檔案
:::info
**如果沒有 access-deny 的話會發生甚麼事**
- 完全禁止使用者去敏感目錄或文件(如 .git/ 或 config.php)。
- php 需要 .inc
- 儲存與 DB 連線的 IP
- 如果這些東西使用者可以直接存取的話非常危險
- 所以設定 access-deny 來過濾檔名有包含 `~` 或 `.inc` 的 request
- 告訴使用者無法存取,避免資訊外洩
-> server 要看,但不能給使用者看
:::
- static-file.exclude-extensions:哪些副檔名的檔案,不能被 URL 請求獲取
:::info
**如果沒有 static-file.exclude-extensions 的話會發生甚麼事**
- 伺服器的 document-root 可能包含了某些不應公開的檔案類型(如 .conf, .log, .bak 等),這些檔案可能會被用戶直接通過 URL 存取。
- config.php.bak -> 泄露 PHP 檔案的備份。
- 不會讀取到 -> server 看不到
:::
#### 額外的模組
```bash
server.modules += (
"mod_dirlisting", # 目錄列表模組,當沒有首頁檔案時顯示目錄內容
"mod_staticfile", # 用於處理靜態檔案(如 HTML、CSS、圖片)
)
```
>FIXME: 當需要補充的 modules 放這裡 -> 前面的先跑,如果 mod_staticfile 可能會錯亂掉
>-> 問 BT
- conf-available
- 含所有**可用**的設定檔案,每個設定檔案對應於一個功能或模組
- 例如 FastCGI 支援、Gzip 壓縮、SSL 設定等。
- 檔案名稱通常以模組或功能命名,如 10-userdir.conf、15-ssl.conf 等。
- 這些檔案預設不會自動生效,需要手動開啟
- conf-enabled
- 包含所有**已開啟**的設定檔案,從 conf-available 目錄中的檔案 軟連結(soft link) 來的
- Lighttpd 啟動時會**自動載入**這些檔案的設定
:::info
**啟用 Mod userdir Lab**
#### userdir 是什麼
- 根據網址後面加 user name,會導向各自的家目錄
- 家目錄下的指定資料夾
- ex. 自我介紹 -> 網址後加 username (google.com/~apple)就可看到 apple 家目錄底下指定資料夾內的檔案
- 大家可以各自做自己的,並放在自己的家目錄
#### 啟動 module 的設定檔
- **方法一**:使用 lighty-enabled & lighty-disabled 來啟用和停用 modules
- 啟用:`sudo lighttpd-enable-mod <<modules>>`
- 只需要 modules 名稱,沒有 `編號` & `.conf`
- 停用:`sudo lighttpd-disable-mod <<modules>>`
- **方法二**:手動-使用 Softlink 方式啟用設定檔
- sudo ln -s <要被啟動的 modules 檔案> <conf-enabled 位置>
- ex.
```
sudo ln -s /etc/lighttpd/conf-available/10-userdir.conf
/etc/lighttpd/conf-enabled/
```
- 要記得 restart
#### 開始 LAB
啟動設定檔
- `sudo service lighttpd stop`
- `sudo lighttpd-enable-mod userdir`
- 看一下 `vim /etc/lighttpd/conf-available/10-userdir.conf`
- 
> server.modules += ("mod_userdir")
> "追加"並載入 "mod_userdir" 這個模組的設定檔,如果用 "=" 會把前面的設定檔抹掉
> exclude-user 排除 "root", "postmaster"
> FIXME: 多學英文!
- path 在 public_html
- 重啟 lighttpd:`sudo service lighttpd restart`
使用者設定
- 建立資料夾:`mkdir ~/public_html`
- 給權限
- `chmod 755 /home/<username>` 家目錄也要記得歐!
- `chmod 755 ~/public_html`
- 建立檔案:`vim ~/public_html/index.html`
去看看:127.0.0.1:80/~<username>
:::
:::warning
**try try**
更改 port 至 8080
:::
## Apache (遠古巨獸)
- 安裝: `sudo apt install apache2`
- 歷史最悠久,曾經擁有最高的市場佔有率
- 2019 後被 Nginx 超車
- 有許多模組,可擴展性高
- 由於模組功能強大,因此佔用的系統資源較多。
### Apache2 實作
1. 安裝: `sudo apt install apache2`
2. 查看狀態: `sudo service apache2 status`
3. 看一下 run 在哪個 port:`sudo netstat -ntupl`
4. 在瀏覽器 url 輸入 http://127.0.0.1:80
-> 看一下 Apache2 設定檔資料夾裡面有啥

- apache2.conf
- 主設定檔案:包含 Apache 的全域設定,設定目錄中的其他檔案都是從此檔案載入的
- conf-available & conf-enabled
- 放獨立的功能性設定檔案->針對 apache 本身的設定檔
- 例如:conf-available/security.conf 可能用來控制 Apache 本身的安全性設定
- mods-available & mods-enabled
- 放 Apache 支援的模組相關的設定檔案->針對 apache 模組的設定檔
- 例如:需要開啟 URL 重寫功能,就要開啟 rewrite 模組
- sites-available & sites-enabled
- virtual host 的設定檔案
- 000-default.conf:http 的預設設定檔案
- default-ssl.conf:https 的預設設定檔案
:::warning
**try try**
更改 port 至 8081
:::
## Nginx
> 發音同「engine X」
- 安裝: `sudo apt install nginx`
- 佔有記憶體少、穩定性高,可以同時承受很大的流量
- 採用模組化設計,有大量的模組和第三方模組可供選擇
- 設計的目標是為了超越 Apache,並且在 2019 年成功超越 Apache 成為市場佔有率最高的
>apache 弱點:無法同時承受多人連線
>prefork + event-based
>FIXME: 理解->表達
### Nginx 實作
1. 安裝: `sudo apt install nginx`
2. 查看狀態: `sudo service nginx status`
3. 看一下 run 在哪個 port:`sudo netstat -ntupl`
4. 至 url 輸入 http://127.0.0.1:80
:::danger
**為什麼出現的是 apache2?**

如果剛下載好去 http://127.0.0.1:80 出現 apache2 的頁面
>帶同學看 http response header 的 Server 欄位

:::
-> 看一下 Nginx 設定檔資料夾裡面有啥

- nginx.conf:主設定檔
- 
- `worker_process: auto`
>FIXME: 看如何 auto
- master process 負責監聽 port 再轉送給其他 worker process
#### 虛擬主機設定
```bash=
include /etc/nginx/conf.d/*.conf;
# 類似 lighttpd, lighty
include /etc/nginx/sites-enabled/*;
```
---
- sites-available:設定檔的集中地
- sites-enabled:會被服務運行的設定檔
#### 預設伺服器設定
```bash=
server {
listen 80 default_server; #伺服器監聽 HTTP 的 80 port
listen [::]:80 default_server;
```
#### 網站根目錄與預設首頁
```bash=
root /var/www/html; #設定網站的根目錄,Nginx 會從這裡提供檔案給訪問者。
index index.html index.htm index.nginx-debian.html;
#設定預設首頁檔案的名稱,當用戶訪問目錄時按順序尋找並載入第一個配對到的檔案。
```
- nginx 的 root 預設路徑跟 apache2 的剛好一致,所以剛下載完吃到 apache2 的頁面為正常
- 更改方法
- `sudo service nginx stop`
- `sudo vim /etc/nginx/sites-available/default`
- 改成這樣
- `sudo service nginx restart`
#### 伺服器名稱
```bash
server_name _;
```
- server_name {DomainName}
- 根據 Domain Name 選擇正確的 Server 區塊(設定檔裡面被括弧包起來的東東)
- 比對 virtual host 中有沒有對應的 Server name,如果沒有就會連到 default Server
- **virtual host**:讓同一台 Web Server 運行多個網站或應用程式
- 不用額外增加硬體設備
- server_name _ : 預設,不符合其他 server_name 都會跑來這個區塊
:::info
**default_server & server name**
Nginx 的主設定檔請求處理邏輯:
1. 檢查 port:
根據 HTTP 請求的目標 port(例如 80 或 443),確定對應的 server 區塊
-> port 都一樣,進到下一項檢查
2. 比對 server_name:
使用請求中的 Host 標頭,查找是否有對應的 server_name。
- 如果比對成功,則使用該 server
- 如果比對失敗,則使用對應 port 中的 default_server
3. 返回結果:
根據比對的 server 區塊處理請求,返回對應的內容。
:::
>下面會有 virtual host 的 demo
#### 路徑處理
```bash
location / {
try_files $uri $uri/ =404;
}
```
- location /:比對目錄的所有請求。
- try_files $uri $uri/ =404;
- 舉例:127.0.0.1:80/asd
1. **檢查檔案** (`$uri`):
- 先檢查 document root 路徑的資料夾中是否存在一個名為 `asd` 的檔案。如果存在,它就會提供這個檔案。
- 看 /var/www/html/ 裡有沒有叫 asd 的檔案
2. **檢查目錄**(`$uri/`):
- 若 `asd` 檔案不存在,則繼續檢查是否有名為 `asd` 的目錄(即 `/asd/`)。若存在,它會進入此目錄,並至 `index` 欄位中查找指定的檔案。
- 看有沒有 /var/www/html/asd
- 
3. **回傳 404**:
- 如果 `asd` 既不是檔案也不是目錄,Nginx 會按照 `try_files` 指令的最後一個參數,回傳一個 `404 Not Found`
:::info
**Location 設定 Lab**
#### 修改檔案
- `sudo service nginx stop`
- `sudo vim /etc/nginx/sites-available/default` 新增一個 location
```conf=
location /hi {
try_files $uri $uri/ =401;
}
```
- 至 `/var/www/html` 底下新增一個 `hi` 資料夾,並在裡面新增一個 `index.html`
```html=
<h1>HI! Is me!! </h1>
```
- ` sudo service nginx restart`
#### 開網頁看
- 127.0.0.1:80 -> 預設網頁
- 127.0.0.1:80/hi -> 剛剛創好的 location 網頁
- 亂打看看?
>FIXME: 偷偷紀錄 這裡我是 8022 port
:::
:::warning
**try try**
更改 port 至 8022
:::
## Virtual Host
- 允許一台 server 提供多個網站或網頁應用程式,且每個網站可以有自己的 domain name 和網頁內容
- 依據使用者的訊息來提供不同的內容
-> 為了省錢錢
### 基於域名的虛擬主機(Name-Based Virtual Host)
- 使用域名區分不同的網站
- 場景:多個網站共享同一個 IP 地址
- 用法:example1.com 和 example2.com 都運行在同一台伺服器上,伺服器根據域名分配請求

[圖片來源](https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2F%40qtNgFtaqR4Or_CLAuotXjw%2FSJ4NxJjC3#Virtual-Host)
### 基於 IP 的虛擬主機(IP-Based Virtual Host)
- 使用不同的 IP 地址來區分網站
- 場景:每個網站分配一個專屬的 IP 地址

[圖片來源](https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2F%40qtNgFtaqR4Or_CLAuotXjw%2FSJ4NxJjC3#Virtual-Host)
### 基於 Port 的虛擬主機(Port-Based Virtual Host)
- 利用 port 來區別不同的網站
- 場景:在不使用多個域名或 IP 的情況下,運行多個內部應用或 API、節省域名註冊費用或額外的 IP 地址需求。
[圖片來源](https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2F%40qtNgFtaqR4Or_CLAuotXjw%2FSJ4NxJjC3#Virtual-Host)
:::info
**用 Nginx 的 Name-Based Virtual Host Lab**
- 記得先 `sudo service nginx stop`
- ==記得先備份==
- `sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default_backup`
1. `sudo vim /etc/nginx/sites-available/default`
```bash
server {
listen 8022 default_server;
listen [::]:8022 default_server;
root /var/www/html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location /hi {
try_files $uri $uri/ =401;
}
}
#### 到最下面將註解刪掉
server {
listen 8022; # 我們一律都改成 8022 port
listen [::]:8022;
server_name example.com;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
```
2. 新增 example.com 的資料夾
- `sudo mkdir /var/www/example.com`
- `sudo vim /var/www/example.com/index.html`
```
Welcome to example.com
```
3. 開啟 nginx `sudo service nginx start`
4. `telnet localhost 8022`
- 到預設 default_server
- GET / HTTP/1.1
Host: asdf (亂打)
- 記得按兩下 enter
- 會回傳預設的網頁(Nginx 的 default 網頁)
- 到 example.com
- GET / HTTP/1.1
Host: example.com
- 記得按兩下 enter
- 會回傳 Welcome to example.com
:::warning
**為什麼用 telnet?**
可設定 Host->模擬以這台主機的身份進來
>FIXME: `curl` 方法(可能更好的方法)
:::
>FIXME: 跟大家說其他的怎麼改
用瀏覽器->沒有
開terminal-> 無法解析到 ->改 /etc/hosts->再開
## Proxy
### Forward Proxy (正向代理)
>FIXME: 限制 client 上網(大公司的機密)
連到遙遠的地方->用cache proxy->前人走過後人成乘涼(中繼站)
load 通常都是 reverse proxy
匿名 proxy

[圖片來源](https://www.linkedin.com/posts/alexxubyte_systemdesign-coding-interviewtips-activity-6990698121835986944-_gl8?utm_source=share&utm_medium=member_desktop)
- 目的:
- 可以隱藏 client 的身份,保護 client!
- 可以突破一些網路的限制,連到其他原本被限制瀏覽的網站!
- 一些機構可以對內部成員做網路限制地存取,讓成員不能讀取特定網站
>情境:假設班上同學對考試有問題,跟 TA 申訴, TA 轉向去問老師
運作方式:同學 A(客戶端)把問題(請求)告訴 TA(正向代理),TA 代替同學跟老師(伺服器)溝通,然後將對方的回應傳回給你。
正向代理特徵:老師(伺服器)只知道 TA 問的,不知道真正問問題的人是同學 A(隱藏客戶端)。
>問一樣的TA直接答cache proxy
### Reverse Proxy (反向代理)

[圖片來源](https://notes.yxy.ninja/System-Design/Proxy/Reverse-Proxy-%28%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%29)
- 目的:
- 位於伺服器前,代表伺服器接收客戶端的請求。
- 客戶端不知道真正的伺服器,請求會由代理伺服器分發至後端伺服器。
- 用於負載平衡、安全性強化(如隱藏內部伺服器)、SSL 加密等。
>情境:學校有多個內部部門,像教務處、學務處、總務處、圖書館、校長室等,但學生和家長不需要直接與這些部門溝通。
運作方式:學校設置了一個統一的「接待處」窗口,所有的請求都先到接待處,由接待處分配到相關的部門。
學生或家長(用戶端)提出需求(申請成績單),接待處(反向代理)收到請求,根據需求內容判斷,將請求轉發給內部的「教務處」處理。
「教務處」完成申請後,將結果返回給接待處,接待處再將結果交給學生或家長。
反向代理特徵:內部部門(伺服器)被保護起來,只有接待處(反向代理)對外公開。學生與家長不會知道具體是誰處理了請求(例如教務處的哪位老師)。
>這樣像 API Gateway
>ex.有事找柏緯->延伸-> 有助教群
依照規則(輪流)丟給其他助教做,再給柏緯 (load)
->又有人問之前問過的,如果柏緯還記得就直接答(cache proxy)
### Reverse Proxy LAB
- 用 nginx reverse proxy 到 `apache(8081)` & `https://www.google.com`
- 
[圖片來源](https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2F%40qtNgFtaqR4Or_CLAuotXjw%2FSJ4NxJjC3#Nginx-%E5%AF%A6%E4%BD%9C)
- `sudo service nginx stop`
- `sudo vim /etc/nginx/sites-available/nginx-proxy`
```conf=
server {
listen 80;
server_name nginxproxy;
location /proxygoogle/ {
proxy_pass https://google.com/;
}
location /proxyapache2/ {
proxy_pass http://127.0.0.1:8081/;
}
location / {
proxy_pass http://127.0.0.1:8080/; #lighttpd
}
}
```
- `sudo ln -s /etc/nginx/sites-available/nginx-proxy /etc/nginx/sites-enabled/`
- 新增主機紀錄
- `sudo vim /etc/hosts`
- `127.0.0.1 nginxproxy`
- `sudo service nginx restart`
- `http://nginxproxy/proxyapache2/`
- `http://nginxproxy/proxygoogle/`
- `http://nginxproxy/`
## Load Balance (負載平衡)
- 將流量合理分配,以提升各個 Server 的資源使用率及可用性
- 避免流量集中給同一台 Server 造成**超載/過載/爆掉**使服務無法正常運行
>情境:在超市結賬時,有多個收銀台開放,顧客可以選擇排隊結賬。
運作方式:超市安排一名引導員(負載平衡器),將新來的顧客引導到當前最空閒或最少人的收銀台,確保每個收銀台的工作量均衡。
特點:每個收銀員(伺服器)負責結算顧客的賬單,顧客分散排隊,避免擁擠。
#### nginx 模擬 load balance Lab
將服務**分流**到 localhost:8080 (lighttpd) 跟 yahoo.com
- `sudo service nginx stop`
- 至 `/etc/nginx/sites-available/` 設定相關檔案
- `sudo vim /etc/nginx/sites-available/nginx-lb`
- 
```conf=
upstream lsa.lab {
server localhost:8080;
server tw.search.yahoo.com;
}
server {
listen 8070;
server_name lbnginx;
location / {
proxy_pass http://lsa.lab;
}
}
```
:::info
**upstream**
- 紀錄要分流的 IP
- 後面接的名稱單純變數名稱,隨便命名沒關係
- 預設使用 Round-Robin (RR) 來分配流量
- 輪流
:::
- 新增一個 DomainName
- `sudo vim /etc/hosts`
- 127.0.0.1 lbnginx
- Soft Link 到 `nginx/sites-enabled/`
- `sudo ln -s /etc/nginx/sites-available/nginx-lb /etc/nginx/sites-enabled/`
- 確認設定檔有沒有問題
- `sudo nginx -t`
- 沒有問題的話就 restart
- `sudo service nginx restart`
- 測試時間~
- 到 http://lbnginx:8070 瘋狂 `F5`
- 會看到 yahoo 跟 lighttpd 輪流切換