Java云原生案例

wen java案例 1

本文目录导读:

Java云原生案例

  1. 案例背景:电商平台订单系统
  2. 技术栈选型
  3. 核心代码示例
  4. Docker 镜像构建
  5. Kubernetes 部署配置
  6. 可观测性配置
  7. CI/CD 流水线
  8. 关键场景代码示例
  9. 最佳实践总结

Java在云原生领域的应用非常广泛,尤其是结合Spring Boot、Spring Cloud、Kubernetes和容器化技术。

下面我将通过一个电商微服务系统的完整案例,来展示Java如何落地云原生架构。


案例背景:电商平台订单系统

整体架构图

┌─────────────────────────────────────────────────────────────┐
│                      Kubernetes Cluster                     │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐   │
│  │  API网关  │──│ 用户服务  │──│ 订单服务  │──│ 商品服务  │   │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘   │
│       │              │             │            │          │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐   │
│  │  Nacos    │  │  MySQL   │  │  Redis   │  │  Kafka   │   │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │       Prometheus + Grafana + ELK + SkyWalking       │  │
│  └──────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

技术栈选型

领域 技术选型 说明
基础框架 Spring Boot 3.x 快速构建微服务
微服务 Spring Cloud Alibaba 服务注册、配置中心、网关
容器化 Docker 应用容器化
编排调度 Kubernetes (K8s) 容器编排、自动扩缩容
服务网格 Istio (可选) 流量管理、安全
可观测性 Prometheus + Grafana 指标监控
链路追踪 SkyWalking 分布式追踪
日志收集 ELK (Elasticsearch + Logstash + Kibana) 日志汇聚分析
CI/CD Jenkins + GitLab CI 持续集成与部署

核心代码示例

基础项目结构(以订单服务为例)

<!-- pom.xml -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.1.5</version>
</parent>
<dependencies>
    <!-- Spring Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 服务发现 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!-- 配置中心 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <!-- 分布式事务 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    </dependency>
    <!-- 服务调用 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!-- 限流熔断 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    <!-- 数据库 -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.3</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
    </dependency>
</dependencies>

主启动类

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}

订单控制器

@RestController
@RequestMapping("/api/orders")
@Slf4j
public class OrderController {
    @Autowired
    private OrderService orderService;
    @Autowired
    private ProductServiceClient productServiceClient;
    /**
     * 创建订单(包含分布式事务)
     */
    @PostMapping
    @GlobalTransactional(name = "create-order-tx")  // Seata 分布式事务
    public Result<OrderVO> createOrder(@RequestBody CreateOrderDTO dto) {
        log.info("创建订单请求:{}", dto);
        // 第一步:扣减库存(调用商品服务)
        productServiceClient.deductStock(dto.getProductId(), dto.getQuantity());
        // 第二步:创建订单
        Order order = orderService.createOrder(dto);
        // 第三步:异步发送消息(通知用户、统计等)
        kafkaTemplate.send("order-created", JSON.toJSONString(order));
        return Result.success(convertToVO(order));
    }
    /**
     * 查询订单(带 Redis 缓存)
     */
    @GetMapping("/{orderId}")
    public Result<OrderVO> getOrder(@PathVariable Long orderId) {
        // 防止缓存雪崩
        String key = "order:" + orderId;
        OrderVO orderVO = redisTemplate.opsForValue().get(key);
        if (orderVO == null) {
            // 分布式锁,防止缓存击穿
            String lockKey = "lock:order:" + orderId;
            boolean locked = redisTemplate.opsForValue()
                .setIfAbsent(lockKey, "1", Duration.ofSeconds(5));
            if (locked) {
                try {
                    Order order = orderService.getOrder(orderId);
                    orderVO = convertToVO(order);
                    // 设置随机过期时间,防止缓存雪崩
                    int randomTime = 300 + new Random().nextInt(60);
                    redisTemplate.opsForValue().set(
                        key, orderVO, Duration.ofSeconds(randomTime));
                } finally {
                    redisTemplate.delete(lockKey);
                }
            } else {
                // 等待后重试
                Thread.sleep(100);
                return getOrder(orderId);
            }
        }
        return Result.success(orderVO);
    }
}

使用 OpenFeign 调用商品服务

