首页 > 技术文章 > Nginx

xk-xk 2022-01-25 23:27 原文

Nginx介绍

Nginx简介

  • Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的。从2004年发布至今,凭借 开源的力量, 已经接近成熟与完善。
  • Nginx功能丰富,可作为HTTP服务器,也可作为反向代理服务器,邮件服务器。支持FastCGI、 SSL、Virtual Host、URL Rewrite、Gzip等功能。并且支持很多第三方的模块扩展。
  • 官方:http://www.nginx.org/

Nginx特点

  • 支持高并发,消耗内存资源少
  • 具有多种功能
    • 网站web服务功能
    • 网站负载均衡功能
    • 正向代理反向代理
  • 网站缓存功能
  • 在多种系统平台都可以部署
  • nginx实现网络通讯时使用的是异步网络IO模型:epoll模型,参考博客:https://segmentfault.co m/a/1190000003063859#item-3-13

工作原理

  • Nginx由内核和一系列模块组成,内核提供web服务的基本功能,如启用网络协议,创建运行环境,接 收和分配客户端请求,处 理模块之间的交互。Nginx的各种功能和操作都由模块来实现。Nginx的模块从结构上分为核心模块、基础模块和第三方模块。
  • 1)核心模块: HTTP模块、EVENT模块和MAIL模块
  • 2)基础模块: HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块
  • 3)第三方模块: HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块及用 户自己开发的模块

Nginx架构和进程

Nginx架构

Nginx服务部署安装

yum安装

  • yum安装,安装前需要先安装扩展源
[root@VM-12-6-centos ~]# yum install -y epel-release.noarch
[root@VM-12-6-centos ~]# yum install -y nginx
  • 启动nginx
[root@VM-12-6-centos ~]# systemctl start nginx.service
[root@VM-12-6-centos ~]# systemctl status nginx.service
/usr/sbin/nginx

重启:nginx -s reload
关闭:nginx -s stop
不能混合使用
pkill nginx

image-20220125101414210

  • 关闭防火墙和selinux
systemctl stop firewalld.service
setenforce 0

结构介绍

配置文件

[root@VM-12-6-centos nginx]# cp nginx.conf{,.bak}
[root@VM-12-6-centos nginx]# grep -Ev "#|^$" /etc/nginx/nginx.conf.bak > /etc/nginx/nginx.conf
[root@VM-12-6-centos nginx]# cat /etc/nginx/nginx.conf.bak | grep -Ev "#|^$"
=====================第一个部分,配置文件的主区域===main模块=============
user nginx;    # 定义worker进程的管理用户
worker_processes auto;   # 定义worker进程数,auto会自动调整为CPU核数
error_log /var/log/nginx/error.log;  # 定义错误日志
pid /run/nginx.pid;   # 定义pid文件
include /usr/share/nginx/modules/*.conf;  
=====================第二个部分,配置文件的事件区域==多进程多线程=========
events {
    worker_connections 1024;
}
# 一个worker进程最大能够处理的请求数  
# 定义一个worker进程可以同时接受1024个请求
=====================第三个部分,配置文件的http区域====================
http {
    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  /var/log/nginx/access.log  main; # 指定日志文件路径
    sendfile            on; 
# 允许sendfile方式传输文件 ,sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝。
    tcp_nopush          on;
# 在sendfile启动下,使用TCP_CORK套接字,当有数据时,先别着急发送, 确保数据包已经装满数据, 避免了网络拥塞
    tcp_nodelay         on; # 接连接保持活动状态,有数据包就发,二选一
    keepalive_timeout   65; # 超时时间
    types_hash_max_size 4096; # 连接超时时间
    include             /etc/nginx/mime.types;
    # 文件扩展名与文件类型映射表
    default_type        application/octet-stream;
    # 默认文件类型,默认为text/plain
    include /etc/nginx/conf.d/*.conf;
    server {
        listen       80;  # 指定监听的端口
        listen       [::]:80;
        server_name  _;   # 指定网站主机名
        root         /usr/share/nginx/html;  # 定义站点目录的位置
        include /etc/nginx/default.d/*.conf;  # 定义首页文件
        error_page 404 /404.html;
        location = /404.html {
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
}

image-20220125141436202

log_format日志格式说明

$remote_addr与$http_x_forwarded_for:用以记录客户端的ip地址
$remote_user:用来记录客户端用户名称
$time_local:用来记录访问时间与时区
$request:用来记录请求的url与HTTP协议
$status:用来记录请求状态;成功是200
$body_bytes_sent:记录发送给客户端文件主体内容大小
$http_referer:用来记录从哪个页面链接访问过来的
$http_user_agent:记录客户端浏览器的相关信息

location表达式

  • ~表示执行一个正则匹配,区分大小写
  • ~*表示执行一个正则匹配,不区分大小写
  • ^~表示普通字符匹配。使用前缀匹配,如果匹配成功,则不再匹配其他location
  • =进行普通字符精准匹配,也就是完全匹配
  • @它定义一个命名的location,使用在内部定向时,例如error_page,try_files
  • 优先级:=/^/,~*/常规字符串
location = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}

location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}
A:请求 /
B: 请求 index.html
C: 请求 /documents/document.html
D: 请求 /images/1.jpg
E: 请求 /documents/document.gif

客户端相关配置

keepalive_timeout   # 保持连接的超时时长
keepalive_requests  # 一次连接允许请求资源的最大数量
keepalive_disable  # 对某种浏览器禁用长连接
send_timeout  # 向客户端发送响应报文的超时时长
client_body_buffer_size  # 接收客户端请求报文的body部分的缓冲区大小
client_body_temp_path
# 设定用于存储客户端请求报文的body部分的临时存储路径及子目录结构和数量
limit_rate # 限制响应给客户端的传输速率
limit_except # 限制对指定的请求方法之外的其它方法的使用客户端

日志切割

  1. /etc/logrotate.d/nginx:可以实现日志切割

  2. 日志切割方式一

    1. mv /var/log/nginx/access.log /var/log/nginx/access_$(date +%F).log
    2. 重启nginx systemctl restart nginx
    3. 可以写入脚本并进行日志轮询
  3. 日志切割方式二,使用专用的文件切割程序--logrotate

[root@localhost logrotate.d]# cat /etc/logrotate.conf
# see "man logrotate" for details
# rotate log files weekly
weekly # 定义默认日志切割周期
# keep 4 weeks worth of backlogs
rotate 4 # 定义只保留几个切割后的文件
# create new (empty) log files after rotating old ones
create # 切割后创建出一个相同的源文件,后面可以跟上文件权限、属主、属组
# use date as a suffix of the rotated file
dateext # 定义角标,扩展名称信息
# uncomment this if you want your log files compressed
#compress # 是否对切割后的文件进行压缩处理
# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp and btmp -- we'll rotate them here
/var/log/wtmp { 	# 当都对某个文件进行切割配置
monthly
create 0664 root utmp
minsize 1M
rotate 1
}
/var/log/btmp {
missingok
monthly
create 0600 root utmp
rotate 1
}

搭建一个网站

  • 编写虚拟主机配置文件
[root@VM-12-6-centos nginx]# cd conf.d/
[root@VM-12-6-centos conf.d]# vim www.conf
server{
        listen          *:8080;
        server_name www.xkxk.com;
        location / {
        root /usr/share/nginx/html;
        index xkxk.html;
}
}
  • 编写网站代码
[root@VM-12-6-centos nginx]# vim xkxk.html
OK啦,好兄弟!
  • 赋予网站代码权限
[root@VM-12-6-centos nginx]# chown 777 xkxk.html
  • 编写hosts文件,做好域名解析((如果windows需要访问也要在这个目录下的hosts文件做相同操作 C:\Windows\System32\drivers\etc)
[root@VM-12-6-centos conf.d]# vim /etc/hosts

101.43.86.75  www.xkxk.com
  • 重启nginx服务(使用reload平滑重启,以下两种方式不能混用)
[root@VM-12-6-centos conf.d]# systemctl reload nginx.service
[root@VM-12-6-centos conf.d]# nginx -s reload
  • 访问测试
root@VM-12-6-centos conf.d]# ss -tnl
State       Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN      0      128     *:8080                *:*                  
LISTEN      0      128     *:80                  *:*  

[root@VM-12-6-centos conf.d]# curl www.xkxk.com:8080
OK啦,好兄弟!

搭建多个网站

  • 准备好配置文件
[root@VM-12-6-centos conf.d]# ll
总用量 12
-rw-r--r--. 1 root root 107 9月 25 16:45 bbs.conf
-rw-r--r--. 1 root root 109 9月 25 16:45 blog.conf
-rw-r--r--. 1 root root 107 9月 25 16:44 www.conf
[root@VM-12-6-centos conf.d]# cat *.conf
server {
listen *:8080;
server_name bbs.eagle.com;
location / {
root /html/bbs;
index index.html;
}
}
server {
listen *:8080;
server_name blog.eagle.com;
location / {
root /html/blog;
index index.html;
}
}
server {
listen *:8080;
server_name www.eagle.com;
location / {
root /html/www;
index index.html;
}
}
  • 准备站点目录以及首页文件
[root@VM-12-6-centos conf.d]# mkdir -p /html/{www,bbs,blog}
[root@VM-12-6-centos conf.d]# for name in {www,bbs,blog};do echo "<h1> $name </h1>" >/html/$name/index.html;done;
  • 重启nginx
1 [root@VM-12-6-centos conf.d]# systemctl reload nginx.service
  • 访问测试
[root@VM-12-6-centos conf.d]# curl www.eagle.com:8080<h1> www </h1>
[root@VM-12-6-centos conf.d]# curl bbs.eagle.com:8080<h1> bbs </h1>
[root@VM-12-6-centos conf.d]# curl blog.eagle.com:8080<h1> blog </h1>

Nginx相关模块

https://nginx.org/en/docs/

模块参考

ngx_http_access_module

  • 实现基于ip的访问控制功能
  • 代码实例
server{
	...
	deny 192.168.1.1;
	allow 192.168.1.0/24;
	allow 10.1.1.0/16;
	allow 2001:0db8::/32;
	deny all;
}

ngx_http_auth_basic_module

  • 使用基于用户的访问控制,使用basic机制进行用户认证
  • 代码实例
location / {
	auth_basic		"closed site"
	auth_basic_user_file conf/htpasswd;
}
htpasswd -bc /etc/nginx/conf/htpasswd admin 123546
将文件权限改为600观察现象
  • htpasswd工具介绍

    yum install httpd-tools.x86_64 -y

    • -c:创建一个密码文件
    • -n:不会更新文件,显示文件内容信息
    • -b:免交互式输入用户密码信息
    • -l:读取密码采用标准输入方式,并不做检查
    • -m:使用md5的加密算法
    • -B:使用bcrypt对密码进行加密
    • -C:使用bcrypt algorithm对密码进行加密
    • -d:密码加密方式
    • -s:加密方式
    • -P:不进行加密
    • -D:删除指定用户

ngx_httpd_stub_startus_module模块

  • 相关日志的设置
  • 代码实例
log_format compression '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';

access_log /spool/logs/nginx-access.log compression buffer=32k;

ngx_http_gzip_module模块

  • 使用gzip方式压缩响应的过滤器
  • 代码实例
gzip on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain application/xml;

ngx_http_ssl_module模块

  • 定义HTTPS的相关配置
  • 代码实例
