Performance Tuning trong Kubernetes

Tổng Quan

Performance tuning trong Kubernetes là quá trình tối ưu hóa hiệu suất của cluster, applications và infrastructure để đạt được throughput cao nhất với latency thấp nhất và resource utilization hiệu quả.

Resource Management và Optimization

CPU và Memory Requests/Limits

# Kubernetes Deployment với optimized resource configuration
apiVersion: apps/v1
kind: Deployment
metadata:
  name: high-performance-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: high-performance-app
  template:
    metadata:
      labels:
        app: high-performance-app
    spec:
      containers:
      - name: app-container
        image: myapp:latest
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "1000m"
        env:
        - name: JVM_OPTS
          value: "-Xms512m -Xmx896m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"

Java Application Performance Monitoring

// Performance monitoring service for Java applications in Kubernetes
@Component
public class KubernetesPerformanceMonitor {

    private final MeterRegistry meterRegistry;
    private final Timer responseTimeTimer;
    private final Counter requestCounter;
    private final Gauge memoryGauge;

    public KubernetesPerformanceMonitor(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        this.responseTimeTimer = Timer.builder("http.request.duration")
                .description("HTTP request duration")
                .register(meterRegistry);
        this.requestCounter = Counter.builder("http.requests.total")
                .description("Total HTTP requests")
                .register(meterRegistry);
        this.memoryGauge = Gauge.builder("jvm.memory.used")
                .description("JVM memory usage")
                .register(meterRegistry, this, this::getMemoryUsage);
    }

    public void recordRequest(String endpoint, long durationMs) {
        responseTimeTimer.record(durationMs, TimeUnit.MILLISECONDS);
        requestCounter.increment(Tags.of("endpoint", endpoint));
    }

    private double getMemoryUsage(KubernetesPerformanceMonitor monitor) {
        Runtime runtime = Runtime.getRuntime();
        return runtime.totalMemory() - runtime.freeMemory();
    }

    public PerformanceMetrics getMetrics() {
        return PerformanceMetrics.builder()
                .avgResponseTime(responseTimeTimer.mean(TimeUnit.MILLISECONDS))
                .totalRequests(requestCounter.count())
                .memoryUsage(getMemoryUsage(this))
                .build();
    }
}

@Data
@Builder
public class PerformanceMetrics {
    private double avgResponseTime;
    private double totalRequests;
    private double memoryUsage;
    private double cpuUsage;
    private double throughput;
}

JVM Tuning cho Kubernetes

Garbage Collection Optimization

// GC tuning configuration và monitoring
@Configuration
public class JVMTuningConfiguration {

    @Value("${app.jvm.heap-size:1g}")
    private String heapSize;

    @Value("${app.jvm.gc-algorithm:G1GC}")
    private String gcAlgorithm;

    @PostConstruct
    public void configureJVM() {
        // Dynamic JVM configuration based on container resources
        configureHeapSize();
        configureGarbageCollection();
        enablePerformanceLogging();
    }

    private void configureHeapSize() {
        long containerMemory = getContainerMemoryLimit();
        long heapSize = (long) (containerMemory * 0.8); // 80% of container memory

        System.setProperty("java.opt.heap.max", 
            String.format("-Xmx%dm", heapSize / 1024 / 1024));
        System.setProperty("java.opt.heap.initial", 
            String.format("-Xms%dm", heapSize / 2 / 1024 / 1024));
    }

    private void configureGarbageCollection() {
        switch (gcAlgorithm.toUpperCase()) {
            case "G1GC":
                System.setProperty("java.opt.gc", 
                    "-XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:G1HeapRegionSize=16m");
                break;
            case "PARALLEL":
                System.setProperty("java.opt.gc", 
                    "-XX:+UseParallelGC -XX:ParallelGCThreads=4");
                break;
            case "ZGC":
                System.setProperty("java.opt.gc", 
                    "-XX:+UseZGC -XX:+UnlockExperimentalVMOptions");
                break;
        }
    }

    private long getContainerMemoryLimit() {
        try {
            // Read from cgroup memory limit
            Path memoryLimitPath = Paths.get("/sys/fs/cgroup/memory/memory.limit_in_bytes");
            String limitStr = Files.readString(memoryLimitPath).trim();
            return Long.parseLong(limitStr);
        } catch (Exception e) {
            return Runtime.getRuntime().maxMemory();
        }
    }

    private void enablePerformanceLogging() {
        System.setProperty("java.opt.logging", 
            "-Xlog:gc*:gc.log:time -XX:+PrintGCDetails -XX:+PrintGCTimeStamps");
    }
}

Application-Level Performance Optimization

Connection Pool Tuning

// Database connection pool optimization for Kubernetes environments
@Configuration
public class DatabasePerformanceConfiguration {

    @Value("${spring.datasource.url}")
    private String databaseUrl;

    @Bean
    @Primary
    public DataSource optimizedDataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl(databaseUrl);
        config.setUsername("${spring.datasource.username}");
        config.setPassword("${spring.datasource.password}");

        // Performance optimizations
        int podCount = getPodCount();
        int coreCount = Runtime.getRuntime().availableProcessors();

        // Optimize connection pool size based on pod count and CPU cores
        config.setMaximumPoolSize(Math.min(coreCount * 2, 20));
        config.setMinimumIdle(Math.max(coreCount, 5));
        config.setConnectionTimeout(30000); // 30 seconds
        config.setIdleTimeout(600000); // 10 minutes
        config.setMaxLifetime(1800000); // 30 minutes
        config.setLeakDetectionThreshold(60000); // 1 minute

        // Connection validation
        config.setConnectionTestQuery("SELECT 1");
        config.setValidationTimeout(5000);

        // Performance settings
        config.addDataSourceProperty("cachePrepStmts", "true");
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
        config.addDataSourceProperty("useServerPrepStmts", "true");
        config.addDataSourceProperty("useLocalSessionState", "true");
        config.addDataSourceProperty("rewriteBatchedStatements", "true");
        config.addDataSourceProperty("cacheResultSetMetadata", "true");

        return new HikariDataSource(config);
    }

    private int getPodCount() {
        try {
            // Get pod count from Kubernetes API or environment
            String replicaCount = System.getenv("REPLICA_COUNT");
            return replicaCount != null ? Integer.parseInt(replicaCount) : 1;
        } catch (Exception e) {
            return 1;
        }
    }
}

Caching Strategy Implementation

// Multi-level caching strategy for Kubernetes applications
@Service
public class KubernetesCacheService {

    private final RedisTemplate<String, Object> redisTemplate;
    private final CacheManager localCacheManager;
    private final KubernetesClient kubernetesClient;

    @Autowired
    public KubernetesCacheService(RedisTemplate<String, Object> redisTemplate,
                                  CacheManager localCacheManager,
                                  KubernetesClient kubernetesClient) {
        this.redisTemplate = redisTemplate;
        this.localCacheManager = localCacheManager;
        this.kubernetesClient = kubernetesClient;
    }

    public <T> T getFromCache(String key, Class<T> type, Supplier<T> dataProvider) {
        // Level 1: Local cache (fastest)
        T result = getFromLocalCache(key, type);
        if (result != null) {
            return result;
        }

        // Level 2: Distributed cache (Redis)
        result = getFromDistributedCache(key, type);
        if (result != null) {
            putInLocalCache(key, result);
            return result;
        }

        // Level 3: Database/External service (slowest)
        result = dataProvider.get();
        if (result != null) {
            putInDistributedCache(key, result);
            putInLocalCache(key, result);
        }

        return result;
    }

    @SuppressWarnings("unchecked")
    private <T> T getFromLocalCache(String key, Class<T> type) {
        Cache cache = localCacheManager.getCache("local");
        if (cache != null) {
            Cache.ValueWrapper wrapper = cache.get(key);
            return wrapper != null ? (T) wrapper.get() : null;
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    private <T> T getFromDistributedCache(String key, Class<T> type) {
        try {
            Object cached = redisTemplate.opsForValue().get(key);
            return cached != null ? (T) cached : null;
        } catch (Exception e) {
            log.warn("Failed to get from distributed cache: {}", e.getMessage());
            return null;
        }
    }

    private void putInLocalCache(String key, Object value) {
        Cache cache = localCacheManager.getCache("local");
        if (cache != null) {
            cache.put(key, value);
        }
    }

    private void putInDistributedCache(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value, Duration.ofMinutes(30));
        } catch (Exception e) {
            log.warn("Failed to put in distributed cache: {}", e.getMessage());
        }
    }

