nginx正向代理、反向代理


Nginx 是一個高性能的 HTTP 和反向代理服務器,特點是占用內存少,並發能力強,事實上 Nginx 的並發能力確實在同類型的網頁服務器中表現較好。

Nginx 專為性能優化而開發,性能是其最重要的要求,十分注重效率,有報告 Nginx 能支持高達 50000 個並發連接數(這個結果不唯一,依據服務器的配置情況而定)

一、正向代理(透明代理,代理上網)

適用於局域網訪問外部網絡,只能通過代理服務器來訪問,這種代理服務就被稱為正向代理。

通常某些服務因為安全問題,限制固定訪問,因此可以通過正向代理解決

訪問某些國外的服務訪問慢,可以通過正向代理中繼緩解丟包和延遲高的問題

 正向代理的配置

http {
	resolver 8.8.8.8;
	server {
		listen 8088;
		location / {
			proxy_pass http://$http_host$request_uri;
		}
	}
}

nginx實現代理上網,有三個關鍵點必須注意,其余的配置跟普通的nginx一樣
1.增加dns解析resolver

2.增加無server_name名的server

3.proxy_pass指令

resolver表示DNS服務器
location表示匹配用戶訪問的資源,並作進一步轉交和處理,可用正則表達式匹配
proxy_pass表示需要代理的地址
$http_host 表示用戶訪問資源的主機部分
$request_uri 表示用戶訪問資源的URI部分。
如,http://nginx.org/download/nginx-1.6.3.tar.gz,則$http_host=nginx.org,$request_uri=/download/nginx-1.6.3.tar.gz。

可以不設置監聽端口號,nginx默認監聽80端口,除非你要修改監聽端口,可以用listen字段指定。

實戰案例1:

之前的編譯nginx的基礎上,我們對nginx二進制增加新的模快ngx_http_proxy_connect_module

cd /root/workspace/packages/nginx && git clone https://github.com/chobits/ngx_http_proxy_connect_module.git

./configure --prefix=/webserver/nginx18 --user=www --group=www --with-pcre --with-zlib=/root/workspace/packages/nginx/zlib-1.2.8 --with-openssl=/root/workspace/packages/nginx/openssl-1.0.2d --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --add-module=/root/workspace/packages/nginx/ngx_devel_kit-0.3.0 --with-ld-opt=-ljemalloc --with-stream --with-http_ssl_module --add-module=/root/workspace/packages/nginx/nginx_upstream_check_module-0.3.0 --with-http_gzip_static_module --add-module=/root/workspace/packages/nginx/ngx_http_proxy_connect_module

缺少的庫文件

# wget https://ftp.pcre.org/pub/pcre/pcre-8.00.tar.gz
# tar xf pcre-8.00.tar.gz && cd pcre-8.00 && ./configure --enable-utf8 --disable-shared --with-pic && make && make install

# tar xf jemalloc-4.5.0.tar.bz2
# cd jemalloc-4.5.0 && ./configure && make && make install
# echo '/usr/local/lib' >> /etc/ld.so.conf.d/local.conf
# ldd /webserver/nginx18/sbin/nginx
	linux-vdso.so.1 =>  (0x00007ffd2cb5d000)
	libjemalloc.so.2 => /usr/local/lib/libjemalloc.so.2 (0x00007fd040db2000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007fd040bae000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fd040992000)
	libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fd04075b000)
	libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fd0404eb000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fd04011e000)
	libm.so.6 => /lib64/libm.so.6 (0x00007fd03fe1c000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fd041005000)
	libfreebl3.so => /lib64/libfreebl3.so (0x00007fd03fc19000)

缺少包

# find /  -iname  "libpcre.so.3" # 找不到
# ldd /webserver/nginx18/sbin/nginx
libpcre.so.3 => not found

注:ldd本身不是一個程序,而僅是一個shell腳本:ldd可以列出一個程序所需要得動態鏈接庫(so)

# echo '/lib/x86_64-linux-gnu' > /etc/ld.so.conf.d/local.conf
# ldconfig
# ldd /webserver/nginx18/sbin/nginx |grep 'libpcre.so.3'
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fd0404eb000)

測試編譯是否正常