@FeignClient(name = "product-service", fallback = ProductServiceFallback.class)
public interface ProductServiceClient {
    @PostMapping("/api/products/deductStock")
    Result<Void> deductStock(@RequestParam("productId") Long productId,
                             @RequestParam("quantity") Integer quantity);
    @GetMapping("/api/products/{id}")
    Result<ProductVO> getProduct(@PathVariable("id") Long id);
}
// 熔断降级处理
@Component
public class ProductServiceFallback implements ProductServiceClient {
    @Override
    public Result<Void> deductStock(Long productId, Integer quantity) {
        // 降级策略:返回提示或走备用逻辑
        return Result.error("商品服务不可用,请稍后重试");
    }
}

Sentinel 限流配置

@Configuration
public class SentinelConfig {
    @PostConstruct
    public void initFlowRules() {
        // 设置订单接口的限流规则
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("createOrder");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        rule.setCount(100);  // 每秒最多100个请求
        // 设置热点参数限流
        ParamFlowRule paramRule = new ParamFlowRule("productId")
            .setGrade(QPS)
            .setCount(50)
            .setDurationInSec(1);
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
        ParamFlowRuleManager.loadRules(Collections.singletonList(paramRule));
    }
}

Docker 镜像构建

Dockerfile

# 多阶段构建
FROM maven:3.8-openjdk-17 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
# 运行时镜像
FROM openjdk:17-alpine
RUN apk add --no-cache tzdata \
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone
WORKDIR /app
COPY --from=builder /app/target/order-service.jar app.jar
# 非root用户运行,提高安全性
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
EXPOSE 8080
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD wget -q -O /dev/null http://localhost:8080/actuator/health || exit 1
# JVM 优化参数
ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75.0", "-XX:InitialRAMPercentage=50.0", 
            "-XX:+UseContainerSupport", "-Djava.security.egd=file:/dev/./urandom",
            "-jar", "app.jar"]

Kubernetes 部署配置

订单服务部署文件 order-service.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
  namespace: ecommerce
  labels:
    app: order-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      # 优雅停止
      terminationGracePeriodSeconds: 30
      containers:
      - name: order-service
        image: registry.example.com/ecommerce/order-service:v1.0.0
        ports:
        - containerPort: 8080
          name: http
        # 资源限制
        resources:
          requests:
            cpu: 500m
            memory: 512Mi
          limits:
            cpu: "1"
            memory: 1Gi
        # 探针配置
        livenessProbe:
          httpGet:
            path: /actuator/health
            port: http
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 3
        readinessProbe:
          httpGet:
            path: /actuator/health
            port: http
          initialDelaySeconds: 15
          periodSeconds: 5
        # 环境变量
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "prod"
        - name: NACOS_ADDR
          valueFrom:
            configMapKeyRef:
              name: ecommerce-config
              key: nacos.addr
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
---
apiVersion: v1
kind: Service
metadata:
  name: order-service
  namespace: ecommerce
spec:
  selector:
    app: order-service
  ports:
  - port: 8080
    targetPort: http
  type: ClusterIP
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: order-service-hpa
  namespace: ecommerce
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: order-service
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

使用 Helm 管理配置

values.yaml:

# values.yaml
replicaCount: 3
image:
  repository: registry.example.com/ecommerce/order-service
  tag: v1.0.0
  pullPolicy: Always
# 资源管理
resources:
  requests:
    cpu: 500m
    memory: 512Mi
  limits:
    cpu: 1
    memory: 1Gi
# HPA
autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPU: 70
  targetMemory: 80
# 配置
config:
  profiles:
    active: prod
  nacos:
    addr: nacos:8848

可观测性配置

Prometheus 指标暴露

# application.yml
management:
  endpoints:
    web:
      exposure:
        include: "*"
  metrics:
    export:
      prometheus:
        enabled: true
  health:
    show-details: always

自定义业务指标

@RestController
public class MetricsController {
    private final MeterRegistry meterRegistry;
    public MetricsController(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }
    @PostMapping("/api/orders")
    public Result<OrderVO> createOrder(@RequestBody CreateOrderDTO dto) {
        // 记录业务指标
        long startTime = System.currentTimeMillis();
        try {
            // 业务逻辑
            Order order = orderService.createOrder(dto);
            // 记录成功调用
            meterRegistry.counter("orders.created.success").increment();
            return Result.success(convertToVO(order));
        } catch (Exception e) {
            // 记录失败调用
            meterRegistry.counter("orders.created.failure").increment();
            throw e;
        } finally {
            // 记录调用耗时
            meterRegistry.timer("orders.created.time").record(
                Duration.ofMillis(System.currentTimeMillis() - startTime)
            );
        }
    }
}

SkyWalking 链路追踪配置

<!-- pom.xml -->
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>8.16.0</version>
</dependency>
# 在 Kubernetes 中启动参数
- name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
  value: "skywalking-oap:11800"
- name: SW_AGENT_NAME
  value: "order-service"

CI/CD 流水线

# .gitlab-ci.yml
stages:
  - build
  - test
  - package
  - deploy
variables:
  DOCKER_REGISTRY: registry.example.com
  APP_NAME: order-service
# 编译阶段
build:
  stage: build
  image: maven:3.8-openjdk-17
  script:
    - mvn clean compile
  only:
    - main
    - develop
# 测试阶段
test:
  stage: test
  image: maven:3.8-openjdk-17
  services:
    - mysql:8.0
    - redis:7
  variables:
    MYSQL_DATABASE: test_db
    MYSQL_ROOT_PASSWORD: root
  script:
    - mvn test
  coverage: '/Coverage:\d+\.\d+%/'
# 打包镜像
package:
  stage: package
  image: docker:24
  services:
    - docker:24-dind
  script:
    - docker build -t $DOCKER_REGISTRY/$APP_NAME:$CI_COMMIT_SHORT_SHA .
    - docker tag $DOCKER_REGISTRY/$APP_NAME:$CI_COMMIT_SHORT_SHA $DOCKER_REGISTRY/$APP_NAME:latest
    - docker push $DOCKER_REGISTRY/$APP_NAME:$CI_COMMIT_SHORT_SHA
    - docker push $DOCKER_REGISTRY/$APP_NAME:latest
# 部署到K8s
deploy:
  stage: deploy
  image: alpine/k8s:1.28
  script:
    # 更新镜像版本
    - kubectl set image deployment/order-service \
      order-service=$DOCKER_REGISTRY/$APP_NAME:$CI_COMMIT_SHORT_SHA -n ecommerce --record
    # 滚动更新检查
    - kubectl rollout status deployment/order-service -n ecommerce --timeout=5m
  environment:
    name: production
  only:
    - main

关键场景代码示例

分布式事务(Seata)

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private StockFeignClient stockClient;
    /**
     * 创建订单并扣减库存(分布式事务)
     */
    @GlobalTransactional(name = "create-order", rollbackFor = Exception.class)
    @Override
    public Order createOrder(CreateOrderDTO dto) {
        // 1. 检查订单
        if (dto.getQuantity() <= 0) {
            throw new BusinessException(400, "商品数量必须大于0");
        }
        // 2. 调用库存服务扣减库存
        Result<Void> stockResult = stockClient.deductStock(
            dto.getProductId(), dto.getQuantity()
        );
        if (!stockResult.isSuccess()) {
            throw new BusinessException(500, "扣减库存失败: " + stockResult.getMessage());
        }
        // 3. 创建订单
        Order order = new Order();
        order.setProductId(dto.getProductId());
        order.setQuantity(dto.getQuantity());
        order.setAmount(dto.getProductPrice() * dto.getQuantity());
        order.setStatus(OrderStatus.CREATED);
        orderMapper.insert(order);
        return order;
    }
}

异步消息处理

@Service
public class OrderMessageListener {
    @Autowired
    private OrderService orderService;
    @Autowired
    private NotificationService notificationService;
    /**
     * 处理订单创建事件
     */
    @KafkaListener(topics = "order-created", groupId = "order-group")
    public void onOrderCreated(OrderCreatedMessage message) {
        // 模拟异步处理
        // 1. 异步发送通知
        notificationService.sendOrderNotification(message.getMobile(), message.getOrderId());
        // 2. 更新统计
        statsService.incrementOrderCount();
    }
    /**
     * 处理超时未支付订单
     */
    @KafkaListener(topics = "order-timeout", groupId = "order-timeout-group")
    public void onOrderTimeout(OrderIdMessage message) {
        // 关闭超时订单
        orderService.closeOrder(message.getOrderId());
    }
}

最佳实践总结

✅ 云原生设计原则

原则 实施方法
12要素 环境配置外置、无状态化、日志为事件流
弹性设计 自动扩缩容、熔断降级、限流
不可变基础设施 镜像构建、基础设施即代码(IaC)
可观测性 Metrics + Logs + Tracing 三支柱
安全 服务间加密、最小权限、密钥管理

✅ 关键要点

  1. 配置管理:使用 ConfigMap 和 Secret,避免配置硬编码
  2. 健康检查:必须配置 Liveness 和 Readiness 探针
  3. 资源限制:合理设置 CPU/内存的 requests 和 limits
  4. 优雅停机:配置 terminationGracePeriodSeconds
  5. 故障演练:定期进行混沌工程实验(如 Chaos Mesh)

抱歉,评论功能暂时关闭!