1.6 资源管理最佳实践

发布于:2025-02-11 ⋅ 阅读:(15) ⋅ 点赞:(0)

1.6 资源管理最佳实践

1.6.1 多环境资源配置策略(企业级方案)

Profile机制深度解析

启动参数
spring.profiles.active
环境变量
配置文件
application-{profile}.properties
激活的Profile
加载对应配置

多维度配置方案

# application.yml(公共配置)
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.zaxxer.hikari.HikariDataSource

---
# 开发环境配置
spring:
  profiles: dev
  datasource:
    url: jdbc:mysql://dev-db:3306/app?useSSL=false
    username: dev_user
    password: dev123
    hikari:
      maximum-pool-size: 5

---
# 生产环境配置
spring:
  profiles: prod
  datasource:
    url: jdbc:mysql://prod-cluster:3306/app?useSSL=true
    username: ${DB_PROD_USER}
    password: ${DB_PROD_PASS}
    hikari:
      maximum-pool-size: 20
      connection-timeout: 3000

Profile激活策略

// 1. 启动参数指定
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application.class);
        app.setAdditionalProfiles("prod", "azure");
        app.run(args);
    }
}

// 2. 条件化Bean配置
@Configuration
@Profile("cloud")
public class CloudConfig {
    @Bean
    public CloudService cloudService() {
        return new AzureCloudService();
    }
}

// 3. 测试环境专用配置
@TestConfiguration
@Profile("test")
public class MockConfig {
    @Bean
    @Primary
    public PaymentService mockPaymentService() {
        return new MockPaymentService();
    }
}

1.6.2 加密配置安全处理方案(金融级安全)

Jasypt集成全流程

<!-- Maven依赖 -->
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>3.0.5</version>
</dependency>
// 加密工具类
public class ConfigEncryptor {
    public static void main(String[] args) {
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setPassword(System.getenv("CONFIG_SECRET"));
        
        String plainText = "sensitive_data";
        String encrypted = encryptor.encrypt(plainText);
        System.out.println("ENC(" + encrypted + ")");
    }
}

安全配置实践

# application-secure.properties
spring.datasource.password=ENC(4Bv7dsf8sKjeiT9sLkja8W2xzlpT4r4T)

# 启动参数设置密钥
java -jar app.jar --jasypt.encryptor.password=${CONFIG_SECRET_KEY}

Kubernetes密钥管理方案

# Kubernetes部署文件
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
data:
  db-password: NkJ2N2RzZjhzS2plaVQ5c0xramE4VzJ4emxwVDRyNFQK
  api-key: VGhpcyBpcyBhIHNlY3JldCBrZXkK
// 动态获取K8s密钥
@Value("${secrets.db-password}")
private String decodedDbPassword;

1.6.3 国际化消息资源高级用法(多语言电商系统)

消息资源配置架构

resources/
├─ messages/
│  ├─ messages.properties(默认)
│  ├─ messages_en_US.properties
│  ├─ messages_zh_CN.properties
│  └─ messages_ja_JP.properties
└─ application.yml

动态消息加载实现

@Configuration
public class I18nConfig {
    
    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = 
            new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:messages/messages");
        messageSource.setDefaultEncoding("UTF-8");
        messageSource.setCacheMillis(5000); // 5秒刷新
        return messageSource;
    }

    @Bean
    public LocalResolver localeResolver() {
        SessionLocaleResolver resolver = new SessionLocaleResolver();
        resolver.setDefaultLocale(Locale.ENGLISH);
        return resolver;
    }
}

// 业务层使用示例
@Service
public class ProductService {
    private final MessageSource messageSource;

    public String getLocalizedMessage(String code, Locale locale, Object... args) {
        return messageSource.getMessage(code, args, locale);
    }

    public void showError(HttpServletRequest request) {
        Locale locale = LocaleContextHolder.getLocale();
        String message = messageSource.getMessage("error.insufficient_stock", 
            new Object[]{product.getName()}, locale);
        throw new BusinessException(message);
    }
}

Thymeleaf多语言集成

<!-- 前端页面示例 -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title th:text="#{page.title}"></title>
</head>
<body>
    <h1 th:text="#{welcome.message(${user.name})}"></h1>
    
    <!-- 语言切换 -->
    <div>
        <a th:href="@{/?lang=en}">English</a>
        <a th:href="@{/?lang=zh_CN}">中文</a>
        <a th:href="@{/?lang=ja_JP}">日本語</a>
    </div>
</body>
</html>

动态消息更新方案

// 消息热更新端点
@RestController
@RequiredArgsConstructor
public class MessageReloadController {
    private final ReloadableResourceBundleMessageSource messageSource;

    @PostMapping("/admin/i18n/reload")
    public ResponseEntity<String> reloadMessages() {
        messageSource.clearCache();
        return ResponseEntity.ok("Messages reloaded at " + new Date());
    }

    @PostMapping("/admin/i18n/update")
    public ResponseEntity<String> updateMessage(
        @RequestParam String code,
        @RequestParam String value,
        @RequestParam String lang) throws IOException {

        String fileName = "messages_" + lang + ".properties";
        Path filePath = Paths.get("src/main/resources/messages/" + fileName);
        
        Properties props = new Properties();
        try (InputStream in = Files.newInputStream(filePath)) {
            props.load(in);
        }
        
        props.setProperty(code, value);
        
        try (OutputStream out = Files.newOutputStream(filePath)) {
            props.store(out, "Updated at " + new Date());
        }
        
        return ResponseEntity.ok("Message updated");
    }
}

1.6.4 资源监控与防护(生产环境必备)

连接池监控配置

@Configuration
public class DataSourceConfig {
    
    @Bean
    public HikariDataSource dataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/app");
        config.setUsername("root");
        config.setPassword("securepass");
        config.setMaximumPoolSize(20);
        config.setMetricRegistry(Metrics.globalRegistry);
        return new HikariDataSource(config);
    }

    @Bean
    public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
        return registry -> registry.config()
            .commonTags("application", "order-service");
    }
}

资源防护策略

@Configuration
public class ResourceProtectionConfig implements WebMvcConfigurer {
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 静态资源防护
        registry.addResourceHandler("/static/**")
            .addResourceLocations("classpath:/static/")
            .setCachePeriod(3600)
            .resourceChain(true)
            .addResolver(new EncodedResourceResolver())
            .addTransformer(new CssLinkResourceTransformer());
        
        // 敏感文件屏蔽
        registry.addResourceHandler("/**")
            .addResourceLocations("classpath:/public/")
            .setUseLastModified(true)
            .resourceChain(true)
            .addResolver(new PathResourceResolver() {
                @Override
                protected Resource getResource(String resourcePath, 
                    Resource location) throws IOException {
                    if (resourcePath.endsWith(".gitignore")) {
                        return null;
                    }
                    return super.getResource(resourcePath, location);
                }
            });
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到