Nginx详解

文章目录

  • 1. 概述
  • 2. Nginx的功能介绍
  • 3. Nginx的模块介绍
  • 4. Nginx的工作原理
  • 5. Nginx安装与配置
  • 6. Nginx的配置文件
    • 6.1 nginx.conf配置文件详解
    • 6.2 全局段配置参数
    • 6.3 events段配置参数
    • 6.4 http段--upstream
    • 6.5 http段--server
    • 6.6 http段--location
    • 6.7 php配置
    • 6.8 https配置
    • 6.9 开启状态页面
    • 6.10 URI重定向指令rewrite
    • 6.11 判断参数if
    • 6.12 反向代理和负载均衡


1. 概述


什么是Nginx?

  • Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。其特点是占有内存少,并发能力强
  • Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。
  • Nginx将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。

Nginx有什么特性?

  • 在高连接并发的情况下,nginx是Apache服务器不错的替代品,能够支持高达50000个并发连接数的响应
  • 使用epoll and kqueue作为开发模型
  • nginx作为负载均衡服务器:nginx既可在内部直接支持和PHP程序对外进行服务,也可支持作为HTTP代理服务器对外进行服务
  • nginx采用C进行编写,不论系统资源开销还是CPU使用效率都比Perlbal要好很多

Nginx有哪些优点?

  • 高并发连接:官方测试能够支撑5万并发连接,在实际生产环境中跑到2-3万并发连接数
  • 内存消耗少:在3万并发连接下,开启的10个nginx进程才消耗150M内存(15M*10=150M)
  • 配置文件非常简单:风格跟程序一样通俗易懂
  • 成本低廉:nginx为开源软件,可以免费使用。而购买F5 BIG-IP、NetScaler等硬件负载均衡交换机则需要十多万至几十万人民币
  • 支持Rewrite重写规则:能够根据域名、URL的不同,将HTTP请求分到不同的后端服务器群组
  • 内置的健康检查功能:如果Nginx Proxy后端的某台Web服务器宕机了,不会影响前端访问
  • 节省带宽:支持GZIP压缩,可以添加浏览器本地缓存的Header头
  • 稳定性高:用于反向代理,宕机的概率微乎其微
  • 模块化设计:模块可以动态编译
  • 外围支持好:文档全,二次开发和模块较多
  • 支持热部署:可以不停机重载配置文件
  • 支持事件驱动、AIO(AsyncIO,异步IO)、mmap(Memory Map,内存映射)等性能优化

Nginx的应用场景:

  • 静态服务器。(图片,视频服务)另一个lighttpd。并发几万,html,js,css,flv,jpg,gif等。
  • 动态服务,nginx——fastcgi 的方式运行PHP,jsp。(PHP并发在500-1500,MySQL 并发在300-1500)。
  • 反向代理,负载均衡。日pv2000W以下,都可以直接用nginx做代理。
  • 缓存服务。类似 SQUID,VARNISH。

2. Nginx的功能介绍


基本功能:

  • 静态资源的web服务器,能缓存打开的文件描述符
  • http、smtp、pop3协议的反向代理服务器
  • 缓存加速、负载均衡
  • 支持FastCGI(fpm,LNMP),uWSGI(Python)等
  • 模块化(非DSO机制),过滤器zip、SSI及图像的大小调整
  • 支持SSL

拓展功能:

  • 基于名称和IP的虚拟主机
  • 支持keepalive(长连接)
  • 支持平滑升级
  • 定制访问日志、支持使用日志缓冲区提高日志存储性能
  • 支持URL重写
  • 支持路径别名
  • 支持基于IP及用户的访问控制
  • 支持速率限制,支持并发数限制

3. Nginx的模块介绍


nginx的模块从结构上分为核心模块、基础模块和第三方模块

  • HTTP模块、EVENT模块和MAIL模块等属于核心模块
  • HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块属于基本模块
  • HTTP Upstream模块、Request Hash模块、Notice模块和HTTP Access Key模块属于第三方模块

用户根据自己的需要开发的模块都属于第三方模块。正是有了如此多模块的支撑,nginx的功能才会如此强大


