nginx-Web服务器

nginx最常用的是作为一个web服务器,既能代理静态资源,也能转发请求。

以下是本博客的目录:
在这里插入图片描述

建立虚拟服务

使用listen指令指定ip和端口:

server {
    listen 127.0.0.1:8080;
    # The rest of server configuration
}
  1. 如果没有指定端口,则为默认80;
  2. 如果没有指定IP,则监听所有的IP(一台电脑可以有几个IP吧);
  3. 如果没有listen指令,则监听80/tcp或者8000/tcp ,视系统而定。

如果多个虚拟服务监听相同的IP和端口,那么nginx会比较请求的Host参数和server_name来决定选择哪一个虚拟服务。
sever_name可以是以下几种形式:

  1. 全称
  2. 包含通配符(*)
  3. 正则表达式(以~开头)(注意,nginx采用的是perl语言的正则表达式语法)

如果有多个虚拟服务的server_name匹配Host,nginx使用以下次序来选择(由具体到抽象):

  1. 全称
  2. 以*开头
  3. 以*结尾
  4. 正则表达式(如果有多个满足,按配置文件的次序选择第一个满足的虚拟服务)

最后,如果Host没有匹配任何server_name,则选择默认的虚拟服务;一般默认是第一个server块,除非用default_server指定默认的虚拟服务。

server {
    listen      80 default_server;
    ...
}

配置路径

location指令的参数可以是:

  1. 前缀字符串(必须是路径的开头,不能是路径的中间部分或者末尾部分)
  2. 正则表达式(perl正则表达式语法)

对于1,/some/path/能匹配/some/path/document.html,但是不能匹配/my-site/some/path;
对于2,

  1. 如果以~开头,则大小写敏感;
  2. 如果~*开头,则大小写不敏感;
location ~ \.html? {
    ...
}

上面的代码匹配任何包含.html或者.htm的路径。
匹配路径时,正则表达式的优先级要高于前缀字符串
nginx处理请求时,选择路径的逻辑如下:

  1. 测试所有的前缀字符串;
  2. =定义了uri和前缀字符串的精准匹配,如果精准匹配找到,则搜索停止;
  3. 如果匹配的最长前缀字符串以^~开头,则正则表达式不会被检查;
  4. 保存最长的前缀字符串;
  5. 测试所有的正则表达式;
  6. 如果有正则表达式匹配,则选取相应的路径;
  7. 如果没有正则表达式匹配,则选取保存的最长前缀字符串所在的路径。

注意,规则3改变了正则表达式和前缀字符串的优先级,如果最长的前缀字符串没有以^~开头,则会检查正则表达式,这个最长的前缀字符串是否被选取,要等正则表达式匹配结束才知道。

=一般用在频繁请求的路径,这样可以加快代理速度,因为一旦匹配,搜索停止。

一个location块既可以代理静态资源也可以转发请求:

server {
    location /images/ {
        root /data;
    }

    location / {
        proxy_pass http://www.example.com;
    }
}

如果请求匹配第一个location,则会提供/data目录下的文件;如果请求匹配第二个location,则会转发到http://www.example.com。
root指令指定了系统文件的服务路径,uri的请求路径会追加到服务路径之后,共同组成目标文件的全路径。上面的例子中,请求/images/example.png的目标路径是/data/images/example.png。
proxy_pass指令转发请求到目标服务器,目标服务器的应答会回传给客户端。上面的例子中,任何不以/images/开头的请求都会转发到目标服务器上。

使用变量

可以在配置文件中使用变量让nginx在不同的场景有着不同的请求处理方式。变量是具名的值,并且是运行时计算的,通常用作指令的参数。变量以$开头的名称表示。变量是根据nginx的状态定义的信息,比如正被处理请求的属性。

nginx预置了很多的系统变量,比如核心HTTP变量,可以使用set,map和geo指令来定义用户变量。大多变量都是运行时计算的,并且和请求挂钩。比如$remote_addr包含了客户端的IP地址,$uri保存了URI值。

返回状态码

有些网站能够立即返回错误码和重定向码,比如页面被临时或者永久移除。实现这个功能最简单的办法是使用return指令。比如:

location /wrong/url {
    return 404;
}

return指令的第一个参数是返回码。第二个参数是可选的,可以是重定向地址(针对返回码:301,302,303和307),也可以是应答的文本。例如:

location /permanently/moved/url {
    return 301 http://www.example.com/moved/here;
}

return指令可以包含在location和server中。

资源重写

