Nginx

https://segmentfault.com/a/1190000003063859#item-3-13

Nginx介绍

Nginx 则是免费的、开源的、⾼性能的HTTP和反向代理服务器、邮件代理服务器、以及TCP/UDP代理服务器 解决C10K问题(10K Connections)
Nginx官⽹:https://nginx.org
Nginx 商业版为Nginx Plus:https://www.nginx.com/products/nginx/

  • nginx的其它的⼆次发⾏版:Tengine:由淘宝⽹发起的Web服务器项⽬。它在Nginx的基础上,针对⼤访问量⽹站的需求,添加了很多⾼级功能和特性。Tengine的性能和稳定性已经在⼤型的⽹站如淘宝⽹,天猫商城等得到了很好的检验。它的最终⽬标是打造⼀个⾼效、稳定、安全、易⽤的Web平台,从2011年12⽉开始,Tengine成为⼀个开源项⽬,官⽹http://tengine.taobao.org/
  • OpenResty:基于 Nginx 与 Lua 语⾔的⾼性能 Web 平台, 章亦春团队开发,官⽹:http://o
    penresty.org/cn/
    Nginx功能介绍
  • 静态的web资源服务器html,图⽚,js,css,txt等静态资源
  • 结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
  • http/https协议的反向代理
  • imap4/pop3协议的反向代理
  • tcp/udp协议的请求转发(反向代理)
    基础特性
  • 模块化设计,较好的扩展性
  • ⾼可靠性 远远超过apache
  • ⽀持热部署:不停机更新配置⽂件,升级版本,更换⽇志⽂件
  • 低内存消耗:10000个keep-alive连接模式下的⾮活动连接,仅需2.5M内存
  • event-driven,aio,mmap(内存映射),sendfile
  • nginx实现网络通讯时使用的是异步网络IO型:epoll模型,参考博客:https://segmentfault.co
    m/a/1190000003063859#item-3-13

web服务相关的功能

虚拟主机(server)
⽀持 keep-alive 和管道连接(利⽤⼀个连接做多次请求)
访问⽇志(⽀持基于⽇志缓冲提⾼其性能)
url rewirte
路径别名
基于IP及⽤⼾的访问控制
⽀持速率限制及并发数限制
重新配置和在线升级⽽⽆须中断客⼾的⼯作进程

Nginx架构和进程

Nginx架构
在这里插入图片描述

Nginx进程结构

  • web请求处理机制
    • 多进程方式:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程响应客户端,直到用户关闭连接,这样的优势是处理速度快。子进程之间相互独立,但是如果访问过大会导致服务器资源耗尽而无法提供请求。
    • 多线程方式:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程来个客户方进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器对系统资源的要求,但是多线程也有自己的缺点。即当多个线程位于同一个进程内工作的时候,可以相互访问同样的内存地址空间,所以他们相互影响,一旦主进程挂掉则所有子线程都不能工作了,IIS服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳
      定。
  • Nginx是多进程组织模型,而且是一个由Master主进程和Worker工作进程组成。但是其实Nginx里也有线程。
    - 主进程(master process)的功能
对外接口:接收外部的操作(信号)
对内转发:根据外部的操作的不同,通过信号管理worker
监控:监控worker进程的运行状态,worker进程异常终止后,自动重启worker进程
读取Nginx配置文件并验证其有效性和正确性
建立、绑定和关闭socket连接
按照配置生成、管理和结束工作进程
接受外界指令,比如重启、升级及退出服务器等指令
不中断服务,实现平滑升级,重启服务并应用新的配置
开启日志文件,获取文件描述符
不中断服务,实现平滑升级,升级失败进行回滚处理
编译和处理perl脚本
  • 工作进程(worker process)的功能:
所有Worker进程都是平等的
实际处理:网络请求,由Worker进程处理
Worker进程数量:在nginx.conf 中配置,一般设置为核心数,充分利用CPU资源,同时,避免
进程数量过多,避免进程竞争CPU资源,增加
上下文切换的损耗
接受处理客户的请求
将请求依次送入各个功能模块进行处理
I/O调用,获取响应数据
与后端服务器通信,接收后端服务器的处理结果
缓存数据,访问缓存索引,查询和调用缓存数据
发送请求结果,响应客户的请求
接收主程序指令,比如重启、升级和退出等

在这里插入图片描述
在这里插入图片描述

Nginx进程间通信

