前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >腾讯云无服务器函数开发网址导航

腾讯云无服务器函数开发网址导航

作者头像
上山打老虎了
发布2022-06-15 08:38:52
4.2K0
发布2022-06-15 08:38:52
举报
文章被收录于专栏:Article

概述

开发一个网址导航来实践腾讯云无服务器函数的功能,因为我有一丢丢的收集癖,一直就想有一个自己的导航,虽然现在各种导航网址遍地开花,但是这并不妨碍我再造一个轮子,可能我的轮子还是平行四边形的呢。

前期准备

什么是 SCF ?我们能利用 SCF 做什么?serverless 要怎么用?优势是什么? 不足点又是什么?对于想尝鲜无服务器函数功能的小伙伴前期要有一定的知识储备,没有银弹,合适的才是最好的。

文档指南

初期看文档,看看腾讯云无服务器函数支持哪些语言和响应的版本,函数和函数能否相互调用(可以调用)等,了解腾讯云给出的功能范围,确定我能通过这些功能做什么事。别忘了还有计费模式,你得知道是怎么扣费的!

思考🤔

对于 serverless 的应用场景目前只要是在以下几个方面:

  1. 事件请求场景
  2. 流量突发场景
  3. 处理大数据场景

同时推荐具备无状态的特性,对于网址导航这个功能,页面偏静态,接口调用少,我需要

  1. 一个定时服务来下载对应网址的 favicon 文件
  2. 收集用户的投稿链接
  3. 页面加载时获取内容

基本功能包含增删改查,除了查询,其他的功能我也不需要权限,管理员自己就能 cover 掉,不和其他业务强绑定关联,模块自身独立,除非后续迭代,当前的应用场景是匹配 serverless 能力的。

整体架构

其实可以做的功能还有很多,但不一定是刚需,目前只要满足最基本的使用即可。

定时任务的频率

现实场景中,Favicon 的变动频度是很小的,所以只需要一个定时任务就可以实现。由于函数的执行时间也是有限制的,理想情况下一次图片抓取主要取决于「网站能否被打开」,因为部分网站可能会被“特殊照顾”,只考虑国内的一些网站的话,执行时间控制在 5 秒以内还是绰绰有余的。但你还是无法保证每次从数据库中取出的这些链接都能被执行完,实际情况也确实是不可能完成,所以我们需要在定时的基础上,人为的做一个控制:判断上一次修改时间距离当前时间是否大于N(单位可以是天,也可以是小时,分钟),这样函数被定时启动的时候只下载之前没有被 Download 的网页图标。

关键代码:

代码语言:javascript
复制
exports.main_handler = async (event, context, callback) => {
    const lists = await sqlAction.query('select * from tableName where deleted=0');
    const during =  60 * 60 * 24 * 5 * 1000; // 5 天
    for (const item of lists) {
        const past = new Date(item.update_time).getTime();
        const now = new Date().getTime();
        if (now - past >= during || isNaN(past)) {
            const fileName = await download(item.link, item.name);
            if (fileName) {
                await sqlAction.query(`update tableName set favicon='${fileName}', update_time='${helper.formatDate(new Date().getTime())}' where id=${item.id}`);
            }
        }
    }
    return 'success';
};

COS 存储

定时任务抓取的小图标需要保存到 cos 上作为静态资源,这里我并没有使用腾讯云的服务,因为某🐂的 http 访问有免费额度,所以我使用 ta 来上传抓取的资源,因为是定时抓取,所以需要对文件可覆盖,不能使用随机ID命名的方式,否则资源会越来越多,后期还要做清理。使用其他云存储的也是同理。

上传代码:

代码语言:javascript
复制
const mac = new qiniu.auth.digest.Mac(qiniu.ak, qiniu.sk);
const config = new qiniu.conf.Config();
// 空间对应的机房
config.zone = qiniu.zone.Zone_z1;
// 是否使用https域名
config.useHttpsDomain = true;
// 上传是否使用cdn加速
config.useCdnDomain = true;

// 这种配置方式可以相同文件名覆盖
const options = {
    scope: 'bucketName:' + name,
};

const putPolicy = new qiniu.rs.PutPolicy(options);
const uploadToken = putPolicy.uploadToken(mac);

const formUploader = new qiniu.form_up.FormUploader(_config);
const putExtra = new qiniu.form_up.PutExtra();
const path = process.cwd() + '/icons/' + name;
// 文件上传
formUploader.putFile(uploadToken, name, path, putExtra, function (respErr, respBody, respInfo) {
    if (respErr) {
        reject(respErr);
        throw respErr;
    }
    if (respInfo.statusCode == 200) {
        resolve(respBody)
    } else {
        reject(respBody)
    }
});

静态页面

对于单页应用是可以放在任意的静态服务器上,或者 CDN 上,但是对于有 SEO 要求的网页来说,服务端渲染是少不了的,这里使用了相对简单的方式。函数调数据库读取内容,NodeJs 使用 ejs 引擎来渲染。

渲染代码:

代码语言:javascript
复制
let html = fs.readFileSync(path.resolve(__dirname, './index.html'), {
    encoding: 'utf-8'
});
html = Ejs.render(html.toString(), {
    title: 'Nox导航 - 互联网从这开始',
    list: result
});

return {
    isBase64Encoded: false,
    statusCode: 200,
    headers: { 'Content-Type': 'text/html' },
    body: html
}

反向代理

由于部署好的页面只有一个访问路径,如果使用二维码分享的话就无所谓了,但是要对外服务的话这个路径暴露出去就不太合适了,需要用 Nginx 做一次代理。

代理设置:

代码语言:javascript
复制
location /daohang {
    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_redirect https://service-8nvzq5f1-1251487239.ap-shanghai.apigateway.myqcloud.com/release/navigation-index  /;
    proxy_set_header Accept-Encoding "";
    proxy_set_header User-Agent $http_user_agent;
    proxy_set_header Accept-Language "zh-CN";
    proxy_connect_timeout      240;
    proxy_send_timeout         240;
    proxy_read_timeout         240;
    # note, there is not SSL here! plain HTTP is used
    proxy_pass https://service-8nvzq5f1-1251487239.ap-shanghai.apigateway.myqcloud.com/release/navigation-index;
    sub_filter_once off;
}

最后我们可以使用 https://www.noxxxx.com/daohang 来访问了!

注意点

1. 部署 html 页面,需要开启集成响应功能,否则返回的内容不能被识别为 html。

2. Mysql 调用后需要 dstory 掉,否则整个函数运行会超时。

3. 本地调试运行函数后报异常,抛出的错误信息没有具体的代码行数,通常需要优先检查自己的代码逻辑是不是有问题,比如说取对象属性名时,对象为空的情况,也会有类似下面的这种错误,单看报错日志看不出什么…

总结

通过腾讯云的 scf 插件结合 visual studio code,无服务器函数在开发过程中,只需要聚焦业务功能的实现,同时,本地可以近乎一键部署到线上,效率非常高,运维部署层面上可以节省很多时间和精力。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年10月06日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 前期准备
  • 文档指南
  • 思考🤔
  • 整体架构
  • 定时任务的频率
  • COS 存储
  • 静态页面
  • 反向代理
  • 注意点
  • 总结
相关产品与服务
云函数
云函数(Serverless Cloud Function,SCF)是腾讯云为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。您只需使用平台支持的语言编写核心代码并设置代码运行的条件,即可在腾讯云基础设施上弹性、安全地运行代码。云函数是实时文件处理和数据处理等场景下理想的计算平台。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档