uri请求在处理的过程中可以被rewrite指令多次修改,该指令有一个可选参数和2个必填参数。第一个参数(必填)定义了uri必须匹配的正则表达式。第二个参数是匹配的uri的代替uri。第三个可选参数是一个标志,用来停止后续的rewrite指令或者发送一个重定向码(301或302)。比如:

location /users/ {
    rewrite ^/users/(.*)$ /show?user=$1 break;
}

如上,第二个参数通过匹配正则表达式捕获。
server和location块中可包含多个rewrite指令。nginx按照次序依次执行。当一个server块匹配时,server块中的rewrite指令会执行一次。
nginx处理完一系列的rewrite指令之后,会根据新的uri来匹配location。如果location块包含rewrite指令,这些rewrite指令会被依次执行。如果有rewrite指令匹配,则会根据新的uri开启新一轮的location搜索。
下面的例子展示了rewrite和return指令的用法:

server {
    ...
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
    rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra  last;
    return  403;
    ...
}

这个配置区别两种uri,类似(/download/some/media/file)的uri被重写为(/download/some/mp3/file.mp3)。因为last标志,nginx跳过下游指令(第二个rewrite指令和return指令),并继续用新的uri匹配。类似的,像/download/some/audio/file的uri会被替换为 /download/some/mp3/file.ra,如果uri没有匹配任何rewrite指令,nginx返回403给客户端。

有两个打断匹配过程的指令:

  • last-停止执行当前server或者location块的rewrite指令,并且搜索匹配新uri的location块,然后执行里面的rewrite指令(意味着uri可以再次更改)。
  • break-与last指令类似,停止执行当前块的rewrite指令,但取消搜索匹配新uri的location块。新location块的rewrite指令并不会执行。

应答重写

有时需要重写或者改变应答的内容,用一个字符串替换另一个字符串。可以使用sub_filter指令定义要应用的重写。该指令支持变量和替换链,使更复杂的更改成为可能。

例如,可以更改指向代理以外的服务器的绝对链接。

location / {
    sub_filter      /blog/ /blog-staging/;
    sub_filter_once off;
}

另一个例子把方法从http://更改为htttp_s://并把请求头的字段从localhost地址改为主机名。sub_filter_once指令指示nginx连续地应用location块中的sub_filter指令。

location / {
    sub_filter     'href="http://127.0.0.1:8080/'    'href="https://$host/';
    sub_filter     'img src="http://127.0.0.1:8080/' 'img src="https://$host/';
    sub_filter_once on;
}

要注意的是已经被一个sub_filter指令修改的应答将不会再被另一个sub_filter修改。

处理错误

使用error_page指令,可以配置nginx返回一个自定义页面和一个错误页,代替一个不同的错误码,或者重定向浏览器到一个不同的uri。下面这个例子中,error_page指定(/404.html)和404错误码一起返回。

error_page 404 /404.html;

注意该指令并不表示错误会立即返回(return指令才会立即返回),只是指示当错误发生时,nginx该如何处理。错误码可以从目标服务器或者nginx运行时发生(例如,当nginx找不到客户端请求的文件时返回404)。

下面的例子中,当nginx不能找到页面时,替换404为301,并且重定向客户端到http:/example.com/new/path.html。当客户端还试着用旧的uri访问该页时会很有用。301告知浏览器该页已经永久性移动,在返回结果时,需自动地将旧的地址换成新的地址。

location /old/path.html {
    error_page 404 =301 http:/example.com/new/path.html;
}

下面的配置是这样的一个例子,当文件找不到时,nginx会把请求转发到后端。由于error_page指令的=后面没有指定状态码,返回的状态码将由目标服务器决定(并不一定是404)。

server {
    ...
    location /images/ {
        # Set the root directory to search for the file
        root /data/www;

        # Disable logging of errors related to file existence
        open_file_cache_errors off;

        # Make an internal redirect if the file is not found
        error_page 404 = /fetch$uri;
    }

    location /fetch/ {
        proxy_pass http://backend/;
    }
}

error_page指令指示nginx在找不到文件时做一个内部的重定向。error_page指令的最后一个参数中的$uri变量保存了当前请求的uri,该uri在重定向时传递。

例如,如果/images/some/file未找到,就会被替换成/fetch/images/some/file,开启新一轮的location搜索。最终,请求会被代理到第二个location的http://backend/。

open_file_cache_errors指令防止在文件未找到时写入错误信息。这里没有必要打开该指令因为文件缺失会被正确地处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值