Nginx由内核和模块组成。Nginx本身做的工作实际很少, 当它接到一个HTTP请求时, 它仅仅是通过查找配置文件将此次请求映射到一个location block, 而此location中所配置 的各个指令则会启动不同的模块去完成工作, 因此模块可以看做Nginx真正的劳动工作者。 通常一个location中的指令会涉及一个handler模块和多个filter模块(当然, 多个location 可以复用同一个模块) 。handler模块负责处理请求, 完成响应内容的生成, 而filter模块对 响应内容进行处理。
用户根据自己的需要所开发的模块都属于第三方模块。正是有了这么多模块的支撑,Nginx的功能才会如此强大。 Nginx的模块从结构上分为核心模块、基础模块和第三方模块:
核心模块:HTTP模块、EVENT模块和MAIL模块;
基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块;
第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP AccessKey模块。
Nginx的模块从功能上分为如下三类:
Handlers(处理器模块) :此类模块直接处理请求, 并进行输出内容和修改headers 信息等操作。Handlers处理器模块一般只能有一个;
Filters(过滤器模块) :此类模块主要对其他处理器模块输出的内容进行修改操作, 最后由Nginx输出;
Proxies(代理类模块) :此类模块是Nginx的HTTP Upstream之类的模块, 这些 模块主要与后端一些服务比如FastCGI等进行交互, 实现服务代理和负载均衡等 功能。
(1)、先搭建Nginx
############Nginx搭建###########
[root@localhost opt]# tar xzvf nginx-1.15.9.tar.gz
[root@localhost nginx-1.15.9]# useradd -M -s /bin/nologin nginx
[root@localhost opt]# yum -y install gcc gcc-c++ make pcre-devel zlib-devel
[root@localhost opt]# cd nginx-1.15.9/
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module
[root@localhost opt]# make -j3 && make install
#########优化路径#########
[root@localhost nginx-1.15.9]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
[root@localhost nginx-1.15.9]# ls -l /usr/local/sbin/nginx
[root@localhost nginx-1.15.9]# nginx -t ### 检查配置文件
#########启动、重新配置、停止Nginx############
[root@localhost nginx-1.15.9]# nginx
[root@localhost ~]# killall -s HUP nginx
[root@localhost ~]# killall -s QUIT nginx
#########添加Nginx系统服务##########
[root@localhost ~]# vi /lib/systemd/system/nginx.service
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/bin/kill -s HUP $MAINPID
ExecStop=/usr/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
[root@localhost ~]# chmod 754 /lib/systemd/system/nginx.service
[root@localhost ~]# systemctl enable nginx.service
[root@localhost ~]# systemctl start nginx
(2)、隐藏版本号
##########隐藏版本号################
[root@localhost ~]# curl -I http://20.0.0.6 ### 查看网站版本号
HTTP/1.1 200 OK
Server: nginx/1.15.9 ### 版本号
Date: Sun, 06 Sep 2020 05:52:47 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Sun, 06 Sep 2020 05:47:40 GMT
Connection: keep-alive
ETag: "5f5477fc-264"
Accept-Ranges: bytes
隐藏Nginx版本号有两种方式:
第一种是修改Nginx源码文件,指定不显示版本号
第二种是修改Nginx的主配置文件
1、修改配置文件方式
将Nginx的配置文件中的server_tokens选项值设置为off,如果有该配置项,加上即可
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf
http {
include mime.types;
default_type application/octet-stream;
server_tokens off; ###此处新增代码,含义是将版本号关闭
[root@localhost ~]# 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@localhost ~]# systemctl restart nginx.service ### 重启服务
测试:然后用Wireshark抓包软件抓包测试一下,版本号应该隐藏了。
2、设置版本信息
Nginx源码文件/opt/nginx-1.15.9/src/core/nginx.h包含了版本信息,可以随意设置,然后重新编译安装,隐藏版本信息。
[root@localhost ~]# vi /opt/nginx-1.15.9/src/core/nginx.h
#define NGINX_VERSION "1.1.1" ### 修改版本号
#define NGINX_VER "IIS" NGINX_VERSION ### 修改服务器类型
[root@localhost ~]# cd /opt/nginx-1.15.9/
[root@localhost nginx-1.15.9]#
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module
[root@localhost nginx-1.15.9]# make -j3 && make install
[root@localhost nginx-1.15.9]# cd /usr/local/nginx/conf/
[root@localhost conf]# vi nginx.conf
http {
include mime.types;
default_type application/octet-stream;
server_tokens on; ### 打开版本号
[root@localhost conf]# systemctl restart nginx.service ###重启
###########测试一下版本号和服务器类型更改了没################
[root@localhost conf]# curl -I http://20.0.0.6
HTTP/1.1 200 OK
Server: IIS 1.1.1 ### 版本号和服务器类型已经更改
Date: Sun, 06 Sep 2020 06:34:21 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Sun, 06 Sep 2020 06:14:14 GMT
Connection: keep-alive
ETag: "5f547e36-264"
Accept-Ranges: bytes
(3)、修改用户与组
1、指定用户与组参数
[root@localhost ~]# cd /opt/nginx-1.15.9/
[root@localhost nginx-1.15.9]#
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module
2、配置用户与组
修改Nginx配置文件的Nginx指定用户与组
[root@localhost opt]# cd /usr/local/nginx/conf/
[root@localhost conf]# vi nginx.conf
user nginx nginx; ### 修改用户为nginx,组为nginx
[root@localhost conf]# systemctl restart nginx
[root@localhost conf]# ps aux |grep nginx
root 23044 0.0 0.0 20560 628 ? Ss 02:40 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 23045 0.0 0.0 23100 1396 ? S 02:40 0:00 nginx: worker process
root 23059 0.0 0.0 112708 976 pts/0 S+ 02:41 0:00 grep --color=auto nginx
(4)、配置网页缓存时间
以图片作为缓存对象,上传51xit.jpg图片到/usr/local/nginx/html的工作目录,访问http://20.0.0.6/51xit.jpg,用wireshark工具进行抓包,查看响应报文,没有图片的缓存信息查看报文没有缓存信息。
1、修改Nginx的配置文件,在新location段加入expires参数,指定缓存的时间1d一天
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf
location ~ \.(gif|jpg|jepg|png|bmp|ico)$ {
root html;
expires 1d; ### 指定缓存时间1天
}
2、重启Nginx服务,访问wireshark抓包
[root@localhost ~]# systemctl restart nginx ### 重启nginx服务
测试:在/usr/local/nginx/html里面添加一张51xit.jpg图片,然后wireshark抓包查看一下缓存时间对不对
(5)、日志分割
日志切割 随着Nginx运行时间的增加, 产生的日志也会逐渐增加,为了方便掌握Nginx的运行 状态, 需要时刻关注Nginx日志文件。太大的日志文件对监控是一个大灾难,不便于分析排查,需要定期的进行日志文件的切割。
编写脚本/opt/feng e.sh
把Nginx的日志文件/usr/local/ng in x/logs/access.log移动到, 目录/var/log/ng in x下面, 以当前时间做为日志文件的名称, 然后用kill-USR1创建新的日志文件/usr/local/nginx/logs/access.log, 最后删除30天之前的日志文件。
[root@localhost ~]# vi /opt/fenge.sh
#!/bin/bash
#Filename: fenge.sh
d=$(date -d "-1 day" "+%Y%m%d")
logs_path="/var/log/nginx"
pid_path="/usr/local/nginx/logs/nginx.pid"
[ -d $logs_path ] || mkdir -p $logs_path
mv /usr/local/nginx/logs/access.log ${logs_path}/test.com-access.log-$d
kill -USR1 $(cat $pid_path)
find $logs_path -mtime +30 |xargs rm -rf
[root@localhost ~]# chmod +x /opt/fenge.sh ###给执行权限
[root@localhost opt]# ./fenge.sh ### 执行分割脚本
[root@localhost opt]# ls /var/log/nginx/
test.com-access.lo test.com-access.log-20200905 ###按日期分割了日志文件
[root@localhost opt]# cat /usr/local/nginx/logs/access.log ###原来的位置文件重新创建
########设置crotab任务,定期执行脚本自动进行日志分割#########
[root@localhost opt]# crontab -e
30 1 * * * /opt/fenge.sh
(6)、设置连接超时
在企业网站中,为了避免同一个客户长时间占用连接,造成资源浪费,可设置相应的连 接超时参数, 实现控制连接访问时间。可以修改配置文件nginx.conf, 设置keepalive_timeout 超时时间。
[root@localhost opt]# vi /usr/local/nginx/conf/nginx.conf
keepalive_timeout 65 180; ### 默认65秒,设置超时180秒
client_header_timeout 80;
client_body_timeout 80;
[root@localhost opt]# systemctl restart nginx ###重启nginx服务
测试:浏览器输入20.0.0.6,然后wireshark抓包查看一下连接超时时间
Nginx深入优化
(7)、更改进程数
在高并发环境中,需要启动更多的Nginx进程以保证快速响应,用以处理用户的请求,避免造成阻塞。使用ps aux命令查看Nginx运行进程的个数。
[root@localhost ~]# ps aux |grep nginx
root 76128 0.0 0.0 20560 628 ? Ss 03:26 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 76129 0.0 0.0 23100 1652 ? S 03:26 0:00 nginx: worker process
root 76201 0.0 0.0 112708 972 pts/0 S+ 03:33 0:00 grep --color=auto nginx
其中master是Nginx的主进程,开启了1个,worker 是子进程,进程也是开启了1个。
修改Ng in x的配置文件的worker_processes参数, 一般设为CPU的个数或者核数, 在高并发的情况下可设置为CPU个数或者核数的2倍, 可以查看CPU的核数以确定参数
[root@localhost ~]# cat /proc/cpuinfo |grep -c "physical" ###查看CPU的核数以确定参数。
8
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf
worker_processes 8; ###根据刚刚查的核数,把数字改成8.
修改完后,重启服务,使用ps aux查看运行进程数的变化情况。
[root@localhost ~]# ps aux|grep nginx ### 可以看到现在是8个进程
root 76329 0.0 0.0 20560 700 ? Ss 03:40 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 76330 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker process
nginx 76331 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker process
nginx 76332 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker process
nginx 76333 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker process
nginx 76334 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker process
nginx 76335 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker process
nginx 76336 0.0 0.0 23100 1404 ? S 03:40 0:00 nginx: worker process
nginx 76337 0.0 0.0 23100 1404 ? S 03:40 0:00 n
(8)、配置网页压缩
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf
gzip on;
gzip_buffers 4 64k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_min_length 1k;
gzip_vary on;
gzip_types text/plain text/javascript application/x-javascript text/css text/xml application/xml application/xml+rss;
###上面的配置解释###
gzip on:开启gzip压缩输出;
gzip_min_length 1k:用于设置允许压缩的页面最小字节数;
gzip_buffers 416k:表示申请4个单位为16k的内存作为压缩结果流缓存,默认值 是申请与原始数据大小相同的内存空间来存储gzip压缩结果;
Zip_http_version 1.0:用于设置识别http协议版本, 默认是1.1,目前大部分浏览 器已经支持gzip解压,但处理最慢,也比较消耗服务器CPU资源;
Gzip_comp_level 2:用来指定gzip压缩比, 1压缩比最小, 处理速度最快; 9压缩 比最大,传输速度快,但处理速度最慢,使用默认即可;
Gzip_types text/plain:压缩类型, 是对哪些网页文档启用压缩功能;
Gzip_vary on:选项可以让前端的缓存服务器缓存经过gzip压缩的页面
[root@localhost ~]# vi /usr/local/nginx/html/index.html
<h1>xxxxxx</h1> ###在这里面随便加东西,让index.html大于1k就行
测试:浏览器输入20.0.0.6/index.html,然后wireshark抓包查看一下压缩情况。
(9)、配置防盗链
###防盗链需要准备两台主机模拟盗链###
20.0.0.6 www.51xit.top 源主机
20.0.0.5 www.52xit.top 盗链主机
###修改windows的 C:\Windows\System32\drivers\etc\host文件,设置域名和映射关系
20.0.0.6 www.51xit.top
20.0.0.5 www.52xit.top
###在盗链主机的工作目录编写盗链页面index.html,即盗源主机的图片###
[root@localhost ~]# cd /usr/local/httpd/htdocs/
[root@localhost htdocs]# vi index.html
<html>
<head>
<title>--盗图测试--</title>
</head>
<body><h1>盗图页面</h1>
<img src=http://20.0.0.6/51xit.jpg />
</body>
</html>
```bash
测试:浏览器输入20.0.0.5,查看能不能正常盗链
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200906173304830.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDczMzAyMQ==,size_16,color_FFFFFF,t_70#pic_center)
```bash
###在主机配置Nginx防盗链###
[root@localhost ~]# cd /usr/local/nginx/conf/
[root@localhost conf]# vi nginx.conf
location ~* \.(gif|jpg|jepg|png|bmp|ico)$ {
valid_referers none blocked *.51xit.top 51xit.top;
if ($invalid_referer) {
rewrite ^/ https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=202451072,4165552475&fm=26&gp=0.jpg;
}
}
[root@localhost conf]# systemctl restart nginx
(10)、FPM参数优化
####################安装PHP环境#####
yum -y install \
libjpeg \
libjpeg-devel \
libpng libpng-devel \
freetype freetype-devel \
libxml2 \
libxml2-devel \
zlib zlib-devel \
curl curl-devel \
openssl openssl-devel
#######上传php-7.1.10.tar.bz2包到opt目录下#####
cd /opt
tar xjvf php-7.1.10.tar.bz2
cd php-7.1.10
./configure \
--prefix=/usr/local/php \
--with-apxs2=/usr/local/httpd/bin/apxs \
--with-mysql-sock=/usr/local/mysql/mysql.sock \
--with-mysqli \
--with-zlib \
--with-curl \
--with-gd \
--with-jpeg-dir \
--with-png-dir \
--with-freetype-dir \
--with-openssl \
--enable-mbstring \
--enable-xml \
--enable-session \
--enable-ftp \
--enable-pdo \
--enable-tokenizer \
--enable-zip
make -j3 && make install
cp php.ini-development /usr/local/php/lib/php.ini
vi /usr/local/php/lib/php.ini
mysqli.default_socket = /usr/local/mysql/mysql.sock
date.timezone = Asia/Shanghai
[root@localhost php-7.1.10]# /usr/local/php/bin/php -m //验证安装的模块
[root@localhost php-7.1.10]# vi /etc/httpd.conf //在合适位置新增
AddType application/x-httpd-php .php ###添加
AddType application/x-httpd-php-source .phps ###添加
<IfModule dir_module>
DirectoryIndex index.php index.html ###找到这个添加
</IfModule>
[root@localhost php-7.1.10]# rm -f /usr/local/httpd/htdocs/index.html ###删除
[root@localhost php-7.1.10]# vi /usr/local/httpd/htdocs/index.php ###创建新的
<?php
phpinfo();
?>
[root@localhost php-7.1.10]# systemctl restart httpd.service
测试:20.0.0.6
#####FPM参数优化###
[root@localhost php-7.1.10]# cd /usr/local/php/etc/php-fpm.d
[root@localhost etc]# vi www.conf
pm=dynamic
pm.max_children=20
pm.start_servers=5
pm.min_spare_servers=2
pm.max_spare_servers=8
FPM启动时有5个进程,最小空闲2个进程,最大空闲8个进程,最多可以有20个进程存在。
一、pm.max_children多大合适?
这个值原则上是越大越好, php-cgi的进程多了就会处理的很快, 排队的请求就会很少。
设置”max children”也需要根据服务器的性能进行设定。
计算方式如下:
一般来说一台服务器正常情况下每一个php-cgi所耗费的内存在20M~30M左右, 因此我的”max_children”我设置成40个,
20M*40=800M也就是说在峰值的时候所有PHP-CGI所耗内存在800M以内, 低于我的有效内存2Gb。
而如果我的”max_children”设置的较小, 比如5-10个, 那么php-cgi就会“很累“, 处理速度也很慢, 等待的时间也较长,占用的CPU也很高。
如果长时间没有得到处理的请求就会出现504 Gateway Time-out这个错误, 而正在处理的很累的那几个php-cgi如果遇到了问题就会出现502Bad gateway这个错误。
max_children较好的设置方式根据req/s(吞吐率, 单位时间里服务器处理的最大请求数, 单位req/s) 来设置, 若程序是100D req/s的处理能力, 那么就设置100比较好, 这是动态来调整的。