第15章

☁️ 云计算架构

掌握云计算服务模型、云原生应用设计和无服务器架构等现代云计算技术

学习目标

云服务模型

云计算提供了三种主要的服务模型:基础设施即服务(IaaS)、平台即服务(PaaS)和软件即服务(SaaS)。每种模型提供不同层次的抽象和管理责任分工。

核心理解

云服务模型的选择直接影响应用的架构设计、开发效率和运维复杂度。

三种服务模型对比

IaaS - 基础设施即服务

特点:提供虚拟化的计算资源,包括虚拟机、存储、网络等基础设施。

  • 用户控制操作系统和应用
  • 灵活性高,可定制性强
  • 需要管理操作系统和中间件
  • 典型服务:AWS EC2、Azure VM
PaaS - 平台即服务

特点:提供应用开发和部署平台,包括运行时环境、开发工具等。

  • 专注于应用开发
  • 自动化运维和扩展
  • 开发效率高
  • 典型服务:Heroku、Google App Engine
SaaS - 软件即服务

特点:提供完整的软件应用,用户通过网络访问使用。

  • 即开即用,无需安装
  • 多租户架构
  • 按需付费
  • 典型服务:Office 365、Salesforce

责任共担模型

在云计算中,安全和管理责任在云服务提供商和用户之间分担。理解这种责任分工对于正确使用云服务至关重要。

责任层次(从下到上):

物理安全     [云提供商负责] [云提供商负责] [云提供商负责]
硬件设施     [云提供商负责] [云提供商负责] [云提供商负责]
网络控制     [云提供商负责] [云提供商负责] [云提供商负责]
主机操作系统  [用户负责]     [云提供商负责] [云提供商负责]
网络流量保护  [用户负责]     [用户负责]     [云提供商负责]
平台配置     [用户负责]     [用户负责]     [云提供商负责]
身份访问管理  [用户负责]     [用户负责]     [用户负责]
应用程序     [用户负责]     [用户负责]     [用户负责]
数据         [用户负责]     [用户负责]     [用户负责]

服务模型:      IaaS          PaaS          SaaS

云原生应用设计

云原生(Cloud Native)是一种构建和运行应用程序的方法,充分利用云计算的优势。云原生应用具有弹性、可观测、可管理等特性。

云原生核心原则

容器化

将应用及其依赖打包到容器中,确保环境一致性和可移植性。

  • Docker容器技术
  • 镜像版本管理
  • 轻量级虚拟化
微服务架构

将应用拆分为小型、独立的服务,每个服务负责特定的业务功能。

  • 服务独立部署
  • 技术栈多样化
  • 故障隔离
动态编排

使用Kubernetes等编排工具自动管理容器的生命周期。

  • 自动扩缩容
  • 服务发现
  • 负载均衡

云原生技术栈

CNCF技术栈
  • 容器运行时:Docker、containerd、CRI-O
  • 容器编排:Kubernetes、Docker Swarm
  • 服务网格:Istio、Linkerd、Consul Connect
  • 监控观测:Prometheus、Grafana、Jaeger
  • CI/CD:Jenkins、GitLab CI、Tekton
  • 存储:Rook、Longhorn、OpenEBS

12-Factor应用方法论

12-Factor应用是一套构建SaaS应用的方法论,旨在提高应用的可移植性、可扩展性和可维护性。这些原则特别适用于云原生应用开发。

核心因子

1-4因子:基础
  • 代码库:一个代码库,多个部署
  • 依赖:显式声明和隔离依赖
  • 配置:在环境中存储配置
  • 后端服务:把后端服务当作附加资源
5-8因子:部署
  • 构建发布运行:严格分离构建和运行
  • 进程:以无状态进程运行应用
  • 端口绑定:通过端口绑定提供服务
  • 并发:通过进程模型进行扩展
9-12因子:运维
  • 易处理:快速启动和优雅终止
  • 开发环境与线上环境等价
  • 日志:把日志当作事件流
  • 管理进程:后台管理任务当作一次性进程

实践示例

# 配置外部化示例 - docker-compose.yml
version: '3.8'
services:
  web:
    image: myapp:latest
    environment:
      - DATABASE_URL=${DATABASE_URL}
      - REDIS_URL=${REDIS_URL}
      - SECRET_KEY=${SECRET_KEY}
    ports:
      - "8000:8000"
    depends_on:
      - db
      - redis
  
  db:
    image: postgres:13
    environment:
      - POSTGRES_DB=${DB_NAME}
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
  
  redis:
    image: redis:6-alpine
    
