小白的另一个身份居然是顶流站姐!她要给爱豆搭建一个网站,分享生图精修图。上面的所有图片都希望自动加上水印。这在很多论坛社区里是基本操作了,大咖教小白用函数计算+OSS轻松实现。
业务场景描述
在Web应用中,有很多在类型,其中针对有一种是针对电商、图片处理网站中当客户上传到OSS的图片进行大小裁剪或者批量加上防盗水印,通常的做法是搭建一个在线服务器并部署Web应用来进行处理,程序需要按照一定规则来定时来触发事件,这样的情况下,会有3个明显的工作需要额外来考虑:
需要搭建Web应用服务器(不管有没有图片处理,空置率会比较高)
需要编写相关OSS代码来处理这块事情(需要专门维护一套运行处理代码)
需要考虑图片处理的及时性如何保障(要考虑并发和定时器的执行方法)
以上问题,我们仅仅需要通过阿里云的函数计算产品来设置简单事件触发器和编写一些简单OSS的程序就能完美解决上述问题,下面让我们来看看这个任务的如何分解。
整体架构图
首先来对比一下新老架构有什么不同,老架构需要考虑三个地方的处理,例如处理OSS图片的内容、触发条件的处理、以及搭建应用服务器等。
老的框架
如下图,需要考虑蓝色部分,图片转码需要编写相关代码进行处理。
蓝色标注是老架构中需要关注的,程序需要一种机制对上传来的图片进行设置,例如从OSS的某个目录进行定期扫描,并批量发送到图片进行加水印,大小变化等,并把处理过的图片,用户需要搭建Web应用,需要编写相关OSS的处理,还需要有个机制能定期做程序处理。
总结下来需要用户关注内容点:
对图片的处理需要编写相关代码
在OSS上把转码后的图片转移到新的Bucket,需要维护相关代码
需要考虑图片处理的及时性
新框架
用户仅仅需要在Function Compute(函数计算)上设置触发器+函数,例如,监控某个Bucket下的PutObject的事件,当用户把图片上传到OSS的某个Bucket,
马上触发后续的函数代码,函数代码的无非就是把图片进行处理,并把图片转移到新的bucket中,整个过程,不需要搭建Web服务器,不需要写触发条件,
也无需关注整个服务状态如何。纯粹的事件触发后续程序,详见下图分解,仅仅一处蓝色圆圈就是需要编写的代码。
整个业务处理流程:
源码实例
基于新框架的内容,我把相关代码按块来分解,按照两块内容来处理,控制台上的操作和Fcli命令行工具的使用。
通过控制台的操作(控制台操作时间较久远,截图仅供参考,请以目前实际控制台展示为准)
1、 开通service
2、新增函数计算
新建函数计算里,需要选择运行环境。这个示例中选在线编辑,输入编写代码即可。
代码段:
'use strict';
module.exports.handler = function(event, context, callback) {
var co = require('co'); //设置初始的OSS环境变量
var OSS = require('ali-oss');
var client = new OSS({
region: 'oss-cn-shanghai',
accessKeyId: ‘your accessKeyId’, //输入你的accessKeyId
accessKeySecret:’ your accessKey Secret’, //输入你的accessKeySecret
bucket: 'function-demo-bucket' //输入华东2区的bucket name
});
//读取bucket下的目录
co(function* () {
var result = yield client.list({
prefix: 'tmp/'
});
var name ;
var nameArray = result.objects;
for(var index=0; index < nameArray.length; index++){
var str = nameArray[index].name;
if (str.indexOf('.jpg') > 0){
console.log(str);
//把处理后的图片存放到执行环境的/tmp目录下(tmp目录能存放的256MB文件)
var resize = yield client.get(str,'/tmp/example-resize.jpg',{process: 'image/resize,m_fixed,w_128,h_128'});
//删除掉被处理完成的图片,防止第多次被处理
var del = yield client.delete(str);
console.log(del);
//把新处理后的图片转移到新目录下
name = new Date().getTime()+'.jpg';
var put = yield client.put('resource/'+ name,'/tmp/example-resize.jpg',{
meta: {
year: 2017,
people: 'wenyi'
}
});
callback(null, "New pic Name is : "+name);
console.log(name);
}
}
callback(null, "Invk OSS is OK!");
}).catch(function(err){
console.log(err)
});
};
3、设置OSS 的Trigger
在这个选项页里,我们选中华东2的Bucket和触发事件,触发事件目前控制台仅支持通过OSS进行触发,但是通过API或者SDK可以编写自行触发的事件。在这里,我列举控制台的方式来处理。
设置到这个地方,肯定有人会跑出来说,为什么不直接用OSS本身的URL进行resize呀,你考虑一点都没错,但是当我想把resize后的图片再存下来,怎么搞?或者我是不同Bucket下的,怎么搞?再或者,我想跨region保存,怎么搞?涉及到一系列问题,都交给OSS的SDK来处理,就要写大量代码。哪么通过FC,在一个函数中都可以自定义搞定,这样灵活方便的事情,显然不用再搭建执行环境来处理,交给FC即可。
函数计算的OSS的Trigger设置如下:
注意:由于本案例是在同一个bucket中操作图片,如果不设置前缀或者后缀做区分图片处理类型,会死循环的生成很多图片。
在OSS上的文件夹的目录结构如下:
4、查看执行结果
整个业务执行结束,完成了完整的一个例子。
本文作者:文意,转载自云栖社区