nginx模块从功能上分为三类:

  • Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。handlers处理器模块一般只能有一个
  • Filters(过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由nginx输出
  • Proxies(代理器模块)。就是nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如fastcgi等操作交互,实现服务代理和负载均衡等功能

nginx基本模块:

基本模块,指的是nginx默认的功能模块,它们提供的指令,允许你使用定义nginx基本功能的变量,在编译时不能被禁用,包括:

  • 核心模块:基本功能和指令,如进程管理和安全。常见的核心模块指令,大部分是放置在配置文件的顶部
  • 事件模块:在Nginx内配置网络使用的能力。常见的events(事件)模块指令,大部分是放置在配置文件的顶部
  • 配置模块:提供包含机制

具体模块介绍可参考 Nginx官方文档


4. Nginx的工作原理


Nginx 由内核和模块组成,启动 Nginx 后,Nginx 的模块被自动加载,与 Apache 不一样,首先将模块编译为一个 so 文件,然后在配置文件中指定是否进行加载

在解析配置文件时,Nginx的每个模块都有可能去处理某个请求,但是同一个处理请求只能由一个模块来完成

Nginx 本身做的工作实际很少,当它接到一个 HTTP 请求时,它仅仅是通过查找配置文件将此次请求映射到一个 location block,而此 location 中所配置的各个指令则会启动不同的模块去完成工作,因此模块可以看做 Nginx 真正的劳动工作者。通常一个 location 中的指令会涉及一个 handler 模块和多个 filter 模块(当然,多个 location 可以复用同一个模块)。handler 模块负责处理请求,完成响应内容的生成,而 filter 模块对响应内容进行处理。


Nginx进程模型

Nginx详解_第1张图片

启动 nginx 时,会启动一个 master 进程,在创建 master 进程时,先建立需要监听的 socket(listenfd),然后从 master 进程中 fork() 出多个 worker 进程,如此一来每个 worker 进程多可以监听用户请求的 socket 。一般来说,当一个连接进来后,所有在 worker 都会收到通知,但是只有一个进程可以接受这个连接请求,其它的都失败,这是所谓的惊群现象。nginx 提供了一个 accept_mutex(互斥锁),有了这把锁之后,同一时刻,就只会有一个进程在 accpet 连接,这样就不会有惊群问题了


5. Nginx安装与配置


安装依赖包

[root@node2 ~]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ wget
[root@node2 ~]# yum -y groups mark install 'Development Tools'

创建nginx主和组,并创建日志存放目录

[root@node2 ~]# useradd -r -M -s /sbin/nologin nginx
[root@node2 ~]# mkdir -p /var/log/nginx
[root@node2 ~]# chown -R nginx.nginx /var/log/nginx

下载nginx源码包,并安装

[root@node2 ~]# wget http://nginx.org/download/nginx-1.18.0.tar.gz
[root@node2 ~]# tar xf nginx-1.18.0.tar.gz
[root@node2 ~]# cd nginx-1.18.0
[root@node2 nginx-1.18.0]# ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-debug \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=/var/log/nginx/error.log
[root@node2 nginx-1.18.0]# make -j $(grep 'processor' /proc/cpuinfo | wc -l) && make install

配置nginx

[root@node2 ~]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh
[root@node2 ~]# source /etc/profile.d/nginx.sh 
[root@node2 ~]# nginx 
[root@node2 ~]# ss -antl |grep 80
LISTEN     0      128          *:80                       *:*   

访问验证
在这里插入图片描述
能够看到此页面说明nginx安装成功


nginx命令常用选项:

-t  //检查配置文件语法
-v  //输出nginx的版本
-c  //指定配置文件的路径
-s  //发送服务控制信号,可选值有{
     stop|quit|reopen|reload}

6. Nginx的配置文件


nginx主配置文件:/usr/local/nginx/conf/nginx.conf

  • 默认启动nginx时,使用的配置文件是:安装路径/conf/nginx.conf文件
  • 可以在启动nginx时通过-c选项来指定要读取的配置文件

nginx常见的配置文件:

配置文件 作用
nginx.conf nginx的基本配置文件
mime.types MIME类型关联的扩展文件
fastcgi.conf 与fastcgi相关的配置
proxy.conf 与proxy相关的配置
sites.conf 配置nginx提供的网站,包括虚拟主机

6.1 nginx.conf配置文件详解