    public void invalidateCache(String pattern) {
        // Invalidate local cache
        localCacheManager.getCacheNames().forEach(cacheName -> {
            Cache cache = localCacheManager.getCache(cacheName);
            if (cache != null) {
                cache.clear();
            }
        });

        // Invalidate distributed cache
        try {
            Set<String> keys = redisTemplate.keys(pattern);
            if (keys != null && !keys.isEmpty()) {
                redisTemplate.delete(keys);
            }
        } catch (Exception e) {
            log.warn("Failed to invalidate distributed cache: {}", e.getMessage());
        }
    }
}

Network Performance Optimization

Service Mesh Performance Tuning

// Istio service mesh performance configuration
@Component
public class ServiceMeshPerformanceConfig {

    @Value("${istio.proxy.cpu-limit:200m}")
    private String proxyCpuLimit;

    @Value("${istio.proxy.memory-limit:128Mi}")
    private String proxyMemoryLimit;

    public void optimizeServiceMeshPerformance() {
        configureIstioProxy();
        enableCircuitBreaker();
        configureRetryPolicy();
        optimizeLoadBalancing();
    }

    private void configureIstioProxy() {
        // Envoy proxy configuration for performance
        Map<String, String> proxyConfig = Map.of(
            "proxyStatsMatcher", createStatsMatcherConfig(),
            "concurrency", String.valueOf(Runtime.getRuntime().availableProcessors()),
            "proxyMemoryLimit", proxyMemoryLimit,
            "proxyCpuLimit", proxyCpuLimit
        );

        applyProxyConfiguration(proxyConfig);
    }

    private String createStatsMatcherConfig() {
        return """
            {
              "exclusion_list": {
                "patterns": [
                  {
                    "prefix": "cluster.outbound"
                  },
                  {
                    "prefix": "cluster.inbound"
                  }
                ]
              }
            }
            """;
    }

    private void enableCircuitBreaker() {
        CircuitBreakerConfig config = CircuitBreakerConfig.builder()
                .consecutiveErrors(5)
                .interval(Duration.ofSeconds(30))
                .baseEjectionTime(Duration.ofSeconds(30))
                .maxEjectionPercent(50)
                .build();

        applyCircuitBreakerConfig(config);
    }

    private void configureRetryPolicy() {
        RetryPolicyConfig config = RetryPolicyConfig.builder()
                .attempts(3)
                .perTryTimeout(Duration.ofSeconds(2))
                .retryOn("5xx,reset,connect-failure,refused-stream")
                .build();

        applyRetryPolicyConfig(config);
    }

    private void optimizeLoadBalancing() {
        LoadBalancingConfig config = LoadBalancingConfig.builder()
                .algorithm("LEAST_CONN")
                .localityPreference(true)
                .outlierDetection(true)
                .build();

        applyLoadBalancingConfig(config);
    }

    // Helper methods for applying configurations
    private void applyProxyConfiguration(Map<String, String> config) {
        // Implementation for applying Envoy proxy configuration
        log.info("Applied proxy configuration: {}", config);
    }

    private void applyCircuitBreakerConfig(CircuitBreakerConfig config) {
        // Implementation for applying circuit breaker configuration
        log.info("Applied circuit breaker configuration: {}", config);
    }

    private void applyRetryPolicyConfig(RetryPolicyConfig config) {
        // Implementation for applying retry policy configuration
        log.info("Applied retry policy configuration: {}", config);
    }

    private void applyLoadBalancingConfig(LoadBalancingConfig config) {
        // Implementation for applying load balancing configuration
        log.info("Applied load balancing configuration: {}", config);
    }
}

// Supporting classes
@Data
@Builder
public class CircuitBreakerConfig {
    private int consecutiveErrors;
    private Duration interval;
    private Duration baseEjectionTime;
    private int maxEjectionPercent;
}

@Data
@Builder
public class RetryPolicyConfig {
    private int attempts;
    private Duration perTryTimeout;
    private String retryOn;
}

@Data
@Builder
public class LoadBalancingConfig {
    private String algorithm;
    private boolean localityPreference;
    private boolean outlierDetection;
}

Storage Performance Optimization

Persistent Volume Performance Tuning

// Storage performance analyzer và optimizer
@Service
public class StoragePerformanceOptimizer {

