由于企業内部管理的需要,用到了 釘釘的業務事件回調 能力,正好将這個輕量級的接口使用 無伺服器技術 來實作部署,以應對流量無規律下的動态擴充伸縮、按需使用、按量計費等需求。
阿裡雲函數計算版本
由于公司系統部署在阿裡雲,首先選擇使用
阿裡雲函數計算來實作及部署。該接口使用了JVM上語言Kotlin開發,雖然阿裡雲函數計算官方支援的
開發語言有Java但沒有Kotlin。其實無論Java或Kotlin最終部署檔案都是Java Class位元組碼,加上Kotlin與Java良好的互操作性,實測函數計算可以完美支援Kotlin開發(個人認為任意JVM上的開發語言都是支援的)。
同時該函數使用了
表格存儲來持久化回調事件。表格存儲是個按量計費的分布式存儲,有興趣的可以自行查閱文檔了解更多。
該函數通過
API網關和
表格存儲觸發器來觸發。通路日志和執行日志被存儲在
日志服務中。
函數的本地測試和線上部署,使用了函數計算提供的指令行工具
Fun。基于
Fun定義的阿裡雲Serverless模型實作了對函數們使用資源的聲明和編排,內建
Gitlab CI實作了
函數的CI/CD自動化釋出流程。
不涉及公司業務的代碼已
開源在Github,有興趣的可以作為參考。
目前
函數計算有各自的免費配額,在業務量不大的情況下,該服務完全免費。
AWS Lambda版本
AWS Lambda是目前全球使用最為廣泛的serverless服務,同時也是函數計算發展方向的引領者。
由于一些個人原因,筆者最近接觸了部分AWS服務,同時嘗試将釘釘回調函數移植到了
上。阿裡雲上使用的雲服務改為由AWS上對應服務來實作,例如存儲使用了
DynamoDB,日志使用
CloudWatch收集和查詢。
本地測試和部署工具,使用的是
SAM CLI,持續內建和持續部署使用的是
AWS CodeBuild AWS CodePipeline。此外AWS通過
AWS CloudFormation提供一種非常強大的能力,可以将AWS上的各種資源通過配置聲明的方式來管理(也就是現在非常熱門的一個概念--
Infrastructure as Code)。
會為每次一個或多個資源的變更生成ChangeSet,提供檢視對比、版本管理、遇到變更錯誤整體回退等能力。是以,AWS版本也将該項目的CI/CD部署用到的
、
Amazon DynamoDB等資源通過CloudFormation的配置管理起來。
配置代碼段如下,
Description: Create a CodePipeline to include Github source, CodeBuild and Lambda deployment.
Parameters:
AppBaseName:
Type: String
Description: App base name
Default: dingtalk-callback
ArtifactStoreS3Location:
Type: String
Description: Name of the S3 bucket to store CodePipeline artificat.
BranchName:
Description: GitHub branch name
Type: String
Default: master
RepositoryName:
Description: GitHub repository name
Type: String
Default: dingtalk-callback-on-aws
GitHubOAuthToken:
Type: String
NoEcho: true
Resources:
BuildDingtalkProject:
Type: AWS::CodeBuild::Project
Properties:
Name:
Fn::Sub: ${AppBaseName}-build-${AWS::StackName}
Description: Build, test, package dingtalk callback project
ServiceRole:
Fn::GetAtt: [ CodeBuildRole, Arn ]
Artifacts:
Type: S3
Location:
Ref: ArtifactStoreS3Location
Name:
Fn::Sub: ${AppBaseName}-build-${AWS::StackName}
NamespaceType: BUILD_ID
Path:
Fn::Sub: ${AppBaseName}/artifacts
Packaging: NONE
OverrideArtifactName: true
EncryptionDisabled: true
Environment:
Type: LINUX_CONTAINER
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/java:openjdk-11
PrivilegedMode: false
ImagePullCredentialsType: CODEBUILD
EnvironmentVariables:
- Name: s3_bucket
Value:
Ref: ArtifactStoreS3Location
Source:
DingtalkCallbackPipeline:
Type: 'AWS::CodePipeline::Pipeline'
Properties:
Name:
Fn::Sub: ${AppBaseName}-pipeline-${AWS::StackName}
RoleArn:
Fn::GetAtt: [ CodePipelineRole, Arn ]
Stages:
- Name: Source
Actions:
- Name: SourceAction
ActionTypeId:
Category: Source
Owner: ThirdParty
Version: 1
Provider: GitHub
OutputArtifacts:
- Name:
Fn::Sub: ${AppBaseName}-source-changed
Configuration:
Owner: !Ref GitHubOwner
Repo: !Ref RepositoryName
Branch: !Ref BranchName
OAuthToken: !Ref GitHubOAuthToken
PollForSourceChanges: false
RunOrder: 1
- Name: Build
Actions:
- Name: Build_Test_Package
InputArtifacts:
- Name:
Fn::Sub: ${AppBaseName}-source-changed
ActionTypeId:
Category: Build
Owner: AWS
Version: 1
Provider: CodeBuild
OutputArtifacts:
- Name:
Fn::Sub: ${AppBaseName}-packaged-yml
Configuration:
ProjectName:
Ref: BuildDingtalkProject
RunOrder: 1
AWS版本完整的代碼、CloudFormation配置以及部署文檔可以通過
這裡檢視。