文件结构图:
Nginx详解_第2张图片
nginx.conf的内容分为以下几段:

  • main配置段:配置影响nginx全局的指令
    • 配置运行Nginx服务器用户(组)
    • worker process数
    • Nginx进程
    • PID存放路径错误日志的存放路径
    • 配置文件的引入
  • events配置段:配置影响nginx服务器或与用户的网络连接
    • 设置网络连接的序列化
    • 是否允许同时接收多个网络连接
    • 事件驱动模型的选择
    • 最大连接数的配置
  • http配置段:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置
    • 定义MIMI-Type
    • 自定义服务日志
    • 允许sendfile方式传输文件
    • 连接超时时间
    • 单连接请求数上限
  • server段:配置虚拟主机的相关参数,一个http中可以有多个server
    • 配置网络监听
    • 基于名称的虚拟主机配置
    • 基于IP的虚拟主机配置
  • location段:配置请求的路由,以及各种页面的处理情况
    • location配置
    • 请求根目录配置更改
    • location的URI
    • 网站默认首页配置

每个配置指令要以分号结尾

语法:derective value1 [value2 ...];

配置文件支持使用变量

内置变量:模块会提供内建变量定义
自定义变量:set var_name value

6.2 全局段配置参数

配置运行Nginx服务器用户(组)

指令格式:user user [group];
	user:指定可以运行Nginx服务器的用户
	group:可选项,可以运行Nginx服务器的用户组

如果user指令不配置或者配置为user nobody nobody,则默认所有用户都可以启动Nginx进程

是否以守护进程方式运行nginx

指令格式:daemon {
     on|off};

是否以守护进程方式运行nginx,调试时应设置为off

是否以master/worker模型来运行nginx

指令格式:master_process {
     on|off};    

是否以master/worker模型来运行nginx,调试时可以设置为off

worker process数配置

Nginx服务器实现并发处理服务的关键

指令格式:worker_processes number | auto;
	number:Nginx进程最多可以产生的worker process数
	auto:Nginx进程将自动检测

为了避免上下文切换,通常number值设置为cpu总核心数-1或等于总核心数

将进程绑定到某cpu中,避免频繁刷新缓存

指令格式:worker_cpu_affinity cpumask ...;
	cpumask:使用8位二进制表示cpu核心

例:
worker_processes    4;
worker_cpu_affinity 0001 0010 0100 1000;
一共四核,0001表示第一个核心,0010表示第二个核心,0100表示第三个核心,1000表示第四个核心

Nginx进程PID存放路径

指令格式:pid file;
	file:指定存放路径和文件名称如果不指定默认置于路径 logs/nginx.pid

Nginx进程是作为系统守护进程在运行,需要在某文件中保存当前运行程序的主进程号,Nginx支持该保存文件路径的自定义

错误日志的存放路径

指令格式:error_log 位置 级别;
	位置:file | stderr | syslog:server=address[,parameter=value] | memory:size
	级别:debug | info | notice | warn | error | crit | alert | emerg
		若要使用debug级别,需要在编译nginx时使用--with-debug选项

设置所有worker进程最大可以打开的文件数

指令格式:worker_rlimit_nofile number;

设置所有worker进程最大可以打开的文件数,默认为1024

配置文件的引入

指令格式:include file;

该指令主要用于将其他的Nginx配置或者第三方模块的配置引用到当前的主配置文件中

计时器解析度配置

指令格式:timer_resolution interval;

降低工作过程中计时器解析度,从而减少系统调用次数

例:
timer_resolution 100ms;

worker进程的nice值配置

指令格式:worker_priority number;

定义工作进程的优先级,允许的范围通常从 -20 到 20 变化

6.3 events段配置参数

设置网络连接的序列化

指令格式:accept_mutex on | off;

该指令默认为on状态,表示会对多个Nginx进程接收连接进行序列化,防止多个进程对连接的争抢。

说到该指令,首先得阐述一下什么是所谓的 “惊群问题”,可以参考 WIKI百科的解释。就Nginx的场景来解释的话大致
的意思就是:当一个新网络连接来到时,多个worker进程会被同时唤醒,但仅仅只有一个进程可以真正获得连接并处理之。
如果每次唤醒的进程数目过多的话,其实是会影响一部分性能的。

所以在这里,如果accept_mutex on,那么多个worker将是以串行方式来处理,其中有一个worker会被唤醒;反之若
accept_mutex off,那么所有的worker都会被唤醒,不过只有一个worker能获取新连接,其它的worker会重新进入休眠状态

这个值的开关与否其实是要和具体场景挂钩的。

是否允许同时接收多个网络连接

指令格式:multi_accept on | off;

该指令默认为off状态,意指每个worker process 一次只能接收一个新到达的网络连接。若想让每个Nginx的
workerprocess都有能力同时接收多个网络连接,则需要开启此配置

事件驱动模型的选择

指令格式:use model;

model模型可选择项包括:select、poll、kqueue、epoll、rtsig等......

最大连接数的配置

指令格式:worker_connections number;

number默认值为512,表示允许每一个worker process可以同时接受的最大连接数

互斥锁锁文件路径配置

指令格式:lock_file file;

nginx 使用锁定机制实现accept_mutex和序列化对共享内存的访问。在大多数系统上,锁都是使用原子操作实现的,并且忽略此指令。在其他系统上,使用"锁定文件"机制。此指令指定锁文件名称的前缀

6.4 http段–upstream

定义MIME-Type

指令格式:include mime.types;
	    default_type mime-type;

MIME-Type指的是网络资源的媒体类型,也即前端请求的资源类型
include指令将mime.types文件包含进来

cat mime.types
查看mime.types文件内容,发现其就是一个types结构,里面包含了各种浏览器能够识别的MIME类型以及对应类型的文件后缀名字

自定义服务日志

指令格式:access_log path [format];

	path:自定义服务日志的路径
	format:可选项,自定义服务日志的字符串格式。其也可以使用 log_format 定义的格式

允许sendfile方式传输文件

指令格式:sendfile on | off;
	    sendfile_max_chunk size;

前者用于开启或关闭使用sendfile()传输文件,默认off
后者指令若size>0,则Nginx进程的每个workerprocess每次调用sendfile()传输的数据了最大不能超出此值;若size=0则表示不限制。默认值为0

长连接超时时间配置

指令格式:keepalive_timeout timeout [header_timeout];
	
timeout 表示server端对连接的保持时间,默认75秒
header_timeout 为可选项,表示在应答报文头部的 Keep-Alive 域设置超时时间:“Keep-Alive :timeout = header_timeout”

6.5 http段–server

长连接请求数上限

指令格式:keepalive_requests number;

该指令用于限制用户在一个长连接上所能够允许请求的最大资源数

为指定类型的UserAgent禁用长连接

指令格式:keepalive_disable [msie6|safari|none...];

默认为keepalive_disable msie6;

是否对长连接使用TCP_NODELAY选项

指令格式:tcp_nodelay on|off;

为了提升用户体验,通常设为on,默认为on

读取http请求报文首部的超时时长

指令格式:client_header_timeout number;

定义读取客户端请求标头的超时。如果客户端未在此时间内传输整个标头,则请求将终止 408(请求退出)错误,默认为60s

发送响应报文的超时时长

指令格式:send_timeout time;

设置用于向客户端传输响应的超时。超时仅在两个连续写入操作之间设置,而不是用于传输整个响应。如果客户端在此时间内未收到任何消息,则连接将关闭,默认为60s

定义读取客户端请求正文的超时

指令格式:client_body_timeout time;

超时仅设置为两个连续读取操作之间的一个时间段,而不是为整个请求正文的传输。如果客户端在此时间内未传输任何内容,则请求将终止 408(请求退出)错误,默认为60s

配置网络监听

指令格式:

第一种:配置监听的IP地址:
listen IP[:PORT];

第二种:配置监听的端口:
listen PORT;

例:
listen 192.168.207.129:8080;  # 监听具体IP和具体端口上的连接
listen 192.168.207.129;       # 监听IP上所有端口上的连接
listen 8080;                  # 监听具体端口上的所有IP的连接

基于名称和IP的虚拟主机配置

指令格式:server_name name1 name2 ...

name可以有多个并列名称,而且此处的name支持正则表达式书写

例:
server_name ~^www\d+\.myserver\.com$
此时表示该虚拟主机可以接收类似域名  www1.myserver.com  等的请求,而拒绝  www.myserver.com  的域名请求,
所以说用正则表达式可以实现更精准的控制

