下载APP
关闭
讲堂
部落
Python 进阶训练营
算法训练营
架构师训练营
企业服务
极客商城
客户端下载
兑换中心
渠道合作
推荐作者

07 | 后端BaaS化(下):Container Serverless

2020-05-01 蒲松洋
Serverless入门课
进入课程

讲述:蒲松洋

时长20:52大小19.12M

你好,我是秦粤。上节课,我重点给你讲了业务逻辑的拆和合,拆的话可以借助 DDD 的方法论,也可以用动态网络的思想让微服务自然演进;合的话,我们可以用代码编排,也可以用事件流来驱动。另外,我们还了解了微服务拆解后会带来的安全信任问题,这可以通过微服务的跨域认证 JWT 方案解决。我们还了解了后端应用要支持快速迭代或发布,可以参考微服务搭建灰度发布流水线,也就是发布管道。其实我们在使用 FaaS 过程中遇到的很多问题,都可以借助或参考微服务的解决方案。
现在我们再回顾一下 BaaS 化后的“待办任务”Web 服务,我们已经将后端拆解为用户微服务和待办任务微服务,前端用户访问我们的 FaaS 服务,登录后获取到 JWT,通过数据接口 +JWT 安全地访问我们的微服务。而且我们的 FaaS 和微服务都具备了快速迭代的能力。
BaaS化后的“待办任务”Web服务
到这里,我要指出我之前 rule-faas.js 的一个 Bug,如果你之前亲自动手做过实验的话,估计也有发现。这个 Bug 的直接表现是用户初次请求数据时,如果触发了冷启动,返回的待办任务列表就会为空。
究其原因,是因为冷启动时连接数据库会有延时,这直接导致了第一个请求返回的待办任务列表还未同步到消息队列的数据。要解决这个 bug,我们可以用之前讲过的预热 FaaS 或预留实例的方式,但你也要知道,FaaS 函数扩容时,新启动的函数副本也会出现同样的问题。
我前面卖了很多关子,其实 FaaS 在设计时已经考虑到这个问题了,所以在 FaaS 的“函数配置”里,都会提供一项“函数初始化入口”的选项。但你会发现,它同时也会让你配置初始化时间,最少 1 秒。还记得我们在[第 2 课],讲函数执行阶段的一人一半的函数代码初始化时间吗?没错,就是那个时间。
当你配置了“函数初始化入口”,每次启动 FaaS 实例时,系统都会先等待初始化函数执行,而且在函数初始化时间结束后,才会继续执行函数。而从目前平台的配置来看,初始化时至少也需要 1 秒的时间(你去云服务商后台就能看到)。
对很多事件触发的应用场景,FaaS 增加几秒的初始化时间,影响并不大。但对很多后端应用则不然,尤其是 Java 等语言,如果软件包比较大,启动和初始化的时间会更长。
要缩短或绕过初始化的时间,我们要尽可能地利用 Runtime 里面给我们提供的内置能力,例如我们 BaaS 化一直提倡使用服务编排和 HTTP 接口,就是因为云服务商 SDK 和 HTTP 协议,所有语言的 Runtime 里都内置了。
那什么是 Runtime 呢?Runtime 其实就是运行我们代码所需要的函数库和二进制包。FaaS 中的 Runtime 是云服务商预先设计好的,会放一些常用的函数库和二进制包进去,相当于是平台的能力。
但是当我们后端应用 BaaS 化后,想采用 FaaS 方案部署的话则会碰到 Runtime 这个拦路虎。FaaS 虽然已经支持多数主流后端语言,但后端应用根据业务需求,要依赖特殊的函数库或二进制包,FaaS 的官方 Runtime 就无法支持。而且像 Java 等语言,在代码包较大的情况下,FaaS 启动速度很慢,也不适合。例如 Node.js 的 Runtime,其实也包括我们自己安装的 NPM 包,所以相当于我们可以部分定制。但是你也注意到了,我们是整个目录包括 node_modules 一起上传的,也就是说涉及编译的 NPM 包是无法跨操作系统生效的。这种场景下 FaaS 的 Runtime 不可控就会成为我们难以绕过的问题了。当我们遇到 FaaS 无法解决的场景,我们就可以考虑下降一层,使用 FaaS 的底层支撑技术 Docker 容器了。
广义Serverless
还记得我们[第 1 课] 中的广义 Serverless 的图吗?基础设施中的容器,一般情况下指的就是 Docker 容器。Docker 这个技术你肯定或多或少已经用过了,使用它们可以将应用代码和代码依赖的 Runtime 一起打包成一个 Docker 镜像。这个 Docker 镜像,可以在云上、自己的笔记本电脑、同事的电脑上无畅运行,并且完全不用担心环境依赖的问题,因为我们应用的依赖也打包在一起了。
到这里,我们又引入了 Docker 的概念,Docker 出现之后,CaaS(Container as a Service)很快也就流行起来了。为了帮助你理解 IaaS、PaaS、BaaS、CaaS 这几者的关系,我画了张图,希望能从云服务发展的角度,帮你梳理下脉络。
云服务发展进程
图片很好理解,我就不解释了。不过这里要解决一个你可能会有的疑惑:为什么 BaaS 的出现,比 Serverless FaaS 还要早三年?那是因为早期出现的 BaaS 其实是 mBaaS(移动后端即服务),这概念当时也曾经火过一段时间,现在已经被 Google 收购的 FireBase 其实就是做的这个生意。mBaaS 设计之初是专门为移动端提供后端服务的,例如用户管理、角色服务、文件存储服务等等。除了服务对象是移动端之外,跟我们说的 BaaS 概念很像。移动端可以将 BaaS 的所需鉴权算法放到客户端中,并随着客户端的版本定期更新秘钥。但前端却做不到,因此 mBaaS 只局限在移动端,没有火起来。直到 FaaS 的出现,才诞生了 BaaS 的使用场景,mBaaS 也开始转型,支持更广范围的前端场景了。
VM 是一种虚拟化技术,这个我们都知道,其实 Docker 也是一种虚拟化技术,只不过它是利用新版 Linux 内核提供 Namespace、Cgroups 和 Union File System 特性,模拟操作系统的运行环境。它跟虚拟机 VM 最大的区别在于,Docker 是进程模型的。怎么理解这句话呢?我们需要画一张图。
Docker进程模型
从图中我们可以看出,虚拟机是在宿主机上启动一个虚拟机监视器 HyperVisor 管理控制虚拟机的。而虚拟机自身包含整个客户操作系统、函数库依赖和用户的应用,虚拟机操作系统之间相互都是隔离的。经典的 HyperVisor 就是 VirtualBox[1],你感兴趣的话可以下载体验一下。你也可以试想一下,如果我们我们一台虚拟机部署一个微服务,其实资源利用率是很低的。
容器实例则只包含函数库依赖和用户的应用,操作系统是依赖宿主机的用户态模拟的,也就是说容器之间是共享宿主机内核的。所以 Docker 更加轻量,启动速度更快,代码执行速度也更快。
Docker 的容器呢,因为只包含函数库依赖和用户的应用,可以部署到任意 Docker 引擎上,而 Docker 引擎呢,可以安装在你的个人电脑、公司机房或者云上。通常我们容器移动时,是移动容器的硬盘快照,内存中的状态我们比较难复制,这个硬盘快照就是 Docker 镜像。我们给 Docker 的镜像打上标签,标签就像是镜像的唯一标识符 URI,打上后它就可以到处移动了。这个也是 Docker 的核心概念:build、ship、run。
其实你会不会觉得,Docker 的这个层级结构有些眼熟?是的,这正是我们[第 2 课] 中讲的 FaaS 分层。我们回想一下,我当时所说的操作系统容器就是 Docker 模拟的,Runtime 其实就是 Bins/Libs 层。云服务商的冷启动加速,就是利用 Docker 镜像缓存加速。我想你也应该猜到了,其实很多云服务商 FaaS 和 PaaS 的底层技术就是容器即服务 CaaS。
那么接下来,我们就体验一下 Docker 的便利吧。我们的“待办任务”Web 服务,只要添加一个文件,就可以让它变成 Docker 镜像了。

Docker 再探

这里我建议你,最好自己在电脑上安装体验一下 Docker。在主流的操作系统数安装 Docker 都不难的,只需要下载安装包就可以了。

build: Dockerfile

构建是 Docker 最重要的一环。Docker 镜像是硬盘快照,那我们就看看标准的 Docker 硬盘快照如何制作吧。下面就是我们在代码根目录下增加的文件,供你参考:
# FROM是指我们的镜像基于哪个镜像来构建,我们这里是基于jessie linux的Node.js镜像
FROM registry.cn-shanghai.aliyuncs.com/jike-serverless/nodejs
# ENV是设置环境变量
ENV HOME /home/myhome/myapp
# RUN是执行一段命令
RUN mkdir -p /home/myhome/myapp/public
# COPY是将当前目录下的内容拷贝到容器中
COPY . /home/myhome/myapp
COPY public /home/myhome/myapp/public/
COPY node_modules /home/myhome/myapp/node_modules/
# WORKDIR是设置进入容器后的工作目录
WORKDIR /home/myhome/myapp/
# ENTRYPOINT是容器启动后执行的脚本
ENTRYPOINT [ "node","index.js" ]
通常我们使用 Docker 前,先去 Docker Hub 上,找合适的基础镜像。看看基础镜像上都安装了哪些函数库或二进制包,再对比一下要运行自己的应用还缺少哪些函数库和二进制包。在基础镜像的层级上,加上自己的依赖。这样我们就构建好适合自己的镜像了。以后我们就能 FROM 自己的基础镜像,构建自己的应用了。
然后你在项目下执行:docker build 命令,就可以帮你构建 Docker 镜像了。
docker build --force-rm -t myapp -f Dockerfile .
构建好的镜像,我们可以通过 docker run 这个命令在本地调试。
docker run -d -p 3001:3001 -e TEST=abc myapp:latest
然后我们通过浏览器访问http://127.0.0.1:3001,就可以看到我们刚刚构建的 Docker 内容了。你会发现,这不就是我们云上运行的版本吗?是的,既然 FaaS 是用 CaaS 技术实现的。我们当然也可以利用 Docker 实现我们的“待办任务”Web 服务。
为了方便 Docker 例子的展示,这节课的项目代码 index.js,包含了 rule.js 的逻辑。你会发现 index.js 中,我们启动的时候,不用关心初始化需要等待多少秒了,而是直到初始化完成后,才监听 3001 端口,而 Node.js 连接数据库的时间通常也只需要几十毫秒。
Docker版本的“待办任务”Web服务
另外为了方面你观察和调试 Docker 容器实例,我这里给出一个登录 Docker 容器实例的命令。
docker exec -it 容器ID bash

ship: Docker Registry

本地调试完,我们再看看如何部署到云上。Docker 官方的镜像仓库[2]速度太慢,现在的云服务都支持私有的容器镜像仓库[3],上面构建 Dockerfile 里面的 Node.js 镜像,就是用我自己的私有容器仓库搭建的。
你可以登录云服务的容器镜像服务,他们都会告诉你如何 Docker login 到私有 Registry,如何打标签,以及如何上传。
用我们的例子来说,大致会有下面的命令。
未登录过的话,要先登录 Registry。
docker login --username=极客时间serverless registry.cn-shanghai.aliyuncs.com
根据容器镜像仓库的 URI,打标签。镜像 ID 可以通过 docker images 查看。
docker tag 你本地的镜像ID registry.cn-shanghai.aliyuncs.com/jike-serverless/todolist
上传镜像到私有的 Registry 仓库。
docker push registry.cn-shanghai.aliyuncs.com/jike-serverless/todolist

run: Docker Engine

运行 Docker 镜像就很简单了,云服务都支持容器服务 CaaS。你只需要购买好容器服务,就可以从自己私有的容器镜像仓库 Docker Registry 中下载镜像,并运行了。你要是执行过上面的例子,那相信你也能体会到为什么 FaaS 的冷启动速度这么快了。不过需要提醒你一下,这里会产生费用。
运行Docker镜像示意图
另外,我们的专栏是讲 Serverless,但是为了让你理解 Serverless 底层的实现,所以我们也讲到了 Docker 容器的部分内容。对于我们专栏来说,你不用尝试部署云上容器了。
恭喜你,获得 DevOps 奖章一枚!
现在我们了解了容器,也知道了 FaaS 是构建在容器上的。我们的微服务和整个应用都可以部署在 CaaS 之上,容器对我们来说更加可控,因为我们可以通过 Dockerfile 安装我们需要的各种函数库依赖或者二进制文件。但这里还有一个问题,FaaS 的扩缩容是怎么做到的呢?我们如果采用了容器,容器如何做到扩缩容呢?