⼯作进程是有主进程⽣成的,主进程由root启用,主进程使⽤fork()函数,在Nginx服务器启动过程中主进程根据配置⽂件决定启动⼯作进程的数量,然后建⽴⼀张全局的⼯作表⽤于存放当前未退出的所有的⼯作进程,主进程⽣成⼯作进程后会将新⽣成的⼯作进程加⼊到⼯作进程表中,并建⽴⼀个单向的管道并将其传递给⼯作进程,该管道与普通的管道不同,它是由主进程指向⼯作进程的单向通道,包含了主进程向⼯作进程发出的指令、⼯作进程ID、⼯作进程在⼯作进程表中的索引和必要的⽂件描述符等信息,单向管道,工作进程只能监听内容之后读取指令。 主进程与外界通过信号机制进⾏通信,当接到需要处理的信号时,它通过管道向相关的⼯作进程发送正确的指令,每个⼯作进程都有能⼒捕获管道中的可读事件,当管道中有可读事件的时候,⼯作进程就会从管道中读取并解析指令,然后采取相应的执⾏动作,这样就完成了主进程与⼯作进程的交互。
⼯作进程之间的通信原理基本上和主进程与⼯作进程之间的通信是⼀样的,只要⼯作进程之间能够取得彼此的信息,建⽴管道即可通信,但是由于⼯作进程之间是完全隔离的,因此⼀个进程想要知道另外⼀个进程的状态信息就只能通过主进程来设置了。
为了实现⼯作进程之间的交互,主进程在⽣成⼯作进程之后,在⼯作进程表中进⾏遍历,将该新进程的ID以及针对该进程建⽴的管道句柄传递给⼯作进程中的其他进程,为⼯作进程之间的通信做准备,当⼯作进程1向⼯作进程2发送指令的时候,⾸先在主进程给它的其他⼯作进程⼯作信息中找到2的进程ID,然后将正确的指令写⼊指向进程2的管道,⼯作进程2捕获到管道中的事件后,解析指令并进⾏相关操作,这样就完成了⼯作进程之间的通信。
在这里插入图片描述既然是单向管道通信,那么主进程怎么知道自己的子进程是不是工作结束,需要的文件是否就绪?

IO多路复用机制

利用IO多路复用机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就
绪),能够通知程序进行相应的读写操作.

文件描述符:https://baike.baidu.com/item/%E6%96%87%E4%BB%B6%E6%8F%8F%E8%BF%B0%E
7%AC%A6/9809582?fr=aladdin
linux:包含进程相关的所有文件描述符:
在这里插入图片描述io模型:https://segmentfault.com/a/1190000003063859#item-3-13
select:轮询,将所有正在监听的文件描述符都放到一个数组里面。文件描述符数组最大为1024
poll:也是轮询,但解决了数组最大1024的问题,因为采用了链表的方式存储
epoll:不需要轮询了,而是触发了event后会自动去通知,基于事件的通知方式
select:数组的方式
对所有的fd进行轮询,把准备好的fd进行标记
在这里插入图片描述poll:链表的方式
也是对所有的fd进行轮询,把准备好的fd标记
在这里插入图片描述Nginx使用的epoll的异步网络IO模型。

连接建立和请求处理过程

  • Nginx启动时,Master 进程,加载配置文件
  • Master进程,初始化监听的socket
  • Master进程,fork 出多个Worker进程
  • Worker进程,竞争新的连接,获胜方通过三次握手,建立Socket连接,并处理请求
  • 在这里插入图片描述

HTTP处理过程

在这里插入图片描述

Nginx模块介绍

  • nginx有多种模块
    • 核心模块:是Nginx服务器正常运行必不可少的模块,提供错误日志记录、配置文件解析、事件驱动机制、进程管理等核心功能
    • 标准HTTP模块:提供HTTP协议解析相关的功能,比如:端口配置、网页编码设置、HTTP响应头设置 等等
    • 可选HTTP模块:主要用于扩展标准的HTTP功能,让Nginx能处理一些特殊的服务, 比如:Flash 多媒体传输、解析GeolP请求、网络传输压缩、安全协议SSL支持等
    • 邮件服务模块:主要用于支持Nginx的邮件服务,包括对POP3协议、IMAP 协议和SMTP协议的支持
    • Stream服务模块:实现反向代理功能包括TCP协议代理
    • 第三方模块:是为了扩展Nginx服务器应用,完成开发者自定义功能,比如: Json支持、 Lua 支持等
  • nginx高度模块化;1.9.11版本支持动态装载和卸载
  • 模块分类:
    • 标准模块
      • HTTP模块:ngx_http_*
        • HTTP Core modules 默认功能
        • HTTP Optional modules 需要编译时指定
      • Mail模块:ngx_mail_*
      • Stream模块:ngx_stream_*
    • 第三方模块
      • https://nginx.org/en/docs/

Nginx安装

nginx安装可以分为yum或者源码安装,但是推荐使用源码编译安装

  • yum的版本比较旧(没有epel-release库根本都没有nginx)
  • 编译安装可以更方便自定义相关路径
  • 使用源码编译可以自定义相关功能,自定义编译的模块,更方便业务的上的使用

基于yum安装的nginx

查看当前系统中的nginx版本