6.6 http段–location

location配置

指令格式为:location [ = | ~ | ~* | ^~ ] uri {
     ...}

这里的uri分为标准uri和正则uri,两者的唯一区别是uri中是否包含正则表达式

uri前面的方括号中的内容是可选项,解释如下:
“=”:用于标准uri前,要求请求字符串与uri严格匹配,一旦匹配成功则停止
“~”:用于正则uri前,并且区分大小写
“~*”:用于正则uri前,但不区分大小写
“^~”:用于标准uri前,要求Nginx找到标识uri和请求字符串匹配度最高的location后,立即使用此location处理请求,
	 而不再使用location块中的正则uri和请求字符串做匹配

请求根目录配置

指令格式:root path;

path:Nginx接收到请求以后查找资源的根目录路径

当然,还可以通过alias指令来更改location接收到的URI请求路径,指令为:
alias path;
# path为修改后的根路径

设置网站的默认首页

指令格式:index file ......

file可以包含多个用空格隔开的文件名,首先找到哪个页面,就使用哪个页面响应请求

例:
index.php、index.jsp、index.html...

安装nginx-echo模块

//下载模块
[root@node1 ~]# wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz

//解压
[root@node1 ~]# tar xf v0.61.tar.gz

//查看原来的编译参数
[root@node1 ~]# nginx -V
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log

//重新编译nginx
[root@node1 nginx-1.18.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --add-module=/root/echo-nginx-module-0.61
//在最后加上--add-module=/root/echo-nginx-module-0.61
[root@node1 nginx-1.18.0]# make

//将nginx安装目录中的nginx文件备份
[root@node1 ~]# mv /usr/local/nginx/sbin/nginx /opt

//将我们重新编译的nginx文件复制到nginx安装目录中
[root@node1 ~]# cp nginx-1.18.0/objs/nginx /usr/local/nginx/sbin/

//重载配置文件
[root@node1 ~]# nginx -s reload

使用正则表达式匹配uri

  • 没有修饰符表示必须以指定模式开始
location /abc {
     
	echo "没有修饰符";
}

使用另一台主机访问:
[root@node2 ~]# curl 192.168.207.129/abc
没有修饰符
[root@node2 ~]# curl 192.168.207.129/abc/
没有修饰符
[root@node2 ~]# curl 192.168.207.129/abc?p1=11&p2=22
没有修饰符
  • =:表示必须与指定的模式精确匹配
location = /abc {
     
	echo "精确匹配";
}

使用另一台主机访问:
[root@node2 ~]# curl 192.168.207.129/abc
精确匹配
[root@node2 ~]# curl 192.168.207.129/abc/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
[root@node2 ~]# curl 192.168.207.129/abc?p1=11&p2=22
精确匹配
  • ~:表示指定的正则表达式要区分大小写
location ~ ^/abc$ {
     
	echo "正则表达式,区分大小写";
}

使用另一台主机访问:
[root@node2 ~]# curl 192.168.207.129/abc
正则表达式,区分大小写
[root@node2 ~]# curl 192.168.207.129/abc/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
[root@node2 ~]# curl 192.168.207.129/abc?p1=11&p2=22
正则表达式,区分大小写
[root@node2 ~]# curl 192.168.207.129/ABC
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
  • ~*:表示指定的正则表达式不区分大小写
location ~* ^/abc$ {
     
            echo "正则表达式,不区分大小写";
        }

使用另一台主机访问:
[root@node2 ~]# curl 192.168.207.129/ABC
正则表达式,不区分大小写
[root@node2 ~]# curl 192.168.207.129/abc
正则表达式,不区分大小写
[root@node2 ~]# curl 192.168.207.129/ABC/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
[root@node2 ~]# curl 192.168.207.129/abc?p1=11&p2=22
正则表达式,不区分大小写
[root@node2 ~]# curl 192.168.207.129/ABC?p1=11&p2=22
正则表达式,不区分大小写

查找顺序和优先级:由高到底依次为

  • 带有=的精确匹配优先
  • 正则表达式按照他们在配置文件中定义的顺序
  • 带有^~修饰符的,开头匹配
  • 带有~或~*修饰符的,如果正则表达式与URI匹配
  • 没有修饰符的精确匹配

( location = 路径 ) --> ( location ^~ 路径 ) --> ( location ~ 正则 ) --> ( location ~* 正则 ) --> ( location 路径 )


访问控制

用于location段
指令格式:allow IP;
		deny IP | all;
		
allow:设定允许哪台或哪些主机访问,多个参数间用空格隔开
deny:设定禁止哪台或哪些主机访问,多个参数间用空格隔开

例:
allow 192.168.1.1/32 172.16.0.0/16;
deny all;

用户认证

指令格式:auth_basic "欢迎信息";
		auth_basic_user_file "/path/to/user_auth_file"

user_auth_file内容格式为:
	username:password

建议用htpasswd来创建user_auth_file文件:
	用法:htpasswd -c -m /path/to/.user_auth_file USERNAME

6.7 php配置

php要启用fpm模型

配置示例:
location ~ \.php$ {
     
  root html;
  fastcgi_pass 127.0.0.1:9000;      //定义反向代理
  fastcgi_index index.php;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  include fastcgi_params;
}

6.8 https配置

自动生成证书脚本可参考 Linux服务管理-httpd

[root@node1 ~]# ./ssl.sh 
[root@node1 ~]# ls
httpd.crt  
httpd.csr  
httpd.key 
[root@node1 ~]# mkdir /usr/local/nginx/ssl
[root@node1 ~]# mv httpd.* /usr/local/nginx/ssl/

配置nginx主配置文件中配置https

[root@node1 ~]# vim /usr/local/nginx/conf/nginx.conf
    server {
     
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate      /usr/local/nginx/ssl/httpd.crt;
        ssl_certificate_key  /usr/local/nginx/ssl/httpd.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;
        }
    }
