Java学习第11天 - Spring Boot高级特性与实战项目

学习时间: 4-5小时
学习目标: 掌握Spring Boot高级特性,包括配置管理、监控、缓存、异步处理等,并完成一个完整的实战项目


详细学习清单


✅ 第一部分:Spring Boot高级配置管理(60分钟)

1. 多环境配置管理

application.yml 主配置文件

yaml 复制代码
# application.yml
spring:
  profiles:
    active: dev  # 默认使用开发环境

# 公共配置
app:
  name: demo-app
  version: 1.0.0
  description: Spring Boot学习项目

# 日志配置
logging:
  level:
    com.example.demo: DEBUG
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n"
    file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
  file:
    name: logs/application.log
    max-size: 10MB
    max-history: 30

开发环境配置

yaml 复制代码
# application-dev.yml
server:
  port: 8080

spring:
  datasource:
    url: jdbc:h2:mem:testdb
    driver-class-name: org.h2.Driver
    username: sa
    password: 
  
  h2:
    console:
      enabled: true
      path: /h2-console

# 开发工具配置
spring:
  devtools:
    restart:
      enabled: true
      additional-paths: src/main/java
      exclude: static/**,public/**

生产环境配置

yaml 复制代码
# application-prod.yml
server:
  port: 80

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/prod_db
    username: ${DB_USERNAME:root}
    password: ${DB_PASSWORD:password}
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000

# 生产环境日志
logging:
  level:
    com.example.demo: INFO
  file:
    name: /var/log/demo-app/application.log

2. 配置属性绑定

配置属性类

java 复制代码
// AppProperties.java
package com.example.demo.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private String version;
    private String description;
    private DatabaseConfig database;
    private SecurityConfig security;

    // Getter和Setter方法
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    public String getVersion() { return version; }
    public void setVersion(String version) { this.version = version; }
    
    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }
    
    public DatabaseConfig getDatabase() { return database; }
    public void setDatabase(DatabaseConfig database) { this.database = database; }
    
    public SecurityConfig getSecurity() { return security; }
    public void setSecurity(SecurityConfig security) { this.security = security; }

    // 内部配置类
    public static class DatabaseConfig {
        private String url;
        private String username;
        private String password;
        private int maxConnections;

        // Getter和Setter
        public String getUrl() { return url; }
        public void setUrl(String url) { this.url = url; }
        
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        
        public int getMaxConnections() { return maxConnections; }
        public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; }
    }

    public static class SecurityConfig {
        private String jwtSecret;
        private int jwtExpiration;
        private boolean enableCors;

        // Getter和Setter
        public String getJwtSecret() { return jwtSecret; }
        public void setJwtSecret(String jwtSecret) { this.jwtSecret = jwtSecret; }
        
        public int getJwtExpiration() { return jwtExpiration; }
        public void setJwtExpiration(int jwtExpiration) { this.jwtExpiration = jwtExpiration; }
        
        public boolean isEnableCors() { return enableCors; }
        public void setEnableCors(boolean enableCors) { this.enableCors = enableCors; }
    }
}

✅ 第二部分:Spring Boot监控与健康检查(60分钟)

1. Actuator监控端点

添加依赖到pom.xml

xml 复制代码
<!-- Spring Boot Actuator -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- Micrometer Prometheus -->
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

Actuator配置

yaml 复制代码
# application.yml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus,env,configprops
      base-path: /actuator
  endpoint:
    health:
      show-details: always
      show-components: always
    info:
      enabled: true
  info:
    env:
      enabled: true
    git:
      mode: full
  metrics:
    export:
      prometheus:
        enabled: true

自定义健康检查

java 复制代码
// CustomHealthIndicator.java
package com.example.demo.health;

import org.springframework.boot.actuator.health.Health;
import org.springframework.boot.actuator.health.HealthIndicator;
import org.springframework.stereotype.Component;

@Component
public class CustomHealthIndicator implements HealthIndicator {

    @Override
    public Health health() {
        try {
            // 检查数据库连接
            checkDatabaseConnection();
            
            // 检查外部服务
            checkExternalService();
            
            return Health.up()
                    .withDetail("database", "UP")
                    .withDetail("external-service", "UP")
                    .withDetail("timestamp", System.currentTimeMillis())
                    .build();
                    
        } catch (Exception e) {
            return Health.down()
                    .withDetail("error", e.getMessage())
                    .withDetail("timestamp", System.currentTimeMillis())
                    .build();
        }
    }

    private void checkDatabaseConnection() {
        // 模拟数据库连接检查
        if (Math.random() < 0.1) { // 10%概率失败
            throw new RuntimeException("数据库连接失败");
        }
    }

    private void checkExternalService() {
        // 模拟外部服务检查
        if (Math.random() < 0.05) { // 5%概率失败
            throw new RuntimeException("外部服务不可用");
        }
    }
}

2. 自定义监控指标

自定义指标

java 复制代码
// CustomMetrics.java
package com.example.demo.metrics;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class CustomMetrics {

    private final Counter userCreationCounter;
    private final Counter userLoginCounter;
    private final Timer userOperationTimer;

    public CustomMetrics(MeterRegistry meterRegistry) {
        this.userCreationCounter = Counter.builder("user.creation.total")
                .description("用户创建总数")
                .register(meterRegistry);
                
        this.userLoginCounter = Counter.builder("user.login.total")
                .description("用户登录总数")
                .register(meterRegistry);
                
        this.userOperationTimer = Timer.builder("user.operation.duration")
                .description("用户操作耗时")
                .register(meterRegistry);
    }

    public void incrementUserCreation() {
        userCreationCounter.increment();
    }

    public void incrementUserLogin() {
        userLoginCounter.increment();
    }

    public Timer.Sample startUserOperationTimer() {
        return Timer.start();
    }

    public void stopUserOperationTimer(Timer.Sample sample) {
        sample.stop(userOperationTimer);
    }
}

✅ 第三部分:Spring Boot缓存集成(60分钟)

1. Redis缓存配置

添加Redis依赖

xml 复制代码
<!-- Redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Redis连接池 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

Redis配置类

java 复制代码
// RedisConfig.java
package com.example.demo.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration
@EnableCaching
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(jackson2JsonRedisSerializer);

        // Hash的key也采用StringRedisSerializer的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(jackson2JsonRedisSerializer);

        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(30)) // 默认过期时间30分钟
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
                .disableCachingNullValues();

        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(config)
                .build();
    }
}

2. 缓存使用示例

缓存服务类

java 复制代码
// CacheService.java
package com.example.demo.service;

import com.example.demo.model.User;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

@Service
public class CacheService {

    private final Map<Long, User> userDatabase = new HashMap<>();
    private final AtomicLong idGenerator = new AtomicLong(1);

    // 缓存用户信息,key为"user::#{id}"
    @Cacheable(value = "user", key = "#id")
    public User getUserById(Long id) {
        // 模拟数据库查询延迟
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        User user = userDatabase.get(id);
        if (user == null) {
            throw new RuntimeException("用户不存在, ID: " + id);
        }
        return user;
    }

    // 更新缓存
    @CachePut(value = "user", key = "#user.id")
    public User createUser(User user) {
        user.setId(idGenerator.getAndIncrement());
        userDatabase.put(user.getId(), user);
        return user;
    }

    // 更新缓存
    @CachePut(value = "user", key = "#id")
    public User updateUser(Long id, User user) {
        User existingUser = getUserById(id);
        existingUser.setUsername(user.getUsername());
        existingUser.setEmail(user.getEmail());
        userDatabase.put(id, existingUser);
        return existingUser;
    }

    // 清除缓存
    @CacheEvict(value = "user", key = "#id")
    public void deleteUser(Long id) {
        userDatabase.remove(id);
    }

    // 清除所有用户缓存
    @CacheEvict(value = "user", allEntries = true)
    public void clearAllUserCache() {
        // 清除所有用户相关缓存
    }

    // 获取所有用户(不缓存)
    public List<User> getAllUsers() {
        return userDatabase.values().stream().toList();
    }
}

✅ 第四部分:异步处理与定时任务(60分钟)

1. 异步配置

异步配置类

java 复制代码
// AsyncConfig.java
package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@Configuration
@EnableAsync
@EnableScheduling
public class AsyncConfig {

    @Bean(name = "taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("AsyncTask-");
        executor.initialize();
        return executor;
    }

    @Bean(name = "emailExecutor")
    public Executor emailExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(5);
        executor.setQueueCapacity(50);
        executor.setThreadNamePrefix("EmailTask-");
        executor.initialize();
        return executor;
    }
}

2. 异步服务示例

异步邮件服务

java 复制代码
// EmailService.java
package com.example.demo.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;

@Service
public class EmailService {

    private static final Logger logger = LoggerFactory.getLogger(EmailService.class);

    // 异步发送邮件
    @Async("emailExecutor")
    public CompletableFuture<String> sendWelcomeEmail(String email, String username) {
        try {
            // 模拟邮件发送延迟
            Thread.sleep(2000);
            
            String message = String.format("欢迎 %s! 您的账户已创建成功,邮箱: %s", username, email);
            logger.info("发送欢迎邮件成功: {}", message);
            
            return CompletableFuture.completedFuture("邮件发送成功");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            logger.error("邮件发送被中断", e);
            return CompletableFuture.completedFuture("邮件发送失败");
        } catch (Exception e) {
            logger.error("邮件发送失败", e);
            return CompletableFuture.completedFuture("邮件发送失败: " + e.getMessage());
        }
    }

    // 异步批量发送邮件
    @Async("emailExecutor")
    public CompletableFuture<Integer> sendBulkEmails(String[] emails, String subject, String content) {
        int successCount = 0;
        
        for (String email : emails) {
            try {
                // 模拟邮件发送
                Thread.sleep(500);
                logger.info("发送邮件到: {}, 主题: {}", email, subject);
                successCount++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            } catch (Exception e) {
                logger.error("发送邮件到 {} 失败: {}", email, e.getMessage());
            }
        }
        
        return CompletableFuture.completedFuture(successCount);
    }
}

3. 定时任务示例

定时任务服务

java 复制代码
// ScheduledTaskService.java
package com.example.demo.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Service
public class ScheduledTaskService {

    private static final Logger logger = LoggerLoggerFactory.getLogger(ScheduledTaskService.class);
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    // 每5秒执行一次
    @Scheduled(fixedRate = 5000)
    public void taskWithFixedRate() {
        String currentTime = LocalDateTime.now().format(formatter);
        logger.info("固定频率任务执行 - 当前时间: {}", currentTime);
    }

    // 每10秒执行一次,延迟2秒开始
    @Scheduled(fixedDelay = 10000, initialDelay = 2000)
    public void taskWithFixedDelay() {
        String currentTime = LocalDateTime.now().format(formatter);
        logger.info("固定延迟任务执行 - 当前时间: {}", currentTime);
    }

    // 每天凌晨2点执行
    @Scheduled(cron = "0 0 2 * * ?")
    public void dailyTask() {
        String currentTime = LocalDateTime.now().format(formatter);
        logger.info("每日定时任务执行 - 当前时间: {}", currentTime);
        
        // 执行清理任务
        cleanupExpiredData();
    }

    // 每周一上午9点执行
    @Scheduled(cron = "0 0 9 ? * MON")
    public void weeklyTask() {
        String currentTime = LocalDateTime.now().format(formatter);
        logger.info("每周定时任务执行 - 当前时间: {}", currentTime);
        
        // 执行统计任务
        generateWeeklyReport();
    }

    // 每月1号凌晨1点执行
    @Scheduled(cron = "0 0 1 1 * ?")
    public void monthlyTask() {
        String currentTime = LocalDateTime.now().format(formatter);
        logger.info("每月定时任务执行 - 当前时间: {}", currentTime);
        
        // 执行月度清理
        monthlyCleanup();
    }

    private void cleanupExpiredData() {
        logger.info("清理过期数据...");
        // 实现清理逻辑
    }

    private void generateWeeklyReport() {
        logger.info("生成周报...");
        // 实现报表生成逻辑
    }

    private void monthlyCleanup() {
        logger.info("执行月度清理...");
        // 实现月度清理逻辑
    }
}

✅ 第五部分:实战项目:用户管理系统(90分钟)

1. 项目结构

bash 复制代码
demo-app/
├── src/main/java/com/example/demo/
│   ├── DemoApplication.java           # 启动类
│   ├── config/                        # 配置类
│   │   ├── RedisConfig.java
│   │   ├── AsyncConfig.java
│   │   └── AppProperties.java
│   ├── controller/                    # 控制器
│   │   └── UserController.java
│   ├── model/                         # 数据模型
│   │   └── User.java
│   ├── service/                       # 业务服务
│   │   ├── UserService.java
│   │   ├── CacheService.java
│   │   ├── EmailService.java
│   │   └── ScheduledTaskService.java
│   ├── health/                        # 健康检查
│   │   └── CustomHealthIndicator.java
│   └── metrics/                       # 监控指标
│       └── CustomMetrics.java
├── src/main/resources/
│   ├── application.yml                # 主配置
│   ├── application-dev.yml            # 开发环境
│   └── application-prod.yml           # 生产环境
└── pom.xml

2. 完整的用户控制器

UserController.java

java 复制代码
// UserController.java - 完整的用户管理控制器
package com.example.demo.controller;

import com.example.demo.model.User;
import com.example.demo.service.UserService;
import com.example.demo.service.CacheService;
import com.example.demo.service.EmailService;
import com.example.demo.metrics.CustomMetrics;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

@RestController
@RequestMapping("/api/users")
public class UserController {

    private final UserService userService;
    private final CacheService cacheService;
    private final EmailService emailService;
    private final CustomMetrics customMetrics;

    public UserController(UserService userService, CacheService cacheService,
                        EmailService emailService, CustomMetrics customMetrics) {
        this.userService = userService;
        this.cacheService = cacheService;
        this.emailService = emailService;
        this.customMetrics = customMetrics;
    }

    // 创建用户(异步发送欢迎邮件)
    @PostMapping
    public ResponseEntity<?> createUser(@RequestBody User user) {
        try {
            // 开始计时
            var timerSample = customMetrics.startUserOperationTimer();
            
            // 创建用户
            User createdUser = cacheService.createUser(user);
            
            // 异步发送欢迎邮件
            CompletableFuture<String> emailResult = emailService.sendWelcomeEmail(
                user.getEmail(), user.getUsername()
            );
            
            // 增加用户创建计数
            customMetrics.incrementUserCreation();
            
            // 停止计时
            customMetrics.stopUserOperationTimer(timerSample);
            
            return ResponseEntity.ok(Map.of(
                "success", true,
                "message", "用户创建成功",
                "data", createdUser,
                "emailStatus", "邮件发送中..."
            ));
            
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", e.getMessage()
            ));
        }
    }

    // 获取用户(使用缓存)
    @GetMapping("/{id}")
    public ResponseEntity<?> getUserById(@PathVariable Long id) {
        try {
            var timerSample = customMetrics.startUserOperationTimer();
            
            User user = cacheService.getUserById(id);
            
            customMetrics.stopUserOperationTimer(timerSample);
            
            return ResponseEntity.ok(Map.of(
                "success", true,
                "data", user,
                "fromCache", true
            ));
            
        } catch (RuntimeException e) {
            return ResponseEntity.notFound().build();
        }
    }

    // 获取所有用户
    @GetMapping
    public ResponseEntity<?> getAllUsers() {
        List<User> users = cacheService.getAllUsers();
        return ResponseEntity.ok(Map.of(
            "success", true,
            "data", users,
            "total", users.size()
        ));
    }

    // 更新用户
    @PutMapping("/{id}")
    public ResponseEntity<?> updateUser(@PathVariable Long id, @RequestBody User user) {
        try {
            var timerSample = customMetrics.startUserOperationTimer();
            
            User updatedUser = cacheService.updateUser(id, user);
            
            customMetrics.stopUserOperationTimer(timerSample);
            
            return ResponseEntity.ok(Map.of(
                "success", true,
                "message", "用户更新成功",
                "data", updatedUser
            ));
            
        } catch (RuntimeException e) {
            return ResponseEntity.notFound().build();
        }
    }

    // 删除用户
    @DeleteMapping("/{id}")
    public ResponseEntity<?> deleteUser(@PathVariable Long id) {
        try {
            cacheService.deleteUser(id);
            return ResponseEntity.ok(Map.of(
                "success", true,
                "message", "用户删除成功"
            ));
        } catch (RuntimeException e) {
            return ResponseEntity.notFound().build();
        }
    }

    // 批量创建用户
    @PostMapping("/batch")
    public ResponseEntity<?> batchCreateUsers(@RequestBody List<User> users) {
        try {
            List<User> createdUsers = users.stream()
                .map(cacheService::createUser)
                .toList();
            
            // 异步批量发送邮件
            String[] emails = createdUsers.stream()
                .map(User::getEmail)
                .toArray(String[]::new);
            
            CompletableFuture<Integer> emailResult = emailService.sendBulkEmails(
                emails, "账户创建成功", "您的账户已创建成功"
            );
            
            return ResponseEntity.ok(Map.of(
                "success", true,
                "message", "批量创建成功",
                "data", createdUsers,
                "count", createdUsers.size(),
                "emailStatus", "批量邮件发送中..."
            ));
            
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", e.getMessage()
            ));
        }
    }

    // 清除用户缓存
    @DeleteMapping("/cache")
    public ResponseEntity<?> clearUserCache() {
        cacheService.clearAllUserCache();
        return ResponseEntity.ok(Map.of(
            "success", true,
            "message", "用户缓存已清除"
        ));
    }

    // 获取系统状态
    @GetMapping("/status")
    public ResponseEntity<?> getSystemStatus() {
        return ResponseEntity.ok(Map.of(
            "success", true,
            "data", Map.of(
                "cacheEnabled", true,
                "asyncEnabled", true,
                "scheduledTasks", true,
                "timestamp", System.currentTimeMillis()
            )
        ));
    }
}

🎯 今日学习总结

1. 掌握的核心技能

  • ✅ Spring Boot多环境配置管理
  • ✅ Actuator监控与健康检查
  • ✅ Redis缓存集成与使用
  • ✅ 异步处理与定时任务
  • ✅ 自定义监控指标

2. 实战项目特点

  • 多环境配置:开发、生产环境分离
  • 监控体系:健康检查、指标监控、日志管理
  • 性能优化:Redis缓存、异步处理
  • 定时任务:数据清理、报表生成
  • 完整流程:用户CRUD + 邮件通知 + 缓存管理

3. 下一步学习方向

  • Spring Security安全框架
  • 数据库事务管理
  • 微服务架构设计
  • 容器化部署(Docker)
  • 云原生应用开发

学习建议

  1. 动手实践:每个配置都要亲自测试
  2. 监控观察:使用Actuator端点观察应用状态
  3. 性能测试:对比缓存前后的性能差异
  4. 日志分析:学会查看和分析应用日志
  5. 问题排查:遇到问题时学会使用监控工具定位
相关推荐
hqxstudying33 分钟前
mybatis过渡到mybatis-plus过程中需要注意的地方
java·tomcat·mybatis
lichkingyang42 分钟前
最近遇到的几个JVM问题
java·jvm·算法
ZeroKoop1 小时前
多线程文件下载 - 数组切分,截取文件名称
java
Monly211 小时前
IDEA:控制台中文乱码
java·ide·intellij-idea
叫我阿柒啊1 小时前
从全栈开发到微服务架构:一次真实的Java面试实录
java·redis·ci/cd·微服务·vue3·springboot·jwt
superlls2 小时前
(计算机网络)JWT三部分及 Signature 作用
java·开发语言·计算机网络
多工坊2 小时前
【DataGrip】连接达梦数据库后,能查询数据但是看不到表的几种情况分析,达梦数据库驱动包下载DmJdbcDriver18.jar
java·数据库·jar
秋难降3 小时前
优雅的代码是什么样的?🫣
java·python·代码规范
现在就干3 小时前
Spring事务基础:你在入门时踩过的所有坑
java·后端
浮游本尊3 小时前
Java学习第13天 - 数据库事务管理与MyBatis Plus
java