0、nginx代理
反向代理的代码如下:
proxy_pass http://172.96.16.245; 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 { listen 80; server_name localhost; access_log /tmp/phpinfo.log combined_realip; location / { # root /usr/local/nginx/html; # index index.php index.html index.htm; proxy_pass http://172.96.16.245; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/local/nginx/html; } # location ~ \.php$ { # root /usr/local/nginx/html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name; # include fastcgi_params; # }}
正向代理:
server { listen 80 default_server; resolver 119.29.29.29; location / { proxy_pass http://$host$request_uri; }}
Nginx正向代理配置执行说明
resolver 语法:resolver address;
address为DNS服务器的地址,国内通用的DNS 119.29.29.29为dnspod公司提供。 国际通用DNS 8.8.8.8或者8.8.4.4为google提供。 其他可以参考
示例:resolver 119.29.29.29; default_server 之所以要设置为默认虚拟主机,是因为这样就不用设置server_name了,任何域名解析过来都可以正常访问。 proxy_pass 该指令用来设置要代理的目标url,正向代理服务器设置就保持该固定值即可。关于该指令的详细解释在反向代理配置中。
一、负载均衡
1、什么是负载均衡
nginx仅仅作为nginx proxy反向代理使用,因为这个反向代理功能表现的效果就是负载均衡集群的效果,所以就称为nginx负载均衡。
反向代理与负载均衡的区别:
普通负载均衡软件,例如LVS,其实现的功能只是对请求数据包的转发(也可能会改写数据包)、传递,其中DR模式明显的特征是从负载均衡下面的节点服务来看,接收到的请求还是来自访问负载均衡器的客户端的真实用户;而反向代理就不一样了,反向代理接收访问用户的请求后,会代理用户重新发起请求代理下的节点服务器,最后把数据返回给客户端用户,在节点服务器看来,访问的节点服务器的客户端用户就是反向代理服务器了,而非真实的网站访问用户。
总之,负载均衡转发用户请求的数据包,而nginx反向代理是接收用户的请求然后重新发起请求去请求其后面的节点。
实现nginx负载均衡的组件主要有两个:
ngx_http_proxy_module:proxy代理模块,用于把请求后抛给服务器节点或upstream服务器池。
ngx_http_upstream_module:负载均衡模块,可以实现网站的负载均衡功能及节点的健康检查。
2、nginx upstream模块
nginx负载均衡功能依赖于ngx_http_upstream_module模块,所支持的代理方式包括proxy_pass、fastcgi_pass、memcached_pass等。
upstream test # upstream是关键字,后面的test是upstream集群组的名称,可以自己定义,调用时使用这个名字{ server 192.168.10.203:80 weight=1;#server 关键字,后面可以是ip或者域名。如果不指定端口,则默认是80,最后以逗号结束。weight表示权重。 server 192.168.10.204:80 weight=2;}
** server标签参数说明:**
server 192.168.10.203:80 负载均衡后面的RS(Real Server)配置,可以是IP或域名,如果端口不写,默认是80端口。高并发场景下,IP可以换成域名,通过DNS做负载均衡。
weight=1 代表服务器权重,默认是1。权重数字越大表示接收的请求比例越大。
max_fails=1 nginx尝试连接后端主机失败的次数。这个数值是配合proxy_next_upstream、fastcgi_next_upstream和memcached_next_upstream这三个参数来使用的。当nginx接收后端服务器返回这三个参数定义的状态码时,会将这个请求转发给正常工作的后端服务器,例如404、502、503。max_fails默认是1,企业场景建议2~3。比如京东1次。
backup 表示热备配置,备用服务器。当负载均衡算法为ip_hash时,后端服务器在负载均衡中的状态不能是weight和backup。
fail_timeout=10s 在定义max_fails的失败次数后,距离下次检查的间隔时间,默认是10s。如果max_fails=5,就检查5次,如果5次都是502,那么等待10s再去检查一次,如果还是502,在不重新加载nginx配置的情况下,每隔10s再检查一次。常规业务设置为2~3秒。比如京东3秒。
down 标记这个服务器不可用。这参数配合ip_hash使用。
3、负载均衡调度算法
调度算法一般分为两类:
第一类:静态调度算法,即负载均衡器根据自身设置的规则进行分配,不需要考虑后端节点服务器的情况,例如:rr、wrr、ip_hash等算法都属于静态调度算法。
第二类:动态调度算法,即负载均衡器会根据后端节点的当前状态来决定是否分发请求,例如:连接数少的优先获得请求,响应时间短的优先获得请求。例如:least_conn、fair等都属于动态调度算法。
常见算法介绍:
(1)rr轮询(默认调度算法,静态调度算法) 按客户端请求顺序把客户端的请求逐一分配到不同的后端节点服务器,相当于LVS中的rr算法,如果后端节点服务器宕机,宕机的服务器会被自动从节点服务器 池中剔除,以使客户端的用户访问不受影响。新的请求会分配给正常的服务器。 (2)wrr(权重轮询,静态调度算法) 在rr轮询算法的基础上加上权重,即为权重轮询算法。当使用该算法时,权重和用户访问成正比,权重值越大,被转发的请求也就越多。可以根据服务器的配置和性能指定权重值大小。 (3)ip_hash(ip哈希,静态调度算法) 每个请求按客户端IP的hash结果分配,当新的请求到达时,先将其客户端IP通过哈希算法算出一个值,在随后的客户端请求中,客户端IP的哈希值只要相同,就会被分配至同一台服务器,该调度算法可以解决动态网页的session共享问题,但有时候会导致请求分配不均,即无法保证1:1的负载均衡。 (4)fair(动态调度算法) 该算法会根据后端节点服务器的响应时间来分配请求,响应时间短的优先分配。这是更加智能的调度算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。但nginx本身不支持fair算法,必须下载upstream_fair模块。 (5)least_conn 该算法会根据后端节点服务器的连接数来决定分配情况,哪个机子连接数少就分发。 (6)url_hash算法 与ip_hash算法类似,这里是根据访问URL的hash结果来分配请求,让每个URL定向到同一个后端服务器,后端服务器为缓存服务器时效果显著。nginx本身bu支持url_hash算法,必须下载相关包。 (7)一致性hash算法 一致性hash算法一般用于代理后端服务器业务为缓存服务(如squid、memcached)的场景,通过将用户请求的URL或指定字符串进行计算,然后调度到后端服务器上,此后任何用户查找同一个URL或指定字符串都会被调度到这一台服务器上,因此后端的每个节点缓存的内容都是不同的,一致性hash算法可以解决后端某个或某几个节点宕机后,缓存的数据动荡最小。简单nginx负载均衡代码如下:
upstream test{ ip_hash; server 192.168.10.203:80; server 192.168.10.204:80;}server{ listen 80; server_name test.com location / { proxy_pass http://test; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwared_For $proxy_add_x_forwared_for; }}
4、http_proxy_module模块
1、proxy_pass指令介绍
proxy_pass指令属于ngx_http_proxy_module模块,此模块可以将请求转发到另一台服务器。在实际的反向代理工作中,会通过location功能匹配指定的URL,然后把接收到的符合匹配URL的请求通过proxy_pass抛给定义好的upstream节点池。
例如:
location /name/{ proxy_pass http://127.0.0.1/haha/;}
location /haha/test/{ proxy_pass http://127.0.0.1;}
location /name/{ rewrite /name/([^/]+) /users?name=$1 break; proxy_pass http://127.0.0.1;}
2、http proxy模块参数
nginx的代理功能通过http proxy模块来实现。该模块相关参数:
proxy_set_header 设置http请求header项传给后端服务器节点,例如,可以实现让后端的服务器节点获取访问客户端用户的真实ip。
proxy_next_upstream 设置故障转移,语法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 |http_404 | off ...; 默认值: proxy_next_upstream error timeout;
client_body_buffer_size 用于指定客户端主题缓冲区大小。
proxy_connect_timeout 表示反向代理与后端节点服务器连接的超时时间,即发起握手等候响应的超时时间。
proxy_send_timeout 表示代理后端服务器的数据回传时间,即在规定时间之内后端服务器必须传完所有的数据,否则,nginx将断开这个连接。
proxy_read_timeout 设置nginx从代理的后端服务器获取信息的时间,表示连接建立后,nginx等待后端服务器的响应时间,其实是nginx已经进入后端的排队之中等候处理的时间。
proxy_buffer_size 设置缓冲区大小,默认为proxy_buffers设置的大小。
proxy_buffers 设置缓冲区的数量和大小,nginx从代理的后端服务器获取的响应信息,会放到缓冲区。
proxy_busy_buffers_size 用于设置系统很忙时可以使用的proxy_buffers大小,官方推荐的大小为proxy_buffers*2
proxy_temp_file_write_size 指定proxy缓存临时文件的大小。
二、SSL
SSL证书可以到各大机构申请,现在基本都是收费的。当然也可以自己制作,自己制作的证书没有被浏览器厂商承认,所以只能自己测试用。
下面演示自己制作证书,配置SSL。
(1)生成私钥和公钥
1、生成一个私钥
假设网站目录是/htdocs/ssl
[root@node0 ~]# mkdir /htdocs/ssl[root@node0 ~]# cd /htdocs/ssl/[root@node0 ssl]# openssl genrsa -des3 -out tmp.key 2048Generating RSA private key, 2048 bit long modulus..........................................................................................+++..................................................................................................................................................................+++e is 65537 (0x10001)Enter pass phrase for tmp.key:Verifying - Enter pass phrase for tmp.key:[root@node0 ssl]#
生成私钥需要设置密码,假设密码是:123456
生成的这个私钥是有密码的,现在要把这密码去掉:
[root@node0 ssl]# openssl rsa -in tmp.key -out pri.keyEnter pass phrase for tmp.key:writing RSA key[root@node0 ssl]#
输入密码123456后即可,此时的私钥pri.csr就没有密码了。
2、生成请求证书
用刚才的没有加密的私钥去生成请求证书。
[root@node0 ssl]# openssl req -new -key pri.key -out pri.csrYou are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [XX]:State or Province Name (full name) []:Locality Name (eg, city) [Default City]:Organization Name (eg, company) [Default Company Ltd]:Organizational Unit Name (eg, section) []:Common Name (eg, your name or your server's hostname) []:Email Address []:Please enter the following 'extra' attributesto be sent with your certificate requestA challenge password []:An optional company name []:[root@node0 ssl]#
反正是用来自己测试,所以上面的很多信息都没有填写。
3、生成公钥
用前面生成的没有密码的私钥(pri.key)和请求文件(pri.csr)去生成公钥
[root@node0 ssl]# openssl x509 -req -days 365 -in pri.csr -signkey pri.key -out public.crtSignature oksubject=/C=XX/L=Default City/O=Default Company LtdGetting Private key[root@node0 ssl]#
OK,完成。私钥是:pri.key,公钥是:public.crt。
(2)配置ssl
创建虚拟主机,假设配置文件为:ssl.conf,网站目录为:/htdocs/ssl/
[root@node0 ssl]# vim /usr/local/nginx/conf.d/ssl.confserver { listen 443; server_name ssl.com; index index.html index.php; root /htdocs/ssl; ssl on; ssl_certificate /htdocs/ssl/public.crt; ssl_certificate_key /htdocs/ssl/pri.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; location ~ \.php$ { root /htdocs/ssl; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; include fastcgi_params; }}
/usr/local/nginx/conf/fastcgi_params文件中添加:fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
(3)创建测试页
[root@node0 ssl]# echo " " > /htdocs/ssl/index.php
重启nginx服务和清空防火墙。
[root@node0 ssl]# /usr/local/nginx/sbin/nginx -s reload[root@node0 ssl]# iptables -F
浏览器打开:https:192.168.10.205
提示不安全,因为是自己制作的证书。
点击高级--添加例外即可。
OK显示成功:
三、php_fpm之pool
每一个pool可以监听一个端口。默认的pool是[www] 比如自定义一个pool,名字为[haha]
[root@node0 ~]# vim /usr/local/php7/etc/php-fpm.d/www.conf[haha]listen = /tmp/haha.socklisten.mode = 666user = nginxgroup = nginxpm = dynamicpm.max_children = 50pm.start_servers = 20pm.min_spare_servers = 5pm.max_spare_servers = 35pm.max_requests = 500rlimit_files = 1024
保存退出,重新加载
[root@node0 ~]# /usr/local/php7/sbin/php-fpm -t[03-Jul-2018 21:00:27] NOTICE: configuration file /usr/local/php7/etc/php-fpm.conf test is successful[root@node0 ~]# /etc/rc.d/init.d/php-fpm reloadReload service php-fpm done[root@node0 ~]#
查看一下进程:
[root@node0 ~]# ps aux |grep php-fpmroot 4976 1.0 0.4 224596 7088 ? Ss 21:00 0:00 php-fpm: master process (/usr/local/php7/etc/php-fpm.conf)nginx 4977 1.0 0.7 228764 13964 ? S 21:00 0:00 php-fpm: pool wwwnginx 4978 1.3 0.7 228764 13988 ? S 21:00 0:00 php-fpm: pool wwwnginx 4979 0.0 0.3 224588 6480 ? S 21:00 0:00 php-fpm: pool hahanginx 4980 0.0 0.3 224588 6480 ? S 21:00 0:00 php-fpm: pool hahanginx 4981 0.0 0.3 224588 6480 ? S 21:00 0:00 php-fpm: pool hahanginx 4982 0.0 0.3 224588 6480 ? S 21:00 0:00 php-fpm: pool hahanginx 4983 0.0 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4984 0.0 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4985 0.0 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4986 0.0 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4987 0.0 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4988 0.0 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4989 0.0 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4990 0.4 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4991 0.2 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4992 0.3 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4993 0.1 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4994 0.2 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4995 0.2 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4996 0.2 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4997 0.1 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool hahanginx 4998 0.1 0.3 224588 6484 ? S 21:00 0:00 php-fpm: pool haharoot 5028 0.0 0.0 112704 968 pts/1 S+ 21:01 0:00 grep --color=auto php-fpm[root@node0 ~]#
OK,自定义的haha已启动。
四、php-fpm的慢执行日志
在[www]pool中添加以下两行内容
[root@node0 ~]# vim /usr/local/php7/etc/php-fpm.d/www.confrequest_slowlog_timeout = 1slowlog = /usr/local/php7/var/log/www-slow.log
重启php-fpm
[root@node0 ~]# systemctl restart php-fpm
测试:
网站目录为:/htdocs/slow
[root@node0 ~]# mkdir /htdocs/slow[root@node0 ~]# vim /htdocs/slow/slow.php
虚拟主机配置文件:
[root@node0 ~]# vim /usr/local/nginx/conf.d/slow.confserver { listen 8088; server_name node1; location / { root /htdocs/slow; index index.php index.html index.htm; } location ~ \.php$ { root /htdocs/slow; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; include fastcgi_params; } }
清空防火墙,关闭selinux,重启nginx,php-fpm
[root@node0 ~]# iptables -F[root@node0 ~]# setenforce 0[root@node0 ~]# /usr/local/nginx/sbin/nginx -s reload[root@node0 ~]# /etc/rc.d/init.d/php-fpm restartGracefully shutting down php-fpm . doneStarting php-fpm done[root@node0 ~]#
使用curl命名测试:
[root@node0 ~]# curl -x127.0.0.1:8088 node1/slow.php -IHTTP/1.1 200 OKServer: nginx/1.14.0Date: Tue, 03 Jul 2018 13:25:58 GMTContent-Type: text/html; charset=UTF-8Connection: keep-aliveX-Powered-By: PHP/7.2.5[root@node0 ~]#
查看日志:
[root@node0 ~]# cat /usr/local/php7/var/log/www-slow.log [03-Jul-2018 21:26:57] [pool www] pid 5736script_filename = /htdocs/slow/slow.php[0x00007fd06581d090] sleep() /htdocs/slow/slow.php:4[root@node0 ~]#
日志显示/htdocs/slow/slow.php文件的第4行使用了sleep()
五、php-fpm之open_basedir
可以针对每个虚拟主机设置basedir,也可针对每个pool设置basedir。
[root@node0 ~]# vim /usr/local/php7/etc/php-fpm.d/www.confphp_admin_value[open_basedir]=/htdocs/test2:/tmp[root@node0 ~]# /etc/rc.d/init.d/php-fpm restart
测试:
[root@node0 ~]# curl -x127.0.0.1:80 haha1/index.phpNo input file specified.[root@node0 ~]# curl -x127.0.0.1:80 haha1/index.php -IHTTP/1.1 404 Not FoundServer: nginx/1.14.0Date: Tue, 03 Jul 2018 14:09:08 GMTContent-Type: text/html; charset=UTF-8Connection: keep-aliveX-Powered-By: PHP/7.2.5[root@node0 ~]#
把php_admin_value[open_basedir]改为/htdocs/test1:/tmp 重启php-fpm,再测试:
[root@node0 ~]# curl -x127.0.0.1:80 haha1/index.php -IHTTP/1.1 200 OKServer: nginx/1.14.0Date: Tue, 03 Jul 2018 14:10:53 GMTContent-Type: text/html; charset=UTF-8Connection: keep-aliveX-Powered-By: PHP/7.2.5Set-Cookie: zbx_sessionid=28227a56a4d998b32ef6c00517de0347; HttpOnlySet-Cookie: PHPSESSID=js5lu9rp93lc8i49paq6qaicdm; path=/; HttpOnlyExpires: Thu, 19 Nov 1981 08:52:00 GMTCache-Control: no-store, no-cache, must-revalidatePragma: no-cacheX-Content-Type-Options: nosniffX-XSS-Protection: 1; mode=blockX-Frame-Options: SAMEORIGIN[root@node0 ~]#
OK,正常。
六、php-fpm进程管理
配置解释:
pm = dynamic:动态进程管理,也可以是staticpm.max_children = 50 : 最大子进程数pm.start_servers = 20 : 启动服务时会启动的进程数pm.min_spare_servers = 5 : 定义在空闲时段,子进程数的最少值,如果达到这个值,php-fpm服务会自动派生新的子进程pm.max_spare_servers = 35 : 定义在空闲时段,子进程数的最大值,如果高于这个值,php-fpm服务会清理空闲的子进程pm.max_requests = 500 :定义一个字进程最多可以处理多少个进程,这里设置成500,也就是说在一个php-fpm的子进程最多可以处理500个,若达到这个数值时,它就会自动退出。rlimit_files = 1024 :设置文件打开描述符的rlimit限制. 默认值: 系统定义值系统默认可打开句柄是1024,可使用 ulimit -n查看,ulimit -n 2048修改(临时修改)。
扩展
针对请求的uri来代理
根据访问的目录来区分后端的web
nginx长连接
nginx算法分析
nginx中的root和alias区别
nginx的alias和root配置
这个更详细
ssl: