由于当前很多应该都是前后端分离了,同时大量的基于http的分布式和微服务架构,使得很多时候应用和不同项目组之间的系统相互来回调用,关系复杂。如果使用传统的做法,都在应用中进行各种处理和判断,不仅维护复杂、容易出错,还大大增加开发、调试的工作量,在nginx中,有不少的非功能类其实是可以帮我们处理掉的,所以,对于现代开发人员来说,有必要对nginx的location比较熟悉,以便达到事半功倍的效果,比如说,日常的图片上传就是个例子,我们可以将图片上传到特定的目录,然后配置nginx对于用户上传的图片,都转发到特定的目录,该目录不一定是nginx的html目录,甚至是挂载的盘,这样对于一般的应用来说,既可以按应用规划设置文件服务器,也避免了需要安装和维护ftp服务器软件的工作。

nginx配置

因为Nginx是模块化架构,每个模块都会有一系列自己引入的指令,这些指令通常包含在指令块中,比如events模块,就有一个events块。如下所示:

events {
worker_connections 1024;
}

对于最常用的部分,指令块通常层层嵌套。例如:

http {
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/example.com.log;
location ^~ /admin/ {
index index.php;
}
}
}

默认情况下,之块会继承父块中声明的设置,除非明确覆盖。

在nginx的配置中,语法比较复杂,而且不同的指令,可能规则完全不同。

比如root仅接受一个字符,声明服务于网站的文件的根路径。

模块中通常定义了可以用于指令中的变量,变量以$开头。某些指令中不允许使用变量,比如error_log,此时它会被当做字面量处理。

指令的值可以带双引号、带单引号、不带引号,除非使用了特殊符号,此时需要用引号括起来以避免nginx解析误解,对于特殊符号需要当做字面量使用的,需要用\,比如$。

nginx的基本模块包括Core、Events(主要是声明网络机制,某些参数对系统的性能影响较大)、Configuration,这三个模块提供了整个基础架构。

nginx使用多进程架构。

核心模块的主要指令:

  • error_log:声明日志文件的位置,error_log /file/path level;格式,默认是logs/error.log error。main,http, server,location级别都可以自定义。
  • thread_pool:声明一个可供aio指令使用的线程池。主要用于服务于异步较大的文件请求时提高性能,thread_pool name threads=number [max_
  • queue=number];默认为thread_pool default threads=32 max_queue=65536;。
  • worker_processes:声明实际工作进程数,默认情况下,nginx会使用检测到的cpu数量而不是1,这一点现代系统基本上都是动态判断,不像早期一样默认为单核,甚至内存都是动态自己判断和设置。
  • worker_cpu_affinity:声明进程跟cpu的亲和关系,一般仅在多核下使用,格式worker_cpu_affinity 1000 0100 0010 0001;每组代表一个进程,每组中的1代表第几个核心。

events模块的主要指令包括(这些指令必须声明在events块中):

  • use:声明使用的事件模型,现代linux一般都应该使用epoll。
  • worker_connections:声明工作进程可以同时处理的并发连接数。

配置模块的主要指令包括:

  • include指令,在声明的位置插入指定文件的内容,跟spring的import/mybatis的sql一样。nginx内置模块化的文件包括nginx.conf、mime.types、fastcgi_params、proxy.conf、sites.conf,include的值支持通配符。

HTTP Core模块

HTTP Core模块包含了HTTP服务器的所有基础块、指令以及变量,其默认启用,实际上它也是最重要的一个模块。它包含三个主要的块:http,server,location。

  • http块位于最高层,定义了所有和http相关的指令和块。
  • server块声明一个网站,必须声明在http块内。
  • location块声明应用于网站内特定路径的一组设置,可以声明在server块内,或者嵌套在其他location内。

一个典型的http配置结构如下:

主要指令包括:

  • listen:声明监听的地址,listen [address][:port] [additional options];应用于server块。
  • server_name:为server定义一个或多个主机名,server_name hostname1 [hostname2…];如果一个nginx服务提供多个网站时,该值可以用来进行区分。应用于server块。
  • tcp_nopush:启用或者禁用TCP_NOPUSH (FreeBSD)/TCP_CORK(Linux) socket选项,仅在sendfile启用时有效,其作用是nginx尽量在一个tcp包中传输所有HTTP响应头。应用于所有块。
  • sendfile:如果启用,nginx会使用sendfile内核调用处理文件传输,否则nginx会自己传输。应用于所有块。

路径相关指令包括:

  • root:定义服务客户端请求的根目录,默认为html。应用于所有块以及if。
  • alias:声明用来提取文件时的别名路径,根路径不变,应该主要是用于对外公共接口的内部地址变了。
  • error_page:声明特定HTTP返回码的替换页面。格式为error_page code1 [code2…] [=replacement code] [=@block | URI]。应用于所有块以及if。
  • index:定义nginx的默认页面,默认为index.html,可以声明多个。应用于所有块。

客户端请求相关的指令包括:

  • keepalive_requests:一个长连接最多可以请求的数量,默认100,可应用于http, server, location。
  • keepalive_timeout:定义长连接的超时时间,默认75,第二个参数的值会通过http包头传给客户端,格式:keepalive_timeout time1 [time2];应用于http, server, location。
  • send_timeout:声明nginx多久后关闭未活动连接,客户端停止传输数据开始计算未活动,默认60秒。
  • client_body_buffer_size:声明用于存放客户端请求体的缓存大小,默认8k或者16k,具体是系统架构而定。

限制相关的指令包括:

  • limit_except:设置仅支持哪些HTTP方法。应用于location。例如:
location /admin/ {
limit_except GET {
allow 192.168.1.0/24;
deny all;
}
}

格式为:

limit_except METHOD1 [METHOD2…] {
allow | deny | auth_basic | auth_basic_user_file | proxy_pass | perl;
}
  • limit_rate:设置每链接每秒钟的流量,默认不限,应用于http, server, location, if。
  • internal:声明本location仅适用于内部访问,也就是必须通过rewrite才能访问。

文件和缓存相关的指令:

  • directio:当文件超过特定大小时,使用Direct I/O系统机制直接从存储设备读取。应用于http, server, location。

其他指令:

  • merge_slashes:是否合并连续的/为单个/,比如将http://website.com//documents/转换为http://website.com/documents/,默认情况下会报404。应用于http, server, location。
  • resolver:声明nginx使用的自定义的DNS服务器。
  • underscores_in_headers:声明自定义HTTP请求头中是否允许下划线名字,默认为不允许,http头中一般为-分隔。
  • post_action:声明请求执行完成后,nginx调用的uri,特殊情况下可用,比如PV统计。

模块变量

HTTP Core模块包含了很多的变量,分为三类:第一类是在Http请求头中传递的,第二类是http响应头中的,第三类是完全nginx生成的。参考nginx http server第三版 90页。

nginx允许用户声明样式匹配指定的uri,location的语法为:
location [=|~|~*|^~|@] pattern { ... }
第一个可选的参数是修饰符,各修饰符详解如下:

  • =修饰符:完全匹配,也就是直接常量比较。
  • 无修饰符:必须以声明的样式开头,也就是like 'pattern%',通常servlet上下文匹配就是无修饰符的模式。
  • ~修饰符:请求的URI必须大小写敏感的匹配声明样式的正则表达式。如:
server {
server_name website.com;
location ~ ^/abcd$ {
[…]
}
}
  • ~*修饰符:请求的URI必须大小写不敏感的匹配声明样式的正则表达式。
  • ^~修饰符:和无修饰符类似,区别在于如果当前location匹配请求,则不会继续搜索其他的location。
  • @修饰符:定义一个命名location块,这些块不对外开放访问,仅用于内部转发。

搜索顺序和location匹配优先级

很多时候,我们定义的不止一个location,通常至少会有两个,一个是根本身,一个指向后端服务。所以我们需要理解nginx接收到一个请求之后,它如何确定匹配的location。定义在配置文件中的location顺序对于一个请求是否优先匹配没有关系,nginx搜索匹配的样式的顺序如下:

  1. =修饰符的location
  2. 无修饰符的location(如果精确匹配的话)
  3. ^~修饰符的location
  4. ~/~*修饰符的location
  5. 无修饰符的location(如果前缀匹配的话)

Rewrite模块

这个模块的目的就是为了URL重写,URL重写是SEO的关键元素之一。URL重写由rewrite指令执行,它接收一个样式和一个替换URI。

正则表达式规则参考nginx http server第三版P103。
注意,因为正则表达式的{}和nginx指令块冲突,所以如果要使用,必须放到引号中。
捕获,正则表达式中用()括起来的内容会被捕获到一个个内置变量中,$N,N为捕获的索引,从1开始。捕获的变量可以作为指令的值。()也通常和|一起使用,二选一。命名捕获使用?<name>语法设置,例如^/(?<folder>[^/]+)/(?<file>.*)$。
在nginx中,在正则表达式中捕获的值,可以在后续指令中使用,只要不被覆盖即可。