[root@node1 ~]# nginx -s reload

访问验证

在这里插入图片描述

6.9 开启状态页面

指令格式:
location /status {
     
  stub_status {
     on | off};
  allow 192.168.0.0/16;
  deny all;
}

访问状态页面的方式:http://server_ip/status

状态页面信息详解:

状态码 表示的意义
Active connections 2 当前所有处于打开状态的连接数
accepts 总共处理了多少个连接
handled 成功创建多少握手
requests 总共处理了多少个请求
Reading nginx读取到客户端的Header信息数,表示正处于接收请求状态的连接数
Writing nginx返回给客户端的Header信息数,表示请求已经接收完成,
且正处于处理请求或发送响应的过程中的连接数
Waiting 开启keep-alive的情况下,这个值等于active - (reading + writing),
意思就是Nginx已处理完正在等候下一次请求指令的驻留连接

6.10 URI重定向指令rewrite

rewrite模块的作用是用来执行URL重定向。这个机制有利于去掉恶意访问的url,也有利于搜索引擎优化(SEO)

指令格式:rewrite regex replacement flag;

replacement可以是某个路径,也可以是某个URL
		
常见的flag:
	last:表示当前的匹配结束,继续下一个匹配,最多匹配10个到20个,一旦此rewrite规则重写完成后,
		  就不再被后面其它的rewrite规则进行处理,而是由UserAgent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程
	break:中止Rewrite,不再继续匹配,一旦此rewrite规则重写完成后,由UserAgent对新的URL重新发起请求,
		   且不再会被当前location内的任何rewrite规则所检查
	redirect:以临时重定向的HTTP状态302返回新的URL
	permanent:以永久重定向的HTTP状态301返回新的URL

例:
rewrite ^/images/(.*\.jpg)$ /imgs/$1 break;
rewrite ^/bbs/(.*)$ http://www.idfsoft.com/index.html redirect;

nginx使用的语法源于Perl兼容正则表达式(PCRE)库,基本语法为:

标识符 意义
^ 必须以^后的实体开头
$ 必须以$前的实体结尾
. 匹配任意字符
[ ] 匹配指定字符集内的任意字符
[^] 匹配任何不包括在指定字符集内的任意字符串
| 匹配 | 之前或之后的实体
( ) 分组,组成一组用于匹配的实体,通常会有 | 来协助
捕获子表达式,可以捕获放在()之间的任何文本

例:
^(hello|sir)$       //字符串为“hi sir”捕获的结果:$1=hi$2=sir

//这些被捕获的数据,在后面就可以当变量一样使用了

实例:

需求:将images重定向至imgs

//创建imgs目录,并创建测试页面
[root@node2 ~]# mkdir /opt/imgs/
[root@node2 ~]# mv 1.jpg /opt/imgs/
[root@node2 ~]# ls /opt/imgs/
1.jpg
[root@node2 ~]# ls /usr/local/nginx/html/
50x.html  index.html  index.php

//编辑配置文件
[root@node2 ~]# vim /usr/local/nginx/conf/nginx.conf
location /images {
     
            root /opt;            
            rewrite ~*^/images/(.*\.jpg)$ /imgs/$1 break;
        }
[root@node2 ~]# nginx -s reload

访问验证
Nginx详解_第3张图片


6.11 判断参数if

指令格式:if (condition) {
     ...}

常见的condition
	变量名(变量值为空串,或者以“0”开始,则为false,其它的均为true)
	以变量为操作数构成的比较表达式(可使用=!=类似的比较操作符进行测试)
	正则表达式的模式匹配操作:
		~:区分大小写的模式匹配检查
		~*:不区分大小写的模式匹配检查
		!~和!~*:对上面两种测试取反
	测试指定路径为文件的可能性(-f,!-f)
	测试指定路径为目录的可能性(-d,!-d)
	测试文件的存在性(-e,!-e)
	检查文件是否有执行权限(-x,!-x)

基于浏览器实现分离

//创建Safari和Chrome网站目录
[root@node2 ~]# mkdir /usr/local/nginx/html/{Edg,Chrome}
[root@node2 ~]# echo 'this Edg' > /usr/local/nginx/html/Edg/index.html
[root@node2 ~]# echo 'this chrome' > /usr/local/nginx/html/Chrome/index.html

//编辑配置文件
[root@node2 ~]# vim /usr/local/nginx/conf/nginx.conf
        location / {
     
            if ($http_user_agent ~ Edg) {
     
                rewrite ^(.*)$ /Edg/$1 break;
            }
            if ($http_user_agent ~ Chrome) {
     
                rewrite ^(.*)$ /Chrome/$1 break;
            }
            root html;
            index index.html;
        }

        location /Edg {
     
            root html;
        }
        location /Chrome {
     
            root html;
        }
[root@node2 ~]# nginx -s reload

访问验证:

Edg浏览器
在这里插入图片描述

谷歌浏览器
在这里插入图片描述

防盗链案例:

location ~* \.(jpg|gif|jpeg|png)$ {
     
  valid_referers none blocked www.idfsoft.com;
  if ($invalid_referer) {
     
    rewrite ^/ http://www.idfsoft.com/403.html;
  }
}

6.12 反向代理和负载均衡

nginx 通常被用作后端服务器的反向代理,这样就可以很方便的实现动静分离以及负载均衡,从而大大提高服务器的处理能力。

nginx 实现动静分离,其实就是在反向代理的时候,如果是静态资源,就直接从 nginx 发布的路径去读取,而不需要从后台服务器获取了。

但是要注意,这种情况下需要保证后端跟前端的程序保持一致,可以使用 Rsync 做服务端自动同步或者使用 NFS 、MFS 分布式共享存储。

Http Proxy 模块,功能很多,最常用的是 proxy_pass 和 proxy_cache

如果要使用 proxy_cache,需要集成第三方的 ngx_cache_purge 模块,用来清除指定的URL缓存。这个集成需要在安装nginx的时候去做,如:

./configure --add-module=../ngx_cache_purge-1.0 ......

nginx通过 upstream 模块来实现简单的负载均衡,upstream 需要定义在 http 段内

在 upstream 段内,定义一个服务器列表,默认的方式是轮询,如果要确定同一个访问者发出的请求总是由同一个后端服务器来处理,可以设置 ip_hash,如:

upstream idfsoft.com {
     
  ip_hash;
  server 127.0.0.1:9080 weight=5;
  server 127.0.0.1:8080 weight=5;
  server 127.0.0.1:1111;
}

定义好upstream后,需要在server段内添加如下内容:

server {
     
  location / {
     
    proxy_pass http://idfsoft.com;
  }
}

反向代理和负载均衡配置实例:

环境:

主机名 IP
DR 192.168.207.130
RS1 192.168.207.131
RS2 192.168.207.132

在RS上配置apache服务

[root@RS1 ~]# yum -y install httpd
[root@RS1 ~]# echo 'this is rs1' > /var/www/html/index.html
[root@RS1 ~]# systemctl enable --now httpd

[root@RS2 ~]# yum -y install httpd
[root@RS2 ~]# echo 'this is rs2' > /var/www/html/index.html
[root@RS2 ~]# systemctl enable --now httpd

在DR(nginx)上编辑配置文件

[root@DR ~]# vim /usr/local/nginx/conf/nginx.conf
...
//在http段下面添加以下内容
upstream aaa.com {
     
        server 192.168.207.131 weight=3;    //不指定端口默认为80,weight设置权重
        server 192.168.207.132 weight=1;
    }
...
location / {
     
            proxy_pass http://aaa.com;   //更改此行
        }
...
[root@DR ~]# nginx -s reload

访问验证

[root@DR ~]# for i in $(seq 10);do curl 192.168.207.130 ;done
this is rs2
this is rs1
this is rs1
this is rs1
this is rs2
this is rs1
this is rs1
this is rs1
this is rs2
this is rs1

动静分离配置实例:

环境:

主机名 IP 服务
DR 192.168.207.130 nginx
RS1 192.168.207.131 tomcat
RS2 192.168.207.132 httpd

当DR收到请求后,请求动态资源交给RS1处理,请求静态资源交给RS2处理

1. 在RS1上配置tomcat

安装java环境
[root@RS1 ~]# yum -y install java-1.8.0-openjdk java-1.8.0-openjdk-devel

下载tomcat安装包,并解压至指定目录
[root@RS1 ~]# wget http://mirror.bit.edu.cn/apache/tomcat/tomcat-9/v9.0.37/bin/apache-tomcat-9.0.37.tar.gz
[root@RS1 ~]# ls
apache-tomcat-9.0.37.tar.gz
[root@RS1 ~]# tar -xf apache-tomcat-9.0.37.tar.gz -C /usr/local/

创建软连接
[root@RS1 ~]# cd /usr/local/
[root@RS1 local]# ln -s apache-tomcat-9.0.37 tomcat
[root@RS1 local]# ll |grep tomcat
drwxr-xr-x  9 root root 220 Jul 31 16:27 apache-tomcat-9.0.37
lrwxrwxrwx  1 root root  20 Jul 31 16:28 tomcat -> apache-tomcat-9.0.37

在tomcat的网页目录中写一个测试页面
[root@RS1 ~]# cd /usr/local/tomcat/webapps/
[root@RS1 webapps]# mkdir test
[root@RS1 webapps]# vim test/index.jsp
//添加以下内容
<html>
<head>
        <title>test page</title>
</head>
<body>
        <%
            out.println("Hello World");
        %>
</body>
</html>

启动tomcat
[root@RS1 ~]# /usr/local/tomcat/bin/catalina.sh start
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@RS1 ~]# ss -antl
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128     *:22                  *:*                  
LISTEN     0      100    127.0.0.1:25                  *:*                  
LISTEN     0      1        ::ffff:127.0.0.1:8005               :::*                  
LISTEN     0      100    :::8080               :::*                  
LISTEN     0      128    :::22                 :::*                  
LISTEN     0      100       ::1:25                 :::*

访问:
在这里插入图片描述

2. 在RS2上配置apache

[root@RS2 ~]# yum -y install httpd
[root@RS2 ~]# cat /var/www/html/index.html 
this is test
[root@RS2 ~]# systemctl enable --now httpd

访问:
在这里插入图片描述

3. 在DR上配置nginx

[root@DR ~]# vim /usr/local/nginx/conf/nginx.conf
...
upstream danamic {
     
        server 192.168.207.131:8080;
    }

    upstream static {
     
        server 192.168.207.132;
    }
...
location / {
     
            proxy_pass http://static;
        }

        location ~ \.jsp$ {
     
            proxy_pass http://danamic;
        }
[root@DR ~]# nginx -s reload

访问静态资源
在这里插入图片描述

访问动态资源
在这里插入图片描述

你可能感兴趣的:(服务,nginx)