如何构建大型Serverless应用
从路由方式上,Lambda大致可以分为三种架构方式
1:单体应用式
这种方式和传统REST API很相似,以nodejs为例,在service内部使用express框架作路由,如下图所示
代码示例如下
const express = require('express')
const app = express()
app.listen(80, () => {
console.log('express server running at http://127.0.0.1')
})
app.get('/user',(req,res) => {
//向客户端发送json对象
res.send({name:'zs', age:20, gender:'男'})
})
app.post('/user',(req,res) => {
//向客户端发送文本内容
res.send('请求成功')
})
这种方式优点在于和传统编程类似,学习成本、以后的代码迁移成本低。
缺点也很明显,服务会很重,cold start时间久,也不利于代码重用。
2:API Gateway路由方式
路由通过API Gateway完成,每个handler都是单一的处理方法。每个handler都有Serverless.yml做lambda的配置。
代码结构如下
my-app/
service-a/
src/
...
serverless.yml
service-b/
src/
...
serverless.yml
app下有多个service,每个service都有自己的handler和serverless.yml,配置有自己的api gateway,通过Serverless框架的compose方法进行发布。
3:半独立方式
AWS Best Practice并没有这种方式,纯属自己实践中总结
该方式也会在serverless.yml中为每个function配置handler,但不会都配置api gateway。 只为需要通过internet暴露的service配置api gateway。通过其中一个Lambda作为BFF,调度其他Lambda,使用AWS SDK,代码示例如下
public static void invokeFunction(LambdaClient awsLambda, String functionName) {
InvokeResponse res = null ;
try {
//Need a SdkBytes instance for the payload
String json = "{\"Hello \":\"Paris\"}";
SdkBytes payload = SdkBytes.fromUtf8String(json) ;
//Setup an InvokeRequest
InvokeRequest request = InvokeRequest.builder()
.functionName(functionName)
.payload(payload)
.build();
res = awsLambda.invoke(request);
String value = res.payload().asUtf8String() ;
System.out.println(value);
} catch(LambdaException e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
通过查看SDK源码,可以看到LambdaClient的基类是SmithyClient, 再查看其文档,AWS Query Protcol也是基于Http/Https,并无其他。
The AWS Query protocol uses HTTP and serializes HTTP requests using query string parameters and responses using XML.
参考:
https://aws.amazon.com/blogs/compute/best-practices-for-organizing-larger-serverless-applications/
https://www.serverless.com/framework/docs/guides/compose
https://www.serverless.com/blog/serverless-framework-compose-multi-service-deployments
https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-lambda/src/LambdaClient.ts
https://smithy.io/2.0/aws/protocols/aws-query-protocol.html#:~:text=The AWS Query protocol uses HTTP and serializes,using query string parameters and responses using XML.