Nginx基础知识从小白到入门
前言
Nginx现在几乎是众多大型网站的必用技术,大家应该都知道Nginx被F5收购的大事件,章亦春也在专心维护OpenResty项目构建和谐家园,无论你选择Nginx还是OpenResty,都需要对Nginx有一个比较全面的了解,日后才能做到事半功倍。本文以开发者必备的Nginx基础知识为主,在参考文章中罗列了目前比较优秀的Nginx和OpenResty参考教程,希望对大家有帮助。
Nginx基础知识从小白到入门
更新历史
2020年02月25日 - 更新nginx基础知识
2019年11月12日 - 初稿
阅读原文 - https://wsgzao.github.io/post/nginx/
扩展阅读
Nginx基础知识
Nginx是什么?
Nginx 是一个 web 服务器,主要处理客户端和服务器的请求分发。
特点和优势
- 高并发
- 热部署
- 快
- 低功耗
- 热部署
使用和扩展
开源免费的Nginx与商业版Nginx Plus,与之对应的是免费OpenResty与商业版OpenResty
- 开源版 nginx.org
- 商业版 NGINX Plus
- 阿里巴巴 Tengine
- 开源版 OpenResty
- 商业版 OpenResty
陶辉《深入理解 Nginx》作者在极客时间上的讲义PDF已经介绍的非常详细了,如果觉得课程不错可以选择购买尽量少走弯路
nginx正向代理与反向代理
为了便于理解,首先先来了解一下一些基础知识,nginx是一个高性能的反向代理服务器那么什么是反向代理呢?
代理是在服务器和客户端之间假设的一层服务器,代理将接收客户端的请求并将它转发给服务器,然后将服务端的响应转发给客户端。
不管是正向代理还是反向代理,实现的都是上面的功能。
如果你对OSI 七层模型与 TCP/IP 四层模型不是很熟悉可以再回顾下
正向代理
正向代理(forward)意思是一个位于客户端和原始服务器 (origin server) 之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标 (原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。
正向代理是为我们服务的,即为客户端服务的,客户端可以根据正向代理访问到它本身无法访问到的服务器资源。
正向代理对我们是透明的,对服务端是非透明的,即服务端并不知道自己收到的是来自代理的访问还是来自真实客户端的访问。
反向代理
反向代理(Reverse Proxy)方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
反向代理是为服务端服务的,反向代理可以帮助服务器接收来自客户端的请求,帮助服务器做请求转发,负载均衡等。
反向代理对服务端是透明的,对我们是非透明的,即我们并不知道自己访问的是代理服务器,而服务器知道反向代理在为他服务。
nginx基本配置
安装nginx时通常需要编译自己需要的模块,可以使用 rpmbuild 制作 Nginx 的 RPM 包
1 | main # 全局配置 |
如果想要生成nginx规范配置,可以参考nginxconfig.io
下面是 nginx
一些配置中常用的内置全局变量,你可以在配置的任何位置使用它们。
变量名 | 功能 |
---|---|
$host |
请求信息中的 Host ,如果请求中没有 Host 行,则等于设置的服务器名 |
$request_method |
客户端请求类型,如 GET 、POST |
$remote_addr |
客户端的 IP 地址 |
$args |
请求中的参数 |
$content_length |
请求头中的 Content-length 字段 |
$http_user_agent |
客户端 agent 信息 |
$http_cookie |
客户端 cookie 信息 |
$remote_addr |
客户端的 IP 地址 |
$remote_port |
客户端的端口 |
$server_protocol |
请求使用的协议,如 HTTP/1.0 、HTTP/1.1\ |
$server_addr |
服务器地址 |
$server_name |
服务器名称 |
$server_port |
服务器的端口号 |
location匹配规则
语法规则:location [=|~|~*|^~] /uri/ { … }
模式 | 含义 |
---|---|
location = /uri | = 表示精确匹配,只有完全匹配上才能生效 |
location ^~ /uri | ^~ 开头对URL路径进行前缀匹配,并且在正则之前。 |
location ~ pattern | 开头表示区分大小写的正则匹配 |
location ~* pattern | 开头表示不区分大小写的正则匹配 |
location /uri | 不带任何修饰符,也表示前缀匹配,但是在正则匹配之后 |
location / | 通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中的default |
前缀匹配时,Nginx 不对 url 做编码,因此请求为 /static/20%/aa
,可以被规则 ^~ /static/ /aa
匹配到(注意是空格)
多个 location 配置的情况下匹配顺序为:
- 首先精确匹配
=
- 其次前缀匹配
^~
- 其次是按文件中顺序的正则匹配
- 然后匹配不带任何修饰的前缀匹配。
- 最后是交给
/
通用匹配 - 当有匹配成功时候,停止匹配,按当前匹配规则处理请求
意:前缀匹配,如果有包含关系时,按最大匹配原则进行匹配。比如在前缀匹配:location /dir01
与 location /dir01/dir02
,如有请求 http://localhost/dir01/dir02/file
将最终匹配到 location /dir01/dir02
例子,有如下匹配规则:
1 | location = / { |
那么产生的效果如下:
- 访问根目录
/
,比如http://localhost/
将匹配规则A
- 访问
http://localhost/login
将匹配规则B
,http://localhost/register
则匹配规则F
- 访问
http://localhost/static/a.html
将匹配规则C
- 访问
http://localhost/static/files/a.exe
将匹配规则X
,虽然规则C
也能匹配到,但因为最大匹配原则,最终选中了规则X
。你可以测试下,去掉规则 X ,则当前 URL 会匹配上规则C
。 - 访问
http://localhost/a.gif
,http://localhost/b.jpg
将匹配规则D
和规则 E
,但是规则 D
顺序优先,规则 E
不起作用,而http://localhost/static/c.png
则优先匹配到规则 C
- 访问
http://localhost/a.PNG
则匹配规则 E
,而不会匹配规则 D
,因为规则 E
不区分大小写。 - 访问
http://localhost/img/a.gif
会匹配上规则D
,虽然规则Y
也可以匹配上,但是因为正则匹配优先,而忽略了规则Y
。 - 访问
http://localhost/img/a.tiff
会匹配上规则Y
。
访问 http://localhost/category/id/1111
则最终匹配到规则 F ,因为以上规则都不匹配,这个时候应该是 Nginx 转发请求给后端应用服务器,比如 FastCGI(php),tomcat(jsp),Nginx 作为反向代理服务器存在。
nginx日志
Nginx 日志主要有两种:access_log(访问日志) 和 error_log(错误日志)。
access_log 访问日志
access_log 主要记录客户端访问 Nginx 的每一个请求,格式可以自定义。通过 access_log 你可以得到用户地域来源、跳转来源、使用终端、某个 URL 访问量等相关信息。
log_format 指令用于定义日志的格式,语法: log_format name string;
其中 name 表示格式名称,string 表示定义的格式字符串。log_format 有一个默认的无需设置的组合日志格式。
默认的无需设置的组合日志格式
1 | log_format combined '$remote_addr - $remote_user [$time_local] ' |
access_log 指令用来指定访问日志文件的存放路径(包含日志文件名)、格式和缓存大小,语法:access_log path [format_name [buffer=size | off]];
其中 path 表示访问日志存放路径,format_name 表示访问日志格式名称,buffer 表示缓存大小,off 表示关闭访问日志。
log_format 使用示例:在 access.log 中记录客户端 IP 地址、请求状态和请求时间
1 | log_format myformat '$remote_addr $status $time_local'; |
需要注意的是:log_format 配置必须放在 http 内,否则会出现警告。Nginx 进程设置的用户和组必须对日志路径有创建文件的权限,否则,会报错。
定义日志使用的字段及其作用:
字段 | 作用 |
---|---|
$remote_addr与$http_x_forwarded_for | 记录客户端IP地址 |
$remote_user | 记录客户端用户名称 |
$request | 记录请求的URI和HTTP协议 |
$status | 记录请求状态 |
$body_bytes_sent | 发送给客户端的字节数,不包括响应头的大小 |
$bytes_sent | 发送给客户端的总字节数 |
$connection | 连接的序列号 |
$connection_requests | 当前通过一个连接获得的请求数量 |
$msec | 日志写入时间。单位为秒,精度是毫秒 |
$pipe | 如果请求是通过HTTP流水线(pipelined)发送,pipe值为“p”,否则为“.” |
$http_referer | 记录从哪个页面链接访问过来的 |
$http_user_agent | 记录客户端浏览器相关信息 |
$request_length | 请求的长度(包括请求行,请求头和请求正文) |
$request_time | 请求处理时间,单位为秒,精度毫秒 |
$time_iso8601 | ISO8601标准格式下的本地时间 |
$time_local | 记录访问时间与时区 |
error_log 错误日志
error_log 主要记录客户端访问 Nginx 出错时的日志,格式不支持自定义。通过查看错误日志,你可以得到系统某个服务或 server 的性能瓶颈等。因此,将日志利用好,你可以得到很多有价值的信息。
error_log 指令用来指定错误日志,语法: error_log path [level]
; 其中 path 表示错误日志存放路径,level 表示错误日志等级,日志等级包括 debug、info、notice、warn、error、crit、alert、emerg,从左至右,日志详细程度逐级递减,即 debug 最详细,emerg 最少,默认为 error。
注意:error_log off
并不能关闭错误日志记录,此时日志信息会被写入到文件名为 off 的文件当中。如果要关闭错误日志记录,可以使用如下配置:
Linux 系统把存储位置设置为空设备
1 | error_log /dev/null; |
Windows 系统把存储位置设置为空设备
1 | error_log nul; |
另外 Linux 系统可以使用 tail 命令方便的查阅正在改变的文件,tail -f filename 会把 filename 里最尾部的内容显示在屏幕上, 并且不断刷新, 使你看到最新的文件内容。Windows 系统没有这个命令,你可以在网上找到动态查看文件的工具。
nginx负载均衡
Upstream 指定后端服务器地址列表,在 server 中拦截响应请求,并将请求转发到 Upstream 中配置的服务器列表。
1 | upstream balanceServer { |
上面的配置只是指定了 nginx 需要转发的服务端列表,并没有指定分配策略。
默认情况下采用的是轮询策略,将所有客户端请求轮询分配给服务端。这种策略是可以正常工作的,但是如果其中某一台服务器压力太大,出现延迟,会影响所有分配在这台服务器下的用户。
nginx常用命令
1 | # 快速关闭Nginx,可能不保存相关信息,并迅速终止web服务 |
参考文章
以上内容只是nginx的冰山一角,我个人推荐大家跟着官方文档或者类似极客时间的教程学习,可以少走很多弯路
以下为极客时间专栏