Nginx

Nginx

一、Nginx介紹

Nginx是反向代理服務(wù)器??蛻舳酥恍柙L問Nginx端口,Nginx會根據(jù)負(fù)載均衡策略將請求分給各個服務(wù)器,不會造成某一臺服務(wù)器負(fù)載過高的問題;Nginx還可以實現(xiàn)動靜分離,在Nginx上直接處理靜態(tài)資源。

特點:

  1. 穩(wěn)定性極強,可以一直不間斷運行

    1. Nginx提供了非常豐富的配置實例
    2. 占用內(nèi)存小,并發(fā)能力強

二、Nginx安裝

2.1 用Docker-compose安裝Nginx

編寫docker-compose.yml文件

version: '3.1'
services:
  nginx:
    restart: always
    image: daocloud.io/library/nginx:1.13.2
    container_name: nginx
    ports:
      - 80:80

啟動Nginx容器

docker-compose up -d

2.2 Nginx配置文件

在Nginx容器內(nèi)部的 /etc/nginx 目錄下的 nginx.conf 為Nginx的核心配置文件

nginx.conf的內(nèi)容:

## 全局塊 
#   worker_processes的值越大, Nginx的并發(fā)能力越強
#   error_log為Nginx錯誤日志的存放位置
worker_processes 1;
error_log /var/run/nginx.pid;

## event塊
#   worker_connections的值越大, Nginx的并發(fā)能力越強
events {
    worker_connections 1024;
}

## http塊
#   第一個include代表引入一個外部的文件, mime.types中存放著大量的媒體類型
#   第二個include代表引入conf.d目錄下所有以.conf結(jié)尾的配置文件
#   default_type為默認(rèn)的媒體類型
http {
    include /etc/nginx/mime.types
    default_type application/octet-stream
    
    log_format main '$remote_addr - $remote_user [$time_local] "$request"'
                    '$status $body_bytes_sent "$http_referer"'
                    '"$http_user_agent" "$http_x_forwarded_for"'
    
    access_log /var/log/nginx/access.log main;
    
    sendfile on
    #tcp_nopush on;
    
    keepalive_timeout 65;
    
    #gzip on;
    
    include /etc/nginx/conf.d/*.conf;
    
}

/etc/nginx/conf.d/ 目錄下有個默認(rèn)的配置 default.conf 文件,文件內(nèi)是一個server塊,server塊是用在http塊中的

server {
    listen 80;  # Nginx的端口號
    server_name localhost;  # Nginx的ip
    
    location / {
        root /usr/share/nginx/html;  # 將接受到的請求根據(jù)這個路徑去查找靜態(tài)資源
        index index.html index.htm;  # 默認(rèn)響應(yīng)頁面(在root路徑中)
    }
}

2.3 使用數(shù)據(jù)卷與Nginx容器內(nèi)的conf.d目錄創(chuàng)建映射關(guān)系

修改docker-compose.yml文件

version: '3.1'
services:
  nginx:
    restart: always
    image: daocloud.io/library/nginx:1.13.2
    container_name: nginx
    ports:
      - 80:80
    # 數(shù)據(jù)卷
    volumes:
      - /mydata/nginx/conf.d/:/etc/nginx/conf.d

三、Nginx的反向代理

正向代理:

  1. 正向代理服務(wù)器是由客戶端設(shè)立的

    1. 客戶端知道代理服務(wù)器和目標(biāo)服務(wù)器都是誰
    2. 能夠幫助客戶端實現(xiàn)突破訪問權(quán)限,提高訪問速度,對目標(biāo)服務(wù)器隱藏客戶端的IP地址

反向代理:

1. 反向代理服務(wù)器是配置在服務(wù)端的
2. 客戶端不知道訪問的到底是哪一臺服務(wù)器
3. 能夠?qū)崿F(xiàn)負(fù)載均衡,并且可以隱藏服務(wù)器真正的IP地址

3.1 基于Nginx實現(xiàn)反向代理

Step1:準(zhǔn)備一臺目標(biāo)服務(wù)器(用Docker運行一個Tomcat即可)

Step2:編寫 /mydata/nginx/conf.d (因為已經(jīng)做過數(shù)據(jù)卷映射,直接在本地映射的目錄中編寫即可)目錄下的 default.conf 中的server塊

server {
    listen 80;
    server_name localhost;
    
    # 基于反向大力訪問到Tomcat服務(wù)器
    location / {
        # 這個地址是把訪問Nginx的請求轉(zhuǎn)發(fā)到目標(biāo)服務(wù)器的地址
        proxy_pass http://192.168.199.109:8080/;
    }
}

3.2 關(guān)于server塊的location路徑映射

  1. 精準(zhǔn)匹配
## =/xxx 優(yōu)先級最高
#   只能匹配ip:端口號/xxx 路徑別的匹配不上
#   例: 客戶端發(fā)請求www.baidu.com/xxx可以匹配上, 發(fā)www.baidu.com/匹配不上
location = /xxx {
    ...
}
  1. 通用匹配
## 可以匹配所有以 /xxx 開頭的路徑
location /xxx {
    ...
}

## 匹配所有路徑
location / {
    ...
}
  1. 正則匹配
## 匹配以 /xxx 開頭的路徑
location ~ /xxx {
    ...
}
  1. 匹配開頭路徑
## 匹配以 /xxx 開頭的路徑
location ^~ /xxx {
    ...
}
  1. 匹配結(jié)尾路徑
## 匹配以jpg或png結(jié)尾的路徑
location ~* \.(jpg|png)$ {
    ...
}

優(yōu)先級關(guān)系:

  • = /xxx 最高
  • 2完全匹配上的時候 > 匹配結(jié)尾 > 4匹配到開頭 > 3匹配到開頭 > 2匹配到開頭 > 2匹配全部的寫法
  • 一個server塊中可以寫多個location,但是各location編寫的順序應(yīng)該按優(yōu)先級由高到低來寫

四、Nginx的負(fù)載均衡

Nginx的負(fù)載均衡策略:

1. 輪詢:將客戶端發(fā)起的請求平均分配給每一臺服務(wù)器
2. 權(quán)重:根據(jù)服務(wù)器處理速度,將客戶端的請求按指定的權(quán)重分配給服務(wù)器
3. ip hash:根據(jù)發(fā)起請求的客戶端的ip地址,計算一個hash值,再根據(jù)hash值分配到指定的服務(wù)器上

4.1 輪詢

在conf.d下的default.conf的最上方添加upstream塊

## 假設(shè)這三臺tomcat是屬于一個集群, 歸整到upstream中, location轉(zhuǎn)發(fā)時指定upstream即可
upstream my_server {
    server 192.168.199.109:8080;
    server 192.168.199.109:8081;
    server 192.168.199.109:8082;
}

location / {
    proxy_pass http://my_server/;
}

4.2 權(quán)重

在輪詢的基礎(chǔ)上修改default.conf

## 這時候每來20個請求, 有10個訪問8080 6個訪問8081 4個訪問8082
upstream my_server {
    server 192.168.199.109:8080 weight=10;
    server 192.168.199.109:8081 weight=6;
    server 192.168.199.109:8082 weight=4;
}

location / {
    proxy_pass http://my_server/;
}

4.3 ip hash

在輪詢的基礎(chǔ)上修改default.conf

## ip hash的好處是能讓一臺服務(wù)器每次都處理上一次訪問過它的客戶端的請求
upstream my_server {
    ip hash;  # 加上這一句就會按照ip hash的策略來分配請求
    server 192.168.199.109:8080;
    server 192.168.199.109:8081;
    server 192.168.199.109:8082;
}

location / {
    proxy_pass http://my_server/;
}

五、Nginx的動靜分離

Nginx的并發(fā)能力公式:

? worker_process * worker_connections / 4 或 worker_process * worker_connections / 2

? 動態(tài)資源 / 4,靜態(tài)資源只需要 / 2

? 因為動態(tài)資源需要訪問服務(wù)器,而靜態(tài)資源可以存放在Nginx中,即每個請求少了兩次交互

Nginx通過動靜分離,提高了Nginx的并發(fā)能力

5.1 動態(tài)資源代理

在location塊中寫proxy_pass 路徑;即可

location / {
    proxy_pass http:192.168.199.109:8080;
}

5.2 靜態(tài)資源代理

也是在location塊中指定靜態(tài)資源的路徑

示例1:

## location指定的匹配路徑匹配上之后會和root進(jìn)行拼接
#   即當(dāng)前訪問 nginxIP:nginx端口/img 會默認(rèn)顯示nginx容器內(nèi) /data/img 路徑下的 aaa.html 資源
location /img {
    root /data;  # 靜態(tài)資源路徑, 實際上拼接后的路徑為 /data/img
    index aaa.html;  # 默認(rèn)訪問root指定路徑下哪一個資源
}

示例2:

location /img {
    root /data;
    autoindex on;  # 表示以列表的形式展示靜態(tài)資源路徑下的全部內(nèi)容
}

六、Nginx集群

主要是為了解決Nginx單點故障問題

需要準(zhǔn)備keepalive監(jiān)聽Nginx的健康情況;準(zhǔn)備haproxy提供一個虛擬路徑,統(tǒng)一去接收用戶請求

用戶的請求會統(tǒng)一發(fā)送到master節(jié)點上,當(dāng)master宕機(jī)后請求才會發(fā)送給slave節(jié)點

Nginx集群的搭建:

Step1:用Dockerfile將nginx和keepalived組合成一個自定義鏡像

? Dockerfile文件編寫

from nginx:daocloud.io/library/nginx:1.13.2
# 安裝apk
run apk update && apk upgrade  
# 通過apk下載keepalived
run apk add --no-cache bash curl ipvsadm iproute2 openrc keepalived  
# 將當(dāng)前目錄下的entrypoint.sh腳復(fù)制到我們要創(chuàng)建的這個自定義鏡像的容器內(nèi)
copy entrypoint.sh /entrypoint.sh
# 修改這個腳本文件的權(quán)限
run chmod +x /entrypoint.sh
# 啟動容器時執(zhí)行腳本文件
cmd ["/entrypoint.sh"]

Step2:準(zhǔn)備entrypoint.sh腳本

# 啟動keepalived
/usr/sbin/keepalived -D -f /etc/keepalived/keepalived.conf
# 啟動nginx
nginx -g "daemon off;"

Step3:準(zhǔn)備Nginx master和slave的keepalived配置文件

? keepalived-master.conf:

## 指定keepalived查看nginx健康情況的周期
vrrp_script chk_nginx {
    script "pidof nginx"
    interval 2
}

vrrp_instance VI_1 {
    state MASTER  # 指定當(dāng)前是master的keepalived
    interface eth0  # 容器內(nèi)部的網(wǎng)卡名稱
    virtual_router_id 33  # 路由id, 默認(rèn)33即可
    # 優(yōu)先級, master的優(yōu)先級一定要高于slave, 當(dāng)master宕機(jī)后就會把請求發(fā)給第二優(yōu)先級的slave
    priority 200  
    advert_int 1
    
    authentication {
        auth_type PASS
        auth_pass letmein
    }
    
    virtual_ipaddress {
        172.20.128.50  # 虛擬路徑
    }
    
    track_script {
        chk_nginx
    }
}

? keepalived-slave.conf

vrrp_script chk_nginx {
    script "pidof nginx"
    interval 2
}

vrrp_instance VI_1 {
    state BACKUP  # 指定當(dāng)前是slave的keepalived
    interface eth0
    virtual_router_id 33
    priority 100
    advert_int 1
    
    authentication {
        auth_type PASS
        auth_pass letmein
    }
    
    virtual_ipaddress {
        172.20.128.50
    }
    
    track_script {
        chk_nginx
    }
}

Step4:準(zhǔn)備haproxy.cfg文件

global
    log 127.0.0.1 local0
    maxconn 4096
    daemon
    nbproc 4

defaults
    log 127.0.0.1 local3
    mode http
    option dontlognull
    retries 2
    maxconn 2000
    balance roundrobin
    timeout connect 5000ms
    timeout client 5000ms
    timeout server 5000ms
    
frontend main
    bind *:6301
    default_backend webserver
    
backend webserver
    # 這個ip是keepalived中指定的虛擬路徑
    # 當(dāng)訪問haproxy的時候就會通過這個路徑找到兩個nginx
    # 再由keepalived決定請求到底交給哪個nginx
    server nginx_master 172.20.128.50:80 check inter 2000 rise 2 fall 5

Step5:準(zhǔn)備docker-compose.yml文件

version: "3.1"
services:
  ## master naginx的容器
  nginx_master:
    build:
      context: ./
      dockerfile: ./Dockerfile
    ports:
      - 3000:80
    volumes:
      # 表示訪問到這個nginx后默認(rèn)顯示的頁面(需要事先準(zhǔn)備一個index-master.html, 內(nèi)容隨意)
      - ./index-master.html:/usr/share/nginx/html/index.html
      - ./favicon.ico:/usr/share/nginx/html/favicon.ico
      - ./keepalived-master.conf:/etc/keepalived/keepalived.conf
    networks:
      static-network:
        # 固定當(dāng)前nginx在docker容器內(nèi)的ip
        # 如果不固定則nginxdocker容器內(nèi)的ip是隨機(jī)的, 無法和keepalived的虛擬路徑綁定
        ipv4_address: 172.20.128.2
    cap_add:
      - NET_ADMIN
  
  ## slave nginx的容器
  nginx_slave:
    build:
      context: ./
      dockerfile: ./Dockerfile
    ports:
      - 3001:80
    volumes:
      # 表示訪問到這個nginx后默認(rèn)顯示的頁面(需要事先準(zhǔn)備一個index-slave.html, 內(nèi)容隨意)
      - ./index-slave.html:/usr/share/nginx/html/index.html
      - ./favicon.ico:/usr/share/nginx/html/favicon.ico
      - ./keepalived-master.conf:/etc/keepalived/keepalived.conf
    networks:
      static-network:
        ipv4_address: 172.20.128.3
    cap_add:
      - NET_ADMIN
    
    ## haproxy的容器
    proxy:
      image: daocloud.io/daocloud/dockercloud-haproxy:1.6.6
      ports:
        - 80:6301
      volumes:
        - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
    
  networks:
    static-network:
      ipam:
        config:
          - subnet: 172.20.0.0/16

Step6:通過docker-compose啟動配置的所有容器

docker-compose up -d

Step7:測試。訪問服務(wù)器ip:80可以訪問到haproxy,可以看到index-master.html的內(nèi)容;把master的nginx關(guān)閉后再訪問服務(wù)器ip:80可以看到index-slave.html的內(nèi)容。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、Nginx介紹 1.1引言 為什么要學(xué)習(xí) Nginx問題1:客戶端到底要將請求發(fā)送給哪臺服務(wù)器問題2:如果所有...
    yjtuuige閱讀 1,381評論 1 25
  • 一、Nginx介紹 1.1 引言 為什么要學(xué)習(xí)Nginx問題1:客戶端到底要將請求發(fā)送給哪臺服務(wù)器問題2:如果所有...
    藍(lán)胖子的白日夢丶閱讀 3,282評論 0 3
  • 引言: 現(xiàn)如今作為一名Java開發(fā)工程師,不會點運維相關(guān)的技術(shù)都不好意思出去面試,本文是從0開始基于Docker搭...
    one_little_boy閱讀 318評論 0 1
  • 大家好,我是前端dog君,一名95后前端小兵。2019年畢業(yè)于北京化工大學(xué),天津人,不知道有校友和老鄉(xiāng)嘛?對前端的...
    前端dog君閱讀 945評論 0 0
  • Nginx安裝 docker-compose.yml 配置文件 nginx 目錄下 nginx.conf ngin...
    黑人毅的粉絲閱讀 293評論 0 0

友情鏈接更多精彩內(nèi)容