    private final KubernetesClient kubernetesClient;
    private final MetricsCollector metricsCollector;

    public StoragePerformanceOptimizer(KubernetesClient kubernetesClient,
                                       MetricsCollector metricsCollector) {
        this.kubernetesClient = kubernetesClient;
        this.metricsCollector = metricsCollector;
    }

    public StorageOptimizationReport analyzeStoragePerformance(String namespace) {
        List<PersistentVolumeClaim> pvcs = kubernetesClient.persistentVolumeClaims()
                .inNamespace(namespace)
                .list()
                .getItems();

        List<StoragePerformanceMetrics> metrics = new ArrayList<>();

        for (PersistentVolumeClaim pvc : pvcs) {
            StoragePerformanceMetrics pvcMetrics = analyzePVCPerformance(pvc);
            metrics.add(pvcMetrics);
        }

        return generateOptimizationReport(metrics);
    }

    private StoragePerformanceMetrics analyzePVCPerformance(PersistentVolumeClaim pvc) {
        String pvcName = pvc.getMetadata().getName();
        String storageClass = pvc.getSpec().getStorageClassName();

        // Collect IOPS và throughput metrics
        double iops = metricsCollector.getIOPS(pvcName);
        double throughput = metricsCollector.getThroughput(pvcName);
        double latency = metricsCollector.getLatency(pvcName);
        double utilization = metricsCollector.getUtilization(pvcName);

        return StoragePerformanceMetrics.builder()
                .pvcName(pvcName)
                .storageClass(storageClass)
                .iops(iops)
                .throughput(throughput)
                .latency(latency)
                .utilization(utilization)
                .build();
    }

    private StorageOptimizationReport generateOptimizationReport(
            List<StoragePerformanceMetrics> metrics) {

        List<StorageOptimizationRecommendation> recommendations = new ArrayList<>();

        for (StoragePerformanceMetrics metric : metrics) {
            if (metric.getLatency() > 10.0) { // High latency threshold
                recommendations.add(StorageOptimizationRecommendation.builder()
                        .pvcName(metric.getPvcName())
                        .issue("High latency detected")
                        .recommendation("Consider using SSD storage class")
                        .priority("HIGH")
                        .build());
            }

            if (metric.getUtilization() > 85.0) { // High utilization threshold
                recommendations.add(StorageOptimizationRecommendation.builder()
                        .pvcName(metric.getPvcName())
                        .issue("High storage utilization")
                        .recommendation("Increase PVC size or implement data archival")
                        .priority("MEDIUM")
                        .build());
            }

            if (metric.getIops() > 1000 && metric.getStorageClass().equals("standard")) {
                recommendations.add(StorageOptimizationRecommendation.builder()
                        .pvcName(metric.getPvcName())
                        .issue("High IOPS demand with standard storage")
                        .recommendation("Upgrade to high-performance storage class")
                        .priority("HIGH")
                        .build());
            }
        }

        return StorageOptimizationReport.builder()
                .metrics(metrics)
                .recommendations(recommendations)
                .overallScore(calculateOverallScore(metrics))
                .build();
    }

    private double calculateOverallScore(List<StoragePerformanceMetrics> metrics) {
        return metrics.stream()
                .mapToDouble(m -> (100 - m.getLatency()) * 0.4 + 
                               (100 - m.getUtilization()) * 0.3 + 
                               Math.min(m.getIops() / 10, 100) * 0.3)
                .average()
                .orElse(0.0);
    }
}

@Data
@Builder
public class StoragePerformanceMetrics {
    private String pvcName;
    private String storageClass;
    private double iops;
    private double throughput;
    private double latency;
    private double utilization;
}

@Data
@Builder
public class StorageOptimizationRecommendation {
    private String pvcName;
    private String issue;
    private String recommendation;
    private String priority;
}

@Data
@Builder
public class StorageOptimizationReport {
    private List<StoragePerformanceMetrics> metrics;
    private List<StorageOptimizationRecommendation> recommendations;
    private double overallScore;
}

Advanced Performance Profiling

Application Performance Profiling

// Comprehensive performance profiler for Kubernetes applications
@Component
public class KubernetesApplicationProfiler {

    private final MeterRegistry meterRegistry;
    private final ApplicationEventPublisher eventPublisher;