server {
server_name website.com;
location ~* ^/(downloads|files)/(.*)$ {
add_header Capture1 $1;
add_header Capture2 $2;
}
}

nginx区分内外部请求,内部请求由error_page, index, rewrite,try_files, add_before_body, add_after_body生成。内部请求还分两类:

  • 内部重定向(Internal redirects):最常见的内部重定向是rewrite。
  • 子请求(Sub-requests):内部自动触发,一般用的少。

简单的重定向如下:

server {
server_name website.com;
root /var/www/vhosts/website.com/httpdocs/;
location /storage/ {
internal;
alias /var/www/storage/;
}
location /documents/ {
rewrite ^/documents/(.*)$ /storage/$1;
}
}

Rewrite模块的指令包括:

  • rewrite:为当前请求重写URI,格式为rewrite regexp replacement [flag];flag的取值以及含义为:

    • last:当前的重写规则是最后一个,当前重写应用之后,就去寻找新匹配的location。
    • break:当前重写规则应用之后,不再找新的location。
    • redirect:返回302以及新的URI地址。
    • permanent:返回301以及新的URI地址。

    如果声明的URI以http://开头,nginx自动使用redirect标志。

    可应用于server,location,if。

  • break:用来防止后续重写,后面的重写都会被忽略。
  • return:中止处理请求,返回声明的状态码或声明的文本。状态码为204, 400, 402 to 406, 408, 410, 411, 413, 416, and 500 to 504。
  • set:初始化或定义变量。
  • uninitialized_variable_warn:如果为on,nginx为每个遇到的未初始化的变量记录日志。
  • rewrite_log:如果为on,Nginx为每一次重写记录notice级别的日志。

upstream模块

任何以_pass结尾的指令都接受到一组服务器的引用。声明一组服务器的第一步是在http的upstream块内声明一个或多个server指令,如下:

http {
upstream MyUpstream {
server 10.0.0.201;
server 10.0.0.202;
server 10.0.0.203;
}
[…]
}

然后在server块内引用声明的upstream,如下:

server {
server_name example.com;
listen 80;
root /home/example.com/www;
# Proxy all requests to the MyUpstream server group
proxy_pass http://MyUpstream;
[…]
}

nginx提供多种负载均衡机制,P248。从Nginx 1.9.0开始,新增的Stream模块支持TCP负载均衡,这意味原来必须使用LVS或者HAPROXY作为负载均衡机制的模式可以采用NGINX了。
要启用线程池,必须使用--withthreads参数编译nginx,对于经常文件下载的应用,应使用如下配置:

location /downloads/ {
aio threads;
directio 8k;
sendfile on;
}

ngx_http_log_module模块负责以声明的格式记录请求日志。
其主要的两个指令是:

  • log_format:声明日志格式。格式为:log_format name [escape=default|json|none] string ...;默认为log_format combined "...";日志格式可以包含公用变量以及仅在日志写的时候存在的变量。配置总是包含预定义的“combined”格式,如下:
  • access_log:设置写日志的路径、格式以及额外配置。格式为:
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;

默认为access_log logs/access.log combined;

nginx获取环境变量的值

首先参考centos下nginx安装与配置安装所需模块。

With Lua

If you are using Openresty, or have the ngx_lua module and ngx_devel_kit module installed, you are in luck.

You first need to declare what variables you'll be needing somewhere in your nginx.conf file using the envdirective:

env API_KEY;

After that, when you want to access the environment variable, you can use a combination of set_by_lua and os.getenv, like this:

http {   ...   server {     location / {       set_by_lua $api_key 'return os.getenv("API_KEY")';       ...     }   } }

In this example we are assigning the environment variable to one of Nginx variables; we can use $api_key as a regular nginx.conf variable.

With Perl

Using Lua was our preferred approach, since we have OpenResty. If you can't use Lua, a second solution involves using Perl. The first part is similar; you must declare the variables he uses using env:

env API_KEY;

After that, you can combine perl_set and some Perl to do the same thing as before:

http {   ...   server {     location / {       perl_set $api_key 'sub { return $ENV{"API_KEY"}; }';       ...     }   } }

You will need to have the ngx_http_perl_module module enabled in order to be able to use this technique.

