Nginx负载均衡
Nginx负载均衡即为当代理服务器将自定义的域名解析到多个指定IP时,通过upstream来保证用户可以通过代理服务器正常访问各个IP。
配置:
[root@harry-01 ~]# vim /usr/local/nginx/conf/vhost/load.conf
upstream qq_com
#自定义域名
{
ip_hash;
#保证同一个用户始终保持在同一台机器上
#即当域名指向多个IP时,保证每个用户始终解析到同一IP
server 61.135.157.156:80;
server 125.39.240.113:80;
#指定web服务器的IP
}
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;
}
}
检测
代理前
[root@harry-01 ~]# curl -x127.0.0.1:80 www.qq.com
This is harry.com
#使用代理前,会直接解析到默认虚拟主机。
代理后
使用代理后会解析到代理服务器所指向的IP
[root@harry-01 ~]# dig www.qq.com
; <<>> DiG 9.9.4-RedHat-9.9.4-72.el7 <<>> www.qq.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51756
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.qq.com. IN A
;; ANSWER SECTION:
www.qq.com. 97 IN CNAME https.qq.com.
https.qq.com. 397 IN A 121.51.36.46
;; Query time: 23 msec
;; SERVER: 119.29.29.29#53(119.29.29.29)
;; WHEN: 四 12月 13 10:41:57 CST 2018
;; MSG SIZE rcvd: 75
Nginx不支持代理https,只能代理http,新版本的Nginx可以代理tcp。
dig命令
dig命令是常用域名解析工具。
如果服务器中没有该命令,手动安装:yum install -y bind-utils
http、https、tcp
HTTP超文本传输协议(HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。
HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议要比http协议安全。HTTP默认的端口号为80,HTTPS的端口号为443。
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。默认监听80端口。
SSL原理
SSL(Secure Sockets Layer 安全套接层)协议,及其继任者TLS(Transport Layer Security传输层安全)协议,是为网络通信提供安全及数据完整性的一种安全协议。
SSL工作流程
如果虚拟机中没有此工具,手动安装:yum install -y openssl
浏览器发送一个https的请求给服务器;
服务器要有一套数字证书,可以自己制作(后面的操作就是阿铭自己制作的证书),也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出>提示页面,这套证书其实就是一对公钥和私钥;
服务器会把公钥传输给客户端;
客户端(浏览器)收到公钥后,会验证其是否合法有效,无效会有警告提醒,有效则会生成一串随机数,并用收到的公钥加密;
客户端把加密后的随机字符串传输给服务器;
服务器收到加密随机字符串后,先用私钥解密(公钥加密,私钥解密),获取到这一串随机数后,再用这串随机字符串加密传输的数据(该加密为对称加密,所谓对称加密,就是将数据和私钥也就是这个随机字符串>通过某种算法混合在一起,这样除非知道私钥,否则无法获取数据内容);
服务器把加密后的数据传输给客户端;
客户端收到数据后,再用自己的私钥也就是那个随机字符串解密;
生成SSL密钥对
SSL证书就是一对公钥和私钥。
创建私钥
[root@harry-01 ~]# cd /usr/local/nginx/conf/
[root@harry-01 conf]# 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:
140621523077008:error:28069065:lib(40):UI_set_result:result too small:ui_lib.c:831:You must type in 4 to 1023 characters
Enter pass phrase for tmp.key: # 在此指定密码!
转换key,取消密码:
[root@harry-01 conf]# openssl rsa -in tmp.key -out linux.key
Enter pass phrase for tmp.key:
writing RSA key
删除密钥文件:rm -f tmp.key
生成证书请求文件
需要拿这个文件和私钥一起生产公钥文件:
该部分内容如果不购买证书可以自定义;如果是正式应用在网站上,需要规范填写对应信息(购买)。
[root@harry-01 conf]# openssl req -new -key linux.key -out linux.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]:cn
State or Province Name (full name) []:harry
Locality Name (eg, city) [Default City]:Beijing
Organization Name (eg, company) [Default Company Ltd]:Beijing
Organizational Unit Name (eg, section) []:Beijing
Common Name (eg, your name or your server's hostname) []:linux
Email Address []:harry@linux.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123123
An optional company name []:123123
创建公钥
[root@harry-01 conf]# openssl x509 -req -days 365 -in linux.csr -signkey linux.key -out linux.crt
Signature ok
subject=/C=cn/ST=harry/L=Beijing/O=Beijing/OU=Beijing/CN=linux/emailAddress=harry@linux.com
Getting Private key
[root@harry-01 conf]#
Nginx配置SSL
[root@harry-01 vhost]# vim ssl.conf
server
{
listen 443;
server_name aming.com;
index index.html index.php;
root /data/wwwroot/aming.com;
ssl on;
#开启ssl
ssl_certificate aminglinux.crt;
#配置公钥
ssl_certificate_key aminglinux.key;
#配置私钥
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#配置协议
}
[root@harry-01 vhost]# mkdir /data/wwwroot/aming.com
检测
[root@harry-01 vhost]# /usr/local/nginx/sbin/nginx -t
nginx: [emerg] unknown directive "ssl" in /usr/local/nginx/conf/vhost/ssl.conf:7
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
未识别ssl配置,需要重新编译Nginx:
[root@harry-01 vhost]# cd /usr/local/src/nginx-1.12.2/
[root@harry-01 nginx-1.12.2]# ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE Makefile man objs README src
[root@harry-01 nginx-1.12.2]# ./configure --prefix=/usr/local/nginx/ --with-http_ssl_module
[root@harry-01 nginx-1.12.2]# make && make install
[root@harry-01 nginx-1.12.2]# /etc/init.d/nginx restart
Restarting nginx (via systemctl): [ 确定 ]
[root@harry-01 nginx-1.12.2]# netstat -lntp
Active Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 5991/nginx: master tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1735/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2040/master tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 5991/nginx: master tcp6 0 0 :::3306 :::* LISTEN 1990/mysqld tcp6 0 0 :::22 :::* LISTEN 1735/sshd tcp6 0 0 ::1:25 :::* LISTEN 2040/master
测试
[root@harry-01 nginx-1.12.2]#cd /data/wwwroot/aming.com/
[root@harry-01 aming.com]# vim index.html
This is ssl.
添加本地域名:
[root@harry-01 aming.com]#vim /etc/hosts
127.0.0.1 aming.com
[root@harry-01 vhost]# curl https://aming.com/
curl: (60) Peer's certificate issuer has been marked as not trusted by the user.
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option.If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL).If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option.
因为该证书是自己创建的,所以提示证书不被信任!
php-fpm的pool
为了避免因多站点使用同一个pool时因一个站点故障导致pool出问题,进而影响使用同一个pool的其他站点的正常运行,要对每个站点配置一个单独的pool。
增加pool
[root@harry-01 ~]# vim /usr/local/php-fpm/etc/php-fpm.conf
[global]
pid = /usr/local/php-fpm/var/run/php-fpm.pid
error_log = /usr/local/php-fpm/var/log/php-fpm.log
[harry.com]
listen = /tmp/harry.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
[root@harry-01 ~]# /usr/local/php-fpm/sbin/php-fpm -t
[13-Dec-2018 22:33:08] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful
#重新加载配置文件:
[root@harry-01 ~]# /etc/init.d/php-fpm reload
Reload service php-fpm done
查看进程:
root 8671 0.1 0.2 229444 4932 ? Ss 22:35 0:00 php-fpm: master process (/usr/local/php-fpm/etc/php-fpm.conf)
php-fpm 8672 0.0 0.2 229444 4688 ? S 22:35 0:00 php-fpm: pool harry.com
php-fpm 8673 0.0 0.2 229444 4688 ? S 22:35 0:00 php-fpm: pool harry.com
php-fpm 8674 0.0 0.2 229444 4688 ? S 22:35 0:00 php-fpm: pool harry.com
为站点配置pool
把fastcgi_pass地址改为和php-fpm.conf中一样的地址就可以。
location ~ \.php$
{
include fastcgi_params;
fastcgi_pass unix:/tmp/harry.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /data/wwwroot/harry.com$fastcgi_script_name;
}
access_log /tmp/harry.com.log combined_realip;
添加php-fpm.conf子配置文件
为了便于管理,可以将php-fpm中的每个pool单独进行管理。进行如下操作,添加php-fpm子配置文件:
[global]
pid = /usr/local/php-fpm/var/run/php-fpm.pid
error_log = /usr/local/php-fpm/var/log/php-fpm.log
include = etc/php-fpm.d/*.conf
在全局变量版块添加参数“include = etc/php-fpm.d/*.conf”。然后可以清除php-fpm配置文件中其他参数,再到php-fpm.d目录下进行单独设置。
[root@harry-01 vhost]# cd /usr/local/php-fpm/etc/
创建指定目录:
[root@harry-01 etc]# mkdir php-fpm.d
[root@harry-01 etc]# cd php-fpm.d/
[root@harry-01 php-fpm.d]#
#创建php-fpm子配置文件:
[root@harry-01 php-fpm.d]# vim www.conf
[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
[root@harry-01 php-fpm.d]# vim harry.conf
[harry]
listen = /tmp/harry.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
#检查语法错误、重新加载:
[root@harry-01 etc]# /usr/local/php-fpm/sbin/php-fpm -t
[13-Dec-2018 22:53:16] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful
[root@harry-01 etc]# /etc/init.d/php-fpm reload
Reload service php-fpm done
[root@harry-01 etc]#
配置完成后使用ps查看php-fpm进程信息。
php-fpm的慢执行日志
开启慢执行日志:
[root@harry-01 php-fpm.d]# vim /usr/local/php-fpm/etc/php-fpm.d/www.conf
[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
request_slowlog_timeout = 1\
#当请求超过1秒开始记录日志
slowlog = /usr/local/php-fpm/var/log/www-slow.log
#日志存放地址
[root@harry-01 php-fpm.d]# /usr/local/php-fpm/sbin/php-fpm -t
[13-Dec-2018 23:11:52] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful
[root@harry-01 php-fpm.d]# /etc/init.d/php-fpm reload
Reload service php-fpm done
[root@harry-01 php-fpm.d]#
试验
在使用www pool的站点添加文件:
[root@harry-01 php-fpm.d]# vim /data/wwwroot/test.com/sleep.php
<?php
echo "test slow log";
sleep(2);
echo "done";
?>
#检测:
[root@harry-01 php-fpm.d]# curl -x127.0.0.1:80 test.com/sleep.php
test slow logdone
查看慢日志:
[root@harry-01 php-fpm.d]# tail /usr/local/php-fpm/var/log/www-slow.log
[13-Dec-2018 23:26:55] [pool www] pid 6451script_filename = /data/wwwroot/test.com/sleep.php[0x00007fe02560e2e0] sleep() /data/wwwroot/test.com/sleep.php:3
指定open_basedir
当一台服务器跑多个站点时,使用open_basedir限定各个站点所能访问的服务器上的目录的范围。在php-fpm服务中,可以针对每个pool设定open _ basedir。
核心配置参数:
[root@harry-01 ~]# vim /usr/local/php-fpm/etc/php-fpm.d/www.conf
……
php_aming_value[open_basedir]=/data/wwwroot/test.com:/tmp/
创建测试PHP脚本:
[root@harry-01 php-fpm.d]# vim /data/wwwroot/test.com/1.php
<?php
echo "This is a test php of open_basedir";
测试:
[root@harry-01 php-fpm.d]# curl -x127.0.0.1:80 test.com/1.php
This is a test php of open_basedir
php-fpm进程管理
php-fpm中pool配置参数解析:
[root@harry-01 php-fpm.d]# vim www.conf
[www]
listen = /tmp/php-fcgi.sock
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
;定义进程启动方式(dynamic表示动态,static表示静态)
;只有此处设置为dynamic,下面的配置才生效
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
;表示一个子进程最多可接受多少个请求
rlimit_files = 1024
;表示每个子进程打开的多少个文件句柄
request_slowlog_timeout = 1
;当请求超过1秒开始记录日志
slowlog = /usr/local/php-fpm/var/log/www-slow.log
;日志存放地址
php_admin_value[open_basedir]=/data/wwwroot/test.com:/tmp/