利用 Aliyun OSS Nginx proxy module 实现OSS 图片处理回写功能

1、主要介绍内容

此篇文章主要利用Aliyun OSS Nginx proxy module 实现OSS 图片处理回写功能,借助OSS Nginx Proxy module 及 OSS 的上传回调功能实现OSS图片处理回写功能,当然文章目的并不在于强调图片处理回写功能,而是借实现一个例子来利用Aliyun OSS Nginx proxy module,对Nginx 及 Nginx lua 感兴趣的同学可以参照本文描述做出更强大的应用出来,本文如能抛砖引玉的作用那就不枉我花时间写此博客了。

2、开始之前

1、开始之前请稍微阅读下对Aliyun OSS Nginx proxy module 的简单介绍

?spm=0.0.0.0.EZk4yy

2、了解下阿里云OSS 上传回调功能

https://help.aliyun.com/document_detail/oss/api-reference/object/Callback.html?spm=5176.docoss/user_guide/manage_object/list_object.6.238.SAPehH

3、参考文章

在开始之前建议阅读本文之前建议阅读以上两篇参考文档
春哥的Nginx教程,会对Nginx 配置文件有很深的理解
http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html
我的另外一篇博客,会更加理解OSS 提供的服务
?spm=0.0.0.0.IWbHSR

3、主要功能及优势

本文主要实现的功能是处理回写,这里以oss图片处理回写为例介绍如何利用阿里云OSS 提供的callback来进行图片回写。现在很多大图片如果每次都要实时处理那会大大降低用户体验(当然可以利用CDN进行缓存),那么可以通过此方法进行处理图回写,每次进行上传请求时带上callback参数让oss通知到本文中实现的nginx服务器,nginx服务器会自动从oss 拉取经过处理的数据然后再回写带oss中,如果确认成功甚至可以将原图删掉只保留处理图,这些都可以依据上传逻辑进行实现。那么肯定会有读者问那费用呢?这个完全不是问题,因为oss按照请求次数收费相当便宜几乎不要钱,而流量费用也不用担心,买一台和OSS同区域的ECS就可以走内网了,内网流量免费。

4、图片处理回写处理逻辑代码

oss_rewrite.lua

local cjson = require("cjson")

local function get_object_data_from_oss_img(src_object, src_style)
    local res = ngx.location.capture("/" .. src_object .. src_style)
    if res.status ~= ngx.HTTP_OK then
        ngx.log(ngx.ERR, "fetch external url data failed, object :", src_object .. src_style, " status:", tostring(res.status))
        return res.status, nil
    end
    return res.status, res.body
end

local function get_and_process(json_table)
    src_object = json_table["src_object"]
    src_style = json_table["style"]
    dst_object = json_table["dst_object"]
    ngx.log(ngx.INFO, "src_object:", src_object, " style:", src_style, " dst_object:", dst_object)
    if src_object == nil or src_style == nil or dst_object == nil then
        ngx.log(ngx.ERR, "src_object style and dst_object should be not null")
        return ngx.HTTP_BAD_REQUEST
    end

    -- Get processed img data from oss
    local status, write_back_body = get_object_data_from_oss_img(src_object, src_style)

    if status ~= ngx.HTTP_OK then
        return status
    end

    -- Write back
    local res = ngx.location.capture("/" .. dst_object, {
        method = ngx.HTTP_PUT,
        body = write_back_body
    })

    if res.status ~= ngx.HTTP_OK then
        ngx.log(ngx.ERR, "write back to oss failed, object:", dst_object, "status:", tostring(res.status))
        return res.status
    end
    return ngx.HTTP_OK
end

local function parse_and_process_post_body()
    ngx.req.read_body()
    local post_json_body = ngx.req.get_body_data()
    ngx.log(ngx.INFO, post_json_body)
    if post_json_body == nil then
        ngx.log(ngx.ERR, "post request body from oss call_back is empty.")
        return ngx.HTTP_BAD_REQUEST
    end
    -- decode json string and catch json errors
    local succ, json_table = pcall(function()
        return cjson.decode(post_json_body)
    end)
    if succ then
        return get_and_process(json_table)
    else
        ngx.log(ngx.ERR, "post request body from oss call_back is not json.")
        return ngx.HTTP_BAD_REQUEST
    end
end

local method = ngx.req.get_method()
if method == 'GET' or method == "POST" then
    local status = parse_and_process_post_body()
    if status == ngx.HTTP_OK then
        ngx.say("{\"success\": \"true\"}")
    else
        ngx.log(ngx.ERR, "fail write back to oss")
        ngx.exit(status)
    end
else
    ngx.log(ngx.INFO, "do not support this method ", method)
    ngx.exit(ngx.HTTP_BAD_REQUEST)
end

nginx.conf

