电商平台 lnmp 架构之 nginx 优化

Posted 123坤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了电商平台 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;

  1. 修该配置文件
[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"
  1. 反向代理
    此处再开两台机器来观察实验效果,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
  1. 下载与编译
[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。

  1. 备份之前的数据
[root@server1 sbin]# pwd
/usr/local/nginx/sbin
[root@server1 sbin]# ls
nginx
[root@server1 sbin]# mv nginx nginx.old ##将之前的版本重命名,做备份
  1. 复制新版本
[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
  1. 升级新程序

在升级之前,为了避免下线,应该先开启新的进程,然后在关闭之前的进程即可升级完毕;

[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
  1. 版本回退

在做版本回退时,我们还是要先把 /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 的虚拟主机

  1. 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

写入解析之后,再次测试:

在这里插入图片描述

  1. 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 架构之 nginx+tomcat

电商平台 lnmp 架构之 mysql 优化

电商平台 lnmp 架构之 mysql 优化

电商平台 lnmp 架构之 mysql 高速缓存--redis

电商平台 lnmp 架构之 mysql 高速缓存--redis

LNMP平台搭建及优化