本文是官网文档的入门学习笔记,官网链接:Beginner Guide
nginx入门
安装(centos7)
1) 配置yum源:vi /etc/yum.repos.d/nginx.repo
2) 按i进入vi工具的编辑模式,输入下面的yum配置:
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/OS/OSRELEASE/$basearch/
gpgcheck=0
enabled=1
其中baseurl
部分,需要替换实际的参数:
“OS” 换成 “rhel” 或 “centos”,
“OSRELEASE” 换成 “6” 或 “7”
由于我用的是centos7,所以baseurl=http://nginx.org/packages/centos/7/$basearch/
3) 按esc
退出编辑模式,按:
进入命令模式,输入wq
,写入内容并退出vi工具。
4) 安装:yum install -y nginx
简介
nginx
(读作engine x)是一个HTTP服务器,也可以用作反向代理服务器、邮件代理服务器。作者是Igor Sysoev
。俄罗斯很多指明网站如Yandex、 Mail.Ru、 VK、Rambler都长期使用nginx。据Netcraft统计,截至2017年9月,有29.38%商业网站使用ngnix做服务器或做代理,比如有:Dropbox、Netflix、Wordpress.com、FastMail.FM
nginx有一个主进程和几个worker进程。主进程的作用是读取并执行配置,并维护worker进程。worker进程是实际处理请求的进程。
nginx采用事件驱动模型和基于系统的一些机制来高效分发请求给多个worker进程。worker进程的数量可以在配置文件中配置。
nginx的配置文件默认名称是nginx.conf
,一般在以下这些目录中可以找到:
/usr/local/nginx/conf
/etc/nginx
/usr/local/etc/nginx
启动、停止、重新加载配置
可以直接运行nginx
命令启动,nginx启动后,可以通过一下的语法来控制nginx:
nginx -s signal
上面的s代表signal,信号的意思
signal可以是以下的值:
- stop — 快速地关闭
- quit — 优雅地关闭
- reload — 重新加载配置文件
- reopen — 重新打开日志文件
例如,如果需要等待所有worker进程完成请求之后停止nginx,可以执行一下的命令:
nginx -s quit
假如您是使用userA帐号登录linux后启动nginx的,您应该同样使用userA帐号,而不是userB、userC
如果修改了配置文件,需要发送以下命令重新加载配置,否则配置不会生效:
nginx -s reload
当主进程收到重新加载配置的命令后,主进程会检查配置文件的语法并尝试应用新的配置。
如果成功了,主进程会启动一个新的worker进程,并发送消息给旧的worker进程,让旧的worker进程关闭。
如果不成功,主进程会回滚到旧的配置,并继续用旧的配置继续运行。
至于收到关闭命令的旧worker进程,会停止接收新的连接,处理完所有剩下的请求后,旧的worker进程就会结束。
另外,使用Unix系统提供的kill
命令也可以向nginx进程发送关闭的信号(用进程id)。进程id默认是记录在/usr/local/nginx/logs
或/var/run
目录下的nginx.pid
文件中,知道了进程id之后(假如进程id是1628),就可以这样输入命令:
kill -s QUIT 1628
如果需要知道所有正在运行的nginx进程,可以使用ps
命令:
ps -ax | grep nginx
配置文件的结构
nginx是由模块组成的,这些模块是通过在配置文件中声明的指令来控制的。指令有两种:简单指令
(单条语句)和块指令
(代码块)。简单指令
由指令名、参数组成,指令名和参数间用空格隔开,最后以分号(;)结束
。块指令
跟简单指令结构一样,但是区别就是块指令不以分号结束,而是用花括号( { 和 } )括起来
。
如果一个块指令可以在花括号内包含其它指令,那这个块指令叫context
(例如:events, http, server, and location)。
在配置文件中,写在context以外的的指令,就是在main context
中。比如下面的代码,events
和http
指令属于main context
,http中有server,server中有location。
events{
...
}
http{
server{
location{
...
}
}
}
在配置文件中,井号#开头的就是注释。
通过vi /etc/nginx/nginx.conf
打开配置文件,nginx配置文件内容如下:
user nginx;
worker_processes 1; //<--简单指令
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {//<--块指令
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
配置静态资源服务器
web服务器的一个重要功能是对外提供文件访问服务,如图片或静态html页面。接下来,我们将实现这样一个功能:
假设nginx所在的服务器有以下目录:
-
/data/www
目录,用于存放html文件,请自行放一个index.html静态html文件进去 -
/data/images
目录,用于存放的是图片,请自行放一些图片进去
我们需要设置nginx响应外部的请求,把这些目录下的文件提供对外访问。我们需要在配置文件的http
块中设置一个server
块,并在server
块中设置两个location
块。完整的代码如下:
http{
server {
location / {
root /data/www;
}
location /images/ {
root /data;
}
}
}
默认情况下,nginx会监听80
端口,因此无需在server块中配置端口80。
http
下一般会有多个server
配置,这些server块可以用端口
和名称
来区分。
当nginx确定了采用哪个server来处理请求,nginx会拿到请求头
中的URI
信息,与location
指令的参数来匹配。
如下图,就显示了请求头中的请求路径信息:
在下面这段代码中:
location / {
root /data/www;
}
location
是一条指令,/
是指令的参数,location /
的含义是:声明一个前缀,这个前缀会与请求头中的URI信息进行匹配(上面截图)。对于匹配的请求,URI路径会追加到
root指令声明的参数后,组成服务器端文件的路径,即:
/data/www`。
再看一些例子来理解一下:
示例1:
location: /
root: /data/www
请求:http://127.0.0.1
(URI是"",匹配到location /)
服务器文件路径:root的参数 + URI = /data/wwww
+ ""
= /data/www
示例2:
location: /
root: /data/www
请求:http://127.0.0.1/images/test1.jpg
(URI是"/images/test1.jpg",匹配到location /)
服务器文件路径:root的参数 + URI = /data/wwww
+ "/images/test1.jpg"
= /data/wwww/images/test1.jpg
示例3:
location: /images/
root: /data
请求:http://127.0.0.1/images/test1.jpg
(URI是"/images/test1.jpg",匹配到location /images/)
服务器文件路径:root的参数 + URI = /data
+ "/images/test1.jpg"
= /data/images/test1.jpg
一定要看清楚上面2和3的区别!!服务器端文件路径是由root的参数和请求的URI拼出来的,而不是root的参数和location的参数,location的参数是用来匹配请求的
注意:
如果有多个匹配的location
,nginx会选前缀最长的那个。如下面这段代码:
location / {
root /data/www;
}
location /images/ {
root /data;
}
当请求http://127.0.0.1/images/test1.jpg
时,上面两个location都能匹配到URI:/images/test1.jpg。但是由于/images/
比/
长,所以nginx最终会匹配到location /images/
。
注意,这个配置:
location /images/ {
root /data;
}
如果请求是 http://localhost/images/test1.jpg
,由于匹配到/images/
,在服务器上的文件路径应该是 root的参数 + 请求的URI ,即:/data
+ /images/test1.jpg
= /data/images/test1.jpg
加载新配置
如果你未启动nginx,启动后就可以应用新的配置了。如果nginx已经启动,需要执行以下命令让nginx加载新的配置:
nginx -s reload
如果nginx出现问题了,你可以在/usr/local/nginx/logs
或/var/log/nginx
目录下找到access.log
和error.log
,看日志找原因。
完整配置示例:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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;
keepalive_timeout 65;
#gzip on;
server{
location / {
root /data/www;
}
location /images/ {
root /data;
}
}
include /etc/nginx/conf.d/*.conf;
}
配置代理服务器
nginx作为代理服务器的时候,它扮演的是一个中间角色(proxy)。负责接收客户端(client)的请求,代理请求到目标服务器(target),接收目标服务器的响应,最后把响应发送给客户端。其交互过程如下图:
proxied
|--------| request |--------| request |--------|
| |------------>| |------------>| |
| client | | proxy | | target |
| |<------------| |<------------| |
|--------| response |--------| response |--------|
例子:
需求:
假如浏览器请求
http://localhost/
,则把请求代理到http://localhost:8080/
假如浏览器请求http://localhost/test5.jpg
,则不做代理,直接响应本机的/data/images/test5.jpg
实现:
# 省略其它代码...
http {
# 省略其它代码...
#gzip on;
server{
listen 8080;
root /data/up1;
location / {
}
}
server{
location / {
proxy_pass http://localhost:8080;
}
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
include /etc/nginx/conf.d/*.conf;
}
代码解释:
代码段1
:
server{
listen 8080;
root /data/up1;
location / {
}
}
代码段1
的作用是声明一个server,监听8080端口(listen
指令是用来监听的端口的,由于nginx默认是监听80端口,默认监听80端口则可以省略不写)。 root /data/up1
一行声明把所有发送到8080
端口的请求都用/data/up1
目录下的内容来响应(请自行在/data/up1
目录下创建测试用的index.html文件)。
请注意,root /data/up1
是写在server
块中,而不是location块中。
当我们配置了一个 location / { }
,location块中没有root
指令,那这个location就会用server块下的root /data/up1
的配置。
这个有点绕,但是这里是为了说明特殊情况。一般我们用这样就可以:
server{
listen 8080;
location / {
root /data/up1;
}
}
代码段2
:
server{
location / {
proxy_pass http://localhost:8080;
}
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
代码段2
声明了另一个server
,监听80
端口(不是代码段1中的8080端口了!)。
然后,映射了两种不同的请求路径:
- 1)
location /
,如果匹配到这个路径的请求,那将会将请求代理到8080
端口。
比如:
请求:
http://localhost/
(request-A),匹配到location /
,就会再发送一个请求(request-B):http://localhost:8080/
。
然后代码段1
配置的location /
就会匹配到该请求(request-B),就会响应/data/up1/index.html
。
- 2)
location ~ \.(gif|jpg|png)$
,用于匹配.gif、.jpg、.png后缀的图片请求。
比如:
请求
http://localhost/test5.jpg
,在两个location
中会匹配到第二个(location ~ \.(gif|jpg|png)$
),因为第二个location的前缀比第一个location的前缀长。
因此请求不会代理到http://localhost:8080
,而是直接响应配置的/data/images
目录下的test5.jpg
文件(请自行添加测试图片文件)
另外,还需要注意:location ~ \.(gif|jpg|png)$
用了正则表达式来匹配请求,location
指令使用正则表达式,必须跟着一个波浪~
符号做正则表达式的开头。
配置好之后,记得重新加载配置:nginx -s reload
文字看不懂就看图吧
当请求http://localhost/
是,发生的代理过程如下:
|---------| http://localhost/ |------------------------------------------------|
| A |----------------------->| B |----B同时是proxy和target
| client | | match server at port 80 `location /` |
| | | ⬇ |
| | | ⬇proxy to `http://localhost:8080` |
| | | ⬇ |
| | | match server at port 8080 `location /` |
| | | ⬇ |
| | | ⬇serve default index.html file |
| | | ⬇ |
| |<-----------------------| /data/up1/index.html |
|---------| /data/up1/index.html |------------------------------------------------|
当请求http://localhost/test5.jpg
是,没有发生的代理,其响应过程如下:
|---------| http://localhost/test5.jpg |--------------------------------------------------------|
| A |--------------------------->| B |
| client | | match server at port 80 `location ~ \.(gif|jpg|png)$` |
| | | ⬇ |
| | | ⬇serve match image file |
| | | ⬇ |
| |<---------------------------| /data/images/test5.jpg |
|---------| /data/images/test5.jpg |--------------------------------------------------------|
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。