error_log  logs/error.log  debug;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    lua_package_path "/usr/servers/lualib/?.lua;";
    lua_package_cpath "/usr/servers/lualib/?.so;";
    server {
        listen       80;
        server_name  your-server-name; # 注意此项要和CallBack 参数中的Host 保持一致

        resolver 8.8.8.8;
        #lua_code_cache  off; # 加上此配置在每次修改lua 代码后无需reload nginx
        location /oss_write_back {
            content_by_lua_file conf/lua/oss_rewrite.lua;
        }

        location / {
            internal;  #只允许内部跳转
            set $oss_bucket "you-oss-bucket";
            set $oss_auth_id "you-access-key-id";
            set $oss_auth_key "you-access-key-secret";
            rewrite_by_lua_file conf/lua/oss_auth.lua;
        }
        location @oss {
            #eg: bucket-example.oss-cn-qingdao.aliyuncs.com
            proxy_pass http://$oss_bucket.oss-location.aliyuncs.com;
        }
    }
}

5、如何使用上述代码及构造OSS callback 请求

1、准备环境配置文件

自己搭建openresty 环境或者直接pull docker 官方镜像源openresty镜像
将oss_rewrite.lua 放到conf/lua/oss_rewrite.lua 中
http://blog.csdn.net/sunrain_chy/article/details/50935681 提到的oss_auth.lua 放到conf/lua/oss_auth.lua 中
配置好nginx.conf 文件,启动nginx

2、构造Callback 请求

为了演示方便将bucket 权限设置为public-read-write并利用http://blog.csdn.net/sunrain_chy/article/details/50804410这篇文章介绍的方法进行请求构造

构造PUT 请求 call back 参数
callback.txt

{
    "callbackUrl":"your-call-back-url/oss_write_back",
    "callbackHost":"your-call-back-host",
    "callbackBody":"{
            \"src_object\":\"your-src-object-name\",
            \"style\":\"style\",
            \"dst_object\": \"your-dst-object-name\"
        }",
        "callbackBodyType":"application/json"
}

注意这里的your-call-back-host 要与nginx.conf 中的server_name 保持一致,回调url 的location 要是oss_write_back
src_object 为oss上存在的一张图片object,通常设置为此次PUT 请求上传的Object
style 为 oss 图片处理参数
dst_object 为处理图回写到OSS 的objectname
对上述callback.txt 进行base64编码

$ base64 callback.txt | tr -d '\n'

3、构造带CallBack参数的PUT 请求

PUT /test.jpg HTTP/1.1
Host: bucket-example.oss-ch-qingdao.aliyuncs.com
Accept-ncoding: identity
Content-Length: 10584
x-oss-callback-var: eyJ4Om15X3ZhciI6ImZvci1jYWxsYmFjay10ZXN0In0=
x-oss-callback: ewogICAgImNhbGxiYWNrVXJsIjoiMzAuOS4xNjkuNDIvb3NzX3dyaXRlX2JhY2siLAogICAgImNhbGxiYWNrSG9zdCI6IjMwLjkuMTY5LjQyIiwKICAgICJjYWxsYmFja0JvZHkiOiJ7CiAgICAgICAgICAgIFwic3JjX29iamVjdFwiOlwidGVzdC5qcGdcIiwKICAgICAgICAgICAgXCJzdHlsZVwiOlwiQDEwMHdfMTAwaFwiLAogICAgICAgICAgICBcImRzdF9vYmplY3RcIjogXCJ0ZXN0LmpwZ18xMDB4MTAwXCIKICAgICAgICB9IiwKICAgICAgICAiY2FsbGJhY2tCb2R5VHlwZSI6ImFwcGxpY2F0aW9uL2pzb24iCn0K

...imgdata

注意上述x-oss-callback 参数为callback.txt 的base64编码

4、利用nc 将带call back 参数的请求发往oss

5、结果检测

在上述参数配置无误的情况下bucket中会多出来一个名为your-dst-object-name的object,这个object正是由your-src-object-name 带上style 参数经过OSS图片处理过的object。

6、程序运行主线

1、用户发送带callback参数的PUT请求到OSS,OSS根据callback提供的参数会调用用户的应用服务器,也就是我们的nginx
2、nginx 接收到这个请求后解析body参数获取到 源object 处理参数及回写object名,这一步走的是nginx conf 中的 location /oss_write_back
3、Nginx 根据解析出来的post 参数发出一个内部跳转的子请求到 location / 去OSS取出处理参数为style 的处理图,当然取图请求会经过oss_auth.lua 走到location @oss进行签名
4、取出处理图后nginx lua 发出自请求将处理图数据回写到OSS至此回写完成。

时间: 2024-10-31 01:02:14

利用 Aliyun OSS Nginx proxy module 实现OSS 图片处理回写功能的相关文章

Aliyun OSS Nginx proxy module(阿里云OSS Nginx 签名代理模块)