写给大忙人的nginx核心配置详解的更多相关文章

  1. Nginx 核心配置详解

    目录 Nginx 核心配置详解 Nginx 四层访问控制: Nginx账户认证功能: 自定义错误页面: 自定义访问日志: 检测文件是否存在: 长连接配置: 作为下载服务器配置: 作为上传服务器: 其他 ...

  2. PHP的核心配置详解

    1.PHP核心配置详解 代码在不同的环境下执行的结果也会大有不同,可能就因为一个配置问题,导致一个非常高危的漏洞能够利用:也可能你已经找到的一个漏洞就因为你的配置问题,导致你鼓捣很久都无法构造成功的漏 ...

  3. nginx.conf配置详解

    ######Nginx配置文件nginx.conf中文详解##### #定义Nginx运行的用户和用户组 user www www; #nginx进程数,建议设置为等于CPU总核心数. worker_ ...

  4. Nginx location配置详解

    上一篇博客Nginx配置详解已经说过了nginx 的基本配置情况,今天来详细讲述一下nginx的location的配置原则, location是根据Uri来进行不同的定位,location可以把网站的 ...

  5. Nginx的配置详解

    人无再少年,花有重开日——风城玫瑰 德里克·罗斯 Nginx是一款轻量级的HTTP服务器,采用事件驱动的异步非阻塞处理方式框架,这让其具有极好的IO性能,时常用于服务端的反向代理和负载均衡. Ngin ...

  6. 快速部署Python应用:Nginx+uWSGI配置详解

    在PHP里,最方便的就是deployment了,只要把php文件丢到支持PHP的路径里面,然后访问那个路径就能使用了:无论给主机添加多少PHP应用,只要把目录改好就没你的事了,完全不用关心php-cg ...

  7. Nginx基本属性配置详解

    1. Nginx服务的基本配置 1.1 用于调试进程和定位问题的配置项 是否以守护进程的方式运行nginx # 默认on daemon on|off; 是否以master/worker方式工作 # 默 ...

  8. nginx location 配置详解 【转载,整理】

    http://www.nginx.cn/115.html NGINX location 配置参考:http://www.cnblogs.com/zlingh/p/6288994.html https: ...

  9. 快速安装Nginx及配置详解(未完待续)

    导读: Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器,从2007年被德国人开发出来后可以说在市场的占有率一路飙升,因为它支持高并 ...

随机推荐

  1. git cherry-pick 报错 fatal: bad object

    场景:程序员A提交了一个commit到gerrit上,我们叫他为commit_id1,但是还没有review,那就是没有入库,程序员B想再本地拿到这个commitd_id1,既然这个提交没有入库,很明 ...

  2. Windows PyCharm永久激活

    1.下载 链接: https://pan.baidu.com/s/1LvQozk5lXdyk2p8qgGsr3A 提取码: x1t5 放置到 pycharm安装目录的\bin目录下(位置可随意,只要配 ...

  3. 超参数调试、Batch正则化和编程框架

    1.调试处理 2.为超参数选择合适的范围 3.超参数在实践中调整:熊猫与鱼子酱 4.正则化网络的激活函数 5.将batch norm拟合进神经网络 6. 为什么Batch Norm会起作用? 7.测试 ...

  4. iOS 新浪微博-5.3 首页微博列表_集成图片浏览器

    实际上,我们可以使用李明杰在教程里集成的MJPhotoBrowser,地址: http://code4app.com/ios/快速集成图片浏览器/525e06116803fa7b0a000001 使用 ...

  5. mybatis运行原理

    mybatis运行原理 运行过程中涉及到的类或者接口 Resources(c) :用于加载mybatis核心配置文件 XMLConfigBuilder(c) :用于解析xml文件(核心配置文件) Co ...

  6. 笔记 : Ubuntu部署LNMP环境

    一.准备与安装 1. 安装PHP7.1 #添加php源 :~$ sudo add-apt-repository ppa:ondrej/php #更新apt数据,载入php源数据 :~$ sudo ap ...

  7. ling join 报错The specified LINQ expression contains references to queries that are associated with different cont

    The specified LINQ expression contains references to queries that are associated with different cont ...

  8. C#基础知识整理

    年时,北风吹雁雪纷纷,一条秋裤冻上头.冷的连手都懒得动,就随便翻翻书,也没有更新博客,如今年已过,开始投入到正常的工作状态中,趁现在需求还没有来,把C#基础知识梳理一下,其实一直以来就想这样做的,对于 ...

  9. SQL提交数据三种类型

    在数据库的插入.删除和修改操作时,只有当事务在提交到数据库时才算完成. SQL语句提交数据有三种类型:显式提交.隐式提交及自动提交. [1]显式提交 显式提交.即用COMMIT命令直接完成的提交方式. ...

  10. 51ll网产品信息保存为txt文件

    import requests from pyquery import PyQuery as pq url='http://www.51xxx.com/Try/index/p/3' headers={ ...