# /webserver/nginx18/sbin/nginx -t -c /webserver/nginx18/conf/nginx.conf
nginx: the configuration file /webserver/nginx18/conf/nginx.conf syntax is ok
nginx: configuration file /webserver/nginx18/conf/nginx.conf test is successful

正向代理的配置首先保證你的ngx_http_proxy_connect_module模塊被編譯到nginx二進制中

准備正向代理的配置文件

# cat /webserver/nginx18/conf/vhost/proxy.conf
server {
		 # 正向代理監聽的端口
     listen                         0.0.0.0:3128;

     # 正向代理中必須有的DNS解析指令
     resolver                       114.114.114.114;

		 # 啟用日志記錄
     access_log /webserver/nginx18/logs/proxy.log main;
     
     # forward proxy for CONNECT request
     proxy_connect;
     proxy_connect_allow            443 563;
     proxy_connect_connect_timeout  10s;
     proxy_connect_read_timeout     10s;
     proxy_connect_send_timeout     10s;

     # forward proxy for non-CONNECT request
     location / {
         proxy_pass http://$host;
         proxy_set_header Host $host;
     }
 }

然后重啟nginx即可

# /webserver/nginx18/sbin/nginx -t -c /webserver/nginx18/conf/nginx.conf
# /webserver/nginx18/sbin/nginx -s reload -c /webserver/nginx18/conf/nginx.conf #這里面引用了vhost中的配置include vhost/*.conf;

# netstat -tunlp |grep 3128 tcp 0 0 0.0.0.0:3128 0.0.0.0:* LISTEN 16553/nginx: master

正向代理測試

# curl https://github.com/ -I -x 161.101.x.x:3128
HTTP/1.1 200 Connection Established
Proxy-agent: nginx

HTTP/1.1 200 OK
date: Wed, 29 Jul 2020 00:34:11 GMT
content-type: text/html; charset=utf-8
server: GitHub.com
status: 200 OK
vary: X-PJAX, Accept-Encoding, Accept, X-Requested-With, Accept-Encoding
etag: W/"0645355c347925d40eae01189b1372c6"
cache-control: max-age=0, private, must-revalidate
strict-transport-security: max-age=31536000; includeSubdomains; preload
x-frame-options: deny
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
referrer-policy: origin-when-cross-origin, strict-origin-when-cross-origin
expect-ct: max-age=2592000, report-uri="https://api.github.com/_private/browser/errors"
content-security-policy: default-src 'none'; base-uri 'self'; block-all-mixed-content; connect-src 'self' uploads.github.com www.githubstatus.com collector.githubapp.com api.github.com www.google-analytics.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com cdn.optimizely.com logx.optimizely.com/v1/events wss://alive.github.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com; frame-ancestors 'none'; frame-src render.githubusercontent.com; img-src 'self' data: github.githubassets.com identicons.github.com collector.githubapp.com github-cloud.s3.amazonaws.com *.githubusercontent.com customer-stories-feed.github.com spotlights-feed.github.com; manifest-src 'self'; media-src 'none'; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; worker-src github.com/socket-worker.js gist.github.com/socket-worker.js
Set-Cookie: _gh_sess=f8%2BEHC2ipWawJaW%2BRIhaoHDpiKBaMNM9Qs6Kems7FPk0Jc13hBa28rZNLbtC9r3QEMvfN0JqDvOAsyyBKZMiG5QW3biYIFiQ8JxaGd0LjcmIRZ%2BVHqwYqrWVf23JtcsA6r1yIf3c%2BJy9QT92ANFDzxtpehY4F9ZWU7Wm%2B5iIY%2Fcb3h65b4t1ShJTue%2FA2dalNNAxSnvx%2FAm%2Br0p5IQRc9tGfevbWvL0bVYh8nqcezYEcExri65LLIwTwTkCzxasZfvLTQyDus05yMT8uQ%2F28Zw%3D%3D--zMmIhtSvd34s34pS--cFVCt72dLeREVdP%2BwqXrkA%3D%3D; Path=/; HttpOnly; Secure; SameSite=Lax
Set-Cookie: _octo=GH1.1.176641920.1595982853; Path=/; Domain=github.com; Expires=Thu, 29 Jul 2021 00:34:13 GMT; Secure; SameSite=Lax
Set-Cookie: logged_in=no; Path=/; Domain=github.com; Expires=Thu, 29 Jul 2021 00:34:13 GMT; HttpOnly; Secure; SameSite=Lax
Accept-Ranges: bytes
X-GitHub-Request-Id: BDE2:5AA6:205F20:2CDA3C:5F20C405