FaaS 与 Docker 的扩缩容

FaaS 中的扩缩容,我们可以通过云控制台看到在 FaaS 函数配置中的“单实例并发度”。FaaS 的做法比较简单粗暴,需要我们告诉函数服务,我们的单个函数实例可以承载多少的并发量,如果事件触发并发量超出了这个并发度,则会自动扩容。扩容的数量 N,就是这个事件触发量除以单机并发量取整。例如我们设定,我们 rule-faas 函数的单实例并发度为 10,那么当用户并发量是 11 时就会扩容 2 个实例。如果用户并发量达到 100,就会扩容出 10 个实例。
这种做法其实是比较机械式的,我们再看看 FaaS 的“函数指标”监控图。你有没有想到,我们其实可以利用实时监控,去控制扩缩容?例如当单个函数实例承受不了时,内存使用率会越来越高,它的执行时间也会越来越长。
FaaS的“函数指标”监控图
是的,我们在使用 Docker 时,要考虑的就是:监控指标 metrics 以及扩容水位。
监控指标 metrics 就像 FaaS“函数指标”监控图那样,是一系列需要我们关心的单个容器核心指标,包括 CPU 利用率、内存使用率、硬盘使用率、网络连接数等等。
我们将监控指标中的各项数值想象成蓄水,我们监控就像一个蓄水池,一旦某一项超过了蓄水池,水就会溢出。所以,我们要设定水位告警。我们在蓄水池里面画上刻度,当水位到这个刻度,我们就马上给这个蓄水池扩容。
蓄水池案例
Docker 容器本身并不提供扩缩容机制,但我们要让 Docker 自动化扩缩容,就可以用监控指标和水位去设计扩缩容机制。我们需要实时监控容器状态,当容器状态的某一项数值过高时,我们就需要给容器扩容。FaaS 的弹性做法很简洁,而 Docker 的扩缩容机制弹性更高、更加可控。但是 Docker 容器,通常需要我们至少保持 1 个容器实例在线。相信你也知道了 FaaS 的预留实例是怎么做到的了吧?
讲到这里,不知道你发现没有,我们 BaaS 化的三讲,已经默默地实现了微服务的 10 要素。这也是为什么我一直说 BaaS 化和微服务高度重叠。
我们再来回顾一下微服务 10 要素。其中,API、服务调用、服务发现,我们可以通过 RESTful HTTP 接口实现;日志、链路追踪,我们没有展开,但我们可以依赖云服务商提供的日志采集解决;鉴权我们可以用跨域认证 JWT 解决;发布管道,需要我们搭建流水线发布管道;容灾性、监控、扩缩容,我们可以通过实时监控和扩缩容解决。到这儿呢,我们的高铁车厢也终于完成了。
这节课的内容挺多的,需要你动手消化吸收一下。下节课我们再看看,如何利用 K8s 调度我们的 Docker 容器。

总结

BaaS 化的内容,到今天,我们用了三节课讲完了,现在我们一起回顾一下。
我们讲后端应用 BaaS 化的问题,转换为后端应用 NoOps 微服务。所以我们先了解了微服务的 10 要素,并且看到微服务中如何通过消息队列将 Stateful 的节点,变成 Stateless 的。在微服务的拆解过程中,我们学习了微服务的拆解思想 DDD 和动态网络演进,以及拆解后带来的信任问题,需要我们加密身份认证。合并时,除了代码里面编排 HTTP 请求结果,我们还学习了事件流触发获取结果。为了让微服务能够快速迭代,我们还需要自己搭建流水线发布管道。
这节课我们通过 FaaS 和 BaaS 的初始化问题,向你介绍了 FaaS 和 BaaS 依赖的底层实现容器 Docker。Docker 也是一种虚拟化技术,它的核心理念是:build、ship、run。通过将我们的应用代码和应用依赖的函数库、二进制包,打包在一起的方式,解决应用开发环境和运行环境的一致性问题。我们可以借助 Docker 容器维持我们的应用实例,来解决初始化慢的问题。
我们还了解了 FaaS 的扩缩容逻辑是通过用户配置的“函数初始化入口”,以及固定的“初始化超时时间”配合“单实例并发度”来实现的。而我们在容器 Docker,其实可以采用实时监控配合扩容水位,来做到更加弹性的扩缩容策略。
接下来我会通过 K8s 实践我们目前所学到的内容,我们的“待办任务”Web 服务,将在我们本地搭建的 CaaS 环境和 Serverless 环境中开发和调试。

作业

首先,拉取我们lesson07的代码,为“待办任务”部署的 rule-faas 函数添加初始化入口。
这节课的作业呢,就是我们要在本地完全通过 Docker 容器,搭建起我们的“待办任务”Web 服务。除了 css 和 js 静态资源是来自 CDN,其它内容都将运行在 Docker 容器里。
相信你可以通过这个作业,体验到 FaaS 的底层 CaaS 的运行机制。
当然如果你有预算,也可以将 Docker 镜像上传到云服务商的 Registry,在云上购买容器服务就可以部署你的 Docker 镜像,并在云上运行我们的“待办任务”Docker 版本了。这样你就拥有了一个永不停机的 Docker 服务。
另外,我也希望你可以帮助我继续优化我们的课程作业代码。如果你有更好的建议,也可以通过 Github 的 MergeRequest 告知我。
接下来就期待你的作业和建议了。如果今天的内容让你有所收获,也欢迎你把文章分享给身边的朋友,邀请他加入学习。

参考资料

unpreview
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
上一篇
06 | 后端BaaS化(中):业务逻辑的拆与合
下一篇
08 | 搭建私有Serverless(一):K8s和云原生CNCF
 写留言

精选留言(7)

  • 2020-05-02
    在完成课后作业时,将docker镜像部署到了本地,阿里云ECI,阿里云k8s,一切都很美好.
    但是部署到阿里云serverless k8s的时候,遇到了一个坑,给大家分享一下.

    现象: 无法打开todolist页面.
          但是控制面板上看pod和容器组状态正常,无重启记录.

    排查过程:
    1. 使用golang服务制作了一个镜像,端口号也使用3001,部署的服务可以正常访问.
       (说明操作流程和相关配置无问题)
    2. 在控制面板上看,对应的pod运行状态健康,遂在index.js底部添加日志.
       发现初始化的日志出来了,说明服务确实是跑起来了.
    3. 由于控制面板上无法执行kubectl exec -it 操作进入容器.
       顾开启了一个实例,安装了kubectl客户端,登录容器.
       [由于创建serverless k8s集群时未开通API Server 公网连接端点,所以只能在VPC网络中访问k8s API]
    4. 进入容器后,发现curl http://localhost:3001提示连接拒绝.
       使用netstat命令提示命令不存在.
       在容器内直接使用apt-get update ; apt-get install net-tools 由于网络问题,长时间安装不成功.
    5. 修改dockerfile,在制作镜像时执行安装操作.
    6. 重新推送镜像,部署服务,进入容器.
       发现3001端口果真未监听.
       但是netstat -antple中,显示连接了一个阿里云的otsIP地址处于SEND_SYNC阶段.怀疑是网络问题.
       结果ping baidu.com果真是ping不通.
    7. 尝试还原index.js中监听服务的代码
       直接使用: app.listen(PORT, () => console.log(`Example app listening at http://localhost:${PORT}`))
       不再放在client.getRow函数中.
    8. 重新推送镜像,部署服务,进入容器.
       发现可以正常访问todolist主页,只是没有数据.
    9. 猜测是 serverless k8s 默认无法访问公网,需要NAT网关才可以访问公网.
       提交工单,得到证实.
       需要在创建服务时,添加一个注解,在创建pod时绑定一个eip.
       照着工单中的方法,重新还原index.js后部署了一遍,果真可以正常访问todolist首页,且历史记录也有了.

    就一个简单的服务不可用,排查起来是相当的麻烦.还要不走弯路.

    对[suke]同学留言中的一句话很赞同:
    "如果想完全hold住serverless 真是的类似全栈这样的工程师来做"
    展开

    作者回复: 你领先太多了,我还没介绍到K8s呢。
    我们使用很多技术时认知是有一个过程的,一个是理论认知,一个是实践认知。理论认知通过学习就好,实践认知则需要自己去动手碰撞出边界。
    这点做得好的,不得不说AWS和Google云了。基本上理论认知和实践认知很接近。国内云由于各种受限,总有很多坑要踩。所以我更希望大家可以自己动手体验一下。可喜的是,国内云的进步也很快,很多大家发现的问题,都在跟进处理。
    我也回复了suke同学的提问:我们试过单纯使用Serverless,在日常有合适的事件触发函数场景就可以了,不用hold住全部。但理解Serverless引擎盖下的机制,有助于以后可以我们深入这个领域。

    3
  • 2020-05-03
    即便是用了docker,遇到需要编译的npm包,直接复制node_modules目录也可能会因为宿主系统和镜像系统的差异而导致问题吧
    展开

    作者回复: 是的,严谨的流程来说是copy时,应该忽略node_module,而重新执行npm install --production安装node_module依赖。
    不过大部分的nodejs的库没有依赖底层编译库,除了少部分例如CSS SaaS之类的需要关注操作系统编译。所以目前FaaS,也是支持zip包上传,或者运行构建命令。

  • 2020-05-02
    老师我觉得,专栏看到这里,如果想完全hold住serverless 真是的类似全栈这样的工程师来做,如果只是让偏前端的工程师开发页面以及简单的业业务逻辑,在真正开发 以及调试的阶段,很难去完全cover ,但是如果把前端页面以外的工作交给后端工程师,实现起来一个是拆分的太细,想想本来一个很简单的列表查询 我不仅要写业务逻辑的查询 我还要把基础的数据查询接口封装到有状态的服务,开发、维护起来很麻烦,后期维护起来排查问题难度都很大,调用链条还变长,怎么看我都觉得serverless有点舍近求远,不知道老师觉得我这个想法有什么问题
    展开

    作者回复: 其实我是想通过这门课程也让你了解后端工程师的很多工作。我比较赞同的是解决问题工程师,而不是分前后端。

    如果要分前后端,的确如果要hold住整个Serverless架构需要懂运维的全栈工程师。但我们实际使用Serverless协助我们日常的工作并不需要那么深入。你可以理解,你使用FaaS就像可以随时随地调用一个函数处理事件一样。

    不过我觉得理解serverless内部的运行原理,对于你日后想深入学习研究,会大有帮助。而不是简单教你如何用Serverless搭建应用,这方面已经有很多课程了。
    对于前端工程师来说,理想的状态应该是自己负责前端代码和数据编排接口BFF,也就是SFF。而后端工程师给你提供BaaS。
    你的前端资源和数据编排接口一起发布。

    2
  • 2020-05-01
    课后作业:

    1. 由于镜像中有aliyunConfig,所以不建议将镜像公开.(即不要推送到默认的 https://hub.docker.com/)

    2. 我是在template.yml文件中添加了一行`Initializer: index.initializer`实现了作业1:部署的 rule-faas 函数添加初始化入口

    3. 使用阿里云ECI部署时,需要申请弹性公网EIP.
       注意: 这里需要指定端口号3001访问服务, 默认的80端口是无法访问到服务的!!!
       与本地调试一样,某些操作会触发容器重启.

    4. 本地调试时,使用get方法访问`http://localhost:3001/api/rule`可以正常获取结果.
       但是完成/删除(使用put/delete方法)时,会提示403"用户得到授权,但是访问是被禁止的。"
       docker反馈的日志如下:
       ```
       /home/myhome/myapp/node_modules/tablestore/lib/request.js:66
                throw err;
                ^
    Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
        at ServerResponse.setHeader (_http_outgoing.js:470:11)
        at ServerResponse.header (/home/myhome/myapp/node_modules/express/lib/response.js:771:10)
        at ServerResponse.send (/home/myhome/myapp/node_modules/express/lib/response.js:170:12)
        at ServerResponse.json (/home/myhome/myapp/node_modules/express/lib/response.js:267:15)
        at Response.<anonymous> (/home/myhome/myapp/index.js:151:16)
        at Request.<anonymous> (/home/myhome/myapp/node_modules/tablestore/lib/request.js:162:18)
        at Request.callListeners (/home/myhome/myapp/node_modules/tablestore/lib/sequential_executor.js:113:20)
        at Request.emit (/home/myhome/myapp/node_modules/tablestore/lib/sequential_executor.js:81:10)
        at Request.emit (/home/myhome/myapp/node_modules/tablestore/lib/request.js:189:14)
        at Request.transition (/home/myhome/myapp/node_modules/tablestore/lib/request.js:57:10)
       ```
       由于不太懂node.js,所以也不知道如何解决.
       之前部署到阿里云FC时是没有遇到过该问题的.
    展开

    作者回复: 我刚刚看了一下,是因为JWT token的原因。这个分支加了JWT验证,如果不是浏览器访问请求中带JWT token过来,或者token校验失败,put/post/delete都会报403.

    2
  • 2020-05-01
    我感觉谷歌的Cloud Run冷启动要比faas这种快,在腾讯部署的go服务冷启动要2s,cloud run只需要几百毫秒。cloud run是基于knative,不知道是不是因为是容器所以快?

    作者回复: 这个要看底层实现,FaaS的底层也可以是容器的。不过要云服务商通常都会根据自己的主流用户群体去优化启动速度,毕竟这也是给他们自己节省钱。

  • 2020-05-01
    利用实时监控,去控制扩缩容,
    向文中说的,云上有什么服务可以实时监控 一些指标进行扩缩容呢? 现在基本上都是根据并发数来进行扩缩容的

    作者回复: 后面的课程会讲怎么搭建实时监控metrics,云上很多服务都会提供metrics数据面板。

  • 2020-05-01
    这个把服务 docker 化,不就没有办法使用 FaaS 服务了? FaaS 有么有哪个地方可以结合 容器化服务一起使用的?
    展开

    作者回复: docker化,可以使用FaaS。FaaS的HTTP加密触发器,就是需要你在应用中用算法去加密调用的。
    另外我目前讲的Docker化是BaaS。BaaS是个SFF提供RESTFul API的后端服务接口。