volumes:
  postgres_data:

无服务器架构(Serverless)

无服务器架构是一种云计算执行模型,开发者无需管理服务器基础设施,只需关注业务逻辑的实现。云提供商负责服务器的管理、扩展和维护。

重要概念

"无服务器"并不意味着没有服务器,而是指开发者不需要管理服务器,服务器的管理完全由云提供商负责。

Serverless的优势

成本效益
  • 按实际使用付费
  • 无需为空闲资源付费
  • 降低运维成本
  • 减少基础设施投资
自动扩展
  • 根据请求量自动扩缩容
  • 零到无限的扩展能力
  • 无需预先规划容量
  • 处理突发流量
快速开发
  • 专注业务逻辑开发
  • 快速原型和迭代
  • 内置高可用性
  • 简化部署流程

Serverless架构模式

典型的Serverless架构:

[客户端] → [API Gateway] → [Lambda函数] → [数据库/存储]
    ↓              ↓             ↓            ↓
  Web/Mobile    路由/认证    业务逻辑处理   数据持久化
    App         限流/监控    事件驱动      DynamoDB/S3

事件驱动架构:
[事件源] → [事件总线] → [Lambda函数] → [下游服务]
   ↓           ↓           ↓            ↓
 S3上传     EventBridge   图片处理     通知服务
 数据库变更   SQS/SNS     数据转换     邮件发送

函数即服务(FaaS)

函数即服务(Function as a Service)是无服务器计算的一种实现形式,允许开发者上传代码片段(函数),云平台负责执行这些函数并管理底层基础设施。

主要FaaS平台

AWS Lambda
  • 支持多种编程语言
  • 与AWS服务深度集成
  • 事件驱动执行
  • 按毫秒计费
Azure Functions
  • 多种触发器类型
  • 与Azure服务集成
  • 支持容器部署
  • Durable Functions
Google Cloud Functions
  • HTTP和事件触发
  • 与GCP服务集成
  • 自动扩展
  • 源码部署

FaaS函数设计原则

设计最佳实践
  • 单一职责:每个函数只做一件事
  • 无状态:不依赖本地状态,支持并发执行
  • 快速启动:优化冷启动时间
  • 幂等性:重复执行产生相同结果
  • 错误处理:优雅处理异常和重试
  • 监控日志:充分的可观测性

Lambda函数示例

# AWS Lambda函数示例
import json
import boto3
from datetime import datetime

def lambda_handler(event, context):
    """
    处理S3对象上传事件,生成缩略图
    """
    
    # 解析事件
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = event['Records'][0]['s3']['object']['key']
    
    # 检查文件类型
    if not key.lower().endswith(('.jpg', '.jpeg', '.png')):
        return {
            'statusCode': 200,
            'body': json.dumps('Not an image file')
        }
    
    try:
        # 初始化S3客户端
        s3 = boto3.client('s3')
        
        # 下载原始图片
        response = s3.get_object(Bucket=bucket, Key=key)
        image_data = response['Body'].read()
        
        # 生成缩略图(这里简化处理)
        thumbnail_data = generate_thumbnail(image_data)
        
        # 上传缩略图
        thumbnail_key = f"thumbnails/{key}"
        s3.put_object(
            Bucket=bucket,
            Key=thumbnail_key,
            Body=thumbnail_data,
            ContentType='image/jpeg'
        )
        
        # 记录处理结果
        print(f"Generated thumbnail for {key}")
        
        return {
            'statusCode': 200,
            'body': json.dumps({
                'message': 'Thumbnail generated successfully',
                'original': key,
                'thumbnail': thumbnail_key,
                'timestamp': datetime.now().isoformat()
            })
        }
        
    except Exception as e:
        print(f"Error processing {key}: {str(e)}")
        return {
            'statusCode': 500,
            'body': json.dumps({
                'error': 'Failed to process image',
                'details': str(e)
            })
        }

def generate_thumbnail(image_data):
    """
    生成缩略图(实际实现需要使用PIL等图像处理库)
    """
    # 这里是简化的示例
    return image_data  # 实际应该进行图像缩放处理

FaaS的限制和考虑

上一章:容器化架构 返回目录