在上一篇 Nginx 在 CentOS 上的安裝時已經提到了 Nginx 是一個應用廣泛的反向代理服務,可是有的人可能就一臉問號了,反向代理是啥意思?
A proxy server is a go?between or intermediary server that forwards requests for content from multiple clients to different servers across the Internet. A reverse proxy server is a type of proxy server that typically sits behind the firewall in a private network and directs client requests to the appropriate backend server. A reverse proxy provides an additional level of abstraction and control to ensure the smooth flow of network traffic between clients and servers.
Ningx 的官網給出了解釋,https://www.nginx.com/resources/glossary/reverse-proxy-server/。
大致意思是說:
代理服務器是一個中間服務器,它主要是把英特網上的不同客戶端的請求轉發到不同的服務器上。而反向代理服務器則是代理服務器的一種,它也是把英特網上的不同客戶端的請求轉發到不同的服務器上,它這些服務器是位于某個私有網絡中,且該私有網絡具有防火墻(比如防火墻只允許該私有網絡通過一個指定的 IP 與 端口與外網連接)。也就是說我們直接訪問需要訪問的服務器是不通的,如下是 Nginx 官網的 Nginx 配置 API 網關示意圖,但我覺得它同樣能表達反向代理的過程。
另外,反向代理還提供了額外的抽象和控制級別(比如對傳輸數據進行壓縮等等),以確保客戶端和服務器之間的網絡流量順暢。
下面,就介紹一些反向代理的常用的設置。
一、nginx.conf 配置
1.1 用戶配置
如果 nginx 使用 root 用戶運行,那么最好將 nginx.conf 中的 user 配置為 root (默認為 nobody)。不然,如果轉發為目錄時,如果目錄權限不是 777,那么將訪問不到轉發的目錄而報 403 錯誤。
user root;
1.2 引入自定義配置
正常來說,我們可以在 nginx.conf 配置許多個轉發規則,反向解析到不同的服務,比如 api.jiangzhuolin.com 我需要解析到我的 api 服務,mail.jiangzhuolin.com 轉發到我的郵箱服務,file.jiangzhuolin.com 轉發到我的服務器上的某個文件目錄。但是如果全都配置到一個文件里,那么會很亂很難維護。
因此,我們可以把每一個轉發規則分離出去,便于維護。
root 用戶執行如下命令編輯 nginx.conf:
[root@lab1 sbin]# vim ${NGINX_HOME}/conf/nginx.conf
注:${NGINX_HOME} 表示你的 nginx 的安裝路徑,比如:nginx 安裝在 /usr/local/nginx
在文件中添加如下內容,并保存退出:
include vhost/*.conf;
如下所示:
注:
(1) nginx.conf 所在的位置與 nginx 的安裝位置有關。比如,我的 nginx 安裝在 /usr/local/nginx 下, nginx.conf 就應該在 /usr/local/nginx/conf/nginx.conf,如果你的 nginx 安裝在 /usr/nginx 下,那么你的 nginx.conf 就在 /usr/nginx/conf/nginx.conf
(2) include vhost/*.conf 表示引入 vhost 目錄下的所有 .conf 結尾的文件內容
1.3 創建一個自定義配置文件目錄
在 ${NGINX_HOME}/conf 目錄下新建 vhost 目錄:
[root@lab1 conf]# pwd
/usr/local/nginx/conf
[root@lab1 conf]# mkdir vhost
注:vhost 目錄名稱可以為其他,只需要引入對應名稱的目錄下的所有配置文件即可。
二、端口轉發
端口轉發就是將一個域名轉發到監聽某個端口進程服務上。
示例:
在 vhost 目錄下創建 demo.jzl.com.conf :
[root@lab1 vhost]# vi demo.jzl.com.conf
內容如下:
server
{
listen 80;
server_name demo.jzl.com;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.56.130:8081/web-demo/;
}
access_log logs/demo.jzl.com_access.log;
}
注:
(a) server {} 表示的是 nginx 的配置,其中 listen 80 表示 nginx 的監聽端口為 80, server_name demo.jzl.com 表示該主機解析的域名
(b) location / {} 表示的是轉發規則,proxy_pass http://192.168.56.130:8081/web-demo/ 表示當使用 demo.jzl.com 訪問時,轉發到 192.168.56.130 的 8081 端口下的 web-demo 目錄
(c) 當然,你的 192.168.56.130 必須要有程序運行監聽在 8081 端口~,我的 192.168.56.130 上運行了一個 tomcat 監聽端口 8081,tomcat 的 webapps 下部署了一個 context 為 web-demo 程序
(d) 如果你不想設置域名,當然也可以設置 ip ,比如把 demo.jzl.com 換成 192.168.56.130 ,那么當訪問 http://192.168.56.130:80 ,會被 nginx 轉發到 192.168.56.130:8081/web-demo/
三、虛擬域名
如果你的主機沒有由 DNS 解析的域名,那么可以設置虛擬域名來訪問,所謂虛擬域名,就是在我們的 hosts 文件中配置的域名,它只在我們配置的計算機上生效。設置方法如下:
3.1 配置虛擬域名
在你的被訪問的 server 上 ( nginx server) 設置本機域名解析,vi /etc/hosts
,添加內容如下示例:
192.168.56.130 demo.jzl.com
示例:
3.2 配置訪問客戶端的虛擬域名
在你需要訪問遠程 server 的客戶機上也設置一個虛擬域名解析(注意,客戶機必須與遠程 server 網絡連通),此處以本地的 windows 客戶機為例:
打開并編輯下方文件:
C:\Windows\System32\drivers\etc\host
添加內容如下,并保存 (注:直接用 windows 的編輯打開文件可能會沒有權限保存,可以將文件復制出來更改后再覆蓋原文件;也可以使用 notepadd ++ 來編輯文件可以保存):
192.168.56.130 demo.jzl.com
示例如下圖:
驗證:
添加上面的 nginx 配置規則后,需要重啟 nginx。(當然,如果你之前沒啟動 nginx,不用重啟,直接啟動即可)
${NGINX_HOME}/sbin/nginx # 啟動 ngnix
${NGINX_HOME}/sbin/nginx -s reload # 重載 nginx
注:${NGINX_HOME} 代表你 nginx 的安裝目錄,如果你配置了 nginx 的全局環境變量 (參考上一篇 Nginx 安裝),也可以在任意目錄位置直接執行 nginx/nginx -s reload
查看 nginx 的監聽端口以及運行進程號:
[root@lab1 pentaho-server]# netstat -apn|grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 8917/nginx
unix 3 [ ] STREAM CONNECTED 29047 8917/nginx
unix 3 [ ] STREAM CONNECTED 29046 8917/nginx
查看 8080 端口的監聽及運行情況:
[root@lab1 conf]# netstat -apn|grep 8080
tcp 0 0 :::8080 :::* LISTEN 1580/java
瀏覽器中訪問:
可以看到已經配置成功。
四、目錄轉發
示例:
在 vhost 目錄下創建 file.jzl.com.conf :
[root@lab1 vhost]# vi file.jzl.com.conf
內容如下示例:
server {
default_type 'text/html';
charset utf-8;
listen 80; #端口
autoindex on;
server_name file.jzl.com; #域名
access_log /usr/local/nginx/logs/file.jzl.com_access.log combined;
index index.html index.htm index.jsp index.php;
# 轉發規則[目錄轉發]
location / {
root /opt;
add_header Access-Control-Allow-Origin *;
}
location /elk {
alias /data/elk/;
add_header Access-Control-Allow-Origin *;
}
}
注:
(a) autoindex on; 此設置必須加上,表示讓nginx 自動為目錄添加索引。如果不加上,當在瀏覽器中訪問時,會出現403錯誤
(b) root /opt 代表的是定義一個基準目錄,也就是說當我們訪問 file.jzl.com 域名下的 / (file.jzl.com/) 時,會自動轉發到 /opt/ 目錄下。
(c) alias /data/elk/ 表示的是當我們訪問 file.jzl.com 下的 elk (file.jzl.com/elk/) 時,會自動轉發到 /data/elk/ 目錄。另,如果是設置 alias, 目錄最后的 / 不可少,即不能寫成 /data/elk
(d) 配置目錄轉發時,alias 與 root 兩種方式任選一種即可,但需要注意兩種方式使用上的不同。
(e) 配置 server 與 client 的 hosts 文件如下:
瀏覽器中輸入域名訪問如下:
注:如果你已經有 DNS 解析的域名,則完全不用配置 hosts 文件中的本地域名解析了,直接在反向代理中配置具體域名即可。
附錄一、nginx 反向代理
官方反向代理配置介紹地址:
https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
附錄二、nginx laction 配置
官方 location 介紹地址如下:
http://nginx.org/en/docs/http/ngx_http_core_module.html?#location
附錄三、復雜 location 配置示例
server {
listen 80;
autoindex on;
server_name example.jzl.com);
access_log /usr/local/nginx/logs/access.log combined;
index index.html index.htm index.jsp index.php;
if ( $query_string ~* ".*[\;'\<\>].*" ){
return 404;
}
location = / {
root /product/front/mmall_fe/dist/view;
index index.html;
}
location ~ .*\.html$ {
root /product/front/mmall_fe/dist/view;
index index.html;
}
location / {
proxy_pass [http://127.0.0.1:8080/;](http://127.0.0.1:8080/;)
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|flv|ico)$ {
proxy_pass [http://127.0.0.1:8080](http://127.0.0.1:8080/);
expires 30d;
}
location ~ .*\.(js|css)?$ {
proxy_pass [http://127.0.0.1:8080](http://127.0.0.1:8080/);
expires 7d;
}
}