注:-I參數向服務器發出 HEAD 請求,然會將服務器返回的 HTTP 標頭打印出來。    -x參數指定 HTTP 請求的代理。

實戰案例2:

假設局域網內部有一個客戶端IP為192.168.65.122,該客戶端想訪問公網資源http://112.127.97.202:18890。則可以設置一個正向代理服務器,連接公網和局域網。正向代理服務器局域網IP為192.168.65.164,則開放該IP對應的8888端口。

局域網客戶端可通過訪問192.168.65.164:8888來獲取http://112.127.97.202:18890資源。

server {
    listen  192.168.65.164:8888;
    location / {
        proxy_pass  http://112.127.97.202:18890;
    }
}

 運行nginx -s reload命令,使Nginx重新加載配置文件。

打開客戶端瀏覽器,輸入192.168.65.164:8888,即可看到http://112.127.97.202:18890內容

實戰案例3:

server {
    resolver 8.8.8.8;
    resolver_timeout 5s;
 
    listen 0.0.0.0:8080;
 
    access_log  /home/reistlin/logs/proxy.access.log;
    error_log   /home/reistlin/logs/proxy.error.log;
 
    location / {
        proxy_pass $scheme://$host$request_uri;
        proxy_set_header Host $http_host;
 
        proxy_buffers 256 4k;
        proxy_max_temp_file_size 0;
 
        proxy_connect_timeout 30;
 
        proxy_cache_valid 200 302 10m;
        proxy_cache_valid 301 1h;
        proxy_cache_valid any 1m;
    }
}

配置說明:
1,配置 DNS 解析 IP 地址,比如 Google Public DNS,以及超時時間(5秒)。

resolver 8.8.8.8;
resolver_timeout 5s;

2,配置正向代理參數,均是由 Nginx 變量組成。其中 proxy_set_header 部分的配置,是為了解決如果 URL 中帶 "."(點)后 Nginx 503 錯誤。

proxy_pass $scheme://$host$request_uri;
proxy_set_header Host $http_host;

3,配置緩存大小,關閉磁盤緩存讀寫減少I/O,以及代理連接超時時間。

proxy_buffers 256 4k;
proxy_max_temp_file_size 0;
proxy_connect_timeout 30;

4,配置代理服務器 Http 狀態緩存時間。

proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid any 1m;

https://blog.51cto.com/13673090/2306487       正向代理支持https

https://www.devopsman.cn/en/posts/nginx%E6%9D%83%E5%A8%81%E6%8C%87%E5%8D%97%E4%B8%93%E8%BE%91/20200729-nginx%E4%B8%93%E8%BE%91-05-nginx%E6%AD%A3%E5%90%91%E4%BB%A3%E7%90%86%E7%9A%84%E4%BD%BF%E7%94%A8/   詳細,有待學習整理

二、反向代理

客戶端無法感知代理,因為客戶端訪問網絡不需要配置,只要把請求發送到反向代理服務器,由反向代理服務器去選擇目標服務器獲取數據,然后再返回到客戶端。

此時反向代理服務器和目標服務器對外就是一個服務器,暴露的是代理服務器地址,隱藏了真實服務器 IP 地址。

 反向代理配置

server {
        server_name www.baidu.com;
        location / {
                proxy_pass http://www.baidu.com/;
        }
}

 實戰案例1:

/usr/local/nginx/conf/nginx.conf  添加server塊如下:

實現效果:使用nignx反向代理,根據訪問的路徑跳轉到不同端口的服務中,nginx監聽端口為9001

訪問http://192.168.43.193:9001/edu/ 直接跳轉套127.0.0.1:8081

訪問http://192.168.43.193:9001/vod/ 直接跳轉套127.0.0.1:8082

