Nginx 服务详解,从2004年发布至今


文章目录

  • 前言
  • 1. Nginx 概述
    • 1.1 nginx 特点
    • 1.2 nginx 与 apache 的差异
  • 2. Nginx 编译安装与服务控制
    • 2.1 编译安装过程
    • 2.2 nginx 服务控制
    • 2.3 nginx 注册系统服务
    • 2.4 一键编译安装脚本
  • 3. Nginx 配置文件
    • 3.1 nginx.conf 概述
    • 3.2 nginx.conf 模块详解
      • (1) 全局模块
      • (2) events 模块
      • (3) HTTP 模块
        • ① 日志格式设定
        • ② location 配置
      • (4) server 块
      • (5) location 块
  • 4. Nginx 访问控制
    • 4.1 访问状态统计
    • 4.2 基于授权的访问控制
    • 4.3 基于客户端的访问控制 -- 黑名单白名单
  • 5. Nginx 虚拟主机
    • 5.1 基于域名的 nginx 虚拟主机
    • 5.2 基于 IP 的 nginx 虚拟主机
    • 5.3 基于端口的 nginx 虚拟主机


前言

  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 相对一般


nginx Andrew Alexeev

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/
cd /opt/nginx-1.12.2

./configure \
--prefix=/usr/local/nginx \		#指定 nginx 的安装路径
--user=nginx \					#指定用户名
--group=nginx \					#指定组名
--with-http_stub_status_module	#启用 http_stub_status_module 模块以支持状态统计

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 虚拟主机

  虚拟主机使用的是特殊的软硬件技术,它把一台运行在因特网上的服务器主机分成一台台 虚拟 的主机,每台虚拟主机都可以是一个独立的网站,可以具有独立的域名,具有完整的 Intemet 服务器功能(WWW、FTP、Email 等),同一台主机上的虚拟主机之间是完全独立的。从网站访问者来看,每一台虚拟主机和一台独立的主机完全一样。

  利用虚拟主机,不用为每个要运行的网站提供一台单独的 Nginx 服务器或单独运行一组 Nginx 进程。虚拟主机提供了在同一台服务器、同一组 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 学习总结
正反代理与负载均衡

相关内容