第十二章LNMP架构下预习笔记

12.17 Nginx负载均衡

配置文件

upstream qq_com
{
    ip_hash;
    server 61.135.157.156:80;
    server 125.39.240.113:80;
}
server
{
    listen 80;
    server_name www.qq.com;
    location /
    {
        proxy_pass      http://qq_com;
        proxy_set_header Host   $host;
        proxy_set_header X-Real-IP      $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
12.18 ssl原理

12.19 生产ssl密钥对

12.20 Nginx配置ssl

mkdir /data/wwwroot/aming.com

cd /usr/local/src/nginx-1.14.0

./configure --help | grep ssl

./configure --prefix=/usr/local/nginx --with-http_ssl_module

make && make install

12.21 php-fpm的pool

[www]

listen = /tmp/www.sock

listen.mode=666

user = php-fpm

group = php-fpm

pm = dynamic

pm.max_children = 50

pm.start_servers = 20

pm.min_spare_servers = 5

pm.max_spare_servers = 35

pm.max_requests = 500

rlimit_files = 1024

12.22 php-fpm慢执行日志

vim /usr/local/php-fpm/etc/php-fpm.d/www.conf

request_slowlog_timeout = 1
slowlog = /usr/local/php-fpm/var/log/www-slow.log

注意:sock

vim /data/wwwroot/test.com/sleep.php

<?php 
echo "test slow log";
sleep(2);
echo "done";
?>
 

12.23 open_basedir

php_admin_value[open_basedir]=/data/wwwroot/test.com:/tmp/

open_basedir 和虚拟主机里面定义要一致

配置错误日志:

vim /usr/local/php-fpm/etc/php.ini

display_errors = Off

log_errors = On
error_log = /usr/local/php-fpm/var/log/php_errors.log

error_reporting = E_ALL

touch /usr/local/php-fpm/var/log/php_errors.log

chmod 777 /usr/local/php-fpm/var/log/php_errors.log

/etc/init.d/php-fpm restart

把basedir故意改错

12.24 php-fpm进程管理

课堂串讲

一、负载均衡

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 2048
Generating 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.key
Enter 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.csr
You are about to be asked to enter information that will be incorporated
into 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 blank
For 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' attributes
to be sent with your certificate request
A 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.crt
Signature ok
subject=/C=XX/L=Default City/O=Default Company Ltd
Getting 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.conf
server {
   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 "<?php phpinfo(); ?>" > /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.sock
listen.mode = 666
user = nginx
group = nginx
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_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 reload
Reload service php-fpm  done
[root@node0 ~]# 

查看一下进程:

[root@node0 ~]# ps aux |grep php-fpm
root       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 www
nginx      4978  1.3  0.7 228764 13988 ?        S    21:00   0:00 php-fpm: pool www
nginx      4979  0.0  0.3 224588  6480 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4980  0.0  0.3 224588  6480 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4981  0.0  0.3 224588  6480 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4982  0.0  0.3 224588  6480 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4983  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4984  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4985  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4986  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4987  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4988  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4989  0.0  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4990  0.4  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4991  0.2  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4992  0.3  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4993  0.1  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4994  0.2  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4995  0.2  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4996  0.2  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4997  0.1  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
nginx      4998  0.1  0.3 224588  6484 ?        S    21:00   0:00 php-fpm: pool haha
root       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.conf
request_slowlog_timeout = 1
slowlog = /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
<?php

   echo "test slow log";
   sleep(2);
   echo "done";
?>

虚拟主机配置文件:

[root@node0 ~]# vim /usr/local/nginx/conf.d/slow.conf
server {
    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 restart
Gracefully shutting down php-fpm . done
Starting php-fpm  done
[root@node0 ~]# 

使用curl命名测试:

[root@node0 ~]# curl -x127.0.0.1:8088 node1/slow.php -I
HTTP/1.1 200 OK
Server: nginx/1.14.0
Date: Tue, 03 Jul 2018 13:25:58 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-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 5736
script_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.conf
php_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.php
No input file specified.
[root@node0 ~]# curl -x127.0.0.1:80 haha1/index.php -I
HTTP/1.1 404 Not Found
Server: nginx/1.14.0
Date: Tue, 03 Jul 2018 14:09:08 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-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 -I
HTTP/1.1 200 OK
Server: nginx/1.14.0
Date: Tue, 03 Jul 2018 14:10:53 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/7.2.5
Set-Cookie: zbx_sessionid=28227a56a4d998b32ef6c00517de0347; HttpOnly
Set-Cookie: PHPSESSID=js5lu9rp93lc8i49paq6qaicdm; path=/; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN

[root@node0 ~]# 

OK,正常。

六、php-fpm进程管理

配置解释:

pm = dynamic:动态进程管理,也可以是static

pm.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来代理 http://ask.apelearn.com/question/1049

根据访问的目录来区分后端的web http://ask.apelearn.com/question/920

nginx长连接 http://www.apelearn.com/bbs/thread-6545-1-1.html

nginx算法分析 http://blog.sina.com.cn/s/blog_72995dcc01016msi.html

nginx中的root和alias区别 http://blog.csdn.net/21aspnet/article/details/6583335

nginx的alias和root配置 http://www.ttlsa.com/nginx/nginx-root_alias-file-path-configuration/

http://www.iigrowing.cn/shi-yan-que-ren-nginx-root-alias-location-zhi-ling-shi-yong-fang-fa.html 这个更详细

ssl:https://coding.net/u/aminglinux/p/nginx/git/blob/master/ssl/ca.md

猜你喜欢

转载自blog.csdn.net/weixin_37817498/article/details/82859975
今日推荐