    public KubernetesApplicationProfiler(MeterRegistry meterRegistry,
                                         ApplicationEventPublisher eventPublisher) {
        this.meterRegistry = meterRegistry;
        this.eventPublisher = eventPublisher;
    }

    @EventListener
    @Async
    public void profileApplicationStartup(ApplicationReadyEvent event) {
        ProfilerResults results = performStartupProfiling();
        publishProfilingResults(results);
    }

    public ProfilerResults performComprehensiveProfiling() {
        ProfilerResults.Builder builder = ProfilerResults.builder();

        // Memory profiling
        builder.memoryProfile(profileMemoryUsage());

        // CPU profiling
        builder.cpuProfile(profileCPUUsage());

        // Thread profiling
        builder.threadProfile(profileThreadUsage());

        // GC profiling
        builder.gcProfile(profileGarbageCollection());

        // Network profiling
        builder.networkProfile(profileNetworkUsage());

        // Database profiling
        builder.databaseProfile(profileDatabaseConnections());

        return builder.build();
    }

    private MemoryProfile profileMemoryUsage() {
        MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
        MemoryUsage nonHeapUsage = memoryBean.getNonHeapMemoryUsage();

        List<MemoryPoolMXBean> memoryPools = ManagementFactory.getMemoryPoolMXBeans();

        return MemoryProfile.builder()
                .heapUsed(heapUsage.getUsed())
                .heapMax(heapUsage.getMax())
                .heapCommitted(heapUsage.getCommitted())
                .nonHeapUsed(nonHeapUsage.getUsed())
                .nonHeapMax(nonHeapUsage.getMax())
                .memoryPools(memoryPools.stream()
                        .collect(Collectors.toMap(
                                MemoryPoolMXBean::getName,
                                pool -> pool.getUsage().getUsed()
                        )))
                .build();
    }

    private CPUProfile profileCPUUsage() {
        OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();

        return CPUProfile.builder()
                .systemLoadAverage(osBean.getSystemLoadAverage())
                .availableProcessors(osBean.getAvailableProcessors())
                .processCpuLoad(getProcessCpuLoad(osBean))
                .systemCpuLoad(getSystemCpuLoad(osBean))
                .build();
    }

    private ThreadProfile profileThreadUsage() {
        ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();

        return ThreadProfile.builder()
                .totalThreads(threadBean.getThreadCount())
                .daemonThreads(threadBean.getDaemonThreadCount())
                .peakThreads(threadBean.getPeakThreadCount())
                .blockedThreads(getBlockedThreadCount(threadBean))
                .deadlockedThreads(getDeadlockedThreadCount(threadBean))
                .build();
    }

    private GCProfile profileGarbageCollection() {
        List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans();

        Map<String, GCMetrics> gcMetrics = gcBeans.stream()
                .collect(Collectors.toMap(
                        GarbageCollectorMXBean::getName,
                        gc -> GCMetrics.builder()
                                .collectionCount(gc.getCollectionCount())
                                .collectionTime(gc.getCollectionTime())
                                .build()
                ));

        return GCProfile.builder()
                .gcMetrics(gcMetrics)
                .totalGCTime(gcBeans.stream()
                        .mapToLong(GarbageCollectorMXBean::getCollectionTime)
                        .sum())
                .totalGCCount(gcBeans.stream()
                        .mapToLong(GarbageCollectorMXBean::getCollectionCount)
                        .sum())
                .build();
    }

    private NetworkProfile profileNetworkUsage() {
        // Network profiling implementation
        return NetworkProfile.builder()
                .activeConnections(getActiveConnectionCount())
                .networkThroughput(getNetworkThroughput())
                .networkLatency(getNetworkLatency())
                .build();
    }

    private DatabaseProfile profileDatabaseConnections() {
        // Database profiling implementation
        return DatabaseProfile.builder()
                .activeConnections(getDatabaseActiveConnections())
                .connectionPoolUtilization(getConnectionPoolUtilization())
                .averageQueryTime(getAverageQueryTime())
                .slowQueries(getSlowQueries())
                .build();
    }

    // Helper methods
    private double getProcessCpuLoad(OperatingSystemMXBean osBean) {
        if (osBean instanceof com.sun.management.OperatingSystemMXBean) {
            return ((com.sun.management.OperatingSystemMXBean) osBean).getProcessCpuLoad();
        }
        return -1.0;
    }

