资讯专栏INFORMATION COLUMN

Nginx入门

Meathill / 2475人阅读

摘要:据统计,截至年月,有商业网站使用做服务器或做代理,比如有有一个主进程和几个进程。主进程的作用是读取并执行配置,并维护进程。进程是实际处理请求的进程。简单指令由指令名参数组成,指令名和参数间用空格隔开,最后以分号结束。

本文是官网文档的入门学习笔记,官网链接: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中。比如下面的代码,eventshttp指令属于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.logerror.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     |--------------------------------------------------------|

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/39654.html

相关文章

  • 不正宗 docker 入门教程-启动一个容器(1/3)

    摘要:从命名上就知道这是一篇简单粗暴的新手入门教程,为什么要简单粗暴我认为有自学能力的人帮他入门就够了,不能自学的一时半会儿也教不会,不符合入门教程的初衷,建议出门左拐去找找视频教程本章目标大概了解是个什么玩意知道常用的指令参数能启动一个容器不然 从命名上就知道这是一篇简单粗暴的docker新手入门教程, 为什么要简单粗暴? 我认为有自学能力的人帮他入门就够了, 不能自学的一时半会儿也教不会...

    YorkChen 评论0 收藏0
  • Nginx入门及如何反向代理解决生产环境跨域问题

    摘要:还是回到万能的文件,添加匹配规则实现代理转发设置代理转发通过上面的设置,在重启服务,可以让页面中所有包含字段的请求都转为由服务器去向地址发送请求,从而巧妙的解决了浏览器的跨域问题。 1.Nginx入门与基本操作篇 注:由于服务器是windows系统,所以本文主要讲解Nginx在windows下的操作。 首先下载Nginx 解压缩,我们所有的配置基本都在万能的 nginx/conf/...

    Moxmi 评论0 收藏0
  • Nginx 极简入门教程!

    上篇文章和大家聊了 Spring Session 实现 Session 共享的问题,有的小伙伴看了后表示对 Nginx 还是很懵,因此有了这篇文章,算是一个 Nginx 扫盲入门吧! 基本介绍 Nginx 是一个高性能的 HTTP 和反向代理 web 服务器,同时也提供了 IMAP/POP3/SMTP 服务。 Nginx 是由伊戈尔·赛索耶夫为俄罗斯访问量第二的 Rambler.ru 站点开发...

    _DangJin 评论0 收藏0
  • Nginx 安装与配置规则入门

    摘要:即别名,与的匹配规则稍有不同。与的区别只能作用在中,而可以存在和中。后面必须要用结束,否则会找不到文件,而则对可有可无。 Nginx 安装与配置规则入门 nginx 安装与运行 (Mac OS环境) nginx 规则配置入门 一些命令行的配置 一、nginx 安装与运行 (Mac OS环境) 1. 安装 nginx 可通过 Homebrew 可直接安装: $brew install...

    senntyou 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<