![f5ea7ce042d4fa59972c3f81a6b6a082.png](https://i-blog.csdnimg.cn/blog_migrate/a01d442ca8c6c047230a97a8ac054274.jpeg)
概述
在前面的文章中,我们实践过AWS S3如何实现跨区域复制(CRR),将对象从一个region的存储桶复制到另一个region的存储桶。今天来实践一下对于S3事件通知的操作。
S3提供了事件通知功能,可以在存储桶发生某些事件时接收通知。本次实践的目标有两个,一是当存储桶上传新对象时发送电子邮件提醒,二是当存储桶上传图片时进行大小缩放。
![73d809d462de754bd0be6fef748b4144.png](https://i-blog.csdnimg.cn/blog_migrate/a6ecc8a824d76ab0fba2ec4c377bca46.jpeg)
实践1 存储桶上传新对象时发送邮件提醒
这个操作比较简单,S3+SNS即可实现,基本流程如下:
步骤1 创建存储桶
在aws S3控制台上创建一个存储桶xytempbucket(位于欧洲巴黎region),如图1所示
![c6564c449b1590590464adfc6f0f12c0.png](https://i-blog.csdnimg.cn/blog_migrate/d94289f5c663849ff4b256630bd0b975.jpeg)
图1
步骤2 创建SNS通知
在SNS控制台创建一个通知主题xuyisnstopicmail,如图2所示
![f39ec14a862279fa3ef211c6f1c9ade1.png](https://i-blog.csdnimg.cn/blog_migrate/fa05a1e5a3c81116f62f943bd7fbf0d9.jpeg)
图2
注意,在这个主题中需要明确其访问策略,如图3所示
![8726753f7d619445bb702593c9458620.png](https://i-blog.csdnimg.cn/blog_migrate/cc2db9c4ad1b19c15507b3111407eddd.jpeg)
图3
策略主要明确SNS主题名称和aws 存储桶的名称(分别用蓝色标明)。
至此,主题的发布完成,接下来需要订阅该主题。主题界面中点击"创建订阅",开始配置订阅,在"主题ARN"中把上一步发布的主题ARN填进去即可,在"协议"中选择"电子邮件",在"终端节点"中填入email接收地址,点击"创建订阅"即可,如图4所示
![48d908dffecc5536a9918254e541b488.png](https://i-blog.csdnimg.cn/blog_migrate/02495a22289e4dbc6b4e101e65eb137b.jpeg)
图4
此时,只是进行了订阅主题的操作,还没有生效,AWS会发送一封电子邮件至图中所填邮箱,需要据此点击确认对主题的订阅。如图5所示
![bb63b97516e631e7fc7c44ce079e0081.png](https://i-blog.csdnimg.cn/blog_migrate/fc3530d0656839b5dca40454a7619ee4.jpeg)
图5
根据邮件提示操作即可确认订阅成功。
步骤3 在存储桶上配置事件,启用存储桶通知
回到S3控制台,在所选的存储桶->属性->事件栏点击"添加通知",如图6所示
![a784c66560a5955d6cdc7ae8cc8874d7.png](https://i-blog.csdnimg.cn/blog_migrate/6c80289965bdac3ae6b2c076bfe72e06.jpeg)
图6
选择一个合适的事件名称,注意:1)事件类型可能存在一定的冲突而报错,根据需要选择,多试几次(我勾选put和post);2)SNS主题填入前面所创建的主题ARN即可。
步骤4 验证
至此,配置完毕,现在开始验证。在配置之前存储桶中已经存在了7个图片(screen-shot1~screen-shot7),现在从控制台再上传一张xytestpng.png的图片,如图7所示
![d5c6b3383db6d12c3b16501ec1c19ae3.png](https://i-blog.csdnimg.cn/blog_migrate/e74201ca9319250ff357d3077aff0a05.jpeg)
图7
图片上传成功之后,随即qq邮箱传来邮件提醒,查看邮箱,如图8所示
![60a3db9cd672d675bf699852ba155bb5.png](https://i-blog.csdnimg.cn/blog_migrate/85dc3efbc7891d10d583cba0989c9ca7.jpeg)
图8
注意:邮件通知的时间可能有一定的延时,不确定。
至此,实践1完毕。(非常简单,在控制台点击即可完成。)
实践2 存储桶上传图片进行缩放
整体流程:将图片上传到源存储桶,通过事件触发lambda函数,lambda获取上传的图片进行缩放处理,再将处理完成的图片存入到目标存储桶。如图9所示:
![9ccae1877357ca56c25da8a94eff1d81.png](https://i-blog.csdnimg.cn/blog_migrate/98e6fe91cc5b0225c573243040d3da1b.jpeg)
图9
步骤1 创建存储桶
在S3控制台创建存储桶,需要创建两个存储桶,一个是源存储桶xytempbucket,一个是目标存储桶xytempbucketresized(创建过程省略),区域为欧洲巴黎。如图10所示
![99411b51b0ddc415390b30abf0545243.png](https://i-blog.csdnimg.cn/blog_migrate/f1d8130bc317519b782510c6332c762e.jpeg)
步骤2 创建策略
IAM控制台->创建策略,将以下内容复制到json编辑框中,即可生成。
![8c7efe0a4d063535b08b31640cb499bf.png](https://i-blog.csdnimg.cn/blog_migrate/b1480134a26270b51c67974ad742d9ed.jpeg)
图11
注意:其中的源存储桶和目标存储桶要使用自己实际的存储桶ARN。
步骤3 创建角色
策略创建完成后,切换到IAM控制台,创建角色。
![a01dee30c8106c039e7dd4676548614e.png](https://i-blog.csdnimg.cn/blog_migrate/0f61c2749d02903525ea97f20c77266f.jpeg)
图12
创建由lambda服务使用的角色,如图12所示,并将步骤2中创建的策略附加到该角色上,如图13、图14所示。
![00545991103573e61b6e8d707c23a935.png](https://i-blog.csdnimg.cn/blog_migrate/c68b4e5303951245f0f60729c6f71762.jpeg)
图13
![f9713c2cc170bcc1646b4219705677a3.png](https://i-blog.csdnimg.cn/blog_migrate/1d19edac00e1bba1863163b62803bf30.jpeg)
图14
步骤4 创建lambda函数
切换到lambda控制台,创建函数->从头开始创作,填写函数名称,和语音信息,如图15所示
![d697866f097a0cb62ee05eee28326c83.png](https://i-blog.csdnimg.cn/blog_migrate/6e027c7dde14d24de2978b2af77736ac.jpeg)
图15
注意区域要与S3中存储桶的区域一致,选欧洲巴黎。
继续,可以再次添加函数的触发器(也可以暂时不添加,而去S3存储桶的事件属性里添加触发lambda,同样的效果),这里选择S3触发,需要选择源存储桶,事件类型选择put,如图16所示
![608f90794b0ce41cd30c69407be994db.png](https://i-blog.csdnimg.cn/blog_migrate/fd7e2b0a42d985f56ab18283db5f0474.jpeg)
图16
点击"添加"即成功添加了lambda函数的触发器。再编辑lambda函数代码,将下面代码复制进去
var AWS = require("aws-sdk"); var IM = require('imagemagick'); var FS = require('fs'); var compressedJpegFileQuality = 0.80; var compressedPngFileQuality = 0.95; exports.handler = (event, context, callback) => { var s3 = new AWS.S3(); var sourceBucket = "xytempbucket"; var destinationBucket = "xytempbucketresized"; var objectKey = event.Records[0].s3.object.key; var getObjectParams = { Bucket: sourceBucket, Key: objectKey }; s3.getObject(getObjectParams, function(err, data) { if (err) { console.log(err, err.stack); } else { console.log("S3 object retrieval get successful."); var path = require('path'); var tmpname = path.basename(objectKey); var resizedFileName = "/tmp/"+tmpname; var quality; if (resizedFileName.toLowerCase().includes("png")){ quality = compressedPngFileQuality; } else { quality = compressedJpegFileQuality; } var resize_req = { width:"100%