反向代理:反向代理也叫reverse proxy,指的是代理外网用户的请求到内部的指定web服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式。
Nginx除了能够在企业提供高性能的web服务以外,另外还能够将自己不具有的请求经过某种预约义的协议转发至其它服务器处理,不一样的协议就是Nginx服务器与其余服务器进行通讯的一种规范,主要在不一样的场景使用如下模块实现不一样的功能:php
ngx_http_proxy_module: 将客户端的请求以http协议转发至指定服务器进行处理。 ngx_stream_proxy_module:将客户端的请求以tcp协议转发至指定服务器处理。 ngx_http_fastcgi_module:将客户端对php的请求以fastcgi协议转发至指定服务器助理。 ngx_http_uwsgi_module:将客户端对Python的请求以uwsgi协议转发至指定服务器处理。
server { listen 80; charset utf-8; server_name www.a.com; location /app { proxy_pass http://192.168.36.110:80; # 不带斜线将访问的/web,等于访问后端服务器 http://192.168.36.103:80/web/index.html,即后端服务器配置的站点根目录要有web目录才能够被访问,这是一个追加/web到后端服务器。 带斜线,等于访问后端服务器的http://192.168.36.103:80/index.html 内容返回给客户端 index index.html; } } 访问测试 [root@CentOS7 conf.d]#curl -L -i http://www.a.com/app HTTP/1.1 301 Moved Permanently Server: Darius/10.0 Date: Sat, 01 Jun 2019 08:24:33 GMT Content-Type: text/html; charset=iso-8859-1 Content-Length: 234 Connection: keep-alive Location: http://192.168.36.110/app/ HTTP/1.1 200 OK Date: Sat, 01 Jun 2019 08:24:31 GMT Server: Apache/2.4.6 (CentOS) Last-Modified: Sat, 25 May 2019 03:41:28 GMT ETag: "19-589ae171491d6" Accept-Ranges: bytes Content-Length: 25 Content-Type: text/html; charset=UTF-8 <h1>Real Server 110</h1>
[root@CentOS7 conf.d]#vim a.conf server { listen 80; charset utf-8; server_name www.a.com; location /app { index index.html; proxy_pass http://192.168.36.110:80; proxy_hide_header Location; # 若想隐藏多个head头部信息须要再次定义proxy_hide_header,不支持在后面接着写 } } [root@CentOS7 conf.d]#nginx -s reload [root@CentOS7 conf.d]#curl -L -I http://www.a.com/app HTTP/1.1 301 Moved Permanently Server: Darius/10.0 Date: Sat, 01 Jun 2019 08:30:47 GMT Content-Type: text/html; charset=iso-8859-1 Connection: keep-alive
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_set_header HOST $remote_addr; # 添加HOST到报文头部,若是客户端为NAT上网那么其值为客户端的共用的公网IP地址。
proxy_connect_timeout 60s; # 60s为自定义nginx与后端服务器创建链接的超时时间
proxy_send_time time; # 配置nginx项后端服务器或服务器组发起write请求后,等待的超时时间,默认60s
proxy_headers_hash_bucket_size 64; 当配置了 proxy_hide_header和proxy_set_header的时候,用于设置nginx保存HTTP报文头的hash表的上限。html
示例 # 调用缓存功能,须要定义在相应的配置段,如server{...};或者location等 proxy_cache proxycache; proxy_cache_key $request_uri; proxy_cache_valid 200 302 10m; # 对200、302类响应码缓存10分钟 proxy_cache_valid 404 1m; # 对404类响应码缓存1分钟
使用方法: proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
示例:在http配置定义缓存信息
proxy_cache_path /var/cache/nginx/proxy_cache # 定义缓存保存路径,proxy_cache会自动创
建
levels=1:2:2; # 定义缓存目录结构层次,1:2:2能够生成2^4x2^8x2^8=1048576个目录
keys_zone=proxycache:20m; # 指内存中缓存的大小,主要用于存放key和metadata(如:使用次数)
inactive=120s; # 缓存有效时间
max_size=1g; # 最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值mysql
5. proxy_cache_use_stale; 在被代理的后端服务器出现哪一种状况下,可直接使用过时的缓存响应客户端 ```bash proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默认是off
Context: http, server, location proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 请求报文的标准格式以下: X-Forwarded-For: client1, proxy1, proxy2
[root@CentOS7 conf.d]#vim ../conf/nginx.conf # 配置在nginx.conf http配置段 proxy_cache_path /data/nginx/proxycache levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g; [root@CentOS7 conf.d]#cat a.conf server { listen 80; charset utf-8; server_name www.a.com; location /app { # 要缓存的URL或者放在server配置项对全部URL都进行缓存 index index.html; proxy_pass http://192.168.36.110:80; proxy_hide_header Location; proxy_hide_header Connection; proxy_set_header clientip $remote_addr; proxy_cache proxycache; proxy_cache_key $request_uri; proxy_cache_valid 200 302 301 10m; proxy_cache_valid any 1m; } } [root@CentOS7 conf.d]#nginx -t nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok nginx: configuration file /apps/nginx/conf/nginx.conf test is successful [root@CentOS7 conf.d]#nginx -s reload
[root@CentOS7 conf.d]#curl -L http://www.a.com/app [root@CentOS7 conf.d]#ab -n 2000 -c 200 http://www.a.com/app Total transferred: 822000 bytes HTML transferred: 468000 bytes Requests per second: 9413.58 [#/sec] (mean) Time per request: 21.246 [ms] (mean) Time per request: 0.106 [ms] (mean, across all concurrent requests) Transfer rate: 3778.30 [Kbytes/sec] received # 缓存路径结构及文件大小 [root@CentOS7 conf.d]#tree /data/nginx/proxycache/ /data/nginx/proxycache/ ├── 2 │ └── e │ └── 8 └── 7 └── 5 └── b └── 606c5106afffe9fd4f2021504afe7b57 6 directories, 1 file 验证文件内容 [root@CentOS7 conf.d]#head -n100 /data/nginx/proxycache/7/5/b/606c5106afffe9fd4f2021504afe7b57 HTTP/1.1 200 OK Date: Sat, 01 Jun 2019 09:51:06 GMT Server: Apache/2.4.6 (CentOS) Last-Modified: Sat, 01 Jun 2019 09:50:35 GMT ETag: "1388-58a4010131b0d" Accept-Ranges: bytes Content-Length: 5000 Connection: close Content-Type: text/html; charset=UTF-8
nginx基于模块ngx_http_headers_module能够实现对头部报文添加指定的key与值nginx
# 添加自定义首部,以下: add_header name value [always]; add_header X-Via $server_addr; add_header X-Cache $upstream_cache_status; add_header X-Accel $server_name; add_trailer name value [always]; 添加自定义响应信息的尾部, 1.13.2版后支持
[root@CentOS7 conf.d]#cat a.conf server { listen 80; charset utf-8; server_name www.a.com; location /app { index index.html; proxy_pass http://192.168.36.110:80; proxy_set_header clientip $remote_addr; proxy_cache proxycache; proxy_cache_key $request_uri; proxy_cache_valid 200 302 301 10m; proxy_cache_valid any 1m; add_header X-Via $server_addr; add_header X-Cache $upstream_cache_status; add_header X-Accel $server_name; } } [root@CentOS7 conf.d]#nginx -s reload [root@CentOS7 conf.d]#curl -i http://www.a.com/app HTTP/1.1 301 Moved Permanently Server: Darius/10.0 Date: Sat, 01 Jun 2019 10:12:16 GMT Content-Type: text/html; charset=iso-8859-1 Content-Length: 234 Connection: keep-alive Location: http://192.168.36.110/app/ X-Via: 192.168.36.104 X-Cache: MISS # 第一次访问没有使用缓存,再次进行访问测试 X-Accel: www.a.com [root@CentOS7 conf.d]#curl -i http://www.a.com/app HTTP/1.1 301 Moved Permanently Server: Darius/10.0 Date: Sat, 01 Jun 2019 10:12:18 GMT Content-Type: text/html; charset=iso-8859-1 Content-Length: 234 Connection: keep-alive Location: http://192.168.36.110/app/ X-Via: 192.168.36.104 X-Cache: HIT # 第二次访问命中缓存 X-Accel: www.a.com
自定义头部web
第二次访问命中缓存redis
Nginx能够基于ngx_http_upstream_module模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能算法
upstream name { } # 自定义一组服务器,配置在http内 server address [parameters]; # 配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。 # server支持的parameters以下: weight=number # 设置权重,默认为1。 max_conns=number # 给当前server设置最大活动连接数,默认为0表示没有限制。 max_fails=number # 对后端服务器连续监测失败多少次就标记为不可用。 fail_timeout=time # 对后端服务器的单次监测超时时间,默认为10秒。 backup # 设置为备份服务器,当全部服务器不可用时将从新启用次服务器。 down # 标记为down状态。 resolve # 当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启Nginx。 hash KEY consistent; # 基于指定key作hash计算,使用consistent参数,将使用ketama一致性hash算法,适用于后端是Cache服务器(如varnish)时使用,consistent定义使用一致性hash运算,一致性hash基于取模运算。 # 所谓取模运算,就是计算两个数相除以后的余数,好比10%7=3, 7%4=3 hash $request_uri consistent; # 基于用户请求的uri作hash ip_hash; # 源地址hash调度方法,基于的客户端的remote_addr(源地址)作hash计算,以实现会话保持 least_conn; # 最少链接调度算法,优先将客户端请求调度到当前链接最少的后端服务器
[root@CentOS7 conf.d]#vim ../conf/nginx.conf upstream app1 { #hash $request_uri consistent; #ip_hash; # 指定ip_hash算法,根据session调度到同一台后端主机上,当此台主机宕机,则强制切换到另外一台存活的主机上 #least_conn; server 192.168.36.110:80 weight=1 fail_timeout=5s max_fails=3; # 后端服务器状态监测:fail_timeout连续检测多少次失败,max_fails检测时长 server 192.168.36.106:80 weight=1 fail_timeout=5s max_fails=3; server 192.168.36.101:80 weight=1 fail_timeout=5s max_fails=3 backup; # 备用服务器,当其他反向代理服务器宕机,启用备用服务器 } [root@CentOS7 conf.d]#vim a.conf server { listen 80; charset utf-8; server_name www.a.com; location / { index index.html; root /data/nginx/html/pc; } location /app { index index.html; proxy_pass http://app1; } } [root@CentOS7 conf.d]#nginx -s reload 访问测试 [root@CentOS7 conf.d]#while true;do curl http://www.a.com/app/index.html;sleep 0.5;done 192.168.36.110 192.168.36.106 192.168.36.110 192.168.36.106
[root@CentOS7 conf.d]#vim ../conf/nginx.conf upstream app1 { #hash $request_uri consistent; #least_conn; server 192.168.36.110:80 weight=1 fail_timeout=5s max_fails=3; server 192.168.36.106:80 weight=1 fail_timeout=5s max_fails=3; ip_hash; } [root@CentOS7 conf.d]#nginx -s reload 访问测试: [root@CentOS7 conf.d]#while true;do curl http://www.a.com/app/index.html;sleep 0.5;done 192.168.36.106 192.168.36.106 192.168.36.106 192.168.36.106 192.168.36.106 192.168.36.106 宕机测试 [root@CentOS7 conf.d]#while true;do curl http://www.a.com/app/index.html;sleep 0.5;done 192.168.36.106 192.168.36.106 192.168.36.106 192.168.36.106 192.168.36.110 # 请求被强制切换到存活主机上 192.168.36.110 .... 192.168.36.106 # 当修复好宕机主机从新工做,请求将从新回到原来的主机上 192.168.36.106 192.168.36.106
upstream web { server 192.168.36.1 weight=1 max_fails=2 fail_timeout=2; server 192.168.36.2 weight=1 max_fails=2 fail_timeout=2; } upstream image { server 192.168.36.3 weight=1 max_fails=2 fail_timeout=2; server 192.168.36.4 weight=1 max_fails=2 fail_timeout=2; } upstream php { server 192.168.36.5 weight=1 max_fails=2 fail_timeout=2; server 192.168.36.6 weight=1 max_fails=2 fail_timeout=2; } location /{ root html/web; index index.php index.html; } location ~* \.php$ { fastcgi_proxy http://php; } location ~* "\.(.jpg|png|jpeg|gif)" { proxy_pass http://image; }
Nginx在1.9.0版本开始支持tcp模式的负载均衡,在1.9.13版本开始支持udp协议的负载,udp主要用于DNS的域名解析,其配置方式和指令和http 代理相似,其基于ngx_stream_proxy_module模块实现tcp负载,另外基于模块ngx_stream_upstream_module实现后端服务器分组转发、权重分配、状态监测、调度算法等高级功能。sql
stream { #定义stream upstream backend { #定义后端服务器 hash $remote_addr consistent; #定义调度算法 server backend1.example.com:12345 weight=5; #定义具体server server 127.0.0.1:12345 max_fails=3 fail_timeout=30s; server unix:/tmp/backend3; } upstream dns { #定义后端服务器 server 192.168.0.1:53535; #定义具体server server dns.example.com:53; } server { #定义server listen 12345; #监听IP:PORT proxy_connect_timeout 1s; #链接超时时间 proxy_timeout 3s; #转发超时时间 proxy_pass backend; #转发到具体服务器组 } server { listen 127.0.0.1:53 udp reuseport; proxy_timeout 20s; proxy_pass dns; } server { listen [::1]:12345; proxy_pass unix:/tmp/stream.socket; } }
主机名称 | 主机IP | 运行服务 |
---|---|---|
CentOS7 | 192.168.36.104 | Nginx |
CentOS7-1 | 192.168.36.110 | Redis、Mysql |
[root@CentOS7-1 ~]#yum install -y redis [root@CentOS7-1 ~]#vim /etc/redis.conf [root@CentOS7-1 ~]#egrep "^bind" /etc/redis.conf bind 0.0.0.0 [root@CentOS7-1 ~]#systemctl start redis [root@CentOS7-1 ~]#systemctl enable redis Created symlink from /etc/systemd/system/multi-user.target.wants/redis.service to /usr/lib/systemd/system/redis.service. [root@CentOS7-1 ~]#ss -ntl | grep 6379 # Redis基于6379端口进行工做 LISTEN 0 128 *:6379 *:*
[root@CentOS7 ~]#mkdir /apps/nginx/tcp [root@CentOS7 ~]#cd /apps/nginx/tcp/ [root@CentOS7 tcp]#vim tcp.conf stream { upstream redis_server { server 192.168.36.110:6379 max_fails=3 fail_timeout=30s; } server { listen 192.168.36.104:6379; proxy_connect_timeout 3s; proxy_timeout 3s; proxy_pass redis_server; } } [root@CentOS7 tcp]#vim ../conf/nginx.conf include /apps/nginx/tcp/tcp.conf; # 注意此处的include与http模块平级,建议写在http模块上方 [root@CentOS7 tcp]#nginx -t nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok nginx: configuration file /apps/nginx/conf/nginx.conf test is successful [root@CentOS7 tcp]#nginx -s reload # 查看6379端口是否开启 [root@CentOS7 tcp]#ss -ntl | grep 6379 LISTEN 0 128 192.168.36.104:6379 *:* # 测试经过Nginx负载链接Redis [root@CentOS7-1 ~]#redis-cli -h 192.168.36.104 192.168.36.104:6379> set name darius OK 192.168.36.104:6379> get name "darius" 192.168.36.104:6379>
[root@CentOS7-1 ~]#yum install -y mariadb mariadb-server [root@CentOS7-1 ~]#systemctl start mariadb # 启动mariadb数据库服务 [root@CentOS7-1 ~]#systemctl enable mariadb # 开机自启动数据库服务 [root@CentOS7-1 ~]#ss -ntl | grep 3306 # 检查端口是否启动 LISTEN 0 50 *:3306 *:* Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service. [root@CentOS7-1 ~]#mysql_secure_installation # 对数据库进行安全加固 # 对数据库进行受权操做 MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.36.%' IDENTIFIED BY 'centos'; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)
[root@CentOS7 tcp]#vim tcp.conf stream { upstream mysql_server { least_conn; server 192.168.36.110:3306 max_fails=3 fail_timeout=30s; } server { listen 192.168.36.104:3306; proxy_connect_timeout 3s; proxy_timeout 3s; proxy_pass mysql_server; } } [root@CentOS7 tcp]#nginx -t nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok nginx: configuration file /apps/nginx/conf/nginx.conf test is successful [root@CentOS7 tcp]#nginx -s reload # 对负载端口进行检查 [root@CentOS7 tcp]#ss -ntl | grep 3306 LISTEN 0 128 192.168.36.104:3306 *:*
####测试经过nginx负载链接Mysql数据库
[root@CentOS7-1 ~]#mysql -uroot -pcentos -h 192.168.36.104 Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 16 Server version: 5.5.60-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> CREATE DATABASE Darius; Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | Darius | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.00 sec) MariaDB [(none)]>