临沂网站维护公司,东莞网,西安网络公司做网站,怎么把百度放到网站上在 《函数计算本地运行与调试 - Fun Local 基本用法》 中#xff0c;我们介绍了利用 Fun Local 本地运行、调试函数的方法。但如果仅仅这样简单的介绍#xff0c;并不能展现 Fun Local 对函数计算开发的巨大效率的提升。
这一次#xff0c;我们拿一个简单的场景来举例子——…在 《函数计算本地运行与调试 - Fun Local 基本用法》 中我们介绍了利用 Fun Local 本地运行、调试函数的方法。但如果仅仅这样简单的介绍并不能展现 Fun Local 对函数计算开发的巨大效率的提升。
这一次我们拿一个简单的场景来举例子——开发一个简单的爬虫函数代码参考函数计算控制台模板)介绍如何以正确姿势从零开始开发一个自动伸缩、按调用次数收费的 serverless 爬虫应用。
开发步骤
我们将这个完整的应用拆分成多步并且在每一步完成后我们都会进行相应的运行验证。
1. 创建 Fun 项目
首先我们创建一个名为 image-crawler 的目录作为项目的根。然后在该目录下创建一个名为 template.yml 的文件内容为
ROSTemplateFormatVersion: 2015-09-01
Transform: Aliyun::Serverless-2018-04-03
Resources:localdemo:Type: Aliyun::Serverless::ServiceProperties:Description: local invoke demoimage-crawler:Type: Aliyun::Serverless::FunctionProperties:Handler: index.handlerCodeUri: code/Description: Hello world with python2.7!Runtime: python2.7
如果不了解 Fun 定义的 Serverless Application Model可以参考 这里。
操作完成后我们的项目目录结构如下
.
└── template.yml
2. 编写 helloworld 函数代码
在根目录下创建一个名为 code 的目录并在该目录下创建一个名为 index.py 的文件内容为一个简单的 helloworld 函数:
def handler(event, context):return hello world!
在项目根目录下执行:
fun local invoke image-crawler
函数运行成功: 操作完成后我们的项目目录结构如下:
.
├── code
│ └── index.py
└── template.yml
3. 事件触发函数运行
我们简单修改第 2 步的代码将 event 打印到 log 中。
import logginglogger logging.getLogger()def handler(event, context):logger.info(event: event)return hello world!
通过触发事件的方式运行函数得到如下结果 可以看到我们的函数已经能正确接收到触发事件了。
Fun Local 更多帮助信息参考。
4. 获取网页源码内容
接下来我们添加获取网页内容的代码。
import logging
import json
import urlliblogger logging.getLogger()def handler(event, context):logger.info(event: event)evt json.loads(event)url evt[url]html get_html(url)logger.info(html content length: str(len(html)))return Done!def get_html(url):page urllib.urlopen(url)html page.read()return html
代码逻辑比较简单我们这里直接使用了 urllib 库读取网页内容。
运行函数得到以下输出 5. 解析网页中的图片
我们打算通过正则解析网页中包含的 jpg 图片因此这一步会比较繁琐因为涉及到正则表达式的微调。为了能快速的解决问题我们决定利用 fun local 提供的 local debugging 解决问题。local debugging 方法参考 《函数计算本地运行与调试 - Fun Local 基本用法》。
首先我们在下面这一行下个断点
logger.info(html content length: str(len(html)))
然后以 debug 的方式启动vscode 调试器连接后函数会继续运行到我们断点的这一行 我们可以直接在 Locals 一栏看到本地变量其中包含了 html 这个变量也就是我们获取到的 html 源码。我们可以将它的值复制出来分析下然后设计正则表达式。
我们可以先写一个简单的比如可以是 http:\/\/[^\s,]*\.jpg。
怎么快速校验这段代码的正确性呢我们可以利用调试器提供的 Watch(监视) 功能。
创建一个 Watch 变量将下面的值输入进去
re.findall(re.compile(rhttp:\/\/[^\s,]*\.jpg), html)
回车后即可看到代码的执行效果 这里一般不太容易一次写对可以反复修改正则测试直到正确为止。
我们得到的正确的图片解析的逻辑添加到代码中
reg rhttp:\/\/[^\s,]*\.jpg
imgre re.compile(reg)def get_img(html):return re.findall(imgre, html)
然后在 handler 方法中调用即可
def handler(event, context):logger.info(event: event)evt json.loads(event)url evt[url]html get_html(url)img_list get_img(html)logger.info(img_list)return Done!
编写完成后可以继续本地执行验证下结果
echo {url: https://image.baidu.com/search/index?tnbaiduimageword%E5%A3%81%E7%BA%B8} \| fun local invoke image-crawler
可以看到img_list 已经输出到控制台了 6. 将图片上传到 oss
解析到的图片我们选择使用 oss 存储。
首先我们需要通过环境变量配置 OSS Endpoint 以及 OSS Bucket。
在 template 中配置环境变量(需提前创建好 oss bucket:
EnvironmentVariables:OSSEndpoint: oss-cn-hangzhou.aliyuncs.comBucketName: fun-local-test
然后就可以直接在函数中获取到这两个环境变量了
endpoint os.environ[OSSEndpoint]
bucket_name os.environ[BucketName]
另外fun local 运行函数时还会提供一个额外的变量用来标识这是一个本地运行的函数。通过这个标识我们可以用来做一些本地化的操作比如我们可以在线上运行时连接 RDS在本地运行时连接 Mysql。
这里我们用该标识以不同的的方式创建 oss client原因是线上运行时通过 credentials 获取到的是扮演角色的临时 ak有有效期限制而本地运行时没有该限制。oss 提供了这两种方式的构造方法我们直接使用即可
creds context.credentialsif (local):auth oss2.Auth(creds.access_key_id,creds.access_key_secret)
else:auth oss2.StsAuth(creds.access_key_id,creds.access_key_secret,creds.security_token)bucket oss2.Bucket(auth, endpoint, bucket_name)
接着我们遍历所有图片将所有的图片上传到 oss
count 0
for item in img_list:count 1logging.info(item)# Get each picturepic urllib.urlopen(item)# Store all the pictures in oss bucket, keyed by timestamp in microsecond unitbucket.put_object(str(datetime.datetime.now().microsecond) .png, pic)
再在本地运行一下函数
echo {url: https://image.baidu.com/search/index?tnbaiduimageword%E5%A3%81%E7%BA%B8} \| fun local invoke image-crawler
可以从日志看到图片被一张一张的解析出来并被上传到 oss 上了。 登陆 oss 控制台可以看到这些图片。 部署
本地开发完成后我们还需要将其发布到线上让其成为一个可被调用的服务。以往你可能觉得比较麻烦比如要登陆控制台创建服务、创建函数、配置环境变量创建角色等现在有了 fun 后这一切都不需要了。
不过本地与线上还是有些区别的那就是要授权函数计算能够访问 OSS怎么做呢很简单在我们的 template 中加入一行配置即可(Polices 文档可以参考)
Policies: AliyunOSSFullAccess
添加后的 template.yml 内容如下
ROSTemplateFormatVersion: 2015-09-01
Transform: Aliyun::Serverless-2018-04-03
Resources:localdemo:Type: Aliyun::Serverless::ServiceProperties:Description: local invoke demoPolicies: AliyunOSSFullAccessimage-crawler:Type: Aliyun::Serverless::FunctionProperties:Handler: index.handlerCodeUri: code/Description: Hello world with python2.7!Runtime: python2.7EnvironmentVariables:OSSEndpoint: oss-cn-hangzhou.aliyuncs.comBucketName: fun-local-test
然后使用 fun deploy 后可以看到部署成功的日志。 验证
通过控制台验证
登陆控制台可以看到我们的服务、函数、代码、环境变量等都已经就绪了。 在触发事件中写入我们用来测试的 json然后执行 可以发现会获得与本地一致的效果 通过 fcli 验证
fcli 帮助文档 参考。
在终端执行以下命令可以获取函数列表:
fcli function list --service-name localdemo
可以看到我们的 image-crawler 已经创建成功了。
{Functions: [image-crawler,java8,nodejs6,nodejs8,php72,python27,python3],NextToken: null
}
使用以下命令则可以调用函数运行
fcli function invoke --service-name localdemo \--function-name image-crawler \--event-str {url: https://image.baidu.com/search/index?tnbaiduimageword%E5%A3%81%E7%BA%B8}
运行成功后会得到与控制台与 fun local 一致的结果。
小结
至此我们的开发就算告一段落。
本文利用 fun local 提供的本地运行、调试的能力做到了在本地开发函数并且通过反复的执行函数得到反馈以便于快速迭代代码。
在本地开发完成后不需要对代码进行任何修改通过 fun deploy 命令一键部署到云端达到预期的效果。
本文介绍的方法并不是开发函数计算的唯一方式。本文的目的是能够向开发者传达一种信号——开发函数计算时只要身姿正确就会非常享受开发流程也会十分顺畅。祝您使用愉快。 原文链接 本文为云栖社区原创内容未经允许不得转载。