云原生架构
云原生架构(Cloud Native Architecture)是一种充分利用云计算优势的软件架构方式,它使应用程序能够在现代动态环境中高效运行,如公有云、私有云和混合云。
什么是云原生?
云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。
┌─────────────────────────────────────────────────────────────────────────────┐
│ 云原生架构全景 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 应用层 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 微服务A │ │ 微服务B │ │ 微服务C │ │ 微服务D │ │ 微服务E │ │ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │
│ └───────┼───────────┼───────────┼───────────┼───────────┼────────────┘ │
│ │ │ │ │ │ │
│ ┌───────┴───────────┴───────────┴───────────┴───────────┴────────────┐ │
│ │ 服务网格 (Service Mesh) │ │
│ │ 流量管理 │ 安全通信 │ 可观测性 │ 策略执行 │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 容器编排层 (Kubernetes) │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Pod A │ │ Pod B │ │ Pod C │ │ Pod D │ │ Pod E │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ 自动扩缩容 │ 负载均衡 │ 服务发现 │ 配置管理 │ 存储编排 │ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 基础设施层 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 容器 │ │ 虚拟机 │ │ 裸金属 │ │ 网络 │ │ 存储 │ │ │
│ │ │Runtime │ │ VM │ │ Server │ │ │ │ │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
云原生的核心特征
1. 容器化(Containers)
容器是云原生应用的基本构建单元,提供一致的运行环境。
# Dockerfile 示例
FROM openjdk:17-jdk-slim
WORKDIR /app
# 复制依赖
COPY target/dependency/ ./lib/
# 复制应用
COPY target/app.jar ./app.jar
# 非 root 用户运行
RUN addgroup --system appgroup && adduser --system appuser --ingroup appgroup
USER appuser
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/actuator/health || exit 1
# 启动应用
ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=75.0", "-jar", "app.jar"]
2. 微服务(Microservices)
将应用拆分为独立部署的小型服务。
# Kubernetes Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
labels:
app: user-service
spec:
replicas: 3
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
spec:
containers:
- name: user-service
image: registry/user-service:v1.2.3
ports:
- containerPort: 8080
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
3. 服务网格(Service Mesh)
处理服务间通信的基础设施层。
# Istio VirtualService
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: user-service
spec:
hosts:
- user-service
http:
- match:
- headers:
x-canary:
exact: "true"
route:
- destination:
host: user-service
subset: v2
weight: 100
- route:
- destination:
host: user-service
subset: v1
weight: 90
- destination:
host: user-service
subset: v2
weight: 10
4. 不可变基础设施(Immutable Infrastructure)
基础设施一旦部署就不再修改,更新通过替换实现。
# GitOps 工作流
# 1. 开发人员提交代码
# 2. CI 构建镜像并推送到仓库
# 3. GitOps 工具检测到镜像更新
# 4. 自动更新 Kubernetes 部署
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: user-service
spec:
project: default
source:
repoURL: https://github.com/org/gitops-repo
targetRevision: HEAD
path: apps/user-service
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
云原生设计原则
1. 健康报告
应用程序应该提供健康检查端点。
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
@Component
public class DatabaseHealthIndicator implements HealthIndicator {
private final DataSource dataSource;
public DatabaseHealthIndicator(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public Health health() {
try (Connection conn = dataSource.getConnection()) {
if (conn.isValid(1)) {
return Health.up()
.withDetail("database", "PostgreSQL")
.withDetail("status", "connected")
.build();
}
} catch (SQLException e) {
return Health.down()
.withDetail("error", e.getMessage())
.build();
}
return Health.down().build();
}
}
2. 遥测数据
应用程序应该输出日志、指标和追踪信息。
@Service
public class OrderService {
private static final Logger log = LoggerFactory.getLogger(OrderService.class);
private final MeterRegistry meterRegistry;
private final Tracer tracer;
public Order createOrder(CreateOrderRequest request) {
Span span = tracer.nextSpan().name("create-order").start();
try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) {
log.info("Creating order for user: {}", request.getUserId());
// 业务逻辑
Order order = doCreateOrder(request);
// 记录指标
meterRegistry.counter("orders.created").increment();
meterRegistry.timer("order.creation.time")
.record(Duration.between(start, Instant.now()));
log.info("Order created successfully: {}", order.getId());
return order;
} catch (Exception e) {
meterRegistry.counter("orders.failed").increment();
log.error("Failed to create order", e);
throw e;
} finally {
span.end();
}
}
}
3. 弹性设计
应用程序应该能够优雅地处理故障。
@Service
public class PaymentService {
private final PaymentClient paymentClient;
@CircuitBreaker(name = "payment", fallbackMethod = "processPaymentFallback")
@Retry(name = "payment")
@TimeLimiter(name = "payment")
public CompletableFuture<PaymentResult> processPayment(PaymentRequest request) {
return CompletableFuture.supplyAsync(() -> {
return paymentClient.charge(request);
});
}
public CompletableFuture<PaymentResult> processPaymentFallback(
PaymentRequest request, Exception ex) {
// 降级处理:记录待处理支付
return CompletableFuture.completedFuture(
PaymentResult.pending(request.getOrderId())
);
}
}
云原生技术栈
| 类别 | 技术 | 说明 |
|---|---|---|
| 容器运行时 | containerd, CRI-O | 容器执行环境 |
| 编排平台 | Kubernetes, OpenShift | 容器编排管理 |
| 服务网格 | Istio, Linkerd | 服务间通信管理 |
| 可观测性 | Prometheus, Grafana, Jaeger | 监控、日志、追踪 |
| CI/CD | Jenkins, GitLab CI, ArgoCD | 持续集成/部署 |
| 镜像仓库 | Harbor, Docker Registry | 容器镜像管理 |
云原生最佳实践
1. 配置外部化
# ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: user-service-config
data:
application.yml: |
spring:
datasource:
url: jdbc:postgresql://postgres:5432/users
redis:
host: redis
logging:
level:
root: INFO
2. 无状态设计
@Service
public class SessionService {
private final RedisTemplate<String, UserSession> redisTemplate;
public void storeSession(String sessionId, UserSession session) {
redisTemplate.opsForValue().set(
"session:" + sessionId,
session,
Duration.ofHours(24)
);
}
public Optional<UserSession> getSession(String sessionId) {
UserSession session = redisTemplate.opsForValue()
.get("session:" + sessionId);
return Optional.ofNullable(session);
}
}
3. 优雅关闭
@Component
public class GracefulShutdown implements ApplicationListener<ContextClosedEvent> {
private final ExecutorService executorService;
@Override
public void onApplicationEvent(ContextClosedEvent event) {
// 停止接收新请求
// 等待正在处理的请求完成
executorService.shutdown();
try {
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
}
}
}
总结
云原生架构通过容器化、微服务、服务网格等技术,使应用程序能够充分利用云计算的优势。关键在于:
- 容器化:一致的运行环境
- 编排管理:自动化部署和运维
- 可观测性:全面的监控和日志
- 弹性设计:故障自愈和自动扩缩容
"云原生不是关于在哪里运行,而是关于如何构建。" —— CNCF