为了实现跳转OSS和缩略图的功能,我们需要使用nginx的一些功能来实现。
- location
- rewrite
- if指令
- 变量
- image_filter
1. location
Nginx中的location 指令是NginxHttpCoreModule中重要的指令。location 指令,是用来匹配URI进行配置,URI 即语法中的 "/uri " , 可以是字符串或正则表达式。如果使用正则表达式,则必须制定前缀。
__ Location语法语法:location [=|||^~] /uri/ { … } __
语法解释:
= 开头表示精确匹配
/和^~ 开头表示常规字符串
~ 开头表示区分大小写的正则匹配
~* 开头表示不区分大小写的正则匹配
!~ 和 !~ 分别为区分大小写不匹配及不区分大小写不匹配 的正则
示例:
location = / {
# 只匹配"/".
[ configuration A ]
}
location / {
# 匹配任何请求,因为所有请求都是以"/"开始
# 但是更长字符匹配或者正则表达式匹配会优先匹配
[ configuration B ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 开始的请求,并停止匹配 其它location
[ configuration C ]
}
location ~* .(gif|jpg|jpeg)$ {
# 匹配以 gif, jpg, or jpeg结尾的请求.
# 但是所有 /images/ 目录的请求将由 [Configuration C]处理.
[ configuration D ]
}
2.rewrite
rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。rewrite只能放在server{},location{},if{}中,并且只能对域名后边的除去传递的参数外的字符串起作用,例如http://seanlook.com/a/we/index.php?id=1&u=str 只对/a/we/index.php重写。
如果相对域名或参数字符串起作用,可以使用全局变量匹配,也可以使用proxy_pass反向代理。
表明看rewrite和location功能有点像,都能实现跳转,主要区别在于rewrite是在同一域名内更改获取资源的路径,而location是对一类路径做控制访问或反向代理,可以proxy_pass到其他机器。很多情况下rewrite也会写在location里,它们的执行顺序是:
- 执行server块的rewrite指令
- 执行location匹配
- 执行选定的location中的rewrite指令
如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件;循环超过10次,则返回500 Internal Server Error错误。
__语法rewrite regex replacement [flag]; __
flag标志位
- last :相当于Apache的[L]标记,表示完成rewrite
- break : 停止执行当前虚拟主机的后续rewrite指令集
- redirect : 返回302临时重定向,地址栏会显示跳转后的地址
- permanent : 返回301永久重定向,地址栏会显示跳转后的地址
因为301和302不能简单的只返回状态码,还必须有重定向的URL,这就是return指令无法返回301,302的原因了。这里 last 和 break 区别:
- last一般写在server和if中,而break一般使用在location中
- last不终止重写后的url匹配,即新的url会再从server走一遍匹配流程,而break终止重写后的匹配
- break和last都能组织继续执行后面的rewrite指令
3.if指令
if判断指令
语法为if(condition){...},对给定的条件condition进行判断。如果为真,大括号内的rewrite指令将被执行,if条件(conditon)可以是如下任何内容:
当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当做false
直接比较变量和内容时,使用=
或!=
~
正则表达式匹配,~*
不区分大小写的匹配,!~
区分大小写的不匹配
-f
和!-f
用来判断是否存在文件
-d
和!-d
用来判断是否存在目录
-e
和!-e
用来判断是否存在文件或目录
-x
和!-x
用来判断文件是否可执行
例如:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
} //如果UA包含"MSIE",rewrite请求到/msid/目录下
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
} //如果cookie匹配正则,设置变量$id等于正则引用部分
if ($request_method = POST) {
return 405;
} //如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302
if ($slow) {
limit_rate 10k;
} //限速,$slow可以通过 set 指令设置
if (!-f $request_filename){
break;
proxy_pass http://127.0.0.1;
} //如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查
if ($args ~ post=140){
rewrite ^ http://example.com/ permanent;
} //如果query string中包含"post=140",永久重定向到example.com
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked www.jefflei.com www.leizhenfang.com;
if ($invalid_referer) {
return 404;
} //防盗链
}
4.变量
全局变量
下面是可以用作if判断的全局变量
$args
: 这个变量等于请求行中的参数,同$query_string
$content_length
: 请求头中的Content-length字段。
$content_type
: 请求头中的Content-Type字段。
$document_root
: 当前请求在root指令中指定的值。
$host
: 请求主机头字段,否则为服务器名称。
$http_user_agent
: 客户端agent信息
$http_cookie
: 客户端cookie信息
$limit_rate
: 这个变量可以限制连接速率。
$request_method
: 客户端请求的动作,通常为GET或POST。
$remote_addr
: 客户端的IP地址。
$remote_port
: 客户端的端口。
$remote_user
: 已经经过Auth Basic Module验证的用户名。
$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相同。
自定义变量
我们可以在 nginx.conf 文件中有下面这一行配置:
set $a "hello world";
我们使用了标准 ngx_rewrite 模块的 set 配置指令对变量 $a 进行了赋值操作.我们把字符串 hello world 赋给了它。
另一种以arg_
开头的所有变量,这个变量的值是当前请求名为 name 的 URI 参数的值,而且还是未解码的原始形式的值。
我们来看一个比较完整的示例:
location /test {
echo "name: $arg_name";
echo "class: $arg_class";
}
然后在命令行上使用各种参数组合去请求这个 /test 接口:
$ curl 'http://localhost:8080/test'
name:
class:
$ curl 'http://localhost:8080/test?name=Tom&class=3'
name: Tom
class: 3
$ curl 'http://localhost:8080/test?name=hello%20world&class=9'
name: hello%20world
class: 9
5. image_filter
image_filter 是nginx提供的集成图片处理模块,就可以用它实时缩放图片,旋转图片,验证图片有效性以及获取图片宽高以及图片类型信息。
2 模块说明
image_filter off
关闭模块
image_filter test
确保图片是jpeg gif png否则返415错误
image_filter size 100 100
输出有关图像的缩放大小
image_filter rotate 90|180|270
旋转指定度数的图像,參数能够包括变量,单独或一起与resize crop一起使用。
image_filter resize width height
按比例降低图像到指定大小,公降低一个能够还有一个用"-"来表示,出错415,參数值可包括变量,能够与rotate一起使用,则两个一起生效。
image_filter crop width height
按比例降低图像比較大的側面积和还有一側多余的载翦边缘,其他和rotate一样。没太理解
image_filter_buffer 10M
设置读取图像缓冲的最大大小,超过则415错误。
image_filter_interlace on
假设启用,终于的图像将被交错。对于JPEG,终于的图像将在“渐进式JPEG”格式。
image_filter_jpeg_quality 95
设置变换的JPEG图像的期望质量。可接受的值是从1到100的范围内。较小的值通常意味着既降低图像质量,降低数据传输,推荐的最大值为95。參数值能够包括变量。
image_filter_sharpen 100
添加了终于图像的清晰度。锐度百分比能够超过100。零值将禁用锐化。參数值能够包括变量。
image_filter_transparency on
定义是否应该透明转换的GIF图像或PNG图像与调色板中指定的颜色时,能够保留。透明度的损失将导致更好的图像质量。在PNG的Alpha通道总是保留透明度。
配置示例
location ~* /image/(.+)\.jpg$ {
root /data/;
access_log logs/test.access.log;
error_log logs/test.error.log;
set $width $arg_w;
set $height $arg_h;
set $function $arg_function;
set $file $1;
if ( $function = "" ) {
rewrite ^ http://192.168.0.121:8080/v1/AUTH_test/myfiles/$file.jpg permanent;
}
if ( $function = "image/resize" ) {
rewrite /(image)/(.+)\.jpg /v1/AUTH_test/myfiles/$file.jpg;
}
}
location ~* /v1/AUTH_test/myfiles/(.+)\.jpg {
proxy_pass http://192.168.0.121:8080;
set $width $arg_w;
set $height $arg_h;
image_filter resize $width $height;
image_filter_buffer 50M;
image_filter_jpeg_quality 95;
image_filter_transparency on;
}
当访问/image接口下面的图片时,首先会判断是否有function这个参数,如果有,则跳转访问OSS存储的图片文件。如果没有,则读取变量参数arg_w, arg_h的值,进行图片的缩放。
一个完整的数据分流和缩略图配置就完成了
参考: