阅读之前建议先阅读入门Nginx。之后,让我们看一下Nginx的配置。抽象的说,配置Nginx作为web服务器就是定义处理哪些URLS,以及如何处理这些URLS对应的请求。具体来说就是定义一些虚拟服务器(VirtualServers)来控制特定IP和域名的请求。更具体地说,Nginx通过定义一系列位置来控制URIS的选择。每个location都定义了映射到自己的请求的处理场景:返回一个文件或者代理请求,或者根据不同的错误码返回不同的错误页面。此外,根据URI,请求也可以重定向到另一个服务器或位置。设置虚拟服务器监听:Nginx配置文件包含至少一个服务器命令来定义虚拟服务器。当一个请求到来时,Nginx会首先选择一个虚拟服务器来处理这个请求。虚拟服务器在http上下文中的server中定义:http{server{#Serverconfiguration}}注:在http中可以定义多个server服务器配置块使用listen命令监听本地IP和端口号(包括Unix域socketandpath),支持IPv4、IPv6,IPv6地址需要用方括号括起来:server{listen127.0.0.1:8080;#IPv4地址,端口8080#listen[2001:3CA1:10F:1A:121B:0:0:10]:80;#IPv6地址,端口80#listen[::]:80;#监听本机所有的IPv4和IPv6地址,80端口#其余服务器配置}以上配置,如果不写端口号,默认使用80端口,如果不写IP,则所有IP这台机器将被监控。server_name:如果多个服务器的listenIP和端口号完全相同,Nginx会将请求头中的Host与server_name定义的主机名进行比较,选择合适的虚拟服务器处理请求:server{listen80;server_namelufficc.comwww.lufficc.com;...}server_name参数可以是:一个完整??的主机名,如:api.lufficc.com。包含通配符(包含*),例如:*.lufficc.com或api.*。一个正则表达式,以~开头。通配符只能在开头或结尾,并且只能与一个..www.*.example.org和w*.example.org均无效。但是,可以使用正则表达式来匹配这些名称,例如~^www..+.example.org$和~^w.*.example.org$。而*可以匹配多个部分。名称*.example.org不仅匹配www.example.org,还匹配www.sub.example.org。对于正则表达式:Nginx使用的正则表达式与Perl编程语言(PCRE)使用的正则表达式兼容。要使用正则表达式,它必须以~开头。命名正则表达式可以捕获变量,然后用:server{server_name~^(www.)?(?.+)$;location/{root/sites/$domain;}}括号之间的()匹配内容后面也可以用$1引用,$2代表前面第二个()中的内容。所以,上面的内容也可以写成:server{server_name~^(www.)?(.+)$;location/{root/sites/$2;}}一个server_name的例子:server{listen80;server_nameapi.lufficc。com*.lufficc.com;...}同样,如果多个名称与Host标头匹配,Nginx会按以下顺序选择它们:完整的主机名,例如api.lufficc.com。以*开头的最长通配符名称,如:*.lufficc.com。以*结尾的最长通配符名称,如:api.*。要匹配的第一个正则表达式。(按照配置文件中的顺序)优先级为:api.lufficc.com>*.lufficc.com>api.*>regular。如果Host标头与任何server_name都不匹配,Nginx会将请求路由到默认虚拟服务器。默认的虚拟服务器是指:nginx.conf文件中的第一个服务器或者用default_server显式声明:server{server_name~^(www.)?(.+)$;location/{root/sites/$2;}}配置locationURI和位置参数的匹配。选择服务器后,Nginx会根据URIs选择合适的位置来决定是代理请求还是返回文件。location指令接受两种类型的参数:前缀字符串(路径名)前缀字符串参数的正则表达式,URI必须严格以它开头。比如/some/path/参数,会匹配到/some/path/document.html,但是不会匹配到/my-site/some/path,因为/my-site/some/path没有开始与/一些/路径/。location/some/path/{...}对于正则表达式,以~开头表示区分大小写,以~*开头表示不区分大小写。请注意。在路径中应写为..例如,匹配以.html或.htm结尾的URI的位置:location~.html?{...}正则表达式优先于前缀字符串。如果找到匹配的前缀字符串,则仍然查找正则表达式,但如果前缀字符串以^~开头,则不再查找正则表达式。具体搜索匹配过程如下:将URI与所有前缀字符串进行比较。=修饰符表示URI必须等于(不是开始,而是等于)前缀字符串,如果找到,则停止搜索。如果找到的最长前缀匹配字符串以^~开头,则不再搜索要匹配的正则表达式。存储匹配的最长前缀字符串。测试URI与正则表达式的比较。找到第一个匹配的正则表达式后停止。如果没有正则表达式匹配,则用4存放前缀字符串对应的位置。=修饰符的优先级为***。如果网站首页访问频繁,我们可以专门定义一个location来减少搜索匹配的次数(因为搜索到的location被=修饰会停止搜索),提高速度:location=/{...静态文件和代理位置也定义了如何处理匹配的请求:返回静态文件或者交给代理服务器处理。下面的例子中,第一个location返回/data目录下的静态文件,第二个location将请求传递给https://lufficc.com域名的服务器进行处理:server{location/images/{root/data;}location/{proxy_passhttps://lufficc.com;}}root指令定义静态文件的根目录,并与URI拼接形成最终的本地文件路径。如果请求/images/example.png,则拼接后返回本地服务器文件/data/images/example.png。proxy_pass指令将请求传递给URL指向的代理服务器。然后将代理服务器的响应转发给客户端。在上面的示例中,所有对不以/images/开头的URI的请求都将传递给代理服务器进行处理。比如我把proxy_pass设置为https://www.baidu.com/,那么访问http://search.lufficc.com/就会得到和百度首页一样的响应(页面)(有兴趣的童鞋可以试试自己搜索功能,跟百度没什么区别):server{listen80;server_namesearch.lufficc.com;location/{proxy_passhttps://www.baidu.com;}}使用变量(Variables)你可以使用变量让Nginx在不同的请求下面的处理方式不同。变量在运行时计算并用作指令的参数。变量由以$开头的符号表示。变量定义了基于Nginx状态的信息,例如当前正在处理的请求的属性。有许多预定义变量,例如核心HTTP变量,您还可以使用set、map和geo指令定义自定义变量。大多数变量在运行时计算并包含与特定请求相关的信息。例如,$remote_addr包含客户端IP地址,$uri包含当前URI值。一些常用的变量如下:server{一个简单的应用是在从http重定向到https的时候带上路径信息:...return301https://lufficc.com$request_uri;...}如果你的网站返回一个具体的状态码网站上的一些资源已被删除。最快最简洁的方式是使用return命令直接返回:location/wrong/url{return404;}return的第一个参数是响应码。可选的第二个参数可以是要重定向的URL(对应代码301、302、303和307)或响应文本中返回的文本。例如:location/permanently/moved/url{return301http://www.example.com/moved/here;}return指令可以包含在位置和服务器上下文中:server{location/{return404;}}或:server{...return404;location/{...}}错误处理error_page命令可以为特定的错误代码配置一个错误页面,或者重定向到另一个页面。下面的示例将在发生404错误时返回/404.html页面。error_page404/404.html;error_page命令定义了如何处理错误,因此它不会直接返回,而return会立即返回。当代理服务器或Nginx处理相应的错误码时,会返回相应的错误页面。在下面的示例中,当Nginx找不到页面时,它会将代码404替换为代码301,并将客户端重定向到http://example.com/new/path.html。这个配置很有用,例如,当客户端仍然试图访问具有旧URI的页面时,301代码通知浏览器该页面已被删除,需要自动替换为返回的新地址。location/old/path.html{error_page404=301http:/example.com/new/path.html;}重写URI重写指令可以多次修改请求的URI。rewrite的第一个参数是URI需要匹配的正则表达式,第二个参数是要替换的URI。第三个参数是可选的,表示continuation是否可以重写或者返回一个重定向码(301或者302)。例如:location/users/{rewrite^/users/(.*)$/show?user=$1break;}您可以在服务器和位置上下文中包含多个重写指令。Nginx按照指令出现的顺序一条一条地执行指令。选择服务器时,将执行服务器中的重写命令一次。Nginx处理一组重写命令后,它会根据新的URI选择一个位置。如果选择的位置仍然包含重写指令,它们将被顺序执行。如果URI全部匹配,则在处理完所有定义的重写指令后搜索新位置。以下示例将rewrite指令与return指令一起使用:server{...rewrite^(/download/.*)/media/(.*)..*$$1/mp3/$2.mp3last;rewrite^(/download/.*)/audio/(.*)..*$$1/mp3/$2.ralast;return403;...}URIslike/download/some/media/file更改为/download/some/mp3/file.mp3。由于最后一个标志,后续指令(第二个重写指令和返回指令)被跳过,但Nginx继续处理具有更改的URI的请求。同样,/download/some/audio/file等URI被替换为/download/some/mp3/file.ra。如果URI与重写指令不匹配,Nginx将向客户端返回403错误代码。last和break的区别是:last:停止在当前服务器或位置上下文中执行重写指令,但Nginx继续搜索与重写URI匹配的位置,并在新位置应用任何重写指令(意味着URI可能会再次更改Change)。break:停止处理当前上下文中的重写指令,并取消搜索与新URI匹配的位置。不会执行新位置的重写命令。附录共同规律。:匹配除换行符以外的任何字符?:重复0次或1次+:重复1次或多次*:重复0次或多次d:匹配数字^:匹配字符串开头$:匹配字符串介绍{n}:重复n次{n,}:重复n次或多次[c]:匹配单个字符c[a-z]:匹配任意a-z小写字母的全局变量$args:#该变量等于请求行中的参数,同$query_string$content_length:请求标头中的内容长度字段。$content_type:请求标头中的Content-Type字段。$document_root:在当前请求的根指令中指定的值。$host:请求主机头字段,否则为服务器名称。$http_user_agent:客户端代理信息$http_cookie:客户端cookie信息$limit_rate:这个变量可以限制连接速率。$request_method:客户端请求的动作,通常是GET或POST。$remote_addr:客户端的IP地址。$remote_port:客户端的端口。$remote_user:已通过AuthBasicModule认证的用户名。$request_filename:当前请求的文件路径,由root或alias命令和URI请求生成。$scheme:HTTP方案(例如http、https)。$server_protocol:请求使用的协议,一般为HTTP/1.0或HTTP/1.1。$server_addr:服务器地址,这个值可以在完成系统调用后确定。$server_name:服务器名称。$server_port:请求到达服务器的端口号。$request_uri:包含请求参数的原始URI,不带主机名,例如:/foo/bar.php?arg=baz。$uri:当前不带请求参数的URI,$uri不包含主机名,如/foo/bar.html。$document_uri:与$uri相同。例如请求:http://localhost:88/test1/test2/test.php$host:localhost$server_port:88$request_uri:http://localhost:88/test1/test2/test.php$document_uri:/test1/test2/test.php$document_root:/var/www/html$request_filename:/var/www/html/test1/test2/test.php