    private double getSystemCpuLoad(OperatingSystemMXBean osBean) {
        if (osBean instanceof com.sun.management.OperatingSystemMXBean) {
            return ((com.sun.management.OperatingSystemMXBean) osBean).getSystemCpuLoad();
        }
        return -1.0;
    }

    private long getBlockedThreadCount(ThreadMXBean threadBean) {
        ThreadInfo[] threadInfos = threadBean.getThreadInfo(threadBean.getAllThreadIds());
        return Arrays.stream(threadInfos)
                .filter(Objects::nonNull)
                .mapToLong(info -> info.getBlockedCount())
                .sum();
    }

    private long getDeadlockedThreadCount(ThreadMXBean threadBean) {
        long[] deadlockedThreads = threadBean.findDeadlockedThreads();
        return deadlockedThreads != null ? deadlockedThreads.length : 0;
    }

    private ProfilerResults performStartupProfiling() {
        long startTime = System.currentTimeMillis();
        ProfilerResults results = performComprehensiveProfiling();
        long endTime = System.currentTimeMillis();

        results.setProfilingDuration(endTime - startTime);
        return results;
    }

    private void publishProfilingResults(ProfilerResults results) {
        eventPublisher.publishEvent(new ProfilingCompletedEvent(results));
    }

    // Placeholder methods for network và database metrics
    private int getActiveConnectionCount() { return 0; }
    private double getNetworkThroughput() { return 0.0; }
    private double getNetworkLatency() { return 0.0; }
    private int getDatabaseActiveConnections() { return 0; }
    private double getConnectionPoolUtilization() { return 0.0; }
    private double getAverageQueryTime() { return 0.0; }
    private List<String> getSlowQueries() { return new ArrayList<>(); }
}

// Supporting data classes
@Data
@Builder
public class ProfilerResults {
    private MemoryProfile memoryProfile;
    private CPUProfile cpuProfile;
    private ThreadProfile threadProfile;
    private GCProfile gcProfile;
    private NetworkProfile networkProfile;
    private DatabaseProfile databaseProfile;
    private long profilingDuration;
}

@Data
@Builder
public class MemoryProfile {
    private long heapUsed;
    private long heapMax;
    private long heapCommitted;
    private long nonHeapUsed;
    private long nonHeapMax;
    private Map<String, Long> memoryPools;
}

@Data
@Builder
public class CPUProfile {
    private double systemLoadAverage;
    private int availableProcessors;
    private double processCpuLoad;
    private double systemCpuLoad;
}

@Data
@Builder
public class ThreadProfile {
    private int totalThreads;
    private int daemonThreads;
    private int peakThreads;
    private long blockedThreads;
    private long deadlockedThreads;
}

@Data
@Builder
public class GCProfile {
    private Map<String, GCMetrics> gcMetrics;
    private long totalGCTime;
    private long totalGCCount;
}

@Data
@Builder
public class GCMetrics {
    private long collectionCount;
    private long collectionTime;
}

@Data
@Builder
public class NetworkProfile {
    private int activeConnections;
    private double networkThroughput;
    private double networkLatency;
}

@Data
@Builder
public class DatabaseProfile {
    private int activeConnections;
    private double connectionPoolUtilization;
    private double averageQueryTime;
    private List<String> slowQueries;
}

public class ProfilingCompletedEvent extends ApplicationEvent {
    private final ProfilerResults results;

    public ProfilingCompletedEvent(ProfilerResults results) {
        super(results);
        this.results = results;
    }

    public ProfilerResults getResults() {
        return results;
    }
}

Performance Benchmarking và Testing

Load Testing Framework

// Kubernetes-native load testing framework
@Service
public class KubernetesLoadTestingService {

    private final KubernetesClient kubernetesClient;
    private final RestTemplate restTemplate;
    private final ExecutorService executorService;

    public KubernetesLoadTestingService(KubernetesClient kubernetesClient) {
        this.kubernetesClient = kubernetesClient;
        this.restTemplate = new RestTemplate();
        this.executorService = Executors.newFixedThreadPool(100);
    }

    public LoadTestResults executeLoadTest(LoadTestConfiguration config) {
        LoadTestResults.Builder resultsBuilder = LoadTestResults.builder();

        List<Future<RequestResult>> futures = new ArrayList<>();
        long startTime = System.currentTimeMillis();

        // Execute concurrent requests
        for (int i = 0; i < config.getTotalRequests(); i++) {
            Future<RequestResult> future = executorService.submit(() -> {
                return executeRequest(config.getTargetUrl(), config.getRequestMethod());
            });
            futures.add(future);

            // Control request rate
            if (config.getRequestsPerSecond() > 0) {
                try {
                    Thread.sleep(1000 / config.getRequestsPerSecond());
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }

        // Collect results
        List<RequestResult> results = futures.stream()
                .map(future -> {
                    try {
                        return future.get(config.getTimeoutSeconds(), TimeUnit.SECONDS);
                    } catch (Exception e) {
                        return RequestResult.builder()
                                .success(false)
                                .responseTime(-1)
                                .errorMessage(e.getMessage())
                                .build();
                    }
                })
                .collect(Collectors.toList());

        long endTime = System.currentTimeMillis();

        return resultsBuilder
                .results(results)
                .totalDuration(endTime - startTime)
                .successfulRequests(results.stream()
                        .mapToInt(r -> r.isSuccess() ? 1 : 0)
                        .sum())
                .failedRequests(results.stream()
                        .mapToInt(r -> r.isSuccess() ? 0 : 1)
                        .sum())
                .averageResponseTime(results.stream()
                        .filter(RequestResult::isSuccess)
                        .mapToLong(RequestResult::getResponseTime)
                        .average()
                        .orElse(0.0))
                .percentile95ResponseTime(calculatePercentile(results, 95))
                .percentile99ResponseTime(calculatePercentile(results, 99))
                .build();
    }

    private RequestResult executeRequest(String url, String method) {
        long startTime = System.nanoTime();

        try {
            ResponseEntity<String> response;

            switch (method.toUpperCase()) {
                case "GET":
                    response = restTemplate.getForEntity(url, String.class);
                    break;
                case "POST":
                    response = restTemplate.postForEntity(url, "", String.class);
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported HTTP method: " + method);
            }

            long endTime = System.nanoTime();
            long responseTime = (endTime - startTime) / 1_000_000; // Convert to milliseconds

            return RequestResult.builder()
                    .success(response.getStatusCode().is2xxSuccessful())
                    .responseTime(responseTime)
                    .statusCode(response.getStatusCode().value())
                    .build();

        } catch (Exception e) {
            long endTime = System.nanoTime();
            long responseTime = (endTime - startTime) / 1_000_000;

            return RequestResult.builder()
                    .success(false)
                    .responseTime(responseTime)
                    .errorMessage(e.getMessage())
                    .build();
        }
    }

    private double calculatePercentile(List<RequestResult> results, int percentile) {
        List<Long> responseTimes = results.stream()
                .filter(RequestResult::isSuccess)
                .map(RequestResult::getResponseTime)
                .sorted()
                .collect(Collectors.toList());

        if (responseTimes.isEmpty()) {
            return 0.0;
        }

        int index = (int) Math.ceil(percentile / 100.0 * responseTimes.size()) - 1;
        return responseTimes.get(Math.min(index, responseTimes.size() - 1));
    }
}

@Data
@Builder
public class LoadTestConfiguration {
    private String targetUrl;
    private String requestMethod;
    private int totalRequests;
    private int requestsPerSecond;
    private int timeoutSeconds;
    private int concurrentUsers;
}

@Data
@Builder
public class LoadTestResults {
    private List<RequestResult> results;
    private long totalDuration;
    private int successfulRequests;
    private int failedRequests;
    private double averageResponseTime;
    private double percentile95ResponseTime;
    private double percentile99ResponseTime;
}

@Data
@Builder
public class RequestResult {
    private boolean success;
    private long responseTime;
    private int statusCode;
    private String errorMessage;
}

Next Steps

Nội dung này đã được mở rộng chi tiết với: - JVM tuning strategies cho containerized environments - Advanced connection pooling và caching implementations - Service mesh performance optimization - Storage performance analysis tools - Comprehensive application profiling - Load testing frameworks - Real-world Java code examples for Kubernetes performance tuning - Detailed monitoring và observability patterns - Cost-effective resource optimization strategies