Nginx初级入门教程

01 Nginx安装

Nginx的安装还是比较容易的,有离线安装,在线安装多种安装方式,这里我只说最简单的一种,打开我们的命令行终端,直接输入yum命令进行安装:yum install -y nginx

当终端显示出Complete!字样时,则代表我们的Nginx已经安装成功了。

查看Nginx版本:nginx -v #在这里我安装的是1.16.1版本的nginx

02 Nginx基本操作

和我们之前的docker一样,nginx也有一些包括服务的启动,停止,重载等基本操作。

2.1 启动nginx

##在centos7+ 启动nginx服务
systemctl start nginx.service
#centos6+ 上启动nginx服务
service nginx start
#或,简单粗暴一句
nginx

2.2 停止nginx

##在centos7+ 停止nginx服务
systemctl stop nginx.service
#centos6+ 上停止nginx服务
service nginx stop
#粗鲁的停止,下班了,不干了,就算请求来了我也不接了。
nginx -s stop
##优雅的停止,Nginx在退出前完成已经接受的连接请求。
nginx -s quit

 

2.3 重启nginx

当我们修改了nginx的某些配置,为了使配置生效,我们往往需要重启nginx,同样的,linux下依然有两种方式来重启我们的nginx服务:

##在centos7+ 重启nginx服务
systemctl restart nginx.service
#centos6+ 上重启nginx服务
service nginx restart
#使用nginx命令停止,推荐这个
nginx -s reload

而具体使用nginx原生的nginx -s 操作还是linux提供的systemctl ,这个主要看个人喜好,实际两者的功能是差不多的,并没有什么明显的不同。

2.4 其他命令

查看配置文件是否ok:#如果配置文件有问题的话会显示failed,如果没得问题的话,会显示successful  nginx -t

2.5 显示帮助信息:nginx -h #或者 nginx -?

03 Nginx配置

nginx本身作为一个完成度非常高的负载均衡框架,和很多成熟的开源框架一样,大多数功能都可以通过修改配置文件来完成,使用者只需要简单修改一下nginx配置文件,便可以非常轻松的实现比如反向代理,负载均衡这些常用的功能,同样的,和其他开源框架比如tomcat一样,nginx配置文件也遵循着相应的格式规范,并不能一顿乱配,在讲解如何使用nginx实现反向代理,负载均衡等这些功能的配置前,我们需要先了解一下nginx配置文件的结构。

既然要了解nginx的配置文件,那我总得知道nginx配置文件在哪啊,nginx配置文件默认都放在nginx安装路径下的conf目录,而主配置文件nginx.conf自然也在这里面,我们下面的操作几乎都是对nginx.conf这个配置文件进行修改。

可是,我怎么知道我nginx装哪了?我要是不知道nginx装哪了咋办?

这个,细心的朋友们可能会发现,运行nginx -t命令,下面除了给出nginx配置文件是否OK外,同时也包括了配置文件的路径。诺,就是这个:

root@izuf61d3ovm5vx1kknakwrz ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

使用vim打开该配置文件,我们一探究竟,不同版本的配置文件可能稍有不同,我的配置文件内容如下:

# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
 worker_connections 1024;
}
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;
 tcp_nopush on;
 tcp_nodelay on;
 keepalive_timeout 65;
 types_hash_max_size 2048;
 include /etc/nginx/mime.types;
 default_type application/octet-stream;
 # Load modular configuration files from the /etc/nginx/conf.d directory.
 # See http://nginx.org/en/docs/ngx_core_module.html#include
 # for more information.
 include /etc/nginx/conf.d/*.conf;
 server {
 listen 80 default_server;
 listen [::]:80 default_server;
 server_name _;
 root /usr/share/nginx/html;
 # Load configuration files for the default server block.
 include /etc/nginx/default.d/*.conf;
 location / {
 }
 error_page 404 /404.html;
 location = /40x.html {
 }
 error_page 500 502 503 504 /50x.html;
 location = /50x.html {
 }
 }
}

 

? ? ?这一堆都是啥玩意er,完全没有头绪啊

没关系,下面我们就来详细分析一下nginx.conf这个文件中的内容。

按照功能划分,我们通常将nginx配置文件分为三大块,全局块,events块,http块

3.1 第一部分:全局块

首先映入眼帘的这一堆:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

 

我们称之为全局块,知识点呐朋友们,要记住,这里呢,主要会设置一些影响 nginx 服务器整体运行的配置指令,主要包括配 置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数,进程 PID 存放路径、日志存放路径和类型以及配置文件的引入等。

比如 worker_processes auto; 这一行,worker_processes 值越大,我们nginx可支持的并发数量就越多,很多人想这不就爽了吗,我设置成正无穷,无限并发flag达成,秒杀问题轻松解决,这个,受自己服务器硬件限制的,不能乱来。

3.2 第二部分:events 块

events {
 worker_connections 1024;
}

这一堆,就是我们配置文件的第二部分,events 块

起名字这么随意的么,那第三部分是不是叫http块?

wc,这你都知道,是的

events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 work process 下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 word process 可以同时支持的最大连接数等。

3.3 第三部分:http块

内容太多,略

http {
 server {
 }
}

注意:http是一个大块,里面也可以包括很多小块,比如http全局块,server块等。

http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。

而http块中的server块则相当于一个虚拟主机,一个http块可以拥有多个server块。

server块又包括全局server块,和location块。

全局server块主要包括了本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置

location块则用来对虚拟主机名称之外的字符串进行匹配,对特定的请求进行处理。地址定向、数据缓 存和应答控制等功能,还有许多第三方模块的配置也在这里进行。比如,对/usr相关的请求交给8080来处理,/admin则较给8081处理。

说了这么多,我还是不是特别理解咋办,问题不大,接下来我们通过几个实例来帮助大家更好的理解这些配置在实际中所发挥的作用。

04 Nginx配置实战

接下来我们将通过对nginx配置文件的修改来完成反向代理,负载均衡,动静分离的简单配置。

4.1 nginx配置反向代理

我发现很多教程说nginx配置反向代理的时候上来就改host文件,这里的话,因为上一篇文章我们有总结过反向代理的精髓,也就是:

反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器 IP 地址。

所以接下来我们通过一个小栗子,当我们访问服务器的时候,由于我的服务器没备案,阿里云默认80端口没开,所以这里我们设置对外服务的端口为8888,当我们访问8888端口的时候,实际上是跳转到8080端口的。

首先我们用docker启动一个tomcat容器,然后配置端口映射为8080。

等等,不会docker怎么办?不会docker的话,可以看韩数最新的docker初级入门教程(滑稽)

如果对docker不是很了解的话,可以使用传统的linux下运行tomcat,道理是一样的。

然后修改我们的配置文件nginx.conf里面的server块,修改之后的内容如下:

 server {
 listen 8888 ; ##设置我们nginx监听端口为8888
 server_name [服务器的ip地址];
 # Load configuration files for the default server block.
 include /etc/nginx/default.d/*.conf;
 location / {
 proxy_pass http://127.0.0.1:8080; ##需要代理的服务器地址
 index index.html;
 }
 error_page 404 /404.html;
 location = /40x.html {
 }
 error_page 500 502 503 504 /50x.html;
 location = /50x.html {
 }
 }

然后在浏览器中输入:服务器ip:8888 发现浏览器显示出来了8080端口tomcat的欢迎界面,从而实现了隐藏真实服务器地址这样一个反向代理的要求。

哦?看着好神奇哦,那,我之前经常有看到那种,就是各种/image /video 不同的链接对应的是不同的网站,那也是这么做的咯?

聪明,这里我们再新建一个tomcat容器,端口为8081,同时把在容器中tomcat webapps目录新建一个我们自己的目录,这里叫hello,里面新建一个hello.html文件,内容为:<h1>I am Hello<h1>

同时我们在端口为8080的tomcat容器中,在webapps新建我们的文件家hi,并新建hi.html文件,内容为:<h1>I am Hi<h1>

啊,这样的话配置是不是很难啊?

你想多了,敲简单的。

修改我们配置文件中的server快,如下:

server {
 listen 8888 ; ##设置我们nginx监听端口为8888
 server_name [服务器的ip地址];
 # Load configuration files for the default server block.
 include /etc/nginx/default.d/*.conf;
 location /hi/ {
 proxy_pass http://127.0.0.1:8080; ##需要代理的服务器地址
 index index.html;
 }
 
 location /hello/ {
 proxy_pass http://127.0.0.1:8081; ##需要代理的服务器地址
 index index.html;
 }
 error_page 404 /404.html;
 location = /40x.html {
 }
 error_page 500 502 503 504 /50x.html;
 location = /50x.html {
 }
 }

在浏览器中输入:服务器ip:8888/hi/hi.html

浏览器显示 I am hi 对应服务器端口为 8080

在浏览器中输入:服务器ip:8888/hello/hello.html

浏览器显示 I am hello 对应服务器端口为 8081

从而实现了针对不同url请求分发给不同服务器的功能配置。

少侠,且慢,你是不是忘了什么东西,location /hello/ 是什么意思,只能这么写么?

当然不是。学会location指令匹配路径,随便换姿势

location指令说明:

功能:用于匹配URL

语法如下:

1、= :用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配
成功,就停止继续向下搜索并立即处理该请求。
2、~:用于表示 uri 包含正则表达式,并且区分大小写。
3、~*:用于表示 uri 包含正则表达式,并且不区分大小写。
4、^~:用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求字
符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 
块中的正则 uri 和请求字符串做匹配。

注意:如果 uri 包含正则表达式,则必须要有 ~ 或者 ~* 标识。

到这里,关于nginx如何简单的配置一个反向代理服务器就大功告成了,下面我们来说一下怎么实现负载均衡的简单配置。

在nginx中配置负载均衡也是十分容易的,同时还支持了多种负载均衡策略供我们灵活选择。首先依旧是准备两个tomcat服务器,一个端口为8080,一个端口为8081,这里呢,推荐大家用docker部署,太方便了,什么,不会docker,可以移步我的面向后端的docker初级入门教程,真的挺好用,省了很多工作量。

然后修改我们的http块如下:

http {
###此处省略一大堆没有改的配置
 ##自定义我们的服务列表
 upstream myserver{
 server 127.0.0.1:8080;
 server 127.0.0.1:8090;
 }
 server {
 listen 8888 ; ##设置我们nginx监听端口为8888
 server_name [服务器的ip地址];
 # Load configuration files for the default server block.
 include /etc/nginx/default.d/*.conf;
 location / {
 proxy_pass http://myserver; ##叮,核心配置在这里
 proxy_connect_timeout 10; #超时时间,单位秒
 }
 error_page 404 /404.html;
 location = /40x.html {
 }
 error_page 500 502 503 504 /50x.html;
 location = /50x.html {
 }
 }
}
这就完了?当然还没有,之前就有说过,nginx提供了三种不同的负载均衡策略供我们灵活选择,分别是:
  • 轮询(默认方式): 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。
  • 用法:啥也不加,上文实例就是默认的方式,就是默认的
  • 权重(weight): weight 代表权重,默认为 1,权重越高被分配的客户端越多,权重越大,能力越大,责任越大,处理的请求就越多。
  • 用法:
     upstream myserver{
     server 127.0.0.1:8080 weight =1;
     server 127.0.0.1:8090 weight =2;
     }
    

    • ip_hash:每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。
    • 用法:
         
     upstream myserver{
     ip_hash;#可与weight配合使用
     server 127.0.0.1:8080 weight =1;
     server 127.0.0.1:8090 weight =2;
     }
    

    4.3 nginx配置动静分离

    接下来说最后一个实例,动静分离的简单配置。

    等等,我记得明明是四个,明明还有一个正向代理呢?

    这个,爱国守法,人人有责,有需要访问某些国内不能访问的网站需求的同学,可以自行下去查阅资料。

    至于怎么配置正向代理,咱也不知道,咱也不敢说,咱也不敢问。

基础篇回顾:

动静分离就是把很少会发生修改的诸如图像,视频,css样式等静态资源文件放置在单独的服务器上,而动态请求则由另外一台服务器上进行,这样一来,负责动态请求的服务器则可以专注在动态请求的处理上,从而提高了我们程序的运行效率,与此同时,我们也可以针对我们的静态资源服务器做专属的优化,增加我们静态请求的响应速度。

具体的动静分离配置也不是十分的复杂,和负载均衡,反向代理差不多。

为了演示动静分离呢,首先我们需要准备两个文件夹,一个是data文件夹,用来存放我们js,css这些静态资源文件,一个是html文件夹,用来存放我们的html文件。

在html文件夹新建一个html文件,index.html,内容如下:

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>我是一个静态界面</title>
</head>
<script type="text/javascript" src="jquery.js"></script>
<body>
<h1>我是一个静态界面</h1>
<div id="test_div"></div>
</body
</html>
注意,这里我们并没有将jquery.js 这个文件放在html目录下,而是将它放在了另外一个目录data里面,当服务器接需要请求jquery.js这个文件时,并不会去index.html所在的那个服务器去请求这个文件,而是会直接去我们配置好的服务器或者路径去寻找这个js文件,在本实例中,会去data文件夹下面去找这个jquery.js这个文件。
修改server的配置如下:
server {
 listen 8886 ;
 server_name [你的服务器ip地址];
 # Load configuration files for the default server block.
 include /etc/nginx/default.d/*.conf;
 location / {
 root /html/;
 index index.html;
 }
 #拦截静态资源,static里面存放的我们图片什么的静态资源
 location ~ .*\.(gif|jpg|jpeg|bmp|png|ico|js|css)$ {
 root /data/;
 }
 error_page 404 /404.html;
 location = /40x.html {
 }
 error_page 500 502 503 504 /50x.html;
 location = /50x.html {
 }
 }

测试:

在浏览器中输入ip地址:8888/index.html,屏幕上显示我是一个静态界面,同时打开浏览器自带的开发者工具

 

 会发现jquery.js已经被正常请求到了。

05 下面开始技术总结:

安装 nginx

yum update #更新系统软件
cd /
wget nginx.org/download/nginx-1.17.2.tar.gz

解压 tar.gz 压缩包文件,进去 nginx-1.17.2
tar -xzvf nginx-1.17.2.tar.gz
cd nginx-1.17.2

进入文件夹后进行配置检查

./configure

通过安装前的配置检查,发现有报错。检查中发现一些依赖库没有找到,这时候需要先安装 nginx 的一些依赖库

yum -y install pcre* #安装使nginx支持rewrite
yum -y install gcc-c++
yum -y install zlib*
yum -y install openssl openssl-devel

再次进行检查操作 ./configure 没发现报错显示,接下来进行编译并安装的操作
// 检查模块支持
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-mail --with-mail_ssl_module --with-stream --with-stream_ssl_module --with-stream_realip_module --with-stream_ssl_preread_module --with-threads --user=www --group=www
这里得特别注意下,你以后需要用到的功能模块是否存在,不然以后添加新的包会比较麻烦。

查看默认安装的模块支持

命令 ls nginx-1.17.2 查看 nginx 的文件列表,可以发现里面有一个 auto 的目录。

在这个 auto 目录中有一个 options 文件,这个文件里面保存的就是 nginx 编译过程中的所有选项配置。

通过命令:cat nginx-1.17.2/auto/options | grep YES就可以查看

nginx 编译安装时,怎么查看安装模块

编译并安装

make && make install

这里需要注意,模块的支持跟后续的 nginx 配置有关,比如 SSL,gzip 压缩等等,编译安装前最好检查需要配置的模块存不存在。

查看 nginx 安装后在的目录,可以看到已经安装到 /usr/local/nginx 目录了

  whereis nginx

$nginx: /usr/local/nginx

启动 nginx 服务
cd /usr/local/nginx/sbin/
./nginx
服务启动的时候报错了:nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) ,通过命令查看本机网络地址和端口等一些信息,找到被占用的 80 端口 netstat -ntpl 的 tcp 连接,并杀死进程(kill 进程 pid)
netstat -ntpl
kill 进程PID
继续启动 nginx 服务,启动成功
./nginx

在浏览器直接访问 ip 地址,页面出现 Welcome to Nginx! 则安装成功。

nginx 配置

基本结构

main        # 全局配置,对全局生效
├── events  # 配置影响 nginx 服务器或与用户的网络连接
├── http    # 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置
│   ├── upstream # 配置后端服务器具体地址,负载均衡配置不可或缺的部分
│   ├── server   # 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块
│   ├── server
│   │   ├── location  # server 块可以包含多个 location 块,location 指令用于匹配 uri
│   │   ├── location
│   │   └── ...
│   └── ...
└── ...

主要配置含义

  • main:nginx 的全局配置,对全局生效。
  • events:配置影响 nginx 服务器或与用户的网络连接。
  • http:可以嵌套多个 server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。
  • server:配置虚拟主机的相关参数,一个 http 中可以有多个 server。
  • location:配置请求的路由,以及各种页面的处理情况。
  • upstream:配置后端服务器具体地址,负载均衡配置不可或缺的部分。

nginx.conf 配置文件的语法规则

  1. 配置文件由指令与指令块构成
  2. 每条指令以 “;” 分号结尾,指令与参数间以空格符号分隔
  3. 指令块以 {} 大括号将多条指令组织在一起
  4. include 语句允许组合多个配置文件以提升可维护性
  5. 通过 # 符号添加注释,提高可读性
  6. 通过 $ 符号使用变量
  7. 部分指令的参数支持正则表达式,例如常用的 location 指令

内置变量

nginx 常用的内置全局变量,你可以在配置中随意使用:

 

 

常用命令

这里列举几个常用的命令:

nginx -s reload # 向主进程发送信号,重新加载配置文件,热重启 nginx -s reopen # 重启 Nginx nginx -s stop # 快速关闭 nginx -s quit # 等待工作进程处理完成后关闭 nginx -T # 查看当前 Nginx 最终的配置 nginx -t -c <配置路径> # 检查配置是否有问题,如果已经在配置目录,则不需要 -c

以上命令通过 nginx -h 就可以查看到,还有其它不常用这里未列出。

Linux 系统应用管理工具 systemd 关于 nginx 的常用命令:

systemctl start nginx # 启动 Nginx systemctl stop nginx # 停止 Nginx systemctl restart nginx # 重启 Nginx systemctl reload nginx # 重新加载 Nginx,用于修改配置后 systemctl enable nginx # 设置开机启动 Nginx systemctl disable nginx # 关闭开机启动 Nginx systemctl status nginx # 查看 Nginx 运行状态


配置 nginx 开机自启

利用 systemctl 命令

如果用 yum install 命令安装的 nginx,yum 命令会自动创建 nginx.service 文件,直接用命令:


systemctl enable nginx   # 设置开机启动 Nginx
systemctl disable nginx  # 关闭开机启动 Nginx

 

就可以设置开机自启,否则需要在系统服务目录里创建 nginx.service 文件。

创建并打开 nginx.service 文件:vi /lib/systemd/system/nginx.service

内容如下:

[Unit] Description=nginx After=network.target [Service] Type=forking ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx -s reload ExecStop=/usr/local/nginx/sbin/nginx -s quit PrivateTmp=true [Install] WantedBy=multi-user.target
:wq 保存退出,运行 systemctl daemon-reload 使文件生效。
这样便可以通过以下命令操作 nginx 了:
systemctl start nginx.service # 启动nginx服务 systemctl enable nginx.service # 设置开机启动 systemctl disable nginx.service # 停止开机自启动 systemctl status nginx.service # 查看服务当前状态 systemctl restart nginx.service # 重新启动服务 systemctl is-enabled nginx.service #查询服务是否开机启动

通过开机启动命令脚本实现开机自启

创建开机启动命令脚本文件:

vi /etc/init.d/nginx
在这个 nginx 文件中插入一下启动脚本代码,启动脚本代码来源网络复制,实测有效:
#! /bin/bash # chkconfig: - 85 15 PATH=/usr/local/nginx DESC="nginx daemon" NAME=nginx DAEMON=$PATH/sbin/$NAME CONFIGFILE=$PATH/conf/$NAME.conf PIDFILE=$PATH/logs/$NAME.pid scriptNAME=/etc/init.d/$NAME set -e [ -x "$DAEMON" ] || exit 0 do_start() { $DAEMON -c $CONFIGFILE || echo -n "nginx already running" } do_stop() { $DAEMON -s stop || echo -n "nginx not running" } do_reload() { $DAEMON -s reload || echo -n "nginx can't reload" } case "$1" in start) echo -n "Starting $DESC: $NAME" do_start echo "." ;; stop) echo -n "Stopping $DESC: $NAME" do_stop echo "." ;; reload|graceful) echo -n "Reloading $DESC configuration..." do_reload echo "." ;; restart) echo -n "Restarting $DESC: $NAME" do_stop do_start echo "." ;; *) echo "Usage: $scriptNAME {start|stop|reload|restart}" >&2 exit 3 ;; esac exit 0
 

设置所有人都有对这个启动脚本 nginx 文件的执行权限:

chmod a+x /etc/init.d/nginx

把 nginx 加入系统服务中:

chkconfig --add nginx

把服务设置为开机启动:

chkconfig nginx on

eboot 重启系统生效,可以使用上面 systemctl 方法相同的命令:

systemctl start nginx.service # 启动nginx服务
systemctl enable nginx.service # 设置开机启动
systemctl disable nginx.service # 停止开机自启动
systemctl status nginx.service # 查看服务当前状态
systemctl restart nginx.service # 重新启动服务
systemctl is-enabled nginx.service #查询服务是否开机启动

如果服务启动的时候出现 Restarting nginx daemon: nginxnginx: [error] open() "/usr/local/nginx/logs/nginx.pid" failed (2: No such file or directory) nginx not running 的错误,通过 nginx -c 参数指定配置文件即可解决

/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

如果服务启动中出现 nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) 的错误,可以先通过 service nginx stop 停止服务,再启动就好。

配置 nginx 全局可用

当你每次改了 nginx.conf 配置文件的内容都需要重新到 nginx 启动目录去执行命令,或者通过 -p 参数指向特定目录,会不会感觉很麻烦?

例如: 直接执行 nginx -s reload 会报错 -bash: nginx: command not found,需要到 /usr/local/nginx/sbin 目录下面去执行,并且是执行 ./nginx -s reload

这里有两种方式可以解决,一种是通过脚本对 nginx 命令包装,这里介绍另外一种比较简单:通过把 nginx 配置到环境变量里,用 nginx 执行指令即可。步骤如下:

1、编辑 /etc/profile

vi /etc/profile

2、在最后一行添加配置,:wq 保存

export PATH=$PATH:/usr/local/nginx/sbin

3、使配置立即生效

source /etc/profile

这样就可以愉快的直接在全局使用 nginx 命令了。

nginx 常用功能

反向代理

我们最常说的反向代理的是通过反向代理解决跨域问题。

其实反向代理还可以用来控制缓存(代理缓存 proxy cache),进行访问控制等等,以及后面说的负载均衡其实都是通过反向代理来实现的。

server {
    listen    8080;
        # 用户访问 ip:8080/test 下的所有路径代理到 github
        location /test {
         proxy_pass   https://github.com;
        }

        # 所有 /api 下的接口访问都代理到本地的 8888 端口
        # 例如你本地运行的 java 服务的端口是 8888,接口都是以 /api 开头
        location /api {
            proxy_pass   http://127.0.0.1:8888;
        }

}

访问控制

server {
   location ~ ^/index.html {
       # 匹配 index.html 页面 除了 127.0.0.1 以外都可以访问
       deny 192.168.1.1;
       deny 192.168.1.2;
       allow all;
 }
}

上面的命令表示禁止 192.168.1.1 和 192.168.1.2 两个 ip 访问,其它全部允许。从上到下的顺序,匹配到了便跳出,可以按你的需求设置。

负载均衡

通过负载均衡充利用服务器资源,nginx 目前支持自带 4 种负载均衡策略,还有 2 种常用的第三方策略。

轮询策略(默认)

每个请求按时间顺序逐一分配到不同的后端服务器,如果有后端服务器挂掉,能自动剔除。但是如果其中某一台服务器压力太大,出现延迟,会影响所有分配在这台服务器下的用户。

http {
    upstream test.com {
        server 192.168.1.12:8887;
        server 192.168.1.13:8888;
    }
    server {
        location /api {
            proxy_pass  http://test.com;
        }
    }
}

根据服务器权重

例如要配置:10 次请求中大概 1 次访问到 8888 端口,9 次访问到 8887 端口:

http {
    upstream test.com {
        server 192.168.1.12:8887 weight=9;
        server 192.168.1.13:8888 weight=1;
    }
    server {
        location /api {
            proxy_pass  http://test.com;
        }
    }
}

客户端 ip 绑定(ip_hash)

来自同一个 ip 的请求永远只分配一台服务器,有效解决了动态网页存在的 session 共享问题。例如:比如把登录信息保存到了 session 中,那么跳转到另外一台服务器的时候就需要重新登录了。

所以很多时候我们需要一个客户只访问一个服务器,那么就需要用 ip_hash 了。

http {
    upstream test.com {
     ip_hash;
        server 192.168.1.12:8887;
        server 192.168.1.13:8888;
    }
    server {
        location /api {
            proxy_pass  http://test.com;
        }
    }
}

最小连接数策略

将请求优先分配给压力较小的服务器,它可以平衡每个队列的长度,并避免向压力大的服务器添加更多的请求。

http {
    upstream test.com {
     least_conn;
        server 192.168.1.12:8887;
        server 192.168.1.13:8888;
    }
    server {
        location /api {
            proxy_pass  http://test.com;
        }
    }
}

最快响应时间策略(依赖于第三方 NGINX Plus)

依赖于 NGINX Plus,优先分配给响应时间最短的服务器。

http {
    upstream test.com {
     fair;
        server 192.168.1.12:8887;
        server 192.168.1.13:8888;
    }
    server {
        location /api {
            proxy_pass  http://test.com;
        }
    }
}

按访问 url 的 hash 结果(第三方)

按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务器,后端服务器为缓存时比较有效。 在 upstream 中加入 hash 语句,server 语句中不能写入 weight 等其他的参数,hash_method 是使用的 hash 算法

http {
    upstream test.com {
     hash $request_uri;
     hash_method crc32;
     server 192.168.1.12:8887;
     server 192.168.1.13:8888;
    }
    server {
        location /api {
            proxy_pass  http://test.com;
        }
    }
}

采用 HAproxy 的 loadbalance uri 或者 nginx 的 upstream_hash 模块,都可以做到针对 url 进行哈希算法式的负载均衡转发。

gzip 压缩

开启 gzip 压缩可以大幅减少 http 传输过程中文件的大小,可以极大的提高网站的访问速度,基本是必不可少的优化操作:

gzip  on; # 开启gzip 压缩
# gzip_types
# gzip_static on;
# gzip_proxied expired no-cache no-store private auth;
# gzip_buffers 16 8k;
gzip_min_length 1k;
gzip_comp_level 4;
gzip_http_version 1.0;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";

解释一下:

  1. gzip_types:要采用 gzip 压缩的 MIME 文件类型,其中 text/html 被系统强制启用;
  2. gzip_static:默认 off,该模块启用后,Nginx 首先检查是否存在请求静态文件的 gz 结尾的文件,如果有则直接返回该 .gz 文件内容;
  3. gzip_proxied:默认 off,nginx 做为反向代理时启用,用于设置启用或禁用从代理服务器上收到相应内容 gzip 压缩;
  4. gzip_buffers:获取多少内存用于缓存压缩结果,16 8k 表示以 8k*16 为单位获得;
  5. gzip_min_length:允许压缩的页面最小字节数,页面字节数从 header 头中的 Content-Length 中进行获取。默认值是 0,不管页面多大都压缩。建议设置成大于 1k 的字节数,小于 1k 可能会越压越大;
  6. gzip_comp_level:gzip 压缩比,压缩级别是 1-9,1 压缩级别最低,9 最高,级别越高压缩率越大,压缩时间越长,建议 4-6;
  7. gzip_http_version:默认 1.1,启用 gzip 所需的 HTTP 最低版本;
  8. gzip_vary:用于在响应消息头中添加 Vary:Accept-Encoding,使代理服务器根据请求头中的 Accept-Encoding 识别是否启用 gzip 压缩;
  9. gzip_disable 指定哪些不需要 gzip 压缩的浏览器

其中第 2 点,普遍是结合前端打包的时候打包成 gzip 文件后部署到服务器上,这样服务器就可以直接使用 gzip 的文件了,并且可以把压缩比例提高,这样 nginx 就不用压缩,也就不会影响速度。一般不追求极致的情况下,前端不用做任何配置就可以使用啦~

附前端 webpack 开启 gzip 压缩配置,在 vue-cli3 的 vue.config.js 配置文件中:

const CompressionWebpackPlugin = require('compression-webpack-plugin')

module.exports = {
  // gzip 配置
  configureWebpack: config => {
    if (process.env.NODE_ENV === 'production') {
      // 生产环境
      return {
        plugins: [new CompressionWebpackPlugin({
          test: /\.js$|\.html$|\.css/,    // 匹配文件名
          threshold: 1024,               // 文件压缩阈值,对超过 1k 的进行压缩
          deleteOriginalAssets: false     // 是否删除源文件
        })]
      }
    }
  },
  ...
}

HTTP 服务器

nginx 本身也是一个静态资源的服务器,当只有静态资源的时候,就可以使用 nginx 来做服务器:

server {
  listen       80;
  server_name  localhost;

  location / {
      root   /usr/local/app;
      index  index.html;
  }
}

这样如果访问 就会默认访问到 /usr/local/app 目录下面的 index.html,如果一个网站只是静态页面的话,那么就可以通过这种方式来实现部署,比如一个静态官网。

动静分离

就是把动态和静态的请求分开。方式主要有两种:

  • 一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案
  • 一种方法就是动态跟静态文件混合在一起发布, 通过 nginx 配置来分开
# 所有静态请求都由nginx处理,存放目录为 html
location ~ \.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
    root    /usr/local/resource;
    expires     10h; # 设置过期时间为10小时
}

# 所有动态请求都转发给 tomcat 处理
location ~ \.(jsp|do)$ {
    proxy_pass  127.0.0.1:8888;
}

注意上面设置了 expires,当 nginx 设置了 expires 后,例如设置为:expires 10d; 那么,所在的 location 或 if 的内容,用户在 10 天内请求的时候,都只会访问浏览器中的缓存,而不会去请求 nginx 。

请求限制

对于大流量恶意的访问,会造成带宽的浪费,给服务器增加压力。可以通过 nginx 对于同一 IP 的连接数以及并发数进行限制。合理的控制还可以用来防止 DDos 和 CC 攻击。

关于请求限制主要使用 nginx 默认集成的 2 个模块:

  • limit_conn_module 连接频率限制模块
  • limit_req_module 请求频率限制模块

涉及到的配置主要是:

  • limit_req_zone 限制请求数
  • limit_conn_zone 限制并发连接数

通过 limit_req_zone 限制请求数

http{    limit_conn_zone $binary_remote_addrzone=limit:10m; // 设置共享内存空间大    server{     location /{            limit_conn addr 5; # 同一用户地址同一时间只允许有5个连接。        }    }}

如果共享内存空间被耗尽,服务器将会对后续所有的请求返回 503 (Service Temporarily Unavailable) 错误。

当多个 limit_conn_zone 指令被配置时,所有的连接数限制都会生效。比如,下面配置不仅会限制单一 IP 来源的连接数,同时也会限制单一虚拟服务器的总连接数:

limit_conn_zone $binary_remote_addr zone=perip:10m;limit_conn_zone $server_name zone=perserver:10m;server {    limit_conn perip 10; # 限制每个 ip 连接到服务器的数量    limit_conn perserver 2000; # 限制连接到服务器的总数}

通过 limit_conn_zone 限制并发连接数

limit_req_zone $binary_remote_addr zone=creq:10 mrate=10r/s;server{    location /{        limit_req zone=creq burst=5;    }}

限制平均每秒不超过一个请求,同时允许超过频率限制的请求数不多于 5 个。 如果不希望超过的请求被延迟,可以用 nodelay 参数,如:

limit_req zone=creq burst=5 nodelay;

这里只是简单讲讲,让大家有这个概念,配置的时候可以深入去找找资料。

正向代理

正向代理,意思是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理,比如我们使用的 VPN 服务就是正向代理,直观区别(图片来源于 前端开发者必备的 Nginx 知识):

 

配置正向代理:

resolver 8.8.8.8 # 谷歌的域名解析地址
server {
    resolver_timeout 5s; // 设超时时间
    location / {
        # 当客户端请求我的时候,我会把请求转发给它
        # $host 要访问的主机名 $request_uri 请求路径
        proxy_pass http://$host$request_uri;
    }
}

正向代理的对象是客户端,服务器端看不到真正的客户端。

图片防盗链

server {
    listen       80;
    server_name  *.test;

    # 图片防盗链
    location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
        valid_referers none blocked server_names ~\.google\. ~\.baidu\. *.qq.com;  # 只允许本机 IP 外链引用,将百度和谷歌也加入白名单有利于 SEO
        if ($invalid_referer){
            return 403;
        }
    }
}

以上设置就能防止其它网站利用外链访问我们的图片,有利于节省流量

适配 PC 或移动设备

根据用户设备不同返回不同样式的站点,以前经常使用的是纯前端的自适应布局,但是复杂的网站并不适合响应式,无论是复杂性和易用性上面还是不如分开编写的好,比如我们常见的淘宝、京东。

根据用户请求的 user-agent 来判断是返回 PC 还是 H5 站点:

server {
    listen 80;
    server_name test.com;

    location / {
     root  /usr/local/app/pc; # pc 的 html 路径
        if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
            root /usr/local/app/mobile; # mobile 的 html 路径
        }
        index index.html;
    }
}

设置二级域名

新建一个 server 即可:

server {
    listen 80;
    server_name admin.test.com; // 二级域名

    location / {
        root  /usr/local/app/admin; # 二级域名的 html 路径
        index index.html;
    }
}

配置 HTTPS

这里我使用的是 certbot 免费证书,但申请一次有效期只有 3 个月(好像可以用 crontab 尝试配置自动续期,我暂时没试过):

先安装 certbot

wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto

申请证书(注意:需要把要申请证书的域名先解析到这台服务器上,才能申请):

sudo ./certbot-auto certonly --standalone --email admin@abc.com -d test.com -d www.test.com

执行上面指令,按提示操作。

Certbot 会启动一个临时服务器来完成验证(会占用 80 端口或 443 端口,因此需要暂时关闭 Web 服务器),然后 Certbot 会把证书以文件的形式保存,包括完整的证书链文件和私钥文件。

文件保存在 /etc/letsencrypt/live/ 下面的域名目录下。

修改 nginx 配置:

server{
    listen 443 ssl http2; // 这里还启用了 http/2.0

    ssl_certificate /etc/letsencrypt/live/test.com/fullchain.pem; # 证书文件地址
    ssl_certificate_key /etc/letsencrypt/live/test.com/privkey.pem; # 私钥文件地址

    server_name test.com www.test.com; // 证书绑定的域名
}

配置 HTTP 转 HTTPS

server {
    listen      80;
    server_name test.com www.test.com;

    # 单域名重定向
    if ($host = 'www.sherlocked93.club'){
        return 301 https://www.sherlocked93.club$request_uri;
    }

    # 全局非 https 协议时重定向
    if ($scheme != 'https') {
        return 301 https://$server_name$request_uri;
    }

    # 或者全部重定向
    return 301 https://$server_name$request_uri;
}

以上配置选择自己需要的一条即可,不用全部加。

单页面项目 history 路由配置

server {
    listen       80;
    server_name  fe.sherlocked93.club;

    location / {
        root       /usr/local/app/dist;  # vue 打包后的文件夹
        index      index.html index.htm;
        try_files  $uri $uri/ /index.html @rewrites; # 默认目录下的 index.html,如果都不存在则重定向

        expires -1;                          # 首页一般没有强制缓存
        add_header Cache-Control no-cache;
    }

    location @rewrites { // 重定向设置
        rewrite ^(.+)$ /index.html break;
    }
}

vue-router 官网只有一句话 try_files $uri $uri/ /index.html;,而上面做了一些重定向处理。

配置高可用集群(双机热备)

当主 nginx 服务器宕机之后,切换到备份的 nginx 服务器

首先安装 keepalived:

yum install keepalived -y

然后编辑 /etc/keepalived/keepalived.conf 配置文件,并在配置文件中增加 vrrp_script 定义一个外围检测机制,并在 vrrp_instance 中通过定义 track_script 来追踪脚本执行过程,实现节点转移:

global_defs{
   notification_email {
        cchroot@gmail.com
   }
   notification_email_from test@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30 // 上面都是邮件配置
   router_id LVS_DEVEL     // 当前服务器名字,用 hostname 命令来查看
}
vrrp_script chk_maintainace { // 检测机制的脚本名称为chk_maintainace
    script "[[ -e/etc/keepalived/down ]] && exit 1 || exit 0" // 可以是脚本路径或脚本命令
    // script "/etc/keepalived/nginx_check.sh"    // 比如这样的脚本路径
    interval 2  // 每隔2秒检测一次
    weight -20  // 当脚本执行成立,那么把当前服务器优先级改为-20
}
vrrp_instanceVI_1 {   // 每一个vrrp_instance就是定义一个虚拟路由器
    state MASTER      // 主机为MASTER,备用机为BACKUP
    interface eth0    // 网卡名字,可以从ifconfig中查找
    virtual_router_id 51 // 虚拟路由的id号,一般小于255,主备机id需要一样
    priority 100      // 优先级,master的优先级比backup的大
    advert_int 1      // 默认心跳间隔
    authentication {  // 认证机制
        auth_type PASS
        auth_pass 1111   // 密码
    }
    virtual_ipaddress {  // 虚拟地址vip
       172.16.2.8
    }
}

其中检测脚本 nginx_check.sh,这里提供一个:

#!/bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];then
    /usr/sbin/nginx # 尝试重新启动nginx
    sleep 2         # 睡眠2秒
    if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then
        killall keepalived # 启动失败,将keepalived服务杀死。将vip漂移到其它备份节点
    fi
fi

复制一份到备份服务器,备份 nginx 的配置要将 state 后改为 BACKUPpriority 改为比主机小。 设置完毕后各自 service keepalived start 启动,经过访问成功之后,可以把 Master 机的 keepalived 停掉,此时 Master 机就不再是主机了 service keepalived stop,看访问虚拟 IP 时是否能够自动切换到备机 ip addr。

再次启动 Master 的 keepalived,此时 vip 又变到了主机上。

配置高可用集群的内容来源于:Nginx 从入门到实践,万字详解!

其它功能和技巧

代理缓存

nginx 的 http_proxy 模块,提供类似于 Squid 的缓存功能,使用 proxy_cache_path 来配置。

nginx 可以对访问过的内容在 nginx 服务器本地建立副本,这样在一段时间内再次访问该数据,就不需要通过 nginx 服务器再次向后端服务器发出请求,减小数据传输延迟,提高访问速度:

proxy_cache_path usr/local/cache levels=1:2 keys_zone=my_cache:10m;

server {
  listen       80;
  server_name  test.com;

  location / {
      proxy_cache my_cache;
      proxy_pass http://127.0.0.1:8888;
      proxy_set_header Host $host;
  }
}

上面的配置表示: nginx 提供一块 10 M 的内存用于缓存,名字为 my_cache, levels 等级为 1:2,缓存存放的路径为 usr/local/cache

访问日志

访问日志默认是注释的状态,需要可以打开和进行更详细的配置,一下是 nginx 的默认配置:

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  logs/access.log  main;
}

错误日志

错误日志放在 main 全局区块中,童鞋们打开 nginx.conf 就可以看见在配置文件中和下面一样的代码了:

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

nginx 错误日志默认配置为:

error_log logs/error.log error;

静态资源服务器

server {
    listen       80;
    server_name  static.bin;
    charset utf-8;    # 防止中文文件名乱码

    location /download {
        alias           /usr/share/nginx/static;  # 静态资源目录

        autoindex               on;    # 开启静态资源列目录,浏览目录权限
        autoindex_exact_size    off;   # on(默认)显示文件的确切大小,单位是byte;off显示文件大概大小,单位KB、MB、GB
        autoindex_localtime     off;   # off(默认)时显示的文件时间为GMT时间;on显示的文件时间为服务器时间
    }
}

禁止指定 user_agent

nginx 可以禁止指定的浏览器和爬虫框架访问:

# http_user_agent 为浏览器标识
# 禁止 user_agent 为baidu、360和sohu,~*表示不区分大小写匹配
if ($http_user_agent ~* 'baidu|360|sohu') {
    return 404;
}

# 禁止 Scrapy 等工具的抓取
if ($http_user_agent ~* (Scrapy|Curl|HttpClient)) {
    return 403;

请求过滤

根据请求类型过滤

# 非指定请求全返回 403
if ( $request_method !~ ^(GET|POST|HEAD)$ ) {
    return 403;
}

根据状态码过滤

error_page 502 503 /50x.html;
location = /50x.html {
    root /usr/share/nginx/html;
}

这样实际上是一个内部跳转,当访问出现 502、503 的时候就能返回 50x.html 中的内容,这里需要注意是否可以找到 50x.html 页面,所以加了个 location 保证找到你自定义的 50x 页面。

根据 URL 名称过滤

if ($host = zy.com' ) {     #其中 $1是取自regex部分()里的内容,匹配成功后跳转到的URL。     rewrite ^/(.*)$  http://www.zy.com/$1  permanent;}location /test {    // /test 全部重定向到首页    rewrite  ^(.*)$ /index.html  redirect;}

ab 命令

ab 命令全称为:Apache bench,是 Apache 自带的压力测试工具,也可以测试 Nginx、IIS 等其他 Web 服务器:

  • -n 总共的请求数
  • -c 并发的请求数
  • -t 测试所进行的最大秒数,默认值 为 50000
  • -p 包含了需要的 POST 的数据文件
  • -T POST 数据所使用的 Content-type 头信息
ab -n 1000 -c 5000 http://127.0.0.1/ # 每次发送1000并发的请求数,请求数总数为5000。

测试前需要安装 httpd-tools: yum install httpd-tools

泛域名路径分离

这是一个非常实用的技能,经常有时候我们可能需要配置一些二级或者三级域名,希望通过 nginx 自动指向对应目录,比如:

  1. test1.doc.test.club 自动指向 /usr/local/html/doc/test1 服务器地址;
  2. test2.doc.test.club 自动指向 /usr/local/html/doc/test2 服务器地址;
server {    listen       80;    server_name  ~^([\w-]+)\.doc\.test\.club$;    root /usr/local/html/doc/$1;}

泛域名转发

和之前的功能类似,有时候我们希望把二级或者三级域名链接重写到我们希望的路径,让后端就可以根据路由解析不同的规则:

  1. test1.serv.test.club/api?name=a 自动转发到 127.0.0.1:8080/test1/api?name=a
  2. test2.serv.test.club/api?name=a 自动转发到 127.0.0.1:8080/test2/api?name=a
server {    listen       80;    server_name ~^([\w-]+)\.serv\.test\.club$;    location / {        proxy_set_header        X-Real-IP $remote_addr;        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_set_header        Host $http_host;        proxy_set_header        X-NginX-Proxy true;        proxy_pass              http://127.0.0.1:8080/$1$request_uri;    }}

常见问题

nginx 中怎么设置变量

或许你不知道,nginx 的配置文件使用的是一门微型的编程语言。既然是编程语言,一般也就少不了“变量”这种东西,但是在 nginx 配置中,变量只能存放一种类型的值,因为也只存在一种类型的值,那就是字符串。

例如我们在 nginx.conf 中有这样一行配置:

set $name "chroot";

上面使用了 set 配置指令对变量 $name进行了赋值操作,把 "chroot" 赋值给了 $name。nginx 变量名前面有一个 $ 符号,这是记法上的要求。所有的 Nginx 变量在 Nginx 配置文件中引用时都须带上 $ 前缀。这种表示方法和 Perl、PHP 这些语言是相似的。

这种表示方法的用处在哪里呢,那就是可以直接把变量嵌入到字符串常量中以构造出新的字符串,例如你需要进行一个字符串拼接:

server {
  listen       80;
  server_name  test.com;

  location / {
     set $temp hello;
     return "$temp world";
  }
}

以上当匹配成功的时候就会返回字符串 "hello world" 了。需要注意的是,当引用的变量名之后紧跟着变量名的构成字符时(比如后跟字母、数字以及下划线),我们就需要使用特别的记法来消除歧义,例如:

server {
  listen       80;
  server_name  test.com;

  location / {
     set $temp "hello ";
     return "${temp}world";
  }
}

这里,我们在配置指令的参数值中引用变量 $temp 的时候,后面紧跟着 world 这个单词,所以如果直接写作 "$tempworld" 则 nginx 的计算引擎会将之识别为引用了变量 $tempworld. 为了解决这个问题,nginx 的字符串支持使用花括号在 $ 之后把变量名围起来,比如这里的 ${temp},所以 上面这个例子返回的还是 "hello world":

$ curl 'http://test.com/'
    hello world

还需要注意的是,若是想输出 $ 符号本身,可以这样做:

geo $dollar {
    default "$";
}
server {
    listen       80;
    server_name  test.com;

    location / {
        set $temp "hello ";
        return "${temp}world: $dollar";
    }
}

上面用到了标准模块 ngx_geo 提供的配置指令 geo 来为变量 $dollar 赋予字符串 "$" ,这样,这里的返回值就是 "hello world: $" 了。

附 nginx 内置预定义变量

按字母顺序,变量名与对应定义:

  • $arg_PARAMETER #GET 请求中变量名 PARAMETER 参数的值
  • $args #这个变量等于 GET 请求中的参数,例如,foo=123&bar=blahblah;这个变量可以被修改
  • $binary_remote_addr #二进制码形式的客户端地址
  • $body_bytes_sent #传送页面的字节数
  • $content_length #请求头中的 Content-length 字段
  • $content_type #请求头中的 Content-Type 字段
  • $cookie_COOKIE #cookie COOKIE 的值
  • $document_root #当前请求在 root 指令中指定的值
  • $document_uri #与 $uri 相同
  • $host #请求中的主机头(Host)字段,如果请求中的主机头不可用或者空,则为处理请求的 server 名称(处理请求的 server 的 server_name 指令的值)。值为小写,不包含端口
  • $hostname #机器名使用 gethostname 系统调用的值
  • $http_HEADER #HTTP 请求头中的内容,HEADER 为 HTTP 请求中的内容转为小写,-变为_(破折号变为下划线),例如:$http_user_agent(Uaer-Agent 的值)
  • $sent_http_HEADER #HTTP 响应头中的内容,HEADER 为 HTTP 响应中的内容转为小写,-变为_(破折号变为下划线),例如:[公式]sent_http_content_type…
  • $is_args #如果 $args 设置,值为"?",否则为""
  • $limit_rate #这个变量可以限制连接速率
  • $nginx_version #当前运行的 nginx 版本号
  • $query_string #与 $args 相同
  • $remote_addr #客户端的 IP 地址
  • $remote_port #客户端的端口
  • $remote_port #已经经过 Auth Basic Module 验证的用户名
  • $request_filename #当前连接请求的文件路径,由 root 或 alias 指令与 URI 请求生成
  • $request_body #这个变量(0.7.58+)包含请求的主要信息。在使用 proxy_pass 或 fastcgi_pass 指令的 location 中比较有意义
  • $request_body_file #客户端请求主体信息的临时文件名
  • $request_completion #如果请求成功,设为"OK";如果请求未完成或者不是一系列请求中最后一部分则设为空
  • $request_method #这个变量是客户端请求的动作,通常为 GET 或 POST。包括 0.8.20 及之前的版本中,这个变量总为 main request 中的动作,如果当前请求是一个子请求,并不使用这个当前请求的动作
  • $request_uri #这个变量等于包含一些客户端请求参数的原始 URI,它无法修改,请查看 $uri 更改或重写 URI
  • $scheme #所用的协议,例如 http 或者是 https,例如 rewrite ^(.+)$$scheme://example.com$1 redirect
  • $server_addr #服务器地址,在完成一次系统调用后可以确定这个值,如果要绕开系统调用,则必须在 listen 中指定地址并且使用 bind 参数
  • $server_name #服务器名称
  • $server_port #请求到达服务器的端口号
  • $server_protocol #请求使用的协议,通常是 HTTP/1.0、HTTP/1.1 或 HTTP/2
  • $uri #请求中的当前 URI(不带请求参数,参数位于 args ) , 不 同 于 浏 览 器 传 递 的 args),不同于浏览器传递的 args),不同于浏览器传递的 request_uri 的值,它可以通过内部重定向,或者使用 index 指令进行修改。不包括协议和主机名,例如 /foo/bar.html

附 nginx 模块

nginx 模块分类

  • 核心模块:nginx 最基本最核心的服务,如进程管理、权限控制、日志记录;
  • 标准 HTTP 模块:nginx 服务器的标准 HTTP 功能;
  • 可选 HTTP 模块:处理特殊的 HTTP 请求
  • 邮件服务模块:邮件服务
  • 第三方模块:作为扩展,完成特殊功能

模块清单

核心模块

  • ngx_core
  • ngx_errlog
  • ngx_conf
  • ngx_events
  • ngx_event_core
  • ngx_epll
  • ngx_regex

标准 HTTP 模块

  • ngx_http
  • ngx_http_core #配置端口,URI 分析,服务器相应错误处理,别名控制 (alias) 等
  • ngx_http_log #自定义 access 日志
  • ngx_http_upstream #定义一组服务器,可以接受来自 proxy, Fastcgi,Memcache 的重定向;主要用作负载均衡
  • ngx_http_static
  • ngx_http_autoindex #自动生成目录列表
  • ngx_http_index #处理以/结尾的请求,如果没有找到 index 页,则看是否开启了 random_index;如开启,则用之,否则用 autoindex
  • ngx_http_auth_basic #基于 http 的身份认证 (auth_basic)
  • ngx_http_access #基于 IP 地址的访问控制 (deny,allow)
  • ngx_http_limit_conn #限制来自客户端的连接的响应和处理速率
  • ngx_http_limit_req #限制来自客户端的请求的响应和处理速率
  • ngx_http_geo
  • ngx_http_map #创建任意的键值对变量
  • ngx_http_split_clients
  • ngx_http_referer #过滤 HTTP 头中 Referer 为空的对象
  • ngx_http_rewrite #通过正则表达式重定向请求
  • ngx_http_proxy
  • ngx_http_fastcgi #支持 fastcgi
  • ngx_http_uwsgi
  • ngx_http_scgi
  • ngx_http_memcached
  • ngx_http_empty_gif #从内存创建一个 1×1 的透明 gif 图片,可以快速调用
  • ngx_http_browser #解析 http 请求头部的 User-Agent 值
  • ngx_http_charset #指定网页编码
  • ngx_http_upstream_ip_hash
  • ngx_http_upstream_least_conn
  • ngx_http_upstream_keepalive
  • ngx_http_write_filter
  • ngx_http_header_filter
  • ngx_http_chunked_filter
  • ngx_http_range_header
  • ngx_http_gzip_filter
  • ngx_http_postpone_filter
  • ngx_http_ssi_filter
  • ngx_http_charset_filter
  • ngx_http_userid_filter
  • ngx_http_headers_filter #设置 http 响应头
  • ngx_http_copy_filter
  • ngx_http_range_body_filter
  • ngx_http_not_modified_filter

可选 HTTP 模块:

  • ngx_http_addition #在响应请求的页面开始或者结尾添加文本信息
  • ngx_http_degradation #在低内存的情况下允许服务器返回 444 或者 204 错误
  • ngx_http_perl
  • ngx_http_flv #支持将 Flash 多媒体信息按照流文件传输,可以根据客户端指定的开始位置返回 Flash
  • ngx_http_geoip #支持解析基于 GeoIP 数据库的客户端请求
  • ngx_google_perftools
  • ngx_http_gzip #gzip 压缩请求的响应
  • ngx_http_gzip_static #搜索并使用预压缩的以.gz 为后缀的文件代替一般文件响应客户端请求
  • ngx_http_image_filter #支持改变 png,jpeg,gif 图片的尺寸和旋转方向
  • ngx_http_mp4 #支持.mp4,.m4v,.m4a 等多媒体信息按照流文件传输,常与 ngx_http_flv 一起使用
  • ngx_http_random_index #当收到 / 结尾的请求时,在指定目录下随机选择一个文件作为 index
  • ngx_http_secure_link #支持对请求链接的有效性检查
  • ngx_http_ssl #支持 https
  • ngx_http_stub_status
  • ngx_http_sub_module #使用指定的字符串替换响应中的信息
  • ngx_http_dav #支持 HTTP 和 WebDAV 协议中的 PUT/DELETE/MKCOL/COPY/MOVE 方法
  • ngx_http_xslt #将 XML 响应信息使用 XSLT 进行转换

邮件服务模块:

  • ngx_mail_core
  • ngx_mail_pop3
  • ngx_mail_imap
  • ngx_mail_smtp
  • ngx_mail_auth_http
  • ngx_mail_proxy
  • ngx_mail_ssl

第三方模块

  • echo-nginx-module #支持在 nginx 配置文件中使用 echo/sleep/time/exec 等类 Shell 命令
  • memc-nginx-module
  • rds-json-nginx-module #使 nginx 支持 json 数据的处理
  • lua-nginx-module



 



 
 
 







posted on 2021-01-13 15:59  UnmatchedSelf  阅读(243)  评论(0编辑  收藏  举报

导航