博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nginx烂笔头——nginx如何处理一个请求
阅读量:4079 次
发布时间:2019-05-25

本文共 3375 字,大约阅读时间需要 11 分钟。

说明:“Nginx烂笔头”系列Blog是自己对Nginx官方文档的的翻译,用作阅读笔记便于日后查阅的成分居多,无关重要内容会删减,也可能会加入自己的理解。囿于个人水平,一些专业的名称翻译不会太准确,推荐查看。翻译内容如果有错误,欢迎指正。

本文翻译自Nginx官网网页文档。

文章目录

摘要

本文主要描述了nginx是怎样处理不同配置下的请求。

基于名称的虚拟主机

nginx会先决定哪一个虚拟主机来处理一个请求。下面给定了在80端口上的三台虚拟主机的配置。

server {
listen 80; server_name example.org www.example.org; ...}server {
listen 80; server_name example.net www.example.net; ...}server {
listen 80; server_name example.com www.example.com; ...}

上述配置中,nginx只会尝试用请求头中的“Host”字段来决定请求需要转发到哪里。如果Host的值没有匹配如何虚拟主机名或者是请求根本就没有包含Host这个字段,nginx会转发这个请求到这个端口默认的虚拟主机。在前述的配置,默认的虚拟主机是第一个,这个是nginx的默认行为。同样也可以在listen指令中用default_server参数明确的指出默认的虚拟主机。

server {
listen 80 default_server; server_name example.net www.example.net; ...}

default_server参数在0.8.21版本后就可以使用了。在更早的版本,应该使用default参数。

注意,默认虚拟主机是一个监听端口的属性而不是虚拟主机名称的。稍后会后更多的解释。

使用为定义的server name来阻止请求

如果想禁止没有Host字段的请求,可以用下面的配置来丢弃这个请求:

server {
listen 80; server_name ""; return 444;}

server名称设置成空字符串就可以匹配上这些不带Host请求头字段的请求,并且返回一个nginx特别的非标准的返回码来断开这个连接。

在0.8.48以后,这个设置在server上是默认的,所以,server_name ""这个配置key忽略。在之前的版本,服务器的hostname被用作为一个默认的server_name。

混合名称和ip的虚拟主机配置

server {
listen 192.168.1.1:80; server_name example.org www.example.org; ...}server {
listen 192.168.1.1:80; server_name example.net www.example.net; ...}server {
listen 192.168.1.2:80; server_name example.com www.example.com; ...}

上述配置中,nginx首先根据listen指令和server块指令来尝试匹配请求的ip和端口。然后根据匹配上的整个server块指令的server name来测试请求头的Host字段。如果没有找到匹配的server name,请求就会被默认的server处理。例如:192.168.1.1:80端口接收到一个www.example.com的请求会被转发到192.168.1.1:80的默认server处理,因为这个端口中没有www.example.com的server_name。

前面已经说过,default_server是监听端口的属性,不同的监听端口可以配置不同的默认server。

server {
listen 192.168.1.1:80; server_name example.org www.example.org; ...}server {
listen 192.168.1.1:80 default_server; server_name example.net www.example.net; ...}server {
listen 192.168.1.2:80 default_server; server_name example.com www.example.com; ...}

一个简单的PHP站点配置

来看下nginx是怎样选择location来处理一个经典的简单PHP站点

server {
listen 80; server_name example.org www.example.org; root /data/www; location / {
index index.html index.php; } location ~* \.(gif|jpg|png)$ {
expires 30d; } location ~ \.php$ {
fastcgi_pass localhost:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }}

nginx会首先无视配置列表的顺序去查找最具体(最长)的location参数字符串。上面,仅有的location配置“/”会匹配上所有的请求,但是会被放到最后的优先级。然后,nginx会根据配置文件的顺序来查找匹配的正则表达式。如果没有正则表达式被匹配就会使用之前查找出的最长location配置。

注意,所有的location类型只会尝试匹配请求URI不包含参数的部分。因为参数的组合方式有很多种。

/index.php?user=john&page=1/index.php?page=1&user=john

几个例子,说明nginx是如果处理请求的:

  • 一个“/logo.gif”请求首先匹配了“/”前缀的location,然后匹配上了正则表达式".(gif|jpg|png)$",所以,它会被正在表达式所在的location块指令处理。因为这个locatin没有设置root指令,使用了server中的root /data/www,就是说,这个请求会被映射到/data/www/logo.gif,然后返回这个文件给客户端。
  • “/index.php”请求,先匹配上“/”,然后是正则表达式“.(php)$”。所以,它会被发送给监听着localhost:9000端口的FastCGI服务处理。(FastCGI方面java用的比较少,详情可以查看官方文档。)
  • "/about.html"请求只会被“/”前缀匹配上,所以,它就使用这个location来处理了。
  • 处理“/”请求比较复杂。当处理这个请求时,index指令会测试在参数配置的路径root /data/www路径下是否有index文件。如果文件/data/www/index.html不存在,但是/data/www/index.php存在,nginx会做一个内部重定向到"/index.php",nginx会把它当成是从客户端发送过来的请求处理。在上面可以知道,这个请求会被FastCGI server处理。

转载地址:http://vtsni.baihongyu.com/

你可能感兴趣的文章
ios7.1发布企业证书测试包的问题
查看>>
iOS 开发百问
查看>>
Mac环境下svn的使用
查看>>
github简单使用教程
查看>>
如何高效利用GitHub
查看>>
环境分支-git版本管理
查看>>
Spring AOP + Redis + 注解实现redis 分布式锁
查看>>
支付宝生活号服务号 用户信息获取 oauth2 登录对接 springboot java
查看>>
CodeForces #196(Div. 2) 337D Book of Evil (树形dp)
查看>>
uva 12260 - Free Goodies (dp,贪心 | 好题)
查看>>
uva-1427 Parade (单调队列优化dp)
查看>>
【设计模式】学习笔记14:状态模式(State)
查看>>
poj 1976 A Mini Locomotive (dp 二维01背包)
查看>>
斯坦福大学机器学习——因子分析(Factor analysis)
查看>>
linux对于没有写权限的文件如何保存退出vim
查看>>
IntelliJ IDEA 下的svn配置及使用的非常详细的图文总结
查看>>
【IntelliJ IDEA】idea导入项目只显示项目中的文件,不显示项目结构
查看>>
ssh 如何方便的切换到其他节点??
查看>>
JSP中文乱码总结
查看>>
Java实现DES加密解密
查看>>