从云计算到函数计算
点击上方图片了解活动详情!
哈喽各位开发者,为了帮助大家客观了解并使用阿里云函数计算(FC),阿里云开发者社区携手云原生应用平台 Serverless 团队发布 “Serverless 函数计算征集令”,提供免费资源额度邀请你发文评测,7月31日前参与活动,即有机会获得千元好礼 + 千元函数计算资源包!
立即参加:https://developer.aliyun.com/topic/serverless2022
阿 Ser 也精选出一些活动中的优秀征文推荐给大家,下面让我们跟随笔友 “Ethin” 的步伐,看看他眼中的 Serverless 世界吧!
函数计算,你的名字
云计算,是一种基于互联网的计算方式,通过这种方式,共享的软硬件资源和信息可以按需求提供给计算机各种终端和其他设备,使用服务商提供的电脑基建作计算资源,因此用 “云” 来指代 “网络计算资源” 这是一种非常恰当的比喻。
美国国家标准和技术研究院的云计算定义中明确了三种服务模式,分别是软件即服务(SaaS)、平台即服务(PaaS)和基础设施即服务(IaaS)。
阿里云的产品能全部覆盖这三种服务模式,如果分别举个例子那么应该是:宜搭(SaaS 加速器)、函数计算 FC 和云服务器 ECS。
Serverless 计算服务,其基于 PaaS 又不同于 PaaS,因而更多时候被称作功能即服务(Function-as-a-Service,缩写为 FaaS)。函数计算 FC 是阿里云的事件驱动的全托管 Serverless 计算服务产品,我想函数计算 Function Compute 的名字就是这样诞生的。
函数计算,直达应用的核心
ECS ?FC ?
服务器性能能否应对可能突然爆发的用户请求,何时扩容?
服务器上的脚本和业务代码等多少还在健康运行?
外部网络安全威胁到来时如何保障数据安全?
面对诸多问题确实会让人头大,但如果我们摒弃基于服务器的架构而转用 Serverless 架构之后;服务的过程就变成了这样:
函数计算 FC:解放生产力,更专注于应用的业务本身
应用的部署将变得十分容易。我们只要上传基本的代码,同时不需使用 Puppet、Chef、Ansible 或 Docker 来进行配置管理,大大降低了运维成本。
综上所述,相对于传统项目,函数计算 FC 具备以下优势:
用户无需采购和管理服务器等基础设施,运维成本低,安全性更高。(涵盖了云服务器的优势)。
用户只需专注业务逻辑的开发,使用函数计算支持的开发语言设计、优化、测试、审核以及上传自己的应用代码。结合工作流,代码提交自动部署,直接运行!
函数计算 FC 以事件驱动的方式触发应用响应用户请求。与阿里云对象存储 OSS、API 网关、日志服务和表格存储等服务无缝对接,帮助快速构建应用。
简化运维工作,提供日志查询、性能监控和报警等功能快速排查故障。
不用担心性能问题,架构更富有弹性,毫秒级别弹性伸缩,快速实现底层扩容以应对峰值压力。
使用成本低,按需付费,支持百毫秒级别收费。只需为实际使用的计算资源付费,适合有明显波峰波谷的用户访问场景。
函数计算 FC 似乎是真正实现 “像云一样” 的云计算愿景,它很好的诠释了:最大程度利用资源、减少空闲资源浪费的环保理念以及降低学习成本和使用成本的现实需求。
如此妙哉的函数计算该如何体验呢 ?
由繁到简,从长到短
实践:基于 Node.js + Serverless 的 Web 短网址跳转
API 网关/API Gateway 函数计算/Function Compute 对象存储/Object Storage Service 日志服务/Log Service MongoDB Serverless 实例
购买 MongoDB Serverless 版。 新建集合,新建集合其实就相当于新建一个表。创建集合:links、logs。 通过程序代码连接 Serverless 实例,使用方法参见官方文档: https://help.aliyun.com/document_detail/185473.html?
逻辑代码部分示例:(Attention: 该项目还使用了 Express 框架,以便于简化路由处理)
import storage from '../storage'
export default async (req, res): Promise<any> => {
// params from request body or querystring
const params = req.body ?? req.query
const { url = '', slug = '' } = params as { url?: string, slug?: string }
// url is required
if (url === '') {
return res.status(400).send({ message: 'Missing required parameter: url.' })
}
// url format check
if (!/^https?:\/\/.{3,}/.test(url)) {
return res.status(400).send({ message: 'Illegal format: url.' })
}
// custom slug length check
if (slug.length !== 0 && (slug.length < 2 || slug.length > 10)) {
return res.status(400).send({ message: 'Illegal length: slug, (>= 2 && <= 10).' })
}
const getForwarded = (name: string): string => req.headers[`x-forwarded-${name}`]?.toString() ?? ''
try {
// request origin url
const origin = `${getForwarded('proto')}://${getForwarded('host')}/`
// if slug customized
if (slug !== '') {
const existUrl = await storage.getUrlBySlug(slug)
// url & slug are the same.
if (existUrl === url) {
return res.send({ slug, link: origin + slug })
}
// slug already exists
if (existUrl != null) {
return res.status(400).send({ message: 'Slug already exists.' })
}
}
// target url exists
const existSlug = await storage.getSlugByUrl(url)
// url exists & no custom slug
if (existSlug != null && slug === '') {
return res.send({ slug: existSlug, link: origin + existSlug })
}
// create if not exists
const newSlug = await storage.addLink(url, slug)
// response
res.send({ slug: newSlug, link: origin + newSlug })
} catch (e) {
return res.status(500).send({ message: e.message })
}
}
结语
戳下方,立即查看作者原文!