實戰案例2:

    server {
        listen       80;
        server_name  xushuai.erp.com;
 
        location / {
            proxy_pass   http://192.168.183.130:8080;
			proxy_read_timeout 600s;
			proxy_set_header  X-Real-IP  $remote_addr;
			proxy_set_header Host $host:$server_port;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            index  index.html index.htm;
        }

反代案例3:nginx反向代理獲取用戶真實ip

nginx做反向代理時,默認的配置后端獲取到的ip都是來自於nginx,那么如何轉發用戶的真實IP到后端程序呢?
當前端使用nginx代理,后端使用php-fpm時,如果還是使用$_SERVER['REMOTE_ADDR'],那么php程序獲取到的是nginx的ip地址,而不是用戶的真實ip。

    upstream www.264.cn {
     ip_hash;
     server serving-server1.com:80;
     server serving-server2.com:80;
    }
    server {
     listen www.264.cn:80;
     server_name www.264.cn;
     
     location / {
     proxy_pass http://www.264.cn;
     }
     
     proxy_set_header Host $host;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     
    }

在nginx的配置文件中加入下面三個指令,這樣后端php就可以使用$_SERVER['HTTP_X_REAL_IP']獲取到訪客的ip。

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

如果你想使用 $_SERVER['REMOTE_ADDR'],不想修改代碼,那么可以通過修改REMOTE_ADDR的值來實現。經過多層代理后 $http_x_forwared_for 會含有多個ip,其中第一個ip是客戶端的ip,REMOTE_ADDR只能是客戶端的ip,所以可以用正則提取 $http_x_forwarded_for的第一個 ip 給REMOTE_ADDR:

     set $realip $remote_addr;
     if ($http_x_forwarded_for ~ "^(\d+\.\d+\.\d+\.\d+)") {
     set $realip $1;
     }
     fastcgi_param REMOTE_ADDR $realip;

實戰案例4:利用 Nginx 反向代理搭建本地 yum 服務器

注:nginx部署端在外網,同時也要能連通內網服務器

http://www.manongjc.com/detail/20-bmvectntimzbsrw.html

實戰案例5:Nginx 反向代理解決跨域問題

https://blog.csdn.net/qq_19734597/article/details/106344194

https://www.centoscn.vip/2039.html

https://www.runoob.com/w3cnote/nginx-proxy-balancing.html  反向代理

實戰案例6、nginx反向代理配置去除前綴

使用nginx做反向代理的時候,可以簡單的直接把請求原封不動的轉發給下一個服務。設置proxy_pass請求只會替換域名,如果要根據不同的url后綴來訪問不同的服務,則需要通過如下方法:

方法一:加"/"

server {
    listen              8000;
    server_name         abc.com;
    access_log  "pipe:rollback /data/log/nginx/access.log interval=1d baknum=7 maxsize=1G"  main;

    location ^~/user/ {
        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_set_header X-NginX-Proxy true;

        proxy_pass http://user/;
    }

    location ^~/order/ {
        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_set_header X-NginX-Proxy true;

        proxy_pass http://order/;
    }
}

^~/user/表示匹配前綴是user的請求,proxy_pass的結尾有/, 則會把/user/*后面的路徑直接拼接到后面,即移除user

方法二:rewrite

upstream user {
  server localhost:8089 weight=5;
}
upstream order {
  server localhost:8090 weight=5;
}

server {
    listen              80;
    server_name  abc.com;
    access_log  "pipe:rollback /data/log/nginx/access.log interval=1d baknum=7 maxsize=1G"  main;

    location ^~/user/ {
        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_set_header X-NginX-Proxy true;

        rewrite ^/user/(.*)$ /$1 break;
        proxy_pass http://user;
    }

    location ^~/order/ {
        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_set_header X-NginX-Proxy true;

        rewrite ^/order/(.*)$ /$1 break;
        proxy_pass http://order;
    }
}

proxy_pass結尾沒有/rewrite重寫了url。

三、負載均衡

客戶端發送多個請求到服務器,服務器處理請求,有一些可能要與數據庫進行交互,服務器處理完畢之后,再將結果返回給客戶端。

 假設有 15 個請求發送到代理服務器,那么由代理服務器根據服務器數量,平均分配,每個服務器處理 5 個請求,這個過程就叫做負載均衡。

四、動靜分離

為了加快網站的解析速度,可以把動態頁面和靜態頁面交給不同的服務器來解析,加快解析的速度,降低由單個服務器的壓力。

動靜分離之前的狀態:

 動靜分離之后:

什么是動靜分離?把動態請求和靜態請求分開,不是講動態頁面和靜態頁面物理分離,可以理解為 Nginx 處理靜態頁面,Tomcat 處理動態頁面。

動靜分離大致分為兩種:

  • 純粹將靜態文件獨立成單獨域名放在獨立的服務器上,也是目前主流方案。

  • 將動態跟靜態文件混合在一起發布,通過 Nginx 分開。

動靜分離圖析:

配置 Nginx,如下圖:

使用wordpress-5.0.3-zh_CN.tar.gz做實驗

Nginx服務器的配置:

# tar xf wordpress-5.0.3-zh_CN.tar.gz
# mv wordpress/* /data/nginx/php/
# vim /apps/nginx/conf/conf.d/pc.conf
server {
   listen 80;
   server_name www.xxxpc.net;
   location / {
      root /data/nginx/php;       #指定靜態資源的根,wordpress中的html文件和目錄沒有指定靜態文件的具體位置,所以默認會去nginx的/下尋找靜態資源
      index index.html;
   }
   location ~ \.php$ {
      root /data/nginx/php;       #指定php服務器存放資源文件的根路徑
      fastcgi_pass 192.168.38.37:9000;    #發現php后綴的資源,反向代理給指定IP和端口號的php服務器
      fastcgi_index index.php;    #php的默認站點頁面
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;  #告知php服務器用戶請求的資源的絕對路徑和資源名稱
      include fastcgi_params;     #包含fastcgi_params文件中的所有參數
   }
}

php服務器配置:

# tar xf wordpress-5.0.3-zh_CN.tar.gz 
# mv wordpress/* /data/nginx/php/     #把wordpress移動到Nginx所指定的php服務器的動態資源路徑下
# cd /data/nginx/php/
# mysql
MariaDB [(none)]> grant all on wordpress.* to wordpress@'192.168.38.%' identified by 'centos';   #創建php連接數據庫的用戶和密碼
MariaDB [(none)]> create database wordpress;   #創建wordpress用於存放數據的數據庫
[root@localhost php]# cp wp-config-sample.php wp-config.php   #復制php連接數據庫的配置文件
[root@localhost php]# vim wp-config.php    #修改一下php連接數據庫的各種配置即可
[root@localhost php]# systemctl start php72-php-fpm

注:當Nginx和php不在同一台服務器時,Nginx和php各自服務器上都需要有wordpress的各種資源文件;因為用戶請求的資源,只有動態資源才會往php服務器上轉發,靜態資源Nginx自己進行回復;

所以如果php有wordpress資源,但是Nginx上沒有,則會造成頁面無渲染效果;反之,如果Nginx上有wordpress資源,php上沒有,則會提示File not found

https://www.cnblogs.com/dongzhanyi123/category/1806126.html     nginx不錯的整理

五、nginx的配置文件結構

...              #全局塊

events {         #events塊
   ...
}

http      #http塊
{
    ...   #http全局塊
    server        #server塊
    { 
        ...       #server全局塊
        location [PATTERN]   #location塊
        {
            ...
        }
        location [PATTERN] 
        {
            ...
        }
    }
    server
    {
      ...
    }
    ...     #http全局塊
}
  • 1、全局塊:配置影響nginx全局的指令。一般有運行nginx服務器的用戶組,nginx進程pid存放路徑,日志存放路徑,配置文件引入,允許生成worker process數等。
  • 2、events塊:配置影響nginx服務器或與用戶的網絡連接。有每個進程的最大連接數,選取哪種事件驅動模型處理連接請求,是否允許同時接受多個網路連接,開啟多個網絡連接序列化等。
  • 3、http塊:可以嵌套多個server,配置代理,緩存,日志定義等絕大多數功能和第三方模塊的配置。如文件引入,mime-type定義,日志自定義,是否使用sendfile傳輸文件,連接超時時間,單連接請求數等。
  • 4、server塊:配置虛擬主機的相關參數,一個http中可以有多個server。
  • 5、location塊配置請求的路由,以及各種頁面的處理情況

https://www.cnblogs.com/dongye95/p/11096785.html#_label0_0  超長詳細介紹nginx文件結構

 

https://mp.weixin.qq.com/s/8ubl8ZFT5J-DL4b9taBjuA 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM