Nginx反向代理的简单实现
一、Nginx反向代理功能
Nginx不仅能作为Web Server,还具有反向代理、负载均衡和缓存的功能。下面就简单说下这些功能:
1、proxy模块
nginx通过proxy模块实现将客户端的请求代理至上游服务器,此时nginx与上游服务器的连接是通过http协议进行的。nginx在实现反向代理功能时的最重要指令为 proxy_pass,它能够并能够根据URI、客户端参数或其它的处理逻辑将用户请求调度至上游服务器上(upstream server)。
1.1 proxy_pass URL;
设置后端服务器的协议和地址;这条指令可以设置的协议是“http”或者“https”,而地址既可以使用域名或者IP地址加端口(可选)的形式来定义:
proxy_pass http://localhost:8000/uri/;
如果解析一个域名得到多个地址,所有的地址都会以轮转的方式被使用。当然也可以使用服务器组来定义多个地址。
如果proxy_pass没有使用URI,传送到后端服务器的请求URI一般是客户端发起的原始URI,如果nginx改变了请求URI,则请求路径与配置中的路径的匹配部分将被替换为指令中定义的URI:若nginx接到的请求的uri是/name/a.html
#传送到后端服务器的URI是/remote/a.html
location /name/ {
proxy_pass http://172.16.60.20/remote/;
}
======================================================== #传送到后端服务器的URI是/name/a.html
location /name/ {
proxy_pass http://172.16.60.20;
} ========================================================
#注意与上面用法的区别,这里地址末尾带有斜线,实际上被认为定义了URI,该“/”会替换“/name/",传送到后端服务器的URI是/a.html。
location /name/ { proxy_pass http://172.16.60.20/; }
如果使用正则表达式定义路径,则proxy_pass指令不应使用URI。例如:
location ~ ^/mmb {
proxy_pass http://www.kevin.com;
}
在需要代理的路径中,使用rewrite指令改变了URI,那么nginx将使用重写后的URI处理请求,而忽略proxy_pass指令设置的URI。如下面所示的例子中,传送给上游服务器的URI为/index.php?page=<match>。
location / {
rewrite /(.*)$ /index.php?page=$1 break;
proxy_pass http://localhost:8080;
}
1.2 proxy模块的其它指令
① proxy_connect_timeout time;
与后端服务器建立连接的超时时间。一般不可能大于75秒;
② proxy_cookie_domain off;
取消当前配置级别的所有proxy_cookie_domain指令;
如果配置,则格式为:proxy_cookie_domain domain replacement(替代),即设置"Set-Cookie"响应头中的domain属性的替换文本,其值可以为一个字符串、正则表达式的模式或一个引用的变量;例如:
proxy_cookie_domain localhost example.org;
浏览器对 Cookie 有很多限制,如果 Cookie 的 Domain 部分与当前页面的 Domain 不匹配就无法写入。所以如果请求 A 域名,服务器 proxy_pass 到 B 域名,然后 B 服务器输出 Domian=B 的 Cookie,前端的页面依然停留在 A 域名上,于是浏览器就无法将 Cookie 写入。
不仅是域名,浏览器对 Path 也有限制。我们经常会 proxy_pass 到目标服务器的某个 Path 下,不把这个 Path 暴露给浏览器。这时候如果目标服务器的 Cookie 写死了 Path 也会出现 Cookie 无法写入的问题。
③ proxy_cookie_path off;
格式"proxy_cookie_path path replacement;",即设置"Set-Cookie"响应头中的path属性的替换文本,其值可以为一个字符串、正则表达式的模式或一个引用的变量;例如:
proxy_cookie_path /two/ /;
若“Set-Cookie”响应头含有属性“path=/two/some/uri/”,那么该指令会将这个属性改写为“path=/some/uri/”。
④ proxy_hide_header field;
nginx默认不会将"Date"、"Server"、"X-Pad",和"X-Accel-..."响应头发送给客户端。该指令则可以设置额外隐藏的响应头,这些响应头也不会发送给客户端。相反的,如果希望允许传递某些响应头给客户端,可以使用proxy_pass_header指令。
⑤ proxy_set_header field value;
重新定义或者添加发往后端服务器的请求头。value可以包含文本、变量或者它们的组合。例如:
proxy_set_header X-Real-IP $remote_addr; #给请求头中添加客户端IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 默认情况下,只有两个请求头会被重新定义:
proxy_set_header Host $proxy_host;
proxy_set_header Connection close; 如果某个请求头的值为空,那么这个请求头将不会传送给后端服务器:
proxy_set_header Accept-Encoding "";
⑥ proxy_pass_request_headers on|off;
是否将http首部发往上游服务器
⑦ proxy_pass_request_body on|off;
是否将http请求报文的包体部分发往上游服务器
⑧ proxy_redirect [default|off|redirect replacement];
修改上游服务器传来的响应头中的"Location"和"Refresh"字段。例如:
proxy_redirect http://localhost:8000/two/ http://frontend/one/; replacement字符串可以省略服务器名:
proxy_redirect http://localhost:8000/two/ /;
此时将使用代理服务器的主域名和端口号来替换。如果端口是80,可以不加。
⑨ proxy_send_timeout time;
在连接断开之前两次发送至upstream server的写操作的最大间隔时长;
⑩ proxy_read_timeout time;
在连接断开之前两次从接收upstream server接收读操作的最大间隔时长;
1.3 proxy模块的内置变量
① $proxy_host:
后端服务器的主机名和端口;
② $proxy_port:
后端服务器的端口;
③ $proxy_add_x_forwarded_for
将$remote_addr变量值添加在客户端“X-Forwarded-For”请求头的后面,并以逗号分隔。 如果客户端请求未携带“X-Forwarded-For”请求头,$proxy_add_x_forwarded_for变量值将与$remote_addr变量相同
2、upstream模块
如果有多个上游服务器,我们可以把它们放到一个组中,并且给它们赋予不同的权重和类型,进行负载均衡等,这些功能是由upstream模块实现的。
2.1 配置语法:
upstream name {
server address [parameters];
...
} 示例:
upstream web {
server web1.kevin.com weight=5;
server web2.kevin.com:8080;
server unix:/tmp/web3;
server backup1.kevin.com:8080 backup;
} server {
location / {
proxy_pass http://web;
}
}
2.2 uptream使用注意:
① 只能用于http上下文
② 各server只能直接使用IP或主机名,不要加协议
2.3 默认情况下,nginx按加权轮转的方式将请求代理到各上游服务器。与上游服务器通信的时候,如果出现错误,请求会被传给下一个服务器,直到所有可用的服务器都被尝试过。如果所有服务器都返回失败,客户端将会得到最后通信的那个服务器的(失败)响应结果。
2.4 地址可以是域名或者IP地址,端口是可选的(默认是80),或者是指定“unix:”前缀的UNIX域套接字的路径。如果一个域名解析到多个IP,本质上是定义了多个server。
2.5 server后可定义的参数:
① weight=number
设定服务器的权重,默认是1。
② max_fails=number
设定Nginx与服务器通信的尝试失败的次数。在fail_timeout参数定义的时间段内,如果失败的次数达到此值,Nginx就认为服务器不可用。在下一个fail_timeout时间段,服务器不会再被尝试。失败的尝试次数默认是1。设为0就会停止统计尝试次数,认为服务器是一直可用的。
③ fail_timeout=time
默认是10秒,设定统计失败尝试次数的时间段。在这段时间中,服务器失败次数达到指定的尝试次数,服务器就被认为不可用。服务器被认为不可用的时间段。
④ backup
标记为备用服务器。当主服务器不可用以后,请求会被传给这些服务器。
⑤ down
标记服务器永久不可用,可以跟ip_hash指令一起使用
2.6 upstream模块的其它负载均衡算法(用于upstream上下文):
① ip_hash;
作用同lvs中的sh调度算法,将来自于同一个客户端的请求始终调度至同一台后端服务器(除了当服务器不可用的时候)
② least_conn;
将请求发送到活动连接数最少的那台服务器。如果这样的服务器有多台,就尝试按加权轮循来调度
③ sticky cookie name [expires=time] [domain=domain] [httponly] [secure] [path=path];
session绑定,将来自于同一个客户端的请求始终调度至同一台后端服务器,从而实现客户端与后端服务器的session保持。
ip_hash指令无法实现对内网NAT用户的均衡,而sticky指令可以做到;
◆ sticky工作原理
1. 浏览器首次发起请求,请求头未带cookie。nginx接收请求,发现请求头没有cookie,则以轮询方式将请求代理给后端服务器。
2. 后端服务器处理完请求,将响应头和内容返回给nginx。
3. nginx生成cookie,返回给客户端浏览器。cookie的值与后端服务器对应,可能是明文,也可能是md5、sha1等Hash值。
4. 浏览器接收请求,并创建cookie。
5. 浏览器再次发送请求时,带上cookie。
6. nginx接收到cookie,直接转给对应的后端服务器
参数说明:
domain:cookie作用的域名
path:cookie作用的路径
expires:cookie的过期时长
示例如下:
upstream web {
server web1.kevin.com;
server web2.kevin.com;
sticky cookie srv_id expires=1h domain=.kevin.com path=/;
}
2.7 health_check [interval=time] [fails=number] [passes=number] [uri=uri] [match=name];
对上游服务器组进行健康状态检测,用于location中;
参数说明:
interval=time #检测的间隔时长,默认为5秒
fails=number #连续检测失败多少次即认为上游服务器不可用,默认为1次
passes=number #上游服务器从不可用到可用状态时需要连续检测的次数,默认为1次
uri=uri #定义用于健康检测的URI,默认为“/”,即默认检测目标服务器的主页
match=name #指定一段配置来当作检测条件,默认当响应码为2XX或3XX时认为上游服务器是可用的
示例如下:
http {
server {
...
location / {
proxy_pass http://backend;
health_check uri=/.health.html match=welcome;
}
} match welcome { #match配置段要位于http上下文
status 200;
header Content-Type = text/html;
body ~ "Welcome to nginx!";
}
}
3、fastcgi模块
nginx能够通过fastcgi模块实现将客户端的动态文件请求代理至fastcgi server,此时nginx与fastcgi server的通信是通过fastcgi协议进行的
3.1 fastcgi模块的常用指令
①fastcgi_pass address;
指定fastcgi server的地址和端口,也支持使用unix sock;例如:
fastcgi_pass localhost:9000;
fastcgi_pass 192.168.30.20:9000;
fastcgi_pass unix:/tmp/fastcgi.socket;
②fastcgi_bind address | off;
指定联系fpm服务器时使用的地址;
③fastcgi_param parameter value [if_not_empty];
定义传递给fastcgi server的参数;参数值可以是文本、变量或它们的组合,if_not_empty表示不为空时才传递。例如:
fastcgi_param SCRIPT_FILENAME /web/scripts$fastcgi_script_name;
④fastcgi_index name;
默认主页名;就是当URI中的文件名缺省时,使用此文件名
⑤fastcgi_connect_timeout time;
连接fastcgi服务器的超时时长;
⑥fastcgi_send_timeout time;
向fastcgi服务传输数据的超时时长;
3.2 通常建议nginx和fastcgi server(如php-fpm)部署在同一台服务器上,因为二者如果通过网络通信的话会造成额外的性能开销。
3.3 配置示例
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9001;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /web/scripts$fastcgi_script_name;
include fastcgi_params;
}
说明:
①参数SCRIPT_FILENAME保存是的脚本文件的绝对路径;例如,若请求的URI是/test/status.php,那么向fastcgi server传递的脚本文件路径就是/web/scripts/test/status.php
②nginx有两个文件fastcgi_params和fastcgi.conf,它们存放着nginx向fastcgi server传递的参数,二者唯一的区别是后者比前者多了一行 SCRIPT_FILENAME 的定义:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
3.4 通过nginx查看后端php-fpm的运行状态
# vim /etc/php-fpm.d/www.conf(若php-fpm是编译安装,则为主配置文件)
pm.status_path = fpm_status
ping.path = fpm_ping # vim /etc/nginx/nginx.conf
location ~* /(fpm_status|fpm_ping) {
root /www/a.com;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
include fastcgi_params; }
二、nginx的缓存功能
nginx做为反向代理时,能够将来自上游服务器的响应缓存至本地,并在后续的客户端请求同样内容时直接从本地构造响应报文。nginx使用磁盘做缓存;
缓存将遵从上游服务器的响应报文首部中关于缓存的设定,如 "Expires"、"Cache-Control: no-cache"、 "Cache-Control: max-age=XXX"、"private"和"no-store" 等,但nginx在缓存时不会考虑响应报文的"Vary"首部。为了确保私有信息不被缓存,所有关于用户的私有信息可以在上游服务器上通过"no-cache" or "max-age=0"来实现,也可在nginx设定proxy_cache_key必须包含用户特有数据如$cookie_xxx的方式实现,但最后这种方式在公共缓存上使用可能会有风险。因此,在响应报文中含有以下首部或指定标志的报文将不会被缓存。
Set-Cookie
Cache-Control containing "no-cache", "no-store", "private", or a "max-age" with a non-numeric or 0 value Expires with a time in the past
X-Accel-Expires: 0
与缓存有关的指令:
① proxy_cache zone | off;
定义一个用于缓存的共享内存区域,其可被多个地方调用;
② proxy_cache_key string;
设定在存储及检索缓存时用于“键”的字符串,可以使用变量为$uri其值,但使用不当时有可能会为同一个内容缓存多次;另外,将用户私有信息用于键可以避免将用户的私有信息返回给其它用户;
例如:proxy_cache_key "$host$request_uri;
③ proxy_cache_lock on | off;
启用此项,可在缓存未命令中阻止多个相同的请求同时发往upstream,其生效范围为worker级别;
④ proxy_cache_lock_timeout time;
proxy_cache_lock功能的锁定时长;
⑤ proxy_cache_min_uses number;
某响应报文被缓存之前至少应该被请求的次数;
⑥ proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time] ;
定义一个用记保存缓存响应报文的目录,及一个保存缓存对象的键及响应元数据的共享内存区域(keys_zone=name:size),其可选参数有:
levels: 每级子目录名称的长度,有效值为1或2,每级之间使用冒号分隔,最多为3级;
inactive:非活动缓存项从缓存中剔除之前的最大缓存时长;
max_size: 缓存空间大小的上限,当需要缓存的对象超出此空间限定时,缓存管理器将基于LRU算法对其进行清理;
loader_files:缓存加载器的每次工作过程最多为多少个文件加载元数据;
loader_sleep: 缓存加载器的每次迭代工作之后的睡眠时长;
loader_threashold: 缓存加载器的最大睡眠时长;
示例:
proxy_cache_path /data/nginx/cache/one levels=1 keys_zone=one:10m;
proxy_cache_path /data/nginx/cache/two levels=2:2 keys_zone=two:100m;
⑦ proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 |http_504 | http_403 | http_404 | off ...;
在无法联系到upstream服务器时的哪种情形下(如error、timeout或http_500等)让nginx使用本地缓存的过期的缓存对象直接响应客户端请求;
⑧ proxy_cache_valid [code ...] time;
用于为不同的响应设定不同时长的有效缓存时长
例如:
proxy_cache_valid 200 302 10m;
⑨ proxy_cache_methods GET | HEAD | POST ...;
为哪些请求方法启用缓存功能;
⑩ proxy_cache_bypass string;
设定在哪种情形下,nginx将不从缓存中取数据。
proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;
proxy_cache_bypass $http_pragma $http_authorization;
nginx也可将后端fastcgi server的响应结果缓存:
fastcgi_cache
fastcgi_cache_path
fastcgi_cache_valid
...
三、Nginx反向代理简单实现
负载机:A机器:103.110.186.8/192.168.1.8
后端机器1:B机器:192.168.1.102
后端机器2:C机器:192.168.1.103
需求:
-> 访问A机器的8080端口,反向代理到B机器的8080端口;
-> 访问A机器的8088端口,反向代理到C机器的8088端口;
-> 访问http://103.110.86.8:8090/ios,反向代理到B机器http://192.168.1.102:8090/ios/
-> 访问A机器的80端口,负载均衡到后端的两台机器B和C的80端口
操作记录如下:
=========================================================================================
负载机:A机器上的操作记录:
1)编译安装nginx
[root@opd ~]# yum install -y pcre* openssl* gcc gcc+
[root@opd ~]# cd /opt/src
[root@src ~]# wget http://nginx.org/download/nginx-1.8.0.tar.gz
[root@src ~]# tar -zxvf nginx-1.8.0.tar.gz
[root@src ~]# cd nginx-1.8.0
#添加www用户,其中-M参数表示不添加用户家目录,-s参数表示指定shell类型 [root@nginx-1.8.0 ~]#useradd www -M -s /sbin/nologin
[root@nginx-1.8.0 ~]#vim auto/cc/gcc
#将这句注释掉 取消Debug编译模式 大概在179行
#CFLAGS="$CFLAGS -g" #我们再配置下nginx编译参数
[root@nginx-1.8.0 ~]# ./configure --prefix=/opt/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module
[root@nginx-1.8.0 ~]#make
[root@nginx-1.8.0 ~]#make install clean 2)配置nginx
[root@nginx-1.8.0 ~]# cd /opt/nginx/conf
[root@nginx-1.8.0 conf]# vim nginx.conf //这个可以作为nginx安装后的配置规范
http {
include mime.types;
default_type application/octet-stream;
charset utf-8; log_format main '$http_x_forwarded_for $remote_addr $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_cookie" $host $request_time';
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65; fastcgi_connect_timeout 3000;
fastcgi_send_timeout 3000;
fastcgi_read_timeout 3000;
fastcgi_buffer_size 256k;
fastcgi_buffers 8 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on; client_header_timeout 600s;
client_body_timeout 600s; client_max_body_size 100m;
client_body_buffer_size 256k; gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 9;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
gzip_vary on; include vhosts/*.conf;
} [root@nginx-1.8.0 conf]# ulimit -n 65535
[root@nginx-1.8.0 conf]# mkdir vhosts
[root@nginx-1.8.0 conf]# cd vhosts 配置反向代理和负载均衡
[root@nginx-1.8.0 vhosts]# vim 8080.conf
server {
listen 8080;
server_name localhost;
index index.html index.php index.htm;
root /var/www/html; access_log /usr/local/nginx/logs/8080-access.log main;
error_log /usr/local/nginx/logs/8080-error.log; location / {
proxy_pass http://192.168.1.102:8080;
proxy_redirect off ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 300; #跟后端服务器连接超时时间,发起握手等候响应时间
proxy_send_timeout 300; #后端服务器回传时间,就是在规定时间内后端服务器必须传完所有数据
proxy_read_timeout 600; #连接成功后等待后端服务器的响应时间,已经进入后端的排队之中等候处理
proxy_buffer_size 256k; #代理请求缓冲区,会保存用户的头信息以供nginx进行处理
proxy_buffers 4 256k; #同上,告诉nginx保存单个用几个buffer最大用多少空间
proxy_busy_buffers_size 256k; #如果系统很忙时候可以申请最大的proxy_buffers
proxy_temp_file_write_size 256k; #proxy缓存临时文件的大小
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_max_temp_file_size 128m;
}
} [root@nginx-1.8.0 vhosts]# cat 8088.conf
server {
listen 8088;
server_name localhost;
index index.html index.php index.htm;
root /var/www/html; access_log /usr/local/nginx/logs/8088-access.log main;
error_log /usr/local/nginx/logs/8088-error.log; location / {
proxy_pass http://192.168.1.103:8088;
proxy_redirect off ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 600;
proxy_buffer_size 256k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_max_temp_file_size 128m;
}
} 》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
下面这个匹配path的代理设置需要注意几点:
首先一定要保证目标B机器,也就是192.168.1.102的8090端口站点目录下有这个匹配path的目录ios存在!!
也就是要保证A机器本机能顺利访问到目标B机器的8090端口的ios路径,即:
[root@nginx-1.8.0 vhosts]# curl http://192.168.1.102:8090/ios/ #一定要保证这个能从A机器访问成功! 下面几种配置都是可以的: 第一种:
[root@nginx-1.8.0 vhosts]# cat 8090.conf
server {
listen 8090;
server_name localhost;
index index.html index.php index.htm;
root /var/www/html; access_log /usr/local/nginx/logs/8090-access.log main;
error_log /usr/local/nginx/logs/8090-error.log; location /ios/ { #这种情况,这里一定要匹配的是/ios/,不能是/ios
proxy_pass http://192.168.1.102:8090; #一定要保证192.168.1.102机器8090端口站点目录下有ios目录!否则访问会报错404!
proxy_redirect off ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 600;
proxy_buffer_size 256k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_max_temp_file_size 128m;
}
} 第二种:
[root@nginx-1.8.0 vhosts]# cat 8090.conf
server {
listen 8090;
server_name localhost;
index index.html index.php index.htm;
root /var/www/html; access_log /usr/local/nginx/logs/8090-access.log main;
error_log /usr/local/nginx/logs/8090-error.log; location /ios/ {
proxy_pass http://192.168.1.102:8090/ios/;
proxy_redirect off ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 600;
proxy_buffer_size 256k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_max_temp_file_size 128m;
}
} 第三种:
[root@nginx-1.8.0 vhosts]# cat 8090.conf
server {
listen 8090;
server_name localhost;
index index.html index.php index.htm;
root /var/www/html; access_log /usr/local/nginx/logs/8090-access.log main;
error_log /usr/local/nginx/logs/8090-error.log; location /ios {
proxy_pass http://192.168.1.102:8090/ios/; 这种情况,这里一定要匹配的是/ios/,不能是/ios
proxy_redirect off ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 600;
proxy_buffer_size 256k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_max_temp_file_size 128m;
}
} 以上三种配置方法都保证了访问http://103.110.86.8:8090/ios会自动变为http://103.10.86.8:8090/ios/,并代理到http://192.168.1.102:8090/ios/的结果 [root@nginx-1.8.0 vhosts]# cat LB.conf
upstream lb {
server 192.168.1.102:80 max_fails=3 fail_timeout=30s; #max_fails = 3 为允许失败的次数,默认值为1
server 192.168.1.103:80 max_fails=3 fail_timeout=30s; #fail_timeout = 30s 当max_fails次失败后,暂停将请求分发到该后端服务器的时间
} server {
listen 80;
server_name localhost;
index index.html index.php index.htm;
root /var/www/html; access_log /usr/local/nginx/logs/80-access.log main;
error_log /usr/local/nginx/logs/80-error.log; location / {
proxy_pass http://lb;
proxy_redirect off ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 600;
proxy_buffer_size 256k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_max_temp_file_size 128m;
}
} 启动nginx
[root@nginx-1.8.0 vhosts]# /opt/nginx/sbin/nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful [root@host-192-168-1-102 vhosts]# /opt/nginx/sbin/nginx
=====================================================================================
后端机:B机器上的操作记录:
1)编译安装nginx
[root@B ~]# yum install -y pcre* openssl* gcc gcc+
[root@B ~]# cd /opt/src
[root@B ~]# wget http://nginx.org/download/nginx-1.8.0.tar.gz
[root@B ~]# tar -zxvf nginx-1.8.0.tar.gz
[root@B ~]# cd nginx-1.8.0
#添加www用户,其中-M参数表示不添加用户家目录,-s参数表示指定shell类型 [root@nginx-1.8.0 ~]#useradd www -M -s /sbin/nologin
[root@nginx-1.8.0 ~]##vim auto/cc/gcc
#将这句注释掉 取消Debug编译模式 大概在179行
#CFLAGS="$CFLAGS -g" #我们再配置下nginx编译参数
[root@nginx-1.8.0 ~]# ./configure --prefix=/opt/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module
[root@nginx-1.8.0 ~]#make
[root@nginx-1.8.0 ~]#make install clean 2)配置nginx
[root@nginx-1.8.0 ~]# cd /opt/nginx/conf
注意,把默认的nginx.conf文件中的server区域配置注释掉,设置vhosts虚拟主机的配置,如下:
[root@nginx-1.8.0 conf]# vim nginx.conf
user www;
worker_processes 8; events {
worker_connections 65535;
} http {
include mime.types;
default_type application/octet-stream;
charset utf-8; log_format main '$http_x_forwarded_for $remote_addr $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_cookie" $host $request_time';
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65; fastcgi_connect_timeout 3000;
fastcgi_send_timeout 3000;
fastcgi_read_timeout 3000;
fastcgi_buffer_size 256k;
fastcgi_buffers 8 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on; client_header_timeout 600s;
client_body_timeout 600s; client_max_body_size 100m;
client_body_buffer_size 256k; gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 9;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
gzip_vary on; include vhosts/*.conf;
} [root@nginx-1.8.0 conf]# ulimit -n 65535
[root@nginx-1.8.0 conf]# mkdir vhosts
[root@nginx-1.8.0 conf]# cd vhosts [root@nginx-1.8.0 conf]# vim 8080.conf
server {
listen 8080;
server_name localhost;
index index.html index.php index.htm; access_log /usr/local/nginx/logs/8080-access.log main;
error_log /usr/local/nginx/logs/8080-error.log; location ~ / {
root /var/www/html/8080;
index index.html index.php index.htm;
}
} [root@nginx-1.8.0 conf]# vim 8090.conf
server {
listen 8090;
server_name localhost;
index index.html index.php index.htm; access_log /usr/local/nginx/logs/8090-access.log main;
error_log /usr/local/nginx/logs/8090-error.log; location ~ / {
root /var/www/html/8090; #针对上面匹配ios的path代理,要保证站点目录/var/www/html/8080下有ios目录存在
index index.html index.php index.htm;
}
} [root@nginx-1.8.0 conf]# vim 80.conf
server {
listen 80;
server_name localhost;
index index.html index.php index.htm; access_log /usr/local/nginx/logs/80-access.log main;
error_log /usr/local/nginx/logs/80-error.log; location ~ / {
root /var/www/html;
index index.html index.php index.htm;
}
} 启动nginx
[root@nginx-1.8.0 vhosts]# /opt/nginx/sbin/nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful [root@host-192-168-1-102 vhosts]# /opt/nginx/sbin/nginx
==========================================================================================
后端机:C机器上的操作记录
1)编译安装nginx
[root@C ~]# yum install -y pcre* openssl* gcc gcc+
[root@C ~]# cd /opt/src
[root@C ~]# wget http://nginx.org/download/nginx-1.8.0.tar.gz
[root@C ~]# tar -zxvf nginx-1.8.0.tar.gz
[root@C ~]# cd nginx-1.8.0
#添加www用户,其中-M参数表示不添加用户家目录,-s参数表示指定shell类型 [root@nginx-1.8.0 ~]#useradd www -M -s /sbin/nologin
[root@nginx-1.8.0 ~]##vim auto/cc/gcc
#将这句注释掉 取消Debug编译模式 大概在179行
#CFLAGS="$CFLAGS -g" #我们再配置下nginx编译参数
[root@nginx-1.8.0 ~]# ./configure --prefix=/opt/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module
[root@nginx-1.8.0 ~]#make
[root@nginx-1.8.0 ~]#make install clean 2)配置nginx
[root@nginx-1.8.0 ~]# cd /opt/nginx/conf
注意,把默认的nginx.conf文件中的server区域配置注释掉,设置vhosts虚拟主机的配置,如下:
[root@nginx-1.8.0 conf]# vim nginx.conf user www;
worker_processes 8; events {
worker_connections 65535;
} http {
include mime.types;
default_type application/octet-stream;
charset utf-8; log_format main '$http_x_forwarded_for $remote_addr $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_cookie" $host $request_time';
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65; fastcgi_connect_timeout 3000;
fastcgi_send_timeout 3000;
fastcgi_read_timeout 3000;
fastcgi_buffer_size 256k;
fastcgi_buffers 8 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on; client_header_timeout 600s;
client_body_timeout 600s; client_max_body_size 100m;
client_body_buffer_size 256k; gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 9;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
gzip_vary on; include vhosts/*.conf;
} [root@nginx-1.8.0 conf]# vim 80.conf
server {
listen 80;
server_name localhost;
index index.html index.php index.htm; access_log /usr/local/nginx/logs/80-access.log main;
error_log /usr/local/nginx/logs/80-error.log; location ~ / {
root /var/www/html/;
index index.html index.php index.htm;
}
} 启动nginx
[root@nginx-1.8.0 vhosts]# /opt/nginx/sbin/nginx -t
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful [root@host-192-168-1-102 vhosts]# /opt/nginx/sbin/nginx 到此,上面需求中的nginx反向代理和负载均衡就已经配置完成了!
访问http://103.110.86.8:8080的结果显示的就是B机器,即http://192.168.1.102:8080的结果
访问http://103.110.86.8:8088的结果显示的就是C机器,即http://192.168.1.108:8088的结果
访问http://103.110.86.8:8090/ios的结果显示的就是B机器,即http://192.168.1.102:8090/ios/的结果 访问http://103.110.86.8的请求就会被负载给到后端两台机器http://192.168.1.102和http://192.168.1.103 可以在103.110.86.8本机可以使用curl和telnet测试到目标机器是否通顺~
[root@nginx-1.8.0 vhosts]# curl http://192.168.1.102:8080
[root@nginx-1.8.0 vhosts]# telnet 192.168.1.102 8080
说明一下:上面的nginx反向代理的需求,除了nginx反代配置之外,也可以使用iptables的nat转发实现。
比如:访问A机器的8080端口,反向代理到B机器的80端口;iptables的nat转发规则设置如下:
[root@opd ~]# iptables -t nat -A PREROUTING -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.1.102:80
[root@opd ~]# iptables -t nat -A POSTROUTING -d 192.168.1.102 -p tcp -m tcp --sport 80 -j SNAT --to-source 192.168.1.8
[root@opd ~]# iptables -t filter -A INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT [root@opd ~]# service iptables save **************************************
需要注意的是:
要打开A机器的ip转发功能:
[root@opd ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
然后后端机器B的route路由最好也设置成192.168.1.8
************************************** 这样,访问http://103.110.86.8:8080的结果就是http://192.168.1.102的结果
nginx反向代理一例:访问 http://testwx3.wangshibo.com/apiwx3 反向代理到 https://testwww.wangshibo.com
[root@dev-new-test vhosts]# cat testwx3.wangshibo.com.conf
server {
listen 80; server_name testwx3.wangshibo.com;
root /Data/app/xqsj_wx3/dist;
index index.html; location /apiwx3/ {
proxy_pass https://testwww.wangshibo.com/;
}
如上配置后:
访问 http://testwx3.wangshibo.com/apiwx3 自动跳转到 http://testwx3.wangshibo.com/apiwx3/
访问 http://testwx3.wangshibo.com/apiwx3/$1 的内容和 https://testwww.wangshibo.com/$1 内容一致
比如:
访问 http://testwx3.wangshibo.com/apiwx3/xqsj.php?r=HouseGroup/create 显示的内容既是 http://testwww.wangshibo.com/xqsj.php?r=HouseGroup/create 的内容
如果将上面的代理配置改为:
location /apiwx3 {
proxy_pass https://testwww.wangshibo.com;
} 或者
location /apiwx3/ {
proxy_pass https://testwww.wangshibo.com/;
}
那么只能实现:访问 http://testwx3.wangshibo.com/apiwx3 的结果和 https://testwww.wangshibo.com 一致
不能实现:访问http://testwx3.wangshibo.com/apiwx3/$1的内容和https://testwww.wangshibo.com/$1内容一致
Nginx反向代理的简单实现的更多相关文章
- 使用SSL配置Nginx反向代理的简单指南
反向代理是一个服务器,它接收通过Web发出的请求,即http和https,然后将它们发送到后端服务器(或服务器).后端服务器可以是单个或一组应用服务器,如Tomcat,wildfly或Jenkins等 ...
- nginx反向代理的简单配置
有两台机器A和B. A上边是nginx,B上边是tomcat. 现在要通过A的反向代理功能,通过A的nginx访问到B的tomcat. 首先tomcat已经配置好,并且正确启动,可访问. ...
- Nginx反向代理及简单负载均衡配置
nginx配置文件主要分为六个区域:main section.events section.http section.sever section.location section.upstream s ...
- (总结)Linux服务器上最简单的Nginx反向代理配置
Nginx不但是一款高性能的Web服务器,也是高性能的反向代理服务器.下面简单说说Nginx的反向代理功能. 反向代理是什么? 反向代理指以代理服务器来接受Internet上的连接请求,然后将请求转发 ...
- 服务器上nginx反向代理的配置
Nginx不但是一款高性能的Web服务器,也是高性能的反向代理服务器.下面简单说说Nginx的反向代理功能. 反向代理是什么? 反向代理指以代理服务器来接受Internet上的连接请求,然后将请求转发 ...
- Nginx反向代理+负载均衡简单实现(http方式)
1)nginx的反向代理:proxy_pass2)nginx的负载均衡:upstream 下面是nginx的反向代理和负载均衡的实例: 负载机:A机器:103.110.186.8/192.168.1. ...
- Nginx 反向代理、负载均衡、页面缓存、URL重写、读写分离及简单双机热备详解
大纲 一.前言 二.环境准备 三.安装与配置Nginx (windows下nginx安装.配置与使用) 四.Nginx之反向代理 五.Nginx之负载均衡 (负载均衡算法:nginx负载算法 up ...
- 最简单实现跨域的方法:用 Nginx 反向代理
本文作者: 伯乐在线 - 良少 .未经作者许可,禁止转载!欢迎加入伯乐在线 专栏作者. 什么是跨域 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对javascrip ...
- [转] 最简单实现跨域的方法:使用nginx反向代理
[From] http://blog.jobbole.com/90975/ 什么是跨域 跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全 ...
随机推荐
- Asp.net Mvc、webApi配置允许跨域
Web.config 下<system.webServer> 节点下配置 <httpProtocol> <customHeaders> <add name=& ...
- 个人技术博客(α)------javaweb的学习路程
该博文大致内容是学习的一个过程,心得,并不是以技术博客为主,在此说明. 关于javaweb的学习开始的时间大概是从大二下(2017年6.7月份)的暑假开始的,在学长的介绍下加入了实验室进行学习,由于是 ...
- 解决Could not load file or assembly CefSharp.Core.dll的问题
这个问题的中文提示是: 未能加载文件或程序集“CefSharp.Core.dll”或它的某一个依赖项.找不到指定的模块 具体原因是因为CefSharp运行时需要Visual C++ Redistrib ...
- React框架简介
React的基本认识 Facebook开源的一个js库,一个用来动态构建用户界面的js库 英文官网,中文官网 React的特点 Declarative(声明式编码),Component-Based(组 ...
- File类_常见的方法(获取,创建与删除,判断,重命名)
获取: 1.1获取文本名称 1.2获取文件路劲 1.3获取文件大小 1.4获取文件修改或创建时间 import java.io.File; import java.text.DateForma ...
- centos7下安装docker(6镜像总结)
学了很长时间的镜像了,从镜像的分层,缓存的特性,到制作镜像:通过docker commint和docker build创建,再到制作dockerfile以及dockerfile中常用的参数FROM,M ...
- win10搭建ftp服务器的操作方法【图文教程】
我们知道FTP是TCP/IP网络上两台计算机传送文件的协议,使得主机间可以共享文件.对于win10版本的ftp服务器搭建方法可能有部分用户还不是很清楚,下面这篇文章就是关于win10搭建ftp服务器的 ...
- UVA1451 Average
嘟嘟嘟 看到比值,就想到01分数规划,令\(ans = \frac{\sum a_i}{\sum l_i}\),其中\(l\)表示长度,所以\(l_i\)都是\(1\). 然后变一下型,得到\(\su ...
- 1192:放苹果(dp + 搜索)
这道题先用搜索写的,因为我需要先打表来寻找规律. 因为数据量小所以收搜也会过 #include<iostream> #include<cstdio> #include<c ...
- vs2012中如何显示代码行号
打开一个项目,里面没有显示行号 打开工具-选项 选择文本编辑器-C# 在行号前面上打钩 点击确定,就可以看到代码前面显示出行号 6 还可以按此办法添加其他类型文件的代码行号