1.此文章主要介绍内容 本文主要介绍如何利用Nginx lua 实现将阿里云OSS存储空间做到同本地磁盘一样使用.核心是利用Nginx lua 对OSS请求进行签名并利用内部跳转将所有访问本地Nginx的请求加上OSS 签名转发给OSS,实现本地Nginx无缝衔接阿里云OSS,存储空间无限扩展,存储成本无限下降,数据安全%99.99...... . 2.本篇文章使用到的一些工具技术及如何学习和获取 1.lua 本文用到的都是一些基本的lua,基本上花半小时阅读下lua的语法就可以轻松理解本文内容

《深入理解Nginx:模块开发与架构解析》一2.5 用HTTP proxy module配置一个反向代理服务器

2.5 用HTTP proxy module配置一个反向代理服务器 反向代理(reverse proxy)方式是指用代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络中的上游服务器,并将从上游服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外的表现就是一个Web服务器.充当反向代理服务器也是Nginx的一种常见用法(反向代理服务器必须能够处理大量并发请求),本节将介绍Nginx作为HTTP反向代理服务器的基本用法.由于Nginx具有"强悍"

OSS文件上传及OSS与ODPS之间数据连通

场景描述        有这样一种场景,用户在自建服务器上存有一定数量级的CSV格式业务数据,某一天用户了解到阿里云的OSS服务存储性价比高(嘿嘿,颜值高),于是想将CSV数据迁移到云上OSS中,并且未来还想对这些数据做一些离线分析,挖掘其中存在价值,因此需要将OSS中文件再通过一种方式同步到ODPS数加平台上,面对这样需求,小编我经过参考文档,实践,调试并修复Bug,实现出以下一种解决方案. 实现目标     通过OSS的Java SDK以及批量数据通道tunnel SDK实现以下两个功能:

Nginx Upload Module 上传模块测试例子

传统站点在处理文件上传请求时,普遍使用后端编程语言处理,如:Java.PHP.Python.Ruby等.今天给大家介绍Nginx的一个模块,Upload Module上传模块,此模块的原理是先把用户上传的文件保存到临时文件,然后在交由后台页面处理,并且把文件的原名,上传后的名称,文件类型,文件大小set到页面. GitHub: https://github.com/vkholodkov/nginx-upload-module/tree/2.2 Site: http://wiki.nginx.or

nginx上传模块—nginx upload module

nginx上传模块 一. nginx upload module原理 官方文档: http://www.grid.net.ru/nginx/upload.en.html Nginx upload module通过nginx服务来接受用户上传的文件,自动解析请求体中存储的所有文件上传到upload_store指定的目录下.这些文件信息从原始请求体中分离并根据nginx.conf中的配置重新组装好上传参数,交由upload_pass指定的段处理,从而允许处理任意上传文件.每个上传文件中的file字段

nginx upload module的使用

现在的网站,总会有一点与用户交互的功能,例如允许用户上传头像,上传照片,上传附件这类的.PHP写的程序,对于上传文件效率不是很高.幸好,nginx有一个名为upload的module可以解决这个问题.网络上已经有很多关于upload module的文章,但是大部分都是介绍编译安装这些的,对于一些细节叙述不是很清楚,于是自己写了这篇.参考了很多其他人的文档,在此致谢,详细见参考文档部分. 一.upload module的工作原理nginx upload module模块通过nginx服务器来接受用

利用Docker制作Nginx+PHP镜像的步骤详解_docker

前言 这篇文章给大家介绍的是使用Docker制作nginx+php的镜像,本文里的镜像是centos + nginx 1.9.7 + php 5.6.14,下面话不多说,直接看实现的步骤吧.  1.首先下载到nginx和php: nginx-1.9.5.tar.gz 下载:http://nginx.org/en/download.html php-5.6.14.tar.gz   下载:>http://php.net/downloads.php  2.以及扩展包so: memcache-2.2.4

Docker之利用Dockerfile创建Nginx镜像

镜像获取方法 1.使用Dockerfile创建 wget -O- http://www.dwhd.org/wp-content/uploads/2015/11/Dockerfile1 >Dockerfile wget -O- http://www.dwhd.org/wp-content/uploads/2015/11/nginx.conf >nginx.conf wget -O- http://www.dwhd.org/wp-content/uploads/2015/11/run.sh1 &g

利用uniread 解决 Linux下的SQL*Plus 命令行历史回调功能

解决|命令行 利用uniread 解决 Linux下的SQL*Plus 命令行历史回调功能 作者: Fenng 大家知道, 在 Windows 平台 命令行中的 SQL*Plus 有命令行历史回调的功能,在SQL*Plus工具下面,可以利用键盘的"向上向下"箭头键对命令行的进行回调.而在Linux上则没有该功能(虽然 Shell 可以做到这一点,但是 SQL*Plus 不可以). 而该功能对于CLI爱好者来说几乎是不可缺的,不知道为什么 Oracle 不把这个功能加进来.不得而知了.