前言
Nginx 是 lgor Sysoev 为俄罗斯访问量第二的 rambler.ru 站点设计开发的。从 2004 年发布至今,凭借开源的力量,已经接近成熟与完善。Nginx 功能丰富,可作为 HTTP 服务器,也可作为反向代理服务器,邮件服务器。支持 FastCGI、SSL、Virtual Host、URL Rewrite、Gzip 等功能,并且支持很多第三方的模块扩展。
1. Nginx 概述
1.1 nginx 特点
nginx 是一款高性能、轻量级的 web 服务软件,具有以下特点:
- 稳定性高
- 系统资源消耗低
- 对 HTTP 并发连接的处理能力高(单台物理服务器可支持 30000~50000 个并发请求)
1.2 nginx 与 apache 的差异
nginx 是一个基于事件的 web 应用,apache 是一个基于流程的应用
nginx 所有请求都由一个线程处理,apache 单个线程处理单个请求
nginx 避免子进程的概念,apache 是基于子进程的
nginx 在内存消耗和连接方面更好,apache 在内存消耗和连接方面一般
nginx 的性能和可伸缩性不依赖于硬件,apache 依赖于 CPU 和内存等硬件
nginx 支持热部署,apache 不支持热部署
nginx 对于静态文件处理具有更高效率,apache 相对一般
nginx 在反向代理场景具有明显优势,apache 相对一般
2. Nginx 编译安装与服务控制
2.1 编译安装过程
安装前准备
systemctl stop firewalld && systemctl disable firewalld
setenforce 0
iptables -F
yum -y install epel-release && yum clean all && yum makecache
安装软件包
yum -y install pcre-devel zlib-devel gcc gcc-c++ make wget
创建运行用户、组
# nginx 服务程序默认以 nobody 身份运行,建议为其创建专门的用户账号,以便更准确地控制其访问权限
useradd -M -s /sbin/nologin nginx
下载安装包
#版本自选
wget http://nginx.org/download/nginx-1.12.2.tar.gz -P /opt
编译安装 nginx
tar xf /opt/nginx-1.12.2.tar.gz -C /opt/
/opt/nginx-1.12.2/configure \
--prefix=/usr/local/nginx \ #指定 nginx 的安装路径
--user=nginx \ #指定用户名
--group=nginx \ #指定组名
--with-http_stub_status_module #启用 http_stub_status_module 模块以支持状态统计
cd /opt/nginx-1.12.2
make -j 4 && make install
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ #优化路径,让系统识别 nginx 的操作命令
启动 nginx
nginx #我们做了软连接到系统路径,执行 nginx 可直接启动 nginx
2.2 nginx 服务控制
检查、启动、重启、停止 nginx 服务
###检查配置文件是否正确
nginx -t
###启动
nginx
###停止
cat /usr/local/nginx/logs/nginx.pid #存放 nginx 进程号的文件
kill -3 <进程号>
kill -s QUIT <进程号>
killall -3 nginx
killall -s QUIT nginx
###重载
kill -1 <进程号>
kill -s HUP <进程号>
killall -1 nginx
killall -s HUP nginx
###日志分隔,重新打开日志文件
kill -USR1 <进程号>
###平滑升级
kill -USR2 <进程号>
2.3 nginx 注册系统服务
方法一:适用于 Centos 6
cat > /etc/init.d/nginx <<EOF
#!/bin/bash
#chkconfig: - 99 20
#description:Nginx Service Control Script
COM="/usr/local/nginx/sbin/nginx"
PID="/usr/local/nginx/logs/nginx.pid"
case "$1" in
start)
$COM
;;
stop)
kill -s QUIT $(cat $PID)
;;
restart)
$0 stop
$0 start
;;
reload)
kill -s HUP $(cat $PID)
;;
*)
echo "Usage:$0 {start|stop|restart|reload}"
exit 1
esac
exit 0
EOF
chmod +x /etc/init.d/nginx
chkconfig --add nginx #添加为系统服务
systemctl stop nginx
systemctl start nginx
方法二:适用于 Centos 7
#注意:如果先去使用 nginx 启动了服务需要先杀掉进程,不然会冲突
cat > /usr/lib/systemd/system/nginx.service <<EOF
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFile =/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecrReload=/bin/kill -s HUP $MAINPID
ExecrStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
chmod 754 /usr/lib/systemd/system/nginx.service #设置 754 权限是一种安全优化
systemctl daemon-reload
systemctl start nginx.service && systemctl enable nginx.service
2.4 一键编译安装脚本
#!/bin/bash
iptables -F
yum -y install epel-release && yum clean all && yum makecache
yum -y install pcre-devel zlib-devel gcc gcc-c++ make wget
useradd -M -s /sbin/nologin nginx
wget http://nginx.org/download/nginx-1.12.2.tar.gz -P /opt
tar zxvf /opt/nginx-1.12.2.tar.gz -C /opt
cd /opt/nginx-1.12.2
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module
cd /opt/nginx-1.12.2
make -j 4 && make install
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
cat > /usr/lib/systemd/system/nginx.service <<EOF
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
PIDFile =/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecrReload=/bin/kill -s HUP $MAINPID
ExecrStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
chmod 754 /usr/lib/systemd/system/nginx.service
systemctl daemon-reload && systemctl start nginx.service && systemctl enable nginx.service
echo " "
pgrep "nginx" &> /dev/null
if [ $? -eq 0 ];then
echo -e "\033[32mnginx服务运行正常,可 curl 查看\033[0m"
else
echo -e "\033[31mnginx服务运行异常,请检查\033[0m"
fi
3. Nginx 配置文件
3.1 nginx.conf 概述
结构图一
结构图二
主配置文件内容
[root@c7-1 ~]#cat /usr/local/nginx/conf/nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
3.2 nginx.conf 模块详解
(1) 全局模块
配置影响 nginx 全局的指令。一般有运行 nginx 服务器的用户组,nginx 进程 pid 存放路径,日志存放路径,配置文件引入,允许生成 worker process 数等。
user nobody; #运行用户,若编译时未指定则默认为 nobody
worker_processes 1; #工作进程数量,可配置成服务器内核数 * 2,如果网站访问量不大,一般设为 1 就够用了
#eror_log logs/error.log; #错误日志文件的位置
#pid logs/nginx.pid; # PID 文件的位置
(2) events 模块
配置影响 nginx 服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
events {
use epoll; #使用 epoll 模型,2.6 及以上版本的系统内核,建议使用 epoll 模型以提高性能
worker_connections 4096; #每个进程处理 4096 个连接
}
- 如提高每个进程的连接数还需执行 “ulimit -n 65535” 命令临时修改本地每个进程可以同时打开的最大文件数
- 在 Linux 平台上进行高并发 TCP 连接处理时,最高的并发数最都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每个 TCP 连接都要创建一个 socket 句柄,每个 socket 句柄同时也是一个文件句柄)
- 可使用 ulimit -a 命令查看系统允许当前用户进程打开的文件数限制
(3) HTTP 模块
可以嵌套多个 server,配置代理、缓存、日志定义等绝大多数功能和第三方模块的配置。如文件引入、mime-type定义、日志自定义、是否使用 sendfile 传输文件、连接超时时间、单连接请求数等。
http {
##文件扩展名与文件类型映射表
include mime.types;
##默认文件类型
default_type application/octet-stream;
##日志格式设定
#log_format main '$remote_ addr - $remote. user [stime_ local] "$request" '
# '$status $body_ bytes_ sent "Shttp_ referer" '
# "$http_user_agent" "$http_x_forwarded_for"';
##访问日志位置
#access_Log logs/access.log main;
#支持文件发送(下载)
sendfile on;
##此选项允许或禁止使用socket的TCP_CORK的选项( 发送数据包前先缓存数据),此选项仅在使用sendfile的时候使用
#tcp_nopush on;
##连接保持超时时间,单位是秒
#keepalive_timeout 0;
keepalive.timeout 65;
##gzip模块设置,设置是否开启gzip压缩输出
#gzip on;
#Web服务的监听配置
##Web服务的监听配置
server (
##监听地址及端口
listen 80;
##站点域名,可以有多个,用空格隔开
server.name www.xcf.com;
##网页的默认字符集
charset utf-8;
##根目录配置
location / {
##网站根目录的位置/usr/local/nginx/html
root html;
##默认首页文件名
index index.html index.php;
}
##内部错误的反馈页面
error_page 500 502 503 504 /50x.html;
#错误页面配置
location = /50x.html {
root html;
}
}
}
① 日志格式设定
日志格式设定:
$remote_addr 与 $http_x_forwarded_for 用以记录客户端的ip地址;
$remote_user: 用来记录客户端用户名称;
$time_local: 用来记录访问时间与时区;
$request: 用来记录请求的 url 与 http 协议;
$status: 用来记录请求状态码,成功是 200;
$body_bytes_sent: 记录发送给客户端文件主体的内容大小;
$http_referer: 用来记录从哪个页面链接访问过来的;
$http_user_agent: 记录客户端浏览器的相关信息;
- 通常 web 服务器放在反向代理的后面,这样就不能获取到客户的 IP 地址了,通过 $remote_add 拿到的 IP 地址是反向代理服务器的 IP 地址
- 反问代理服务器在转发请求的 http 头信息中,可以增加 x_forwarded_for 信息,用以记录原客户端的 IP 地址和原客户端的请求的服务器地址
② location 配置
常见配置指令:root、alias、proxy_pass
root(根路径配置)
#请求 www.test.com/test/1.jpg,会返回文件 /usr/local/nginx/html/test/1.jpg
alias(别名配置)
#请求 www.test.com/test/1.jpg,会返回文件 /usr/local/nginx/html/1.jpg
proxy_pass(反向代理配置)
# proxy_pass http://127.0.0.1:8080/; //转发请求到 http://127.0.0.1:8080/1.jpg
(4) server 块
配置虚拟主机的相关参数,一个 http 中可以有多个 server。
server {
keepalive_requests 120; #单连接请求上限次数
listen 4545; #监听端口
server_name 127.0.0.1; #监听地址
location ~*^.+$ { #请求的 url 过滤,正则匹配,~为区分大小写,~*为不区分大小写
#root path; #根目录
#index vv.txt; #设置默认页
proxy_pass http://mysvr; #请求转向 mysvr 定义的服务器列表
deny 127.0.0.1; #拒绝的 ip
allow 172.18.5.54; #允许的 ip
}
}
(5) location 块
配置请求的路由,以及各种页面的处理情况。
location / {
root html;
index index.html index.htm;
}
location /status {
stub_status on;
access_log off;
}
location ~*^.+$ {
#root path;
#index vv.txt;
proxy_pass http://mysvr;
deny 127.0.0.1;
allow 172.18.5.54;
}
参考:
nginx 网站服务
nginx 服务详细介绍
nginx 配置详解-菜鸟教程
nginx 配置文件(nginx.conf)配置详解
4. Nginx 访问控制
4.1 访问状态统计
查看安装的 nginx 模块是否包含 --with-http_stub_status_module 模块
/usr/local/nginx/sbin/nginx -V 或 nginx -V
修改 nginx.conf 配置文件,添加 stub_status 配置
重启服务,访问测试
systemctl restart nginx
echo "192.168.10.20 www.test.com" >> /etc/hosts
字段含义
Active connections: 1 #当前的活动链接数
server accepts handled requests #已经处理的连接信息
1 1 1 #已处理的连接数、成功的TCP握手次数、已处理的请求数
Reading: 0 Writing: 1 Waiting: 0 #正在读、写以及等待的连接数
使用脚本监控连接数
[root@c7-1 /data]#cat connect.sh
#!/bin/bash
curl -s www.test.com/status > active.txt
connect=$(awk '/Active/ {print $3}' active.txt)
if [ $connect -gt 1 ];then
echo -e "\033[31m当前连接数过高,请注意!\033[0m"
else
echo -e "\033[32m连接数正常\033[0m"
fi
[root@c7-1 /data]#bash connect.sh
连接数正常
4.2 基于授权的访问控制
生成用户密码认证文件
yum -y install httpd-tools
htpasswd -c /usr/local/nginx/passwd.db zhangsan
chown nginx /usr/local/nginx/passwd.db
chmod 400 /usr/local/nginx/passwd.db
修改主配置文件,添加认证配置项
[root@c7-1 ~]#vim /usr/local/nginx/conf/nginx.conf
......
location / {
root html;
index index.html index.htm;
##添加认证配置
auth_basic "secret"; ##设置密码提示框文字信息
auth_basic_user_file /usr/local/nginx/passwd.db;
}
......
重启服务,访问测试
nginx -t
systemctl restart nginx
//使用虚拟机自带的火狐浏览器访问 www.test.com
4.3 基于客户端的访问控制 – 黑名单白名单
访问控制规则如下:
- deny IP/IP段:拒绝某个 IP 或 IP 段的客户端访问
- allow IP/IP段:允许某个 IP 或 IP 段的客户端访问
- 规则从上往下执行,若匹配则停止,不再往下匹配
systemctl restart nginx
#在 192.168.10.30 机器上测试访问
5. Nginx 虚拟主机
5.1 基于域名的 nginx 虚拟主机
为虚拟主机提供域名解析
echo "192.168.10.20 www.test.com www.abc.com" >> /etc/hosts
为虚拟主机准备网页文档
mkdir -p /var/www/html/test
mkdir -p /var/www/html/abc
echo "<h1>www.test.com</h1>" > /var/www/html/test/index.html
echo "<h1>www.abc.com</h1>" > /var/www/html/abc/index.html
修改 nginx.conf 配置文件,添加如下配置
......
server {
listen 80;
server_name www.test.com;
charset utf-8;
access_log logs/test.access.log;
location / {
root /var/www/html/test;
index index.html index.htm;
}
}
server {
listen 80;
server_name www.abc.com;
charset utf-8;
access_log logs/abc.access.log;
location / {
root /var/www/html/abc;
index index.html index.htm;
}
}
......
重启服务,访问测试
nginx -t
systemctl restart nginx
5.2 基于 IP 的 nginx 虚拟主机
添加网卡
ifconfig ens33:0 192.168.10.21 netmask 255.255.255.0
#删除:ifconfig ens33:0 del 192.168.10.21
修改 nginx.conf 配置文件
......
server {
listen 192.168.10.20:80;
server_name www.test.com;
charset utf-8;
access_log logs/test.access.log;
location / {
root /var/www/html/test;
index index.html index.htm;
}
}
server {
listen 192.168.10.21:80;
server_name www.abc.com;
charset utf-8;
access_log logs/abc.access.log;
location / {
root /var/www/html/abc;
index index.html index.htm;
}
}
......
重启服务,访问测试
nginx -t
systemctl restart nginx
5.3 基于端口的 nginx 虚拟主机
修改 nginx.conf 配置文件
......
server {
listen 192.168.10.20:80;
server_name www.test.com;
charset utf-8;
access_log logs/test.access.log;
location / {
root /var/www/html/test;
index index.html index.htm;
}
}
server {
listen 192.168.10.20:8888;
server_name www.abc.com;
charset utf-8;
access_log logs/abc.access.log;
location / {
root /var/www/html/abc;
index index.html index.htm;
}
}
......
重启服务,访问测试
nginx -t
systemctl restart nginx
————————————————————————————————————————————————————————————
参考:
Nginx 学习总结
正反代理与负载均衡