本文档风哥主要介绍Serverless与Linux实现,包括Serverless的概念、Serverless架构、Serverless平台选择、Serverless环境安装部署、应用部署等内容,参考Red Hat Enterprise Linux 10官方文档中的Containers and virtual machines章节,适合DevOps工程师和开发者在生产环境中使用。更多视频教程www.fgedu.net.cn
Part01-基础概念与理论知识
1.1 Serverless的概念
Serverless是一种云计算模型,由云提供商管理服务器基础设施,开发者只需关注代码开发,无需管理服务器、操作系统、网络等底层资源。学习交流加群风哥微信: itpux-com
- 按需计费:只支付实际使用的资源
- 自动扩缩容:根据负载自动调整资源
- 无服务器管理:无需管理服务器基础设施
- 事件驱动:基于事件触发执行
- 短暂执行:函数执行完成后释放资源
1.2 Serverless架构
Serverless架构主要包括以下组件:
- 函数即服务(FaaS):执行代码的核心组件
- 事件源:触发函数执行的事件
- API网关:管理HTTP请求和响应
- 数据存储:持久化数据存储
- 监控与日志:监控函数执行和日志
1.3 Serverless的优势
Serverless的优势:
- 降低成本:按需计费,减少资源浪费
- 提高开发效率:专注于业务逻辑,无需管理基础设施
- 自动扩缩容:根据负载自动调整资源
- 高可用性:由云提供商保证服务可用性
- 快速部署:代码更新快速部署
- 减少运维成本:无需运维服务器
Part02-生产环境规划与建议
2.1 Serverless平台选择
Serverless平台选择要点:
– AWS Lambda:市场份额最大,功能丰富
– Azure Functions:与Azure生态集成
– Google Cloud Functions:与GCP生态集成
-阿里云函数计算:国内主流平台
-腾讯云函数:国内主流平台
-开源Serverless框架:Serverless Framework、Knative
# 平台选择考虑因素
– 云提供商偏好
– 语言支持
– 性能要求
– 成本
– 生态系统
– 合规要求
# 推荐平台
– 国际业务:AWS Lambda、Google Cloud Functions
– 国内业务:阿里云函数计算、腾讯云函数
– 混合云:Serverless Framework、Knative
2.2 资源规划
资源规划要点:
– 内存:128MB-10GB
– 超时时间:1秒-15分钟
– 并发限制:根据平台限制
# 存储资源
– 临时存储:512MB(AWS Lambda)
– 持久存储:使用对象存储或数据库
# 网络资源
– VPC配置:如需访问私有网络
– 网络带宽:根据流量需求
# 成本规划
– 计算成本:按执行时间和内存计算
– 调用成本:按调用次数计算
– 数据传输成本:按数据传输量计算
2.3 安全规划
安全规划要点:
- 身份认证:配置合适的身份认证机制
- 授权:最小权限原则
- 数据加密:加密传输和存储
- 网络隔离:配置VPC和安全组
- 代码安全:代码审查和安全扫描
- 监控与审计:监控异常行为
Part03-生产环境项目实施方案
3.1 Serverless环境安装部署
3.1.1 安装Serverless Framework
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash –
sudo apt-get install -y nodejs
# 2. 安装Serverless Framework
npm install -g serverless
# 3. 验证安装
serverless –version
# 4. 配置AWS凭证
aws configure
# 输入AWS Access Key ID和Secret Access Key
# 5. 初始化Serverless项目
serverless create –template aws-nodejs –path my-serverless-project
cd my-serverless-project
3.1.2 安装Knative(Kubernetes上的Serverless)
# 可以使用Minikube、kind或云提供商的Kubernetes服务
# 2. 安装Knative Serving
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.8.0/serving-crds.yaml
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.8.0/serving-core.yaml
# 3. 安装网络层
# 对于Kubernetes 1.22+
kubectl apply -f https://github.com/knative/net-kourier/releases/download/knative-v1.8.0/kourier.yaml
# 4. 配置DNS
kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.8.0/serving-default-domain.yaml
# 5. 验证安装
kubectl get pods -n knative-serving
3.2 Serverless配置
3.2.1 Serverless Framework配置
cat > serverless.yml << 'EOF' service: my-serverless-service provider: name: aws runtime: nodejs16.x region: us-east-1 memorySize: 128 timeout: 30 functions: hello: handler: handler.hello events: - http: path: /hello method: get EOF # 2. 创建handler.js cat > handler.js << 'EOF' module.exports.hello = async (event) => {
return {
statusCode: 200,
body: JSON.stringify(
{
message: ‘Hello from Serverless!’,
input: event,
},
null,
2
),
};
};
EOF
# 3. 部署服务
serverless deploy
# 4. 验证部署
serverless info
3.2.2 Knative配置
cat > service.yaml << 'EOF' apiVersion: serving.knative.dev/v1 kind: Service metadata: name: hello-world spec: template: spec: containers: - image: gcr.io/knative-samples/helloworld-go env: - name: TARGET value: "World" EOF # 2. 应用配置 kubectl apply -f service.yaml # 3. 验证服务 kubectl get ksvc # 4. 访问服务 SERVICE_URL=$(kubectl get ksvc hello-world -o jsonpath='{.status.url}') curl $SERVICE_URL
3.3 应用部署
3.3.1 部署Node.js函数
mkdir -p my-nodejs-function
cd my-nodejs-function
# 2. 初始化项目
npm init -y
# 3. 安装依赖
npm install express
# 4. 创建函数代码
cat > handler.js << 'EOF'
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.json({
message: ‘Hello from Node.js Serverless function!’,
timestamp: new Date().toISOString()
});
});
// 导出函数
module.exports.handler = async (event, context) => {
// 模拟Express应用
return {
statusCode: 200,
body: JSON.stringify({
message: ‘Hello from Node.js Serverless function!’,
timestamp: new Date().toISOString()
}),
headers: {
‘Content-Type’: ‘application/json’
}
};
};
EOF
# 5. 配置serverless.yml
cat > serverless.yml << 'EOF'
service: my-nodejs-service
provider:
name: aws
runtime: nodejs16.x
region: us-east-1
functions:
api:
handler: handler.handler
events:
- http:
path: /
method: any
- http:
path: /{proxy+}
method: any
EOF
# 6. 部署函数
serverless deploy
# 7. 验证部署
serverless info
3.3.2 部署Python函数
mkdir -p my-python-function
cd my-python-function
# 2. 创建函数代码
cat > handler.py << 'EOF'
def hello(event, context):
return {
'statusCode': 200,
'body': 'Hello from Python Serverless function!',
'headers': {
'Content-Type': 'text/plain'
}
}
EOF
# 3. 配置serverless.yml
cat > serverless.yml << 'EOF'
service: my-python-service
provider:
name: aws
runtime: python3.9
region: us-east-1
functions:
hello:
handler: handler.hello
events:
- http:
path: /hello
method: get
EOF
# 4. 部署函数
serverless deploy
# 5. 验证部署
serverless info
Part04-生产案例与实战讲解
4.1 无服务器API实现
某企业通过Serverless实现了RESTful API服务。
# API Gateway → Lambda函数 → DynamoDB
# 2. 项目初始化
serverless create –template aws-nodejs –path my-api-service
cd my-api-service
# 3. 安装依赖
npm install aws-sdk uuid
# 4. 创建函数代码
cat > handler.js << 'EOF'
const AWS = require('aws-sdk');
const uuid = require('uuid');
const dynamodb = new AWS.DynamoDB.DocumentClient();
const TABLE_NAME = process.env.TABLE_NAME;
module.exports.create = async (event) => {
const item = JSON.parse(event.body);
const id = uuid.v4();
await dynamodb.put({
TableName: TABLE_NAME,
Item: {
id,
…item,
createdAt: new Date().toISOString()
}
}).promise();
return {
statusCode: 201,
body: JSON.stringify({ id, …item })
};
};
module.exports.get = async (event) => {
const { id } = event.pathParameters;
const result = await dynamodb.get({
TableName: TABLE_NAME,
Key: { id }
}).promise();
if (!result.Item) {
return {
statusCode: 404,
body: JSON.stringify({ error: ‘Item not found’ })
};
}
return {
statusCode: 200,
body: JSON.stringify(result.Item)
};
};
module.exports.update = async (event) => {
const { id } = event.pathParameters;
const updates = JSON.parse(event.body);
const expression = [];
const values = {};
Object.keys(updates).forEach(key => {
expression.push(`${key} = :${key}`);
values[`:${key}`] = updates[key];
});
await dynamodb.update({
TableName: TABLE_NAME,
Key: { id },
UpdateExpression: `SET ${expression.join(‘, ‘)}`,
ExpressionAttributeValues: values,
ReturnValues: ‘ALL_NEW’
}).promise();
return {
statusCode: 200,
body: JSON.stringify({ id, …updates })
};
};
module.exports.delete = async (event) => {
const { id } = event.pathParameters;
await dynamodb.delete({
TableName: TABLE_NAME,
Key: { id }
}).promise();
return {
statusCode: 204
};
};
EOF
# 5. 配置serverless.yml
cat > serverless.yml << 'EOF'
service: my-api-service
provider:
name: aws
runtime: nodejs16.x
region: us-east-1
environment:
TABLE_NAME: ${self:service}-${opt:stage, self:provider.stage}
iam:
role:
statements:
- Effect: Allow
Action:
- dynamodb:PutItem
- dynamodb:GetItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource:
- !GetAtt MyTable.Arn
functions:
create:
handler: handler.create
events:
- http:
path: items
method: post
get:
handler: handler.get
events:
- http:
path: items/{id}
method: get
update:
handler: handler.update
events:
- http:
path: items/{id}
method: put
delete:
handler: handler.delete
events:
- http:
path: items/{id}
method: delete
resources:
Resources:
MyTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:service}-${opt:stage, self:provider.stage}
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
EOF
# 6. 部署服务
serverless deploy
# 7. 测试API
# 创建设备
curl -X POST https://
# 获取设备
curl https://
# 更新设备
curl -X PUT https://
# 删除设备
curl -X DELETE https://
# 8. 应用效果
# 无服务器API服务
# 自动扩缩容
# 按需计费
# 高可用性
# 部署脚本
cat > serverless-api.sh << 'EOF'
#!/bin/bash
# daily_check.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
# 初始化项目
serverless create --template aws-nodejs --path my-api-service
cd my-api-service
# 安装依赖
npm install aws-sdk uuid
# 部署服务
serverless deploy
# 输出API URL
echo "API URL: $(serverless info --verbose | grep ServiceEndpoint | cut -d ' ' -f 2)"
EOF
# 运行部署脚本
bash serverless-api.sh
4.2 无服务器数据处理
某企业通过Serverless实现了数据处理管道。
# S3 → Lambda → DynamoDB
# 2. 项目初始化
serverless create –template aws-nodejs –path my-data-processing
cd my-data-processing
# 3. 安装依赖
npm install aws-sdk
# 4. 创建函数代码
cat > handler.js << 'EOF'
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const dynamodb = new AWS.DynamoDB.DocumentClient();
const TABLE_NAME = process.env.TABLE_NAME;
module.exports.process = async (event) => {
for (const record of event.Records) {
const bucket = record.s3.bucket.name;
const key = record.s3.object.key;
// 读取S3文件
const data = await s3.getObject({ Bucket: bucket, Key: key }).promise();
const content = data.Body.toString();
// 处理数据
const items = JSON.parse(content);
// 写入DynamoDB
for (const item of items) {
await dynamodb.put({
TableName: TABLE_NAME,
Item: item
}).promise();
}
console.log(`Processed ${items.length} items from ${key}`);
}
return {
statusCode: 200,
body: ‘Data processed successfully’
};
};
EOF
# 5. 配置serverless.yml
cat > serverless.yml << 'EOF'
service: my-data-processing
provider:
name: aws
runtime: nodejs16.x
region: us-east-1
environment:
TABLE_NAME: ${self:service}-${opt:stage, self:provider.stage}
iam:
role:
statements:
- Effect: Allow
Action:
- s3:GetObject
Resource:
- arn:aws:s3:::${self:custom.bucket}/*
- Effect: Allow
Action:
- dynamodb:PutItem
Resource:
- !GetAtt MyTable.Arn
custom:
bucket: my-data-bucket-${opt:stage, self:provider.stage}
functions:
process:
handler: handler.process
events:
- s3:
bucket: ${self:custom.bucket}
event: s3:ObjectCreated:*
resources:
Resources:
MyTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:service}-${opt:stage, self:provider.stage}
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
MyBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:custom.bucket}
EOF
# 6. 部署服务
serverless deploy
# 7. 测试数据处理
# 上传测试文件到S3
aws s3 cp test-data.json s3://my-data-bucket-dev/test-data.json
# 查看CloudWatch日志
serverless logs -f process
# 8. 应用效果
# 自动处理S3文件
# 无服务器数据处理
# 按需计费
# 高可用性
# 部署脚本
cat > serverless-data-processing.sh << 'EOF'
#!/bin/bash
# 初始化项目
serverless create --template aws-nodejs --path my-data-processing
cd my-data-processing
# 安装依赖
npm install aws-sdk
# 部署服务
serverless deploy
# 创建测试数据
cat > test-data.json << 'EOF'
[
{"id": "1", "name": "Item 1", "value": 100},
{"id": "2", "name": "Item 2", "value": 200},
{"id": "3", "name": "Item 3", "value": 300}
]
EOF
# 上传测试数据
aws s3 cp test-data.json s3://my-data-bucket-dev/test-data.json
# 查看日志
serverless logs -f process
EOF
# 运行部署脚本
bash serverless-data-processing.sh
4.3 无服务器微服务
某企业通过Serverless实现了微服务架构。
# API Gateway → Lambda函数 → 服务间通信
# 2. 项目初始化
mkdir -p my-microservices
cd my-microservices
# 3. 创建用户服务
mkdir -p user-service
cd user-service
serverless create –template aws-nodejs
# 4. 安装依赖
npm install aws-sdk
# 5. 创建用户服务代码
cat > handler.js << 'EOF'
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
const TABLE_NAME = process.env.TABLE_NAME;
module.exports.createUser = async (event) => {
const user = JSON.parse(event.body);
await dynamodb.put({
TableName: TABLE_NAME,
Item: user
}).promise();
return {
statusCode: 201,
body: JSON.stringify(user)
};
};
module.exports.getUser = async (event) => {
const { id } = event.pathParameters;
const result = await dynamodb.get({
TableName: TABLE_NAME,
Key: { id }
}).promise();
if (!result.Item) {
return {
statusCode: 404,
body: JSON.stringify({ error: ‘User not found’ })
};
}
return {
statusCode: 200,
body: JSON.stringify(result.Item)
};
};
EOF
# 6. 配置用户服务
cat > serverless.yml << 'EOF'
service: user-service
provider:
name: aws
runtime: nodejs16.x
region: us-east-1
environment:
TABLE_NAME: ${self:service}-${opt:stage, self:provider.stage}
iam:
role:
statements:
- Effect: Allow
Action:
- dynamodb:PutItem
- dynamodb:GetItem
Resource:
- !GetAtt UserTable.Arn
functions:
createUser:
handler: handler.createUser
events:
- http:
path: users
method: post
getUser:
handler: handler.getUser
events:
- http:
path: users/{id}
method: get
resources:
Resources:
UserTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:service}-${opt:stage, self:provider.stage}
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
EOF
# 7. 部署用户服务
serverless deploy
# 8. 创建订单服务
cd ..
mkdir -p order-service
cd order-service
serverless create --template aws-nodejs
# 9. 安装依赖
npm install aws-sdk
# 10. 创建订单服务代码
cat > handler.js << 'EOF'
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
const lambda = new AWS.Lambda();
const TABLE_NAME = process.env.TABLE_NAME;
module.exports.createOrder = async (event) => {
const order = JSON.parse(event.body);
// 验证用户存在
try {
const userResponse = await lambda.invoke({
FunctionName: process.env.USER_SERVICE_FUNCTION,
Payload: JSON.stringify({
httpMethod: ‘GET’,
pathParameters: { id: order.userId }
})
}).promise();
const user = JSON.parse(userResponse.Payload);
if (user.statusCode !== 200) {
return {
statusCode: 400,
body: JSON.stringify({ error: ‘User not found’ })
};
}
} catch (error) {
console.error(‘Error calling user service:’, error);
return {
statusCode: 500,
body: JSON.stringify({ error: ‘Internal server error’ })
};
}
// 创建订单
await dynamodb.put({
TableName: TABLE_NAME,
Item: order
}).promise();
return {
statusCode: 201,
body: JSON.stringify(order)
};
};
module.exports.getOrder = async (event) => {
const { id } = event.pathParameters;
const result = await dynamodb.get({
TableName: TABLE_NAME,
Key: { id }
}).promise();
if (!result.Item) {
return {
statusCode: 404,
body: JSON.stringify({ error: ‘Order not found’ })
};
}
return {
statusCode: 200,
body: JSON.stringify(result.Item)
};
};
EOF
# 11. 配置订单服务
cat > serverless.yml << 'EOF'
service: order-service
provider:
name: aws
runtime: nodejs16.x
region: us-east-1
environment:
TABLE_NAME: ${self:service}-${opt:stage, self:provider.stage}
USER_SERVICE_FUNCTION: user-service-dev-getUser
iam:
role:
statements:
- Effect: Allow
Action:
- dynamodb:PutItem
- dynamodb:GetItem
Resource:
- !GetAtt OrderTable.Arn
- Effect: Allow
Action:
- lambda:InvokeFunction
Resource:
- arn:aws:lambda:${self:provider.region}:${AWS::AccountId}:function:user-service-dev-getUser
functions:
createOrder:
handler: handler.createOrder
events:
- http:
path: orders
method: post
getOrder:
handler: handler.getOrder
events:
- http:
path: orders/{id}
method: get
resources:
Resources:
OrderTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:service}-${opt:stage, self:provider.stage}
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
EOF
# 12. 部署订单服务
serverless deploy
# 13. 测试微服务
# 创建用户
curl -X POST https://
# 创建订单
curl -X POST https://
# 获取订单
curl https://
# 14. 应用效果
# 无服务器微服务
# 服务间通信
# 自动扩缩容
# 按需计费
# 部署脚本
cat > serverless-microservices.sh << 'EOF'
#!/bin/bash
# 创建用户服务
mkdir -p user-service
cd user-service
serverless create --template aws-nodejs
npm install aws-sdk
serverless deploy
# 创建订单服务
cd ..
mkdir -p order-service
cd order-service
serverless create --template aws-nodejs
npm install aws-sdk
serverless deploy
# 测试服务
echo "Testing user service..."
curl -X POST https://
echo “\nTesting order service…”
curl -X POST https://
EOF
# 运行部署脚本
bash serverless-microservices.sh
Part05-风哥经验总结与分享
5.1 Serverless最佳实践
Serverless最佳实践:
- 函数设计:函数应该单一职责,避免复杂逻辑
- 资源配置:根据实际需求配置内存和超时时间
- 冷启动优化:减少依赖,使用函数预热
- 错误处理:实现完善的错误处理和重试机制
- 监控与日志:部署监控和日志系统
- 安全:遵循最小权限原则,加密敏感数据
- 成本优化:合理配置资源,避免不必要的执行
- 测试:编写单元测试和集成测试
5.2 Serverless面临的挑战
Serverless面临的挑战:
- 冷启动:函数首次执行时的延迟
- 资源限制:内存、超时时间等限制
- 状态管理:函数是无状态的,需要外部存储
- 调试困难:本地调试和测试复杂
- vendor lock-in:依赖特定云提供商
- 监控复杂性:分布式系统监控复杂
5.3 Serverless的未来发展
Serverless的未来发展趋势:
- 标准化:Serverless标准将逐步统一
- 边缘计算:Serverless扩展到边缘计算
- AI集成:与AI和机器学习结合
- 混合云:支持混合云和多云环境
- 性能优化:减少冷启动时间
- 生态系统:更丰富的工具和服务
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