http {
...
	server {
		listen 443 ssl;
		keepalive_timeout 70;
		ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
		ssl_ciphers AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
		ssl_certificate /usr/local/nginx/conf/cert.pem;
		ssl_certificate_key /usr/local/nginx/conf/cert.key;
		ssl_session_cache shared:SSL:10m;
		ssl_session_timeout 10m;
		...
	}

自签名证书

  • 生成ca证书
cd /apps/nginx
mkdir certs && cd certs
openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -
out ca.crt
  • 生成证书请求文件
openssl req -newkey rsa:4096 -nodes -sha256 -keyout iproute.cn.key -out
iproute.cn.csr
  • 签发证书
openssl x509 -req -days 36500 -in iproute.cn.csr -CA ca.crt -CAkey ca.key -
CAcreateserial -out iproute.cn.crt
cat iproute.cn.crt ca.crt > iproute.crt
  • 验证证书内容
openssl x509 -in iproute.cn.crt -noout -text

Nginx证书配置

server {
	listen 80;
	listen 443 ssl;
	ssl_certificate /apps/nginx/certs/iproute.crt;
	ssl_certificate_key /apps/nginx/certs/iproute.cn.key;
	ssl_session_cache shared:sslcache:20m;
	ssl_session_timeout 10m;
	root /data/nginx/html;
}

ngx_http_rewrite_module模块

  • 将用户请求的URL基于regex所描述的模式进行检查,而后完成替换

ngx_http_referer_module模块

  • 定义referer首部的合法可用值

Nginx代理

介绍

反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内 部网络上的服务 器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器 对外就表现为一个反向代理服务 器,通常使用到的http/https协议和fastgci(将动态内容和http服务器 分离)

代理相关模块及配置

  • nginx代理基于ngx_http_proxy_module模块的功能,该模块有很多配置指令:

正向代理

  1. resolver:指定dns服务器地址

  2. proxy_pass:代理到的地址

  3. resolver_timeout:dns解析超时时长

案例

  • 添加配置文件
[root@VM-12-6-centos ~]# cat /etc/nginx/conf.d/www.conf
server{
	listen *:8090;
	resolver 114.114.114.114;
	location / {
		proxy_pass http://$http_host$request_uri;
	}
}
  • 重启nginx
  • 测试

方法一:

[root@VM-12-6-centost ~]# curl -x 192.168.80.10:8090 "http://www.baidu.com" -I
HTTP/1.1 200 OK
Server: nginx/1.20.1
Date: Wed, 21 Jul 2021 06:16:29 GMT
Content-Type: text/html
Content-Length: 277
Connection: keep-alive
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Etag: "575e1f60-115"
Last-Modified: Mon, 13 Jun 2016 02:50:08 GMT
Pragma: no-cache

方法二;

[root@VM-12-6-centost ~]# export http_proxy=http://192.168.80.10:8090

反向代理相关指令

1.proxy_pass指令

Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except
http://localhost:8000/uri/
http://192.168.56.11:8000/uri/
http://unix:/tmp/backend.socket:/uri/

其中,URL为要设置的被代理服务器的地址,包含传输协议、主机名称或ip地址+端口号等元素。当URL 中不包含URI时,nginx服务器将不改变源地址中的URI,当URL中包含URI时,服务器将会改变源地址中 的URI;

2.proxy_set_header指令

Syntax: proxy_set_header field value;
Default: proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context: http, server, location
# 用户请求的时候HOST的值是www.eagleslab.com, 那么代理服务会像后端传递请求的还是
eagleslab
proxy_set_header Host $http_host;
# 将$remote_addr的值放进变量X-Real-IP中,$remote_addr的值为客户端的ip
proxy_set_header X-Real-IP $remote_addr;
# 客户端通过代理服务访问后端服务, 后端服务通过该变量会记录真实客户端地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

该指令可以更改nginx服务器接收到的客户端请求的请求头信息,然后将新的请求头发送给被代理的服务 器

3.proxy_connect_timeout

Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location

该指令配置nginx服务器与后端被代理服务器尝试建立连接的超时时间

4.proxy_read_timeout

Syntax: proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location

该指令配置nginx服务器向后端被代理服务器发出read请求后,等待响应的超时时间

5.proxy_send_timeout

Syntax: proxy_send_timeout time;
Default: proxy_send_timeout 60s;
Context: http, server, location

该指令配置nginx服务器向后端被代理服务器发出write请求后,等待响应的超时时间

6.proxy_buffering

Syntax: proxy_buffering on | off;
Default: proxy_buffering on;
Context: http, server, location

该指令nginx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端,边收边传,不是全部接收完 再传给客户端

7.proxy_buffer_size

Syntax: proxy_buffer_size size;
Default: proxy_buffer_size 4k|8k;
Context: http, server, location

该指令设置nginx代理保存用户头信息的缓冲区大小

8.proxy_buffers 缓冲区

Syntax: proxy_buffers number size;
Default: proxy_buffers 8 4k|8k;
Context: http, server, location

以上是常见的代理配置指令,除此之外还有很多,诸位可以自行探究

推荐阅读