[root@localhost ~]# yum info nginx
[root@localhost ~]# yum install -y epel-release
[root@localhost ~]# yum -y install nginx
[root@localhost ~]# rpm -ql nginx
[root@localhost ~]# systemctl start nginx
[root@localhost ~]# systemctl enable nginx

官方包源码安装nginx
官方包链接

https://nginx.org/en/download.html

查看官方编译指令

[root@localhost ~]# nginx -V

编译安装

从官网获取源码包

[root@localhost ~]# wget https://nginx.org/download/nginx-1.18.0.tar.gz -P
/usr/local/src/
[root@localhost ~]# cd /usr/local/src
[root@localhost src]# tar xzvf nginx-1.18.0.tar.gz
[root@localhost src]# cd nginx-1.18.0
[root@localhost nginx-1.18.0]# ./configure --help
# 可以查看到编译的一些参数配置的帮助
tar
格式: tar [选项] [文件目录列表]
功能: 对文件目录进行打包备份
选项:
-c 建立新的归档文件
-r 向归档文件末尾追加文件
-x 从归档文件中解出文件
-O 将文件解开到标准输出
-v 处理过程中输出相关信息
-f 对普通文件操作
-z 调用gzip来压缩归档文件,与-x联用时调用gzip完成解压缩
-Z 调用compress来压缩归档文件,与-x联用时调用compress完成解压缩

编译安装

[root@localhost nginx-1.18.0]# yum -y install gcc pcre-devel openssl-devel
zlib-devel
[root@localhost nginx-1.18.0]# useradd -r -s /sbin/nologin nginx
[root@localhost nginx-1.18.0]# ./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
[root@localhost nginx-1.18.0]# make -j 2 && make install
[root@localhost nginx-1.18.0]# chown -R nginx.nginx /apps/nginx
[root@localhost nginx-1.18.0]# ls /apps/nginx/
conf html logs sbin
[root@localhost nginx-1.18.0]# ln -s /apps/nginx/sbin/nginx /usr/bin/
[root@localhost nginx-1.18.0]# which nginx
/usr/bin/nginx
[root@localhost nginx-1.18.0]# nginx -v
  • nginx完成安装以后,有四个主要的目录
    • conf:保存nginx所有的配置文件,其中nginx.conf是nginx服务器的最核心最主要的配置文件,其他的.conf则是用来配置nginx相关的功能的,例如fastcgi功能使用的是fastcgi. conf和fastcgi.params两个文件,配置文件一般都有个样板配置文件,是文件名. default结尾,使用的使用将其复制为并将default去掉即可。
    • html:目录中保存了nginx服务器的web文件,但是可以更改为其他目录保存web文件,另外还有一个50x的web文件是默认的错误页面提示页面。
    • logs:用来保存ngi nx服务器的访问日志错误日志等日志,logs目录可以放在其他路径,比如/var/logs/nginx里面。
    • sbin:保存nginx二进制启动脚本,可以接受不同的参数以实现不同的功能。
[root@localhost nginx-1.18.0]# tree /apps/nginx -C -L 1
查看一层目录下内容,加上颜色区分
/apps/nginx
├── conf
├── html
├── logs
└── sbin

启动和停止nginx测试访问web界面

启动和关闭nginx

[root@localhost nginx-1.18.0]# nginx
[root@localhost nginx-1.18.0]# nginx -s stop

创建nginx自启动文件

此处是与yum安装最主要的区别,这里的自启动文件可以按照自己的要求进行更改,而yum安装不方便直接修改。

