电商平台 lnmp 架构之 nginx 优化
Posted 123坤
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了电商平台 lnmp 架构之 nginx 优化相关的知识,希望对你有一定的参考价值。
电商平台 lnmp 架构之 nginx 优化
1. nginx 的优化
停掉之前的 openresty 开启的 nginx,切换到之前的 nginx ;
[root@server1 conf]# /usr/local/openresty/nginx/sbin/nginx -s stop
[root@server1 conf]# cd
[root@server1 ~]# systemctl start nginx
-
Linux 下高并发 socket 最大连接数所受的各种限制
-
修改用户进程可打开文件数限制
/etc/security/limits.conf
nginx - nofile 65535 -
Linux 系统级的最大打开文件数限制
fs.file-max = 188414 //和内存容量相关 -
修改网络内核对 TCP 连接的有关限制
net.ipv4.ip_local_port_range = 1024 65535 -
限制接收新 TCP 连接侦听队列的大小
net.core.somaxconn = 2048 -
启用 tcp 连接 timewait 快速回收和重用
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1 -
worker_processes ##工作进程数
worker_connections ##单个工作进程并发连接数 -
nginx 作为 http 服务器时:
max_clients = worker_processes * worker_connections -
nginx 作为反向代理服务器时:
max_clients = worker_processes * worker_connections / 2 -
worker_processes ##将其设置为可用的CPU内核数将是一个好的开始
worker_rlimit_nofile ##worker进程的最大打开文件数限制。如果没设置的话,这个值为操作系统的限制。 -
worker_processes 2; ## 最多开启8个
worker_cpu_affinity 01 10; ## cpu有多少个核,就有几位数,1代表内核开启,0代表内核关闭 -
multi_accept on; ## 告诉 nginx 收到一个新连接通知后接受尽可能多的连接;
-
use epoll; ##使用 epoll 模型
-
开启文件高效传输模式,同时设置 tcp_nopush 和 tcp_nodelay 为on,可以防止网路和磁盘IO阻塞。
sendfile on;
tcp_nopush on;
tcp_nodelay on;
- 修该配置文件
[root@server1 conf]# pwd
/usr/local/nginx/conf
[root@server1 conf]# vim nginx.conf
2 user nginx nginx;
3 worker_processes 2; ##工作进程数
4 worker_cpu_affinity 01 10;
##绑定cpu,第一个cpu和第一个work绑定,第二个cpu和第二个work 绑定
13 events {
14 use epoll; ##默认用的是linux内核的epoll模型
15 worker_connections 65535;
##65535并发量,单个工作进程并发连接数;连接数 X 进程数表示当前最大的并发量
16 }
[root@server1 conf]# nginx -s reload ##重新加载
[root@server1 conf]# ps ax | grep nginx
当设定工作进程数为 2 时,重新加载配置文件之后,此时可以看到进程中就开启了两个进程;
当然进程数并不是越多越好,应该和 cpu 数量保持一致才能发挥的更好;可以用命令 lscpu
来查看当前主机的 cpu 数量;
当不知道当前系统的 cpu 数量时,就写入 auto ,会自动根据 cpu 的数量来开启工作进程;但是用 auto 可能会出现负载不稳定的现象;
如:当有 8 个cpu ,可能会前面四个打满,后面四个很闲,为什么出现这种情况? 只能根据日志的输出来判断,程序、文件系统、网络可能都会引起这种情况的发生
所以应该手动指定进程数量。
在 linux 系统中,默认 kernel > system > 软件的权限;当我们写入 65535 时,一个网络连接可能就会消耗掉,对系统来说这是不被允许的。
可以用命令 ulimit -a
来查看系统最大支持的数量;
当数量低于我们写入的值时,就要手动的去设定系统的并发量;
[root@server1 conf]# vim /etc/security/limits.conf ##修改系统的权限
# End of file
nginx - nofile 65535 ##在最后一行写入
当系统支持时,我们还要看内核支持该数量不,用用令 sysctl -a
来查看内核信息;
[root@server1 conf]# sysctl -a |grep file
##看内核最大支持不
fs.file-max = 200067 ##内核的数量大于我们写入的
fs.file-nr = 1024 0 200067
fs.xfs.filestream_centisecs = 3000
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.eth0.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
- 反向代理
此处再开两台机器来观察实验效果,server2 IP 为 172.25.25.2;
server3 IP为 172.25.25.3;在新开的机子中要安装httpd
并写入发布内容用以做测试;
oot@server2 ~]# yum install -y httpd
[root@server2 ~]# systemctl start httpd
[root@server2 ~]# echo server2 > /var/www/html/index.html
[root@server2 ~]# curl localhost ##测试写入的内容
server2
---
[root@server3 ~]# yum install -y httpd
[root@server3 ~]# systemctl start httpd
[root@server3 ~]# echo server3 > /var/www/html/index.html
[root@server3 ~]# curl localhost
server3
在主机中编辑配置文件;
[root@server1 conf]# pwd
/usr/local/nginx/conf
[root@server1 conf]# vim nginx.conf
19 http {
20 upstream westos { ##负载均衡
21 server 172.25.25.2:80;
22 server 172.25.25.3:80;
23 }
49 #location / { ##注释掉本机的发布页面
50 # root html;
51 # index index.php index.html index.htm;
52 #}
53
54 location / { ##当有请求时全部代理到后端
55 proxy_pass http://westos;
56 }
[root@server1 conf]# nginx -t ##检测语法
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@server1 conf]# nginx -s reload ##重载
此时在其他的主机中访问 172.25.25.1 时,会将请求调度到后端;
此时在负载均衡的主机中可以看到端口信息如下,会将所有访问本机的请求通过负载均衡调度到其他的主机中。
2. nginx平滑升级
平滑升级:不需要关闭当前的服务,用户端是感觉不到的。
- 下载 nginx 新版本软件,正常执行./configure 和make 但不要执行
make install
- 下载与编译
[root@server1 ~]# tar zxf nginx-1.19.1.tar.gz
[root@server1 ~]# cd nginx-1.19.1
[root@server1 nginx-1.19.1]# ls
auto CHANGES CHANGES.ru conf configure contrib html LICENSE man README src
[root@server1 nginx-1.19.1]# vim auto/cc/gcc
171 # debug
172 #CFLAGS="$CFLAGS -g" ##注释掉这一行内容
[root@server1 nginx-1.19.1]# ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module
[root@server1 nginx-1.19.1]# make
注:
(1). 此处只用 make 编译就可以,不能做 make install
,因为 make install
会将之前的信息覆盖;
(2). 此处之前如果没有关闭 debug ,要先执行 make clean ,然后关闭 debug ,再编译再 make。
- 备份之前的数据
[root@server1 sbin]# pwd
/usr/local/nginx/sbin
[root@server1 sbin]# ls
nginx
[root@server1 sbin]# mv nginx nginx.old ##将之前的版本重命名,做备份
- 复制新版本
[root@server1 ~]# cd nginx-1.19.1/objs/
[root@server1 objs]# ls
autoconf.err nginx ngx_auto_config.h ngx_modules.c src
Makefile nginx.8 ngx_auto_headers.h ngx_modules.o
[root@server1 objs]# cp nginx /usr/local/nginx/sbin/
[root@server1 objs]# cd /usr/local/nginx/sbin/
[root@server1 sbin]# ls
nginx nginx.old
[root@server1 sbin]# ./nginx.old -v ##查看两个版本是否和预期的一致
nginx version: nginx/1.18.0
[root@server1 sbin]# ./nginx -v
nginx version: nginx/1.19.1
当新的版本已经准备好之后,先检测以下当前运行的版本是否还是为未升级之前的版本;用命令 curl -I localhost
[root@server1 sbin]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Wed, 09 Jun 2021 13:23:29 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 8
Connection: keep-alive
Last-Modified: Wed, 09 Jun 2021 13:01:04 GMT
ETag: "8-5c454de0936a0"
Accept-Ranges: bytes
然后查看当前版本所开启的进程号端口信息;
[root@server1 sbin]# ps ax| grep nginx
4963 ? Ss 0:00 nginx: master process /usr/local/nginx/sbin/nginx
6438 ? S 0:00 nginx: worker process
6439 ? S 0:00 nginx: worker process
13741 pts/0 S+ 0:00 grep --color=auto nginx
- 升级新程序
在升级之前,为了避免下线,应该先开启新的进程,然后在关闭之前的进程即可升级完毕;
[root@server1 sbin]# kill -USR2 4963 ##开启接管 4963 的新进程
[root@server1 sbin]# ps ax| grep nginx
此时虽然准备接管的新进程已经开启,但是数据还是在之前的版本上;需要将之前的结束掉;
[root@server1 sbin]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Sun, 25 Apr 2021 09:43:05 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 8
Connection: keep-alive
Last-Modified: Sun, 25 Apr 2021 08:40:24 GMT
ETag: "8-5c0c7faec7678"
Accept-Ranges: bytes
用命令 kill -WINCH 4963
来结束之前的进程,此时新进程会自动接管;
[root@server1 sbin]# kill -WINCH 4963
[root@server1 sbin]# ps ax| grep nginx
4963 ? Ss 0:00 nginx: master process /usr/local/nginx/sbin/nginx
##此时之前版本的子进程都已经结束,主进程还在是为了版本的回退
13821 ? S 0:00 nginx: master process /usr/local/nginx/sbin/nginx
13822 ? S 0:00 nginx: worker process
13823 ? S 0:00 nginx: worker process
13976 pts/0 S+ 0:00 grep --color=auto nginx
[root@server1 sbin]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.19.1 ##此时版本已经更新
Date: Sun, 25 Apr 2021 09:45:14 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 8
Connection: keep-alive
Last-Modified: Sun, 25 Apr 2021 08:40:38 GMT
ETag: "8-5c0c7fbc78c68"
Accept-Ranges: bytes
- 版本回退
在做版本回退时,我们还是要先把 /usr/local/nginx/sbin/
目录中的程序更改回原来的,然后再做进程的切换;
[root@server1 sbin]# ls
nginx nginx.old
[root@server1 sbin]# mv nginx nginx.new
[root@server1 sbin]# ls
nginx.new nginx.old
[root@server1 sbin]# mv nginx.old nginx
[root@server1 sbin]# ls
nginx nginx.new
#至此新版本为 nginx.new 之前的版本为 nginx
当更改完程序之后,由于之前的版本的主进程还在,用命令 kill -HUP 4963
来唤醒原进程时直接用来开启子进程,然后做切换就可以了;
[root@server1 sbin]# kill -HUP 4963
[root@server1 sbin]# ps ax| grep nginx
[root@server1 sbin]# kill -WINCH 13821
##结束新版本主进程,回退至之前的版本
[root@server1 sbin]# ps ax| grep nginx
[root@server1 sbin]# curl -I localhost
先开启之前版本的进程;
然后结束新版本的进程,回退至老版本;
当确认不需要版本回退时,便可以将之前的主进程 kill 掉就可以了。
3. nginx 的虚拟主机
- nginx的虚拟主机
[root@server1 conf]# pwd
/usr/local/nginx/conf
[root@server1 conf]# vim nginx.conf
48
49 location / {
50 root html;
51 index index.html index.htm; ##删除 php 的发布页面,访问 ip 时访问的是 html
52 }
53
54 #location / {
55 # proxy_pass http://westos;由于在最后写了,此处的便可以删除或者注释掉
56 #}
127 server { ##在最下方写入新的 server 语句块
128 listen 80; ##监听端口
129 server_name www.westos.org; ##域名
130
131 location / {
132 proxy_pass http://westos;当访问域名时做负载均衡
133 }
[root@server1 conf]# nginx -s reload
在当前主机中测试一下,当访问本机时默认访问的是 html 的发布页面;
[root@server1 conf]# curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
在另外的测试主机中来做测试;先写入解析:
[root@foundation39 ~]# vim /etc/hosts
[root@foundation39 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.25.1 server1 www.westos.org
172.25.25.2 server2
172.25.25.3 server3
172.25.25.4 server4
172.25.25.5 server5 mfsmaster
172.25.25.6 server6
172.25.25.7 server7
172.25.25.8 server8
在访问 nginx 虚拟主机的域名时,会被负载均衡调度到后端;
在来一个虚拟主机;编辑配置文件,修改文件内容在做测试:
[root@server1 conf]# vim nginx.conf
136 server {
137 listen 80;
138 server_name www.linux.org;
139
140 location / {
141 root /web1;
142 index index.html; ##当访问域名时会看到写入的发布内容
143 }
144 }
[root@server1 conf]# mkdir /web1
##新建发布目录和写入发布内容
[root@server1 conf]# cd /web1
[root@server1 web1]# vim index.html
[root@server1 web1]# cat index.html
web1
写入解析之后,再次测试:
- htpp 的测试
继续编辑配置文件:
[root@server1 conf]# vim nginx.conf
108 server {
109 listen 443 ssl;
110 server_name localhost;
111
112 ssl_certificate cert.pem;
113 ssl_certificate_key cert.pem;
114
115 ssl_session_cache shared:SSL:1m;
116 ssl_session_timeout 5m;
117
118 ssl_ciphers HIGH:!aNULL:!MD5;
119 ssl_prefer_server_ciphers on;
120
121 location / {
122 root html;
123 index index.html index.htm;
124 }
125 }
仿照机构授权:
[root@server1 conf]# cd /etc/pki/tls/certs/
[root@server1 certs]# ls
ca-bundle.crt ca-bundle.trust.crt make-dummy-cert Makefile renew-dummy-cert
[root@server1 certs]# make cert.pem ##建立认证
umask 77 ; \\
PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` ; \\
PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` ; \\
/usr/bin/openssl req -utf8 -newkey rsa:2048 -keyout $PEM1 -nodes -x509 -days 365 -out $PEM2 ; \\
cat $PEM1 > cert.pem ; \\
echo "" >> cert.pem ; \\
cat $PEM2 >> cert.pem ; \\
rm -f $PEM1 $PEM2
Generating a 2048 bit RSA private key
..+++
.................................................................................+++
writing new private key to '/tmp/openssl.uWPPld'
-----
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) []:shaanxi
Locality Name (eg, city) [Default City]:xi'an
Organization Name (eg, company) [Default Company Ltd]:westos
Organizational Unit Name (eg, section) []:linux
Common Name (eg, your name or your server's hostname) []:server1
Email Address []:westos@westos.org
[root@server1 certs]# mv cert.pem /usr/local/nginx/conf/ ##将认证移动至配置文件所在的目录
[root@server1 certs]# nginx -t ##检测语法
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@server1 certs]# nginx -s reload ##重载
[root@server1 certs]# netstat -antlp | grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* 以上是关于电商平台 lnmp 架构之 nginx 优化的主要内容,如果未能解决你的问题,请参考以下文章
电商平台 lnmp 架构之 mysql 高速缓存--redis