开发者:Serverless 从懵比到实战

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Serverless 是一种执行模型"},{"type":"codeinline","content":[{"type":"text","text":"(execution model)"}]},{"type":"text","text":"。在这种模型中,云服务商负责通过动态地分配资源来执行一段代码。云服务商仅仅收取执行这段代码所需要资源的费用。代码通常会被运行在一个无状态的容器内,并且可被多种事件触发("},{"type":"codeinline","content":[{"type":"text","text":"http 请求"}]},{"type":"text","text":"、数据库事件、监控报警、文件上传、定时任务……)。代码常常会以函数"},{"type":"codeinline","content":[{"type":"text","text":"(function)"}]},{"type":"text","text":"的形式被上传到云服务商以供执行,因此"},{"type":"codeinline","content":[{"type":"text","text":"Serverless"}]},{"type":"text","text":"也会被称作"},{"type":"codeinline","content":[{"type":"text","text":"Functions as a Service"}]},{"type":"text","text":" 或者 "},{"type":"codeinline","content":[{"type":"text","text":"FaaS"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"BaaS"}],"marks":[{"type":"strong"}]},{"type":"text","marks":[{"type":"strong"}],"text":": "},{"type":"codeinline","content":[{"type":"text","text":"Backend as a Service"}],"marks":[{"type":"strong"}]},{"type":"text","marks":[{"type":"strong"}],"text":",这里的"},{"type":"codeinline","content":[{"type":"text","text":"Backend"}],"marks":[{"type":"strong"}]},{"type":"text","marks":[{"type":"strong"}],"text":"可以指代任何第三方提供的应用和服务,比如提供云数据库服务的"},{"type":"codeinline","content":[{"type":"text","text":"Firebase"}],"marks":[{"type":"strong"}]},{"type":"text","marks":[{"type":"strong"}],"text":"和"},{"type":"codeinline","content":[{"type":"text","text":"Parse"}],"marks":[{"type":"strong"}]},{"type":"text","marks":[{"type":"strong"}],"text":",提供统一用户身份验证服务的"},{"type":"codeinline","content":[{"type":"text","text":"Auth0"}],"marks":[{"type":"strong"}]},{"type":"text","marks":[{"type":"strong"}],"text":"和"},{"type":"codeinline","content":[{"type":"text","text":"Amazon Cognito"}],"marks":[{"type":"strong"}]},{"type":"text","marks":[{"type":"strong"}],"text":"等。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"FaaS"}],"marks":[{"type":"strong"}]},{"type":"text","marks":[{"type":"strong"}],"text":": "},{"type":"codeinline","content":[{"type":"text","text":"Functions as a Service"}],"marks":[{"type":"strong"}]},{"type":"text","marks":[{"type":"strong"}],"text":",应用以函数的形式存在,并由第三方云平台托管运行,比如腾讯云云函数 SCF、AWS Lambda 等。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"背景"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那么我们为什么需要"},{"type":"codeinline","content":[{"type":"text","text":"Serverless"}]},{"type":"text","text":"呢?对于这个问题来说,我们可以从日常个人的开发中找到原因。无论是个人博客、小程序,还是个人网站,我们都要面临一个问题:怎么解决服务器部署相关的问题。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对于常规的项目来说,一般的流程莫过于:购买服务器 => 域名备案(这一步可能可以不用,看个人需求) => 环境搭建 => 部署"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那么我们如果仅仅是想要开发一个几乎不太需要多强的后台支持时,却要去做这么多操作,这对于整个项目的开发来说是十分不友好的,很容易就会让人放弃上线的念头。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那么"},{"type":"codeinline","content":[{"type":"text","text":"Serverless"}]},{"type":"text","text":"就是用于解决这个问题的存在,他具备托管服务端各项功能的能力,让你无需进行上述繁琐的步骤就能轻松让你的网站或服务正常运行且可访问,同时能够极大降低个人的维护成本,这对于广大开发者而言无疑是十分实用的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Serverless特点"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"1. 低成本"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"众所周知,我们购买一个云服务器,抛去人力成本不计,单从收费方式上来分析,各厂商都是采用按月计费的方式来收取,也就是即使没有人访问你的网站或服务,每月需要支付的租金都是不变的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"然后再来看"},{"type":"codeinline","content":[{"type":"text","text":"Serverless"}]},{"type":"text","text":"应用,它是按你实际使用的资源量来进行计价的,可以理解为你用多少付多少,可以类比于我们手机流量的方式来收取。同时,根据福布斯2015年发布的一份研究报告,从全年来看,一个典型的数据中心里的服务器平均资源使用率只有可怜的 5%~15%,也就是说如果全部使用"},{"type":"codeinline","content":[{"type":"text","text":"Serverless"}]},{"type":"text","text":",理论上至少可以节省80%的运行成本。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对比分析之后,"},{"type":"codeinline","content":[{"type":"text","text":"Serverless"}]},{"type":"text","text":" 在成本方面无疑是较低的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"2. 自动扩缩容"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"正如上文所述,函数即应用,每一个函数只会服务于特定的功能,它可以随意的进行动态拓展或者收缩容量,同时不会影响到其他函数,并且粒度更小,速度更快。反观我们的单体应用和微服务来说,借助于各种容器编排技术,虽然也能实现自动扩缩容,但由于粒度关系,相比函数,始终会存在一定的资源浪费。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"3. 事件驱动"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"函数本质上实现的是一种 IPO"},{"type":"codeinline","content":[{"type":"text","text":"(Input-Process-Output)"}]},{"type":"text","text":"模型,它是短暂的,是即用即走的。这点是函数区别於单体应用和微服务的另一个特征。不管是单体应用,还是微服务,都是系统中的常驻进程,即便你不使用,它依旧会一直运行。而对于函数来说,没有请求就不需要消耗任何资源,只有在收到请求时才会调动资源进行响应,完成之后就会立刻释放资源,这在节省资源方面无疑是巨大的优点。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"4. 无状态"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"从事件驱动能力中我们提到了它只有在收到请求时才会工作起来,工作完成之后就立刻被释放,也就是各种运行时的内存缓存都是没有太大效益的,不仅如此,同一个请求方式,第二次访问服务时很有可能被调度到其他新的机器上,所以本地缓存方式依旧是失效的,函数只能使用外存(比如"},{"type":"codeinline","content":[{"type":"text","text":"Redis"}]},{"type":"text","text":",数据库)进行缓存,而操作外存都需要通过网络,性能跟内存、本地硬盘相比差了一到两个数量级。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"第一个云函数"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这里将利用腾讯云作为演示平台,首先你需要先登录到腾讯云。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接着打开云函数控制台:"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/52\/523573f16134365c4876accd8b13edd2.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"腾讯云函数控制台"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们选择新建一个云函数,在这里我们可以自由选择开发的语言以及是否需要模板,为了演示方便还是选择勾选模板,然后点击完成,就能进入我们正式的代码编写环节了。"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/8c\/8c28f2e611a56e6b4ffcc3539eabd457.webp","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"代码工作台"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这里我们可以随意的修改函数的返回值,接着就能对它进行测试啦。"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/15\/153e73c1ae72ebab974e2d7e1bf11ffe.webp","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"测试云函数"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"当你看到运行后的返回结果和你编写的代码返回值一致时就说明你的云函数已经在工作中了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"当然,仅仅只是这么测试一下自然很不过瘾,我还想能通过"},{"type":"codeinline","content":[{"type":"text","text":"http"}]},{"type":"text","text":"请求的方式来访问这个云函数,又该怎么做呢?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这个其实也很简单,我们选择左侧的触发管理,新建一个触发策略,并选择触发方式为"},{"type":"codeinline","content":[{"type":"text","text":"API网关"}]},{"type":"text","text":",然后直接点击提交。"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/2d\/2d5924a8b320c4a35f4e692c2e5139ed.webp","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"新建触发策略"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/4d\/4d813a2a18c62a139d579b72414548e9.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"具体操作步骤"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这个时候我们其实已经可以通过"},{"type":"codeinline","content":[{"type":"text","text":"url"}]},{"type":"text","text":"进行访问了,我们复制访问路径,然后在浏览器访问,就能看到我们云函数给我们返回的内容了。"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/76\/76fff514ce99d305153b2502779321fd.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"复制链接"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/bd\/bd9465b961f5886bce69491299b15ea3.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"访问步骤"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"本地开发"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"介绍完在云平台上创建函数的方式,接下来就该介绍如何进行本地开发并部署的方式了:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"1. 安装"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这里将以"},{"type":"codeinline","content":[{"type":"text","text":"Node"}]},{"type":"text","text":"作为开发语言进行演示,更多语言安装方式请参考官方文档。"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"npm i serverless -g"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"先安装对应的包,这里可以安装到全局便于以后使用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接着使用相关命令生成"},{"type":"codeinline","content":[{"type":"text","text":"demo"}]},{"type":"text","text":"模板项目:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"serverless init sls-demo"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"创建完成之后,我们进入生成目录,映入眼帘的就是一个"},{"type":"codeinline","content":[{"type":"text","text":"src"}]},{"type":"text","text":"目录和一个"},{"type":"codeinline","content":[{"type":"text","text":"serverless.yml"}]},{"type":"text","text":"配置文件。我们一般将源代码都放置在"},{"type":"codeinline","content":[{"type":"text","text":"src"}]},{"type":"text","text":"目录下,当然,这个也看个人喜好,如果你不喜欢,可以选择放在任意文件夹下,不过就需要修改一下配置文件中的"},{"type":"codeinline","content":[{"type":"text","text":"src"}]},{"type":"text","text":"字段对应的值了,它默认是指向了当前目录下的"},{"type":"codeinline","content":[{"type":"text","text":"src"}]},{"type":"text","text":"目录。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"组件信息:"}]},{"type":"embedcomp","attrs":{"type":"table","data":{"content":"
字段名是否必选说明
componentcomponent 的名称,可使用 sls registry 命令查询可引入的组件。
name创建的实例名称,每个组件在部署时将创建一个实例。"}}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"参数信息(inputs下对应的字段):"}]},{"type":"embedcomp","attrs":{"type":"table","data":{"content":"
字段名说明
name云函数名称,同时也作为资源 ID。
src代码路径。
handler函数处理方法名称。
runtime云函数运行环境,目前支持:Python2.7、Python3.6、Nodejs6.10、Nodejs8.9、Nodejs10.15、Nodejs12.16、PHP5、PHP7、Go1、Java8 和 CustomRuntime。
region云函数所在的区域。
events触发器。支持的触发器为:timer、apigw、cos、cmq、ckafka 。"}}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"想查询更多详细信息可以参考官方文档。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"2. 开发"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们可以将业务的各项代码都放置在"},{"type":"codeinline","content":[{"type":"text","text":"src"}]},{"type":"text","text":"目录下,这里以当前"},{"type":"codeinline","content":[{"type":"text","text":"demo"}]},{"type":"text","text":"项目举例。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们打开"},{"type":"codeinline","content":[{"type":"text","text":"src\/index.js"}]},{"type":"text","text":",在暴露的这个函数中我们可以尽情的做一些骚操作,然后返回一个结果,并进行测试。你可以连接数据库操作,或者是发起请求等,根据你自己选取的语言来进行代码编写,笔者这里是选择的"},{"type":"codeinline","content":[{"type":"text","text":"Nodejs"}]},{"type":"text","text":"环境进行调试。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不仅如此,我们可以配合其他"},{"type":"codeinline","content":[{"type":"text","text":"Node"}]},{"type":"text","text":"框架"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"3. 部署"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"部署就比较简单了,只要一句小小的命令即可轻松部署到云端:"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"serverless deploy\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你属于第一次部署的话,将会发现在控制台打印出了一个二维码,你需要做的就是用微信进行扫码授权,然后就静待部署完成即可。"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/f0\/f0ead7eab3da2410594249271d413cd1.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"部署效果预览"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这里你部署完成之后会发现你的目录下生成了一个"},{"type":"codeinline","content":[{"type":"text","text":".env"}]},{"type":"text","text":"文件,里面保存了你部署需要用到的私密数据,然后第二次部署时就可以不用扫码就能成功部署了(这个授权信息是有时效的,如果失效则需要重新授权)。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"4. 调试"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"执行触发函数命令,"},{"type":"codeinline","content":[{"type":"text","text":"function="}]},{"type":"text","text":" 后面跟着的是你的云函数名称,这样就能判断是否部署成功了。"}]},{"type":"codeblock","attrs":{"lang":null},"content":[{"type":"text","text":"serverless invoke --inputs function=scfdemo-dev-scf-demo"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"效果预览:"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/9e\/9e3a2e395fea0559f6f5ec0b877a46a4.png","alt":"Image","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"效果预览"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"总结"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"当然这只是一个入门级的教程,这里仅仅只是介绍了"},{"type":"codeinline","content":[{"type":"text","text":"Serverless"}]},{"type":"text","text":"的一小部分功能,而"},{"type":"codeinline","content":[{"type":"text","text":"Serverless"}]},{"type":"text","text":"的强大远非如此,这就需要广大开发者逐步的开启这个新世界的大门了。"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章