# 复制同一版本的nginx的yum安装生成的service文件
[root@localhost ~]# vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/apps/nginx/run/nginx.pid
ExecStart=/apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
[root@localhost ~]# mkdir /apps/nginx/run/
[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
pid /apps/nginx/run/nginx.pid;

验证nginx自启动文件

[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl enable --now nginx
[root@localhost ~]# ll /apps/nginx/run
总用量 4
-rw-r--r--. 1 root root 5 524 10:07 nginx.pid

Nginx核心配置详解

配置文件说明

  • nginx官方帮助文档
    • https://nginx.org/en/docs/
  • tengine帮助文档
    • https://tengine.taobao.org/documentation.html
  • nginx的配置文件的组成部分
    • 主配置文件:nginx.conf
    • 子配置文件:include conf.d/*.conf
    • fastcgi, uwsgi, scgi等协议相关的配置文件
    • mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。MIME参考文档:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types
  • Nginx 主配置文件的配置指令方式
directive value [value2 ...];
注意
(1) 指令必须以分号结尾
(2) 支持使用配置变量
内建变量:由Nginx模块引入,可直接应用
自定义变量:由用户使用set命令定义,格式:set variable_name value;
引用变量:$variable_name
  • 主配置文件结构:四部分
main block:主配置段,既全局配置段,对http,mail都有效
# 事件驱动相关的配置
event {
...
}
# http/https协议相关配置段
http {
...
}
# 默认配置文件不包括下面两个块
# mail协议相关配置段
mail {
...
}
# stream服务器相关配置段
stream {
...
}
# 导入其他路径的配置文件
include /apps/nginx/conf.d/*.conf

默认的nginx.conf配置文件格式说明在这里插入图片描述在这里插入图片描述

全局配置

Main全局配置段常见的配置指令分类

  • 正常允许必备的配置
  • 优化性能相关的配置
  • 用于调试及定位问题相关的配置
  • 时间驱动相关的配置

全局配置说明:
CPU性能优化

user nginx nginx; #启动Nginx工作进程的用户和组
worker_processes [number | auto]; #启动Nginx工作进程的数量,一般设为和CPU核心数
相同
worker_processes 4
worker_cpu_affinity 0001 0010 0100 1000; # 将Nginx工作进程绑定到指定的CPU核心,
默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进程独占一核心CPU,但是可以保障此进
程不会运行在其他核心上,这就极大减少了nginx的工作进程在不同的cpu核心上的来回跳转,减少了
cpu对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务器的性能。
CPU MASK:0001 0号CPU
0010 1号CPU
0100 2号CPU
1000 3号CPU
[root@localhost ~]# watch -n.5 'ps axo pid,cmd,psr |grep nginx'
# 查看nginx进程对应的CPU
6834 nginx: master process /apps 2
47621 nginx: worker process 0
47622 nginx: worker process 1
47623 nginx: worker process 2
47624 nginx: worker process 3
[root@localhost ~]# while true;do ab -c 1000 -n 2000 http://127.0.0.1/;done
# 压力测试

错误日志记录配置

# 错误日志记录配置,语法:error_log file [debug | info | notice | warn | error |
crit | alert |emerg]
# error_log logs/error.log;
# error_log logs/error.log notice;
[root@localhost conf]# vim /apps/nginx/conf/nginx.conf
error_log /apps/nginx/logs/error.log error;

工作优先级与文件并发数

[root@localhost conf]# vim /apps/nginx/conf/nginx.conf
worker_priority 0; #工作进程优先级(-20~19)
worker_rlimit_nofile 65536; #所有worker进程能打开的文件数量上限,包括:Nginx的
所有连接(例如与代理服务器的连接等),而不仅仅是与客户端的连接,另一个考虑因素是实际的并发连
接数不能超过系统级别的最大打开文件数的限制,最好与ulimit -n的值保持一致
[root@localhost ~]# ulimit -n 102400
[root@localhost ~]# vim /etc/security/limits.conf
* soft nofile 102400
* hard nofile 102400
# 查看优先级
[root@localhost ~]# watch -n.5 'ps axo pid,cmd,psr,nice |grep nginx'

其他优化配置

daemon off; # 前台运行nginx服务,用于测试、docker等环境
master_process off|on; # 是否开启Nginx的master-worker工作模式,仅用于开发调试场
景,默认为on
events {
worker_connections 65536; # 设置单个工作进程的最大并发连接数
use epoll; # 使用epoll事件驱动,Nginx支持众多的事件驱动,比如:select、poll、
epoll,只能设置在events模块中
accept_mutex on; # on为同一时刻一个请求轮流由work进程处理,而防止被同时唤醒所有
worker,避免多个睡眠进程被唤醒的设置,默认为off,新请求会唤醒所有worker进程,此过程也被称
为"惊群",因此nginx刚安装完以后要进行适当的优化,建议设置为on
multi_accept on; # on时Nginx服务器的每个工作进程可以同时接受多个新的网络连接,此指令
默认为off,即默认为一个工作进程只能一次接受一个新的网络连接,打开后几个同时接受多个,建议设
置为on
}
  • 默认配置并不支持高并发,在压力测试下会报错
[root@localhost ~]# while true;do ab -c 5000 -n 10000
http://127.0.0.1/;sleep 0.5;done
[root@localhost ~]# tail /apps/nginx/logs/error.log
2021/05/24 12:35:53 [crit] 6828#0: *10996 open()
"/apps/nginx/html/index.html" failed (24: Too many open files), client:
127.0.0.1, server: localhost, request: "GET / HTTP/1.0", host: "127.0.0.1"
2021/05/24 12:35:53 [crit] 6828#0: *10996 open() "/apps/nginx/html/50x.html"
failed (24: Too many open files), client: 127.0.0.1, server: localhost,
request: "GET / HTTP/1.0", host: "127.0.0.1"
[root@localhost ~]# vim /etc/security/limits.conf
* - nproc 100000 #系统最多允许开启多少个进程
[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
worker_rlimit_nofile 65536;
events {
worker_connections 10240;
}
[root@localhost ~]# systemctl restart nginx

http配置块
http协议相关的配置结构

http {
...
... #各server的公共配置
server { # 每个server用于定义一个虚拟主机,第一个server为默认虚拟服务器
...
}
server {
...
server_name # 虚拟主机名
root # 主目录
alias # 路径别名
location [OPERATOR] URL { # 指定URL的特性
...
if CONDOTION {
...
			}
		}
	}
}

http协议配置说明

http {
include mime.types; # 导入支持的文件类型,是相对于/apps/nginx/conf的目录
default_type application/octet-stream; # 除mime.types中文件类型外,设置其
他文件默认类型,访问其他类型时会提示下载不匹配的类型文件
# 日志配置部分
#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; # 允许sendfile方式传输文件 ,sendfile系统调用在两个文件描述符之间
直接传递数据(完全在内核中操作),从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率
很高,被称之为零拷贝。# 允许sendfile方式传输文件 ,sendfile系统调用在两个文件描述符之间
直接传递数据(完全在内核中操作),从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率
很高,被称之为零拷贝。
#tcp_nopush on;#在开启了sendfile的情况下,合并请求后统一发送给客户端
#tcp_nodelay off;#在开启了keeplived模式下的连接是否启用TCP_NODELAY选项,当为
off时,延迟0.2s发送,默认on时,不延迟
#keepalive_timeout 0;
keepalive_timeout 65 65;# 设置会话保持时间,第二个值为响应首部:keepAlived:timeout=65,可以和第一个值不同
#gzip on;#开启文件压缩
server {
listen 80;# 设置监听端口
server_name localhost;# 设置server name,可以空格隔开写多个,并支持正则表达
式,如:*.iproute.cn(泛域名)
}
}

指定响应报文server首部

[root@localhost conf]# curl -I 127.0.0.1
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Thu, 21 Jul 2022 13:20:52 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Thu, 21 Jul 2022 12:30:25 GMT
Connection: keep-alive
ETag: "62d946e1-264"
Accept-Ranges: bytes
charset utf-8;
# 是否在响应报文的Server首部显示nginx版本
server_tokens on | off |build | string
[root@localhost conf]# vim /apps/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost;
charset utf-8;
server_tokens off;
#charset koi8-r;
[root@localhost conf]# curl -I 127.0.0.1

范例:修改server字段

# 如果想自定义响应报文的nginx版本信息,需要修改源码文件,重新编译
# 如果server_tokens on,修改 src/core/nginx.h 修改第13-14行,如下示例
#define NGINX_VERSION "1.68.9"
#define NGINX_VER "mynginx" NGINX_VERSION
如果server_tokens off, 修改 src/http/ngx_http_header_filter_module.c
第49行,如下示例:
static char ngx_http_server_string[] = 'Server: nginx' CRLF;
把其中的nginx改为自己想要的文字即可,如mynginx

例:修改Server头部信息

[root@localhost ~]# vim /usr/local/src/nginx-1.18.0/src/core/nginx.h
# define NGINX_VERSION "1.68.9"
# define NGINX_VER "mynginx/" NGINX_VERSION
[root@localhost ~]# vim /usr/local/src/nginx-
1.18.0/src/http/ngx_http_header_filter_module.c
static u_char ngx_http_server_string[] = "Server: mynginx" CRLF;
修改完成后重新编译
[root@localhost ~]# cd /usr/local/src/nginx-1.18.0
[root@localhost nginx-1.18.0]# ./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
[root@localhost nginx-1.18.0]# make -j 2 && make install
[root@localhost nginx-1.18.0]# systemctl restart nginx
[root@localhost nginx-1.18.0]# curl -I 127.0.0.1

核心配置示例

基于不同的IP、不同的端口以及不用得域名实现不同的虚拟主机,依赖于核心模块ngx_http_core_module实现。
PC站与手机站

  • 定义子配置文件路径,在主配置文件最后添加导入
[root@localhost ~]# mkdir /apps/nginx/conf.d
[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
http {
...
include /apps/nginx/conf.d/*.conf;
}
  • 创建pc网站配置
[root@localhost ~]# vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name www.test.com;
location / {
root /apps/nginx/html/www;
}
}
[root@localhost ~]# mkdir -p /apps/nginx/html/www
[root@localhost ~]# echo "hello world" > /apps/nginx/html/www/index.html
[root@localhost ~]# systemctl reload nginx
[root@localhost conf]# vim /etc/hosts
192.168.175.10 www.test.com
  • 创建移动端的网站配置
[root@localhost ~]# vim /apps/nginx/conf.d/mobile.conf
server {
listen 80;
server_name m.test.com;
location / {
root /apps/nginx/html/mobile;
}
}
[root@localhost ~]# mkdir -p /apps/nginx/html/mobile
[root@localhost ~]# echo "hello mobile" > /apps/nginx/html/mobile/index.html
[root@localhost ~]# systemctl reload nginx
[root@localhost conf]# vim /etc/hosts
192.168.175.10 m.test.com

root与alias

  • root:指定web的家目录,在定义location的时候,文件的绝对路径等于root+location
    范例:
[root@localhost conf]# vim /apps/nginx/conf.d/test.conf
server {
listen 80;
server_name a.test.com;
location / {
root /apps/nginx/html/www;
}
location /about {
root /apps/nginx/html/about; # 这样写其实访问的是/apps/nginx/html/下的
about的about
}
}
[root@localhost conf]# vim /etc/hosts
192.168.175.10 a.test.com
[root@localhost ~]# mkdir -p /apps/nginx/html/about
[root@localhost ~]# echo about > /apps/nginx/html/about/index.html
# 重启Nginx并访问测试,404
[root@localhost conf]# vim /apps/nginx/conf.d/test.conf
server {
listen 80;
server_name a.test.com;
location / {
root /apps/nginx/html/www;
}
location /about {
root /apps/nginx/html; #这样就好了
}
}
# 重启Nginx并访问测试
  • alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于location上下文,此指令使用较少
    例子:
[root@localhost conf]# vim /apps/nginx/conf.d/test.conf
server {
listen 80;
server_name a.test.com;
location / {
root /apps/nginx/html/www;
}
location /about { # 注意about后不要加/,使用alias的时候uri后面加了斜杠,下面的
路径也必须加,不然403错误
alias /apps/nginx/html/about; # 当访问about的时候,会显示alias定义
的/apps/nginx/html/about里面的内容
}
}
# 重启Nginx并访问测试
[root@localhost about]# curl a.test.com/about/

location的详细使用
在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射; ngnix会根据用户请求的URI来检查定义的所有location,按一定的优化级找出一 个最佳匹配,而后应用其配置。
在没有使用正则表达式的时候,nginx会先在server中的多个location选取匹配度最高的一个uri, uri是用户请求的字符串,即域名后面的web文件路径,然后使用该location模块中的正则ur|和字符串,如果匹配成功就结束搜索,并使用此location处理此请求。

location官方帮助:https://nginx.org/en/docs/http/ngx_http_core_module.html#location

  • 语法规则
location [ = | ~ | ~* | ^~ ] uri { ... }

在这里插入图片描述- 匹配优先级从高到低
- = ^~ /* 不带符号

  • 官方示例
The “ / ” request will match configuration A
the “ /index.html ” request will match configuration B
the “ /documents/document.html ” request will match configuration C
the “ /images/1.gif ” request will match configuration D
the “ /documents/1.jpg ” request will match configuration E
location = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}

nginx变量的使用

nginx的变量可以在配置文件中应用,作为功能判断或者日志等场景使用
变量可以分为内置变量和自定义变量
内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值

内置变量
官方文档:https://nginx.org/en/docs/varindex.html
常用内置变量

$remote_addr;
# 存放了客户端的地址,注意是客户端的公网IP
$proxy_add_x_forwarded_for;
# 此变量表示将客户端IP追加请求报文中X-Forwarded-For首部字段,多个IP之间用逗号分隔,如果
请求中没有X-Forwarder-For,就使用$remote_addr
$args;
# 变量中存放了URL中的参数
$document_root;
# 保存了针对当前资源的系统根目录
$document_uri;
# 保存了当前请求中不包含参数的URI,注意是不包含请求的指令,比如/img/logo.png
$host;
# 存放了请求的host名称
limit_rate 10240;
echo $limit_rate;
# 如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置,则显示0
$remote_port;
# 客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口
$remote_user;
# 已经经过Auth Basic Module验证的用户名
$request_body_file;
# 做反向代理时发给后端服务器的本地资源的名称
$request_method;
# 请求资源的方式,GET/PUT等等
$request_filename;
# 当前请求的资源文件的磁盘路径,由root或alias指令与URL请求生成的文件绝对路径
# /apps/nginx/html/www/index.html
$request_uri;
# 包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args
$scheme;
# 请求的协议,例如:http,https,ftp等等
$server_protocol;
# 保存了客户端请求资源使用的协议版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等等
$server_addr;
# 保存了服务器的IP地址
$server_name;
# 请求的服务器的主机名
$server_port;
# 请求的服务器的端口号
$http_<name>
# name为任意请求报文首部字段,表示记录请求报文的首部字段
$http_user_agent;
# 客户端浏览器的详细信息
$http_cookie;
# 客户端的cookie信息
$cookie_<name>
# name为任意请求报文首部字段cookie的key名

自定义变量

假如需要自定义变量名和值,使用指令set $variable value;
语法格式:

Syntax:set $varible value;
Default: -
Context: server, location, if

例:

[root@localhost ~]# vim /apps/nginx/conf.d/www.conf
set $name zs;
echo $name;
set $my_port $server_port;
echo $my_port;
echo "$setver_name:$server_port";

Nginx自定义访问日志

访问日志是记录客户端即用户的具体请求内容信息,全局配置模块中的error_log是记录nginx服务器运行时的日志保存路径和记录日志的level,因此有着本质的区别,而且Nginx的错误日志一般只有一个, 但是访问日志可以在不同server中定义多个,定义一个日志需要使用access_log指定日志的保存路径,使用log_format指定日志的格式,格式中定义要保存的具体日志内容。
访问日志由ngx_http_log_module 模块实现
官方帮助文档:http://nginx.org/en/docs/http/ngx_http_log_module.html
语法格式:

Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time]
[if=condition]];
access_log off;
Default:
access_log logs/access.log combined;
Context: http, server, location, if in location, limit_except

自定义默认格式日志
如果是要保留日志的源格式,只是添加相应的日志内容,则配置如下:

[root@www ~]# vim /apps/nginx/conf/nginx.conf
log_format nginx_format1 '$remote_addr - $remote_user [$time_local]
"$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'$server_name:$server_port';
access_log logs/access.log nginx_format1;
# 重启nginx并访问测试日志格式
# /apps/nginx/logs/access.log

自定义json格式日志

Nginx的默认访问日志记录内容相对比较单一, 默认的格式也不方便后期做日志统计分析,生产环境中通常将nginx日志转换为json日志,然后配合使用ELK做日志收集-统计-分析。

log_format access_json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamhost":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"uri":"$uri",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"tcp_xff":"$proxy_protocol_addr",'
'"status":"$status"}';
access_log logs/access.log access_json;

Nginx压缩功能
Nginx支持对指定类型的文件进行压缩,然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,这样有助于降低出口带宽的利用率,不过会占用相应的CPU资源。
Nginx对文件的压缩功能是依赖于模块ngx_http_gzip_module
官方文档:https://nginx.org/en/docs/http/ngx_http_gzip_module.html

# 启用或禁用gzip压缩,默认关闭
gzip on | off;
# 压缩比由低到高1到9,默认为1
gzip_comp_level level;
# 禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\.";
# gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# 启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1;
# 指定Nginx服务需要向服务器申请的缓存空间的个数和大小,平台不同,默认:32 4k或者 16 8k;
gzip_buffers number size;
# 指明仅对哪些类型的资源执行压缩操作,默认为gzip_types text/html,不用显示指定,否则出错
gzip_types mime-type ...;
# 如果启用压缩,是否在相应报文首部插入"vary: Accept-Encoding",一般建议打开
gzip_vary on | off
# 重启nginx并进行访问测试压缩功能
[root@localhost ~]# curl -I --compressed 127.0.0.1

https功能

Web网站的登录页面都是使用https加密传输的,加密数据以保障数据的安全,HTTPS能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS议,HTTPS其实是有两部分组成: HTTP + SSL/ TLS,也就是在、HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。
在这里插入图片描述https实现过程如下:
1.客户端发起HTTPS请求
1. 客户端访问某个web端的https地址,一般都是443端口
2.服务端的配置
1. 采用https协议的服务器必须要有一套证书,可以通过一些组织申请,也可以自己制作,目前国内很多⽹站都⾃⼰做的,当你访问⼀个⽹站的时候提示证书不可信任就表示证书是⾃⼰做的,证书就是⼀个公钥和私钥匙,就像⼀把锁和钥匙,正常情况下只有你的钥匙可以打开你的锁,你可以把这个送给别⼈让他锁住⼀个箱⼦,⾥⾯放满了钱或秘密,别⼈不知道⾥⾯放了什么⽽且别⼈也打不开,只有你的钥匙是可以打开的。
3.传送证书
1.服务端给客户端传递证书,其实就是公钥,⾥⾯包含了很多信息,例如证书得到颁发机构、过期时间等等。
4.客户端解析证书
1.这部分⼯作是有客户端完成的,⾸先回验证公钥的有效性,⽐如颁发机构、过期时间等等,如果发现异常则会弹出⼀个警告框提示证书可能存在问题,如果证书没有问题就⽣成⼀个随机值,然后⽤证书对该随机值进⾏加密,就像2步骤所说把随机值锁起来,不让别⼈看到。
5.传送4步骤的加密数据
1.就是将⽤证书加密后的随机值传递给服务器,⽬的就是为了让服务器得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值进⾏加密解密了。
6.服务端解密信息
1.服务端用私钥解密5步骤加密后的随机值之后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进⾏对称加密,对称加密就是将信息和私钥通过算法混合在⼀起,这样除非你知道私钥,不然是⽆法获取其内部的内容,而正好客户端和服务端都知道这个私钥,所以只要机密算法够复杂就可以保证数据的安全性。
7.传输加密后的信息
1.服务端将⽤私钥加密后的数据传递给客户端,在客户端可以被还原出原数据内容
8.客户端解密信息
1. 客户端⽤之前⽣成的私钥获解密服务端传递过来的数据,由于数据⼀直是加密的,因此即使第三⽅获取到数据也⽆法知道其详细内容。

https配置参数

nginx的https功能基于模块ngx_http_ssl_module实现,因此如果是编译安装的nginx要使用参数ngx_http_ssl_module开启ssI功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编译安装的nginx需要指定编译参数–with-http_ssl_module开启官方文档:https://nginx.org/en/docs/http/ngx_http_ssl_module.html

配置参数如下:

ssl on | off;
listen 443 ssl;
# 为指定的虚拟主机配置是否启用ssl功能,此功能在1.15.0废弃,使用listen [ssl]替代。
ssl_certificate /path/to/file;
# 当前虚拟主机使用使用的公钥文件,一般是crt文件
ssl_certificate_key /path/to/file;
# 当前虚拟主机使用的私钥文件,一般是key文件
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
# 支持ssl协议版本,早期为ssl现在是TSL,默认为后三个
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
# 配置ssl缓存
off:
# 关闭缓存
none:
# 通知客户端支持ssl session cache,但实际不支持
builtin[:size]# 使用OpenSSL内建缓存,为每worker进程私有
[shared:name:size]# 在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大小,一兆可以存储
4000个会话信息,多个虚拟主机可以使用相同的缓存名称。
ssl_session_timeout time;
# 客户端连接可以复用ssl session cache中缓存的有效时长,默认5m

自签名证书

  • 生成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证书配置

vim /apps/nginx/conf/nginx.conf
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 /apps/nginx/html;
}

虚拟主机

[root@www conf.d]# ll /apps/nginx/conf.d
总用量 12
-rw-r--r--. 1 root root 107 925 16:45 bbs.conf
-rw-r--r--. 1 root root 109 925 16:45 blog.conf
-rw-r--r--. 1 root root 107 925 16:44 www.conf
[root@www conf.d]# cat *.conf
server {
listen *:8080;
server_name bbs.eagle.com;
location / {
root /apps/html/bbs;
index index.html;
}
}
server {
listen *:8080;
server_name blog.eagle.com;
location / {
root /apps/html/blog;
index index.html;
}
}
server {
listen *:8080;
server_name www.eagle.com;
location / {
root /apps/html/www;
index index.html;
}
}

nginx正向代理

可以照着vpn那一套理解方式理解(两台服务器)
知道想要访问哪个网址,请求vpn帮忙访问
server2:
修改其配置文件
在这里插入图片描述server1上:安装nginx

 yum info nginx
 yum install epel-release -y
 yum install nginx -y
 systemctl start nginx 

修改配置文件

vim /etc/nginx/conf.d/www.conf


server{
        listen 8090;
        resolver 114.114.114.114;
        location / {
        proxy_pass http://$http_host$request_uri;
        }

}
查看端口
ss -tnl 可以看到8090端口起来了

在server2上

[root@server1 ~]# curl -x 192.168.120.100:8090 "http://www.baidu.com" -I

或者:
但是export只是临时生效,重启过后便会没有
也可以写在配置文件中,开机便会自动生效。

[root@server1 ~]# export http_proxy=http://192.168.120.100:8090
[root@server1 ~]# echo $http_proxy
http://192.168.120.100:8090

nginx反向代理

案例:

proxy_cache缓存

当我们访问server2的时候我们可以将其内容缓存到server1中
首先在主配置文件里的http字段中加入如下内容:

LNMP架构概述

LNMP是一套技术的组合,L=Linux、N=Nginx、M~=MySQL、P=PHP

LNMP架构是如何工作的

  • 首先nginx服务是不能请求动态请求,那么当用户发起动态请求时,nginx无法处理
  • 当用户发起http请求,请求会被nginx处理,如果是静态资源请求nginx则直接返回,如果是动态请求nginx则通过fastcgi协议转交给后端的PHP程序处理

在这里插入图片描述

Nginx与fastcgi详细工作流程

在这里插入图片描述1. 用户通过http协议发起请求,请求会先抵达LNMP架构中的nginx;
2. nginx会根据用户的请求进行location规则匹配;
3. location如果匹配到请求是静态,则由nginx读取本地直接返回;
4. location如果匹配到请求是动态,则由nginx将请求转发给fastcgi协议;
5. fastcgi收到请求交给php-fpm管理进程,php-fpm管理进程接收到后会调用具体的工作进程
wrapper;
6. wrapper进程会调用PHP程序进行解析,如果只是解析代码,php直接返回;
7. 如果有查询数据库操作,则由php连接数据库(用户 密码 ip)发起查询的操作;
8. 最终数据由mysql–>php–>php-fpm–>fastcgi–>nginx–>http–>user

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值