CI/CD 是一种通过在应用开发阶段引入自动化流程以频繁向客户交付应用的方法。如图所示,CI/CD 的核心概念是持续集成、持续交付和持续部署。
作为一个面向开发和运营团队的解决方案,CI/CD 主要针对集成新代码时所引发的问题。具体而言,CI/CD 可以让持续自动化和持续监控贯穿于应用的整个生命周期(从集成、测试阶段到交付和部署阶段)。这些关联的事务通常被统称为“CI/CD管道”,由开发和运维团队以敏捷方式协同支持。

CI/CD的概念与内容简图
在Serverless架构下,通常会有很多函数构成一个完整的功能或服务,这种比较细粒度的功能往往会给后期项目维护带来极大的不便,包括但不限于函数管理、项目的构建、发布层面等的不便。此时在Serverless架构中,CI/CD就显得尤为重要。更加科学、安全的持续集成和部署过程不仅会让整体的业务流程更加规范,也会在一定程度上降低人为操作、手工集成部署所产生错误的概率,同时也会大规模减轻运维人员的工作负担。
如果想要通过CI/CD平台,科学且方便地进行Serverless应用的持续集成、交付和部署,通常情况下我们需要借助相应的开发者工具,例如 Serverless Framework、Serverless Devs 等。Serverless开发者工具配置到CI/CD平台的流程可以简化为图2-55。

Serverless开发者工具配置到CI/CD平台的流程
在GitHub Action的Yaml文件中,增加Serverless Devs相关下载、配置以及命令执行相关内容。例如,在GitHub仓库中创建文件.github/workflows/publish.yml,文件内容如下:
name: Serverless Devs Project CI/CD
on:
push:
branches: [ master ]
jobs:
serverless-devs-cd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12
registry-url: https://registry.npmjs.org/
- run: npm install
- run: npm install -g @serverless-devs/s
- run: s config add --AccountID ${{secrets.AccountID}} --AccessKeyID
${{secrets.AccessKeyID}} --AccessKeySecret ${{secrets.AccessKeySecret}} -a default
- run: s deploy
与GitHub Action集成主要包括以下几部分内容。
run: npm install -g @serverless-devs/s
run: s config add --AccountID ${{secrets.AccountID}} --AccessKeyID ${{secrets.
AccessKeyID}} --AccessKeySecret ${{secrets.AccessKeySecret}} -a default
run: s deploy
关于密钥的配置:密钥信息是通过${{secrets.*}}获取的,此时,需要将所需要的密钥和对应的Key配置到GitHub Secrets中,例如在上面的案例中,需要AccountID、AccessKeyID、AccessKeySecret三个密钥的 Key 就可以配置相关内容。
找到GitHub Secrets页面,如图所示。

GitHub Secrets页面
创建和配置密钥信息,如图所示。

创建和配置密钥信息页面
此处配置了3对密钥,如图2-58所示。

GitHub仓库配置密钥结果页面
在开启Gitee Go的服务之后,在流水线的 Yaml 文件中,可以增加 Serverless Devs 的相关下载、配置以及命令执行相关内容。
例如,在GitHub仓库中创建文件.github/workflows/publish.yml,文件内容如下:
name: serverless-devs
displayName: 'Serverless Devs Project CI/CD'
triggers: #流水线触发器配置
push:
- matchType: PRECISE
branch: master
commitMessage: ''
stages:
- stage:
name: deploy-stage
displayName: 'Deploy Stage'
failFast: false
steps: #构建步骤配置
- step: npmbuild@1 #采用NPM编译环境
name: deploy-step
displayName: 'Deploy Step'
inputs: #构建输入参数设定
nodeVersion: 14.15 #指定 node 环境版本为 14.15
goals: | #安装依赖,配置相关主题、部署参数并发布部署
node -v
npm -v
npm install -g @serverless-devs/s
s co nfig add --AccountID $ACCOUNTID --AccessKeyID $ACCESSKEYID --AccessKeySecret $ACCESSKEYSECRET -a default
s deploy
与GitHub Action集成的流程类似,与Gitee Go集成主要包括以下几部分内容。
npm install -g @serverless-devs/s
s config add --AccountID $ACCOUNTID --AccessKeyID $ACCESSKEYID --AccessKeySecret
$ACCESSKEYSECRET -a default
s deploy
关于密钥的配置:密钥信息是通过$*获取的,此时将所需的密钥和对应的Key配置到Gitee的环境变量管理中,例如在上面的案例中,需要AccountID、AccessKeyID、AccessKeySecret三个密钥的Key就可以配置相关内容。
找到 Gitee 的环境变量管理页面,如图所示。

Gitee的环境变量管理页面
创建和配置密钥信息,如图所示。

创建和配置密钥信息页面
此处配置了3对密钥,如图所示。

Gitee仓库完成密钥配置页面
在将Serverless Devs集成到Jenkins之前,需要先基于Jenkins官网安装并运行Jenkins。本地启动Jenkins,通过浏览器进入链接 http://localhost:8080并配置完成基础设置,之后新增凭据设置,如下图所示。

Jenkins凭据设置页面
可以根据需要,增加密钥信息。以阿里云为例,新增3个全局凭据:
jenkins-alicloud-account-id : 阿里云 accountId
jenkins-alicloud-access-key-id : 阿里云 accessKeyId
jenkins-alicloud-access-key-secret : 阿里云 accessKeySecret
此时,可以对自身的 Serverless Devs 项目进行完善。创建文件Jenkinsfile:
pipeline {
agent {
docker {
image 'maven:3.3-jdk-8'
}
}
environment {
ALICLOUD_ACCESS = 'default'
ALICLOUD_ACCOUNT_ID = credentials('jenkins-alicloud-account-id')
ALICLOUD_ACCESS_KEY_ID = credentials('jenkins-alicloud-access-key-id')
ALICLOUD_ACCESS_KEY_SECRET = credentials('jenkins-alicloud-access-key-secret')
}
stages {
stage('Setup') {
steps {
sh 'scripts/setup.sh'
}
}
}
}
与Jenkins集成主要内容包括以下两部分。
准备scripts/setup.sh文件,只需要在项目下创建该文件即可。
#!/usr/bin/env bash
echo $(pwd)
curl -o- -L http://cli.so/install.sh | bash
source ~/.bashrc
echo $ALICLOUD_ACCOUNT_ID
s config add --AccountID $ALICLOUD_ACCOUNT_ID --AccessKeyID $ALICLOUD_ACCESS_KEY_
ID --AccessKeySecret $ALICLOUD_ACCESS_KEY_SECRET -a $ALICLOUD_ACCESS
(cd code && mvn package && echo $(pwd))
s deploy -y --use-local --access $ALICLOUD_ACCESS
在该文件中,主要包括以下几个部分。
curl -o- -L http://cli.so/install.sh | bash
s config add --AccountID $ALICLOUD_ACCOUNT_ID --AccessKeyID $ALICLOUD_ACCESS_
KEY_ID --AccessKeySecret $ALICLOUD_ACCESS_KEY_SECRET -a $ALICLOUD_ACCESS
s deploy -y --use-local --access $ALICLOUD_ACCESS
完成密钥配置之后,可以创建一个Jenkins流水线。该流水线的源是目标GitHub地址。接下来,就可以开始运行 Jenkins 流水线,运行结束后可得到相关的结果。
在云效中,可以直接选择Serverless Devs开发者工具,并在自定义命令中输入以下内容:
# input your command here
npm install -g @serverless-devs/s
s config add --AccountID ${ACCOUNTID} --AccessKeyID ${ACCESSKEYID} --AccessKeySecret
${ACCESSKEYSECRET} -a default
s deploy
与GitHub Action、Gitee Go以及Jenkins的配置类似,与云效集成同样主要包括3部分。
npm install -g @serverless-devs/s
s config add --AccountID ${ACCOUNTID} --AccessKeyID
${ACCESSKEYID} --AccessKeySecret
s deploy -y
效果如图所示。

云效命令配置页面
由于在命令中引用了3个重要的环境变量:ACCOUNTID、 ACCESSKEYID、 ACCESSKEYSECRET,因此还需要在环境变量中增加图所示的类似内容。

环境变量配置页面
总结通过上面几个案例不难发现,在做自动化发布时,最核心的3个流程如下。
虽然只是以GitHub Action、Gitee Go、Jenkins、云效几个工具作为案例,实际上无论哪个工具与CI/CD平台集成,上述3个核心流程都不会发生本质变化。另外,上面所列举的流程更多是在做自动化发布,在发布之前有时还需要进行一些测试和重新构建,以便根据具体的实际需要进行适当的完善。
综上所述,如果想非常简单、快速、科学地完成Serverless应用的CI/CD建设,一个完善的开发者工具是必不可少的。
Serverless Devs是一款多云开发者工具。我们可以通过该工具非常简单、快速、方便地部署AWS、阿里云、腾讯云等多个云厂商的函数计算等相关服务。同时,Serverless Devs也是一个开源项目,便于用户随时随地贡献组件、应用。
Serverless应用的可观测性被很多用户所关注。可观测性是通过外部表现判断系统内部状态的方式。在应用开发中,可观测性有助于判断系统内部的健康状况,在系统出现问题时,帮助定位问题、排查问题、分析问题;在系统平稳运行时,帮助评估风险,预测可能出现的问题。
在Serverless应用开发中,如果函数的并发度持续升高,很可能是业务推广团队业务规模迅速扩张。为了避免达到并发度限制而触发流控,开发者就需要提前提高并发度。
以阿里云函数计算为例,阿里云函数计算在可观测性层面提供了多种维度,包括Logging、Metrics以及Tracing等。如图所示:

函数计算可观测性整体图表
在控制台监控中心,我们可以查看整体的Metrics、服务级Metrics以及每个函数的Metrics,还可以看到当前函数计算的请求记录。

函数计算的请求记录
根据不同的请求记录,我们还可以查看函数计算的详细信息。

函数计算的请求详情
除了在控制台的监控中心查看函数的日志等信息,我们还可以在函数详情页面看到函数计算的详细日志信息,

函数计算的日志信息
还可以看到Tracing相关信息,如下图所示。

函数计算的Tracing相关信息
—END—

阿里云、蚂蚁集团的 4 位专家刘宇、田初东、卢萌凯、王仁达(排名不分先后)系统梳理阿里在 Serverless 架构下的 AI 经验,联袂推出新书《Serverless 架构下的 AI 应用开发:入门、实战与性能优化》。
本书是关于 Serverless 架构下机器学习实战的技术书,我们希望通过简单明了的语言、真实的案例,以及开放的源代码,为读者介绍 Serverless 架构与机器学习相关的基础知识,帮助读者在 Serverless 架构下开发、上线机器学习项目。
更多内容关注 Serverless 微信公众号(ID:serverlessdevs),汇集 Serverless 技术最全内容,定期举办 Serverless 活动、直播,用户最佳实践。
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
刚入门rails,开始慢慢理解。有人可以解释或给我一些关于在application_controller中编码的好处或时间和原因的想法吗?有哪些用例。您如何为Rails应用程序使用应用程序Controller?我不想在那里放太多代码,因为据我了解,每个请求都会调用此Controller。这是真的? 最佳答案 ApplicationController实际上是您应用程序中的每个其他Controller都将从中继承的类(尽管这不是强制性的)。我同意不要用太多代码弄乱它并保持干净整洁的态度,尽管在某些情况下ApplicationContr
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain