Files
sa-lessons/modules/module10/sections/01-performance-fundamentals.md
Alexander Abakumov 15e744da49 Initial commit: Complete Software Architecture course with 11 modules
- Added comprehensive course structure with 11 modules
- Included theoretical content, practical examples, and tasks
- Multi-language code examples (Java, Rust, Node.js, Python)
- Detailed analysis of architectural approaches and trade-offs
- Complete caching strategies documentation
- Architecture examples from real-world systems (Twitter, Netflix, Uber)
- Structured navigation and learning path
- Ready for educational use
2025-09-09 22:08:07 +03:00

11 KiB

Основы производительности

Навигация


Что такое производительность

Производительность — это способность системы выполнять задачи за определенное время с использованием доступных ресурсов.

Метрики производительности

1. Throughput (Пропускная способность)

Определение: Количество операций, выполняемых за единицу времени.

Технический пример - Advanced Performance Monitoring System:

// Advanced Performance Metrics Collector
@Component
public class AdvancedPerformanceMetrics {
    
    private final MeterRegistry meterRegistry;
    private final Counter requestCounter;
    private final Timer requestTimer;
    private final Gauge activeConnections;
    private final DistributionSummary responseSize;
    private final Counter errorCounter;
    
    public AdvancedPerformanceMetrics(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        
        // Request metrics
        this.requestCounter = Counter.builder("requests.total")
            .description("Total number of requests")
            .tag("service", "user-service")
            .register(meterRegistry);
            
        this.requestTimer = Timer.builder("request.duration")
            .description("Request processing time")
            .publishPercentiles(0.5, 0.95, 0.99)
            .publishPercentileHistogram()
            .register(meterRegistry);
            
        // Connection metrics
        this.activeConnections = Gauge.builder("connections.active")
            .description("Number of active connections")
            .register(meterRegistry, this, AdvancedPerformanceMetrics::getActiveConnections);
            
        // Response size metrics
        this.responseSize = DistributionSummary.builder("response.size")
            .description("Response size in bytes")
            .publishPercentiles(0.5, 0.95, 0.99)
            .register(meterRegistry);
            
        // Error metrics
        this.errorCounter = Counter.builder("errors.total")
            .description("Total number of errors")
            .register(meterRegistry);
    }
    
    public void recordRequest(Duration duration, int responseSizeBytes, boolean isError) {
        requestCounter.increment();
        requestTimer.record(duration);
        this.responseSize.record(responseSizeBytes);
        
        if (isError) {
            errorCounter.increment();
        }
    }
    
    public PerformanceReport generateReport() {
        return PerformanceReport.builder()
            .throughput(getThroughput())
            .averageLatency(getAverageLatency())
            .p95Latency(getP95Latency())
            .p99Latency(getP99Latency())
            .errorRate(getErrorRate())
            .activeConnections(getActiveConnections())
            .averageResponseSize(getAverageResponseSize())
            .timestamp(LocalDateTime.now())
            .build();
    }
    
    public double getThroughput() {
        double totalTime = requestTimer.totalTime(TimeUnit.SECONDS);
        return totalTime > 0 ? requestCounter.count() / totalTime : 0;
    }
    
    public double getAverageLatency() {
        return requestTimer.mean(TimeUnit.MILLISECONDS);
    }
    
    public double getP95Latency() {
        return requestTimer.percentile(0.95, TimeUnit.MILLISECONDS);
    }
    
    public double getP99Latency() {
        return requestTimer.percentile(0.99, TimeUnit.MILLISECONDS);
    }
    
    public double getErrorRate() {
        double totalRequests = requestCounter.count();
        return totalRequests > 0 ? (errorCounter.count() / totalRequests) * 100 : 0;
    }
    
    private double getActiveConnections() {
        return 0; // Placeholder
    }
    
    public double getAverageResponseSize() {
        return responseSize.mean();
    }
}

// Performance Optimization Service
@Service
public class PerformanceOptimizationService {
    
    @Autowired
    private AdvancedPerformanceMetrics metrics;
    
    @Autowired
    private DatabaseOptimizationService dbOptimizationService;
    
    // Automatic performance optimization
    @Scheduled(fixedRate = 60000) // Every minute
    public void optimizePerformance() {
        PerformanceReport report = metrics.generateReport();
        
        if (needsOptimization(report)) {
            log.warn("Performance optimization triggered: {}", report);
            
            if (report.getAverageLatency() > 1000) {
                optimizeLatency();
            }
            
            if (report.getErrorRate() > 5) {
                optimizeErrorHandling();
            }
            
            if (report.getThroughput() < 100) {
                optimizeThroughput();
            }
        }
    }
    
    private boolean needsOptimization(PerformanceReport report) {
        return report.getAverageLatency() > 1000 || 
               report.getErrorRate() > 5 || 
               report.getThroughput() < 100 ||
               report.getP95Latency() > 2000;
    }
    
    private void optimizeLatency() {
        log.info("Optimizing latency...");
        increaseConnectionPoolSize();
        enableCompression();
        optimizeJVMSettings();
    }
    
    private void optimizeErrorHandling() {
        log.info("Optimizing error handling...");
        enableCircuitBreaker();
        enableRetryLogic();
        improveErrorLogging();
    }
    
    private void optimizeThroughput() {
        log.info("Optimizing throughput...");
        increaseThreadPoolSize();
        enableAsyncProcessing();
        optimizeBatchProcessing();
    }
    
    private void increaseConnectionPoolSize() {
        log.info("Increasing connection pool size");
    }
    
    private void enableCompression() {
        log.info("Enabling compression");
    }
    
    private void optimizeJVMSettings() {
        log.info("Optimizing JVM settings");
    }
    
    private void enableCircuitBreaker() {
        log.info("Enabling circuit breaker");
    }
    
    private void enableRetryLogic() {
        log.info("Enabling retry logic");
    }
    
    private void improveErrorLogging() {
        log.info("Improving error logging");
    }
    
    private void increaseThreadPoolSize() {
        log.info("Increasing thread pool size");
    }
    
    private void enableAsyncProcessing() {
        log.info("Enabling async processing");
    }
    
    private void optimizeBatchProcessing() {
        log.info("Optimizing batch processing");
    }
}

2. Latency (Задержка)

Определение: Время выполнения одной операции.

// Измерение latency
@Service
public class UserService {
    private final Timer requestTimer;
    
    public UserService(MeterRegistry meterRegistry) {
        this.requestTimer = Timer.builder("user.service.duration")
            .register(meterRegistry);
    }
    
    public User getUser(Long id) {
        return requestTimer.recordCallable(() -> {
            // бизнес-логика
            return userRepository.findById(id);
        });
    }
}

3. Resource Utilization (Использование ресурсов)

Определение: Процент использования доступных ресурсов.

// Мониторинг ресурсов
@Component
public class ResourceMonitor {
    private final Gauge cpuUsage;
    private final Gauge memoryUsage;
    private final Gauge diskUsage;
    
    public ResourceMonitor(MeterRegistry meterRegistry) {
        this.cpuUsage = Gauge.builder("system.cpu.usage")
            .register(meterRegistry, this, ResourceMonitor::getCpuUsage);
        this.memoryUsage = Gauge.builder("system.memory.usage")
            .register(meterRegistry, this, ResourceMonitor::getMemoryUsage);
        this.diskUsage = Gauge.builder("system.disk.usage")
            .register(meterRegistry, this, ResourceMonitor::getDiskUsage);
    }
    
    private double getCpuUsage() {
        OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
        return osBean.getProcessCpuLoad();
    }
    
    private double getMemoryUsage() {
        MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
        return (double) heapUsage.getUsed() / heapUsage.getMax();
    }
    
    private double getDiskUsage() {
        File root = new File("/");
        long totalSpace = root.getTotalSpace();
        long freeSpace = root.getFreeSpace();
        return (double) (totalSpace - freeSpace) / totalSpace;
    }
}

Производительность по уровням

1. Application Level

// Оптимизация на уровне приложения
@Service
public class OptimizedUserService {
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private UserCache userCache;
    
    // Оптимизация: кэширование
    @Cacheable("users")
    public User getUser(Long id) {
        return userRepository.findById(id);
    }
    
    // Оптимизация: batch операции
    public List<User> getUsers(List<Long> ids) {
        return userRepository.findByIdIn(ids);
    }
    
    // Оптимизация: асинхронная обработка
    @Async
    public CompletableFuture<Void> processUserAsync(User user) {
        // асинхронная обработка
        return CompletableFuture.completedFuture(null);
    }
}

2. Database Level

// Оптимизация на уровне базы данных
@Repository
public class OptimizedUserRepository {
    
    // Оптимизация: использование индексов
    @Query("SELECT u FROM User u WHERE u.email = :email")
    User findByEmail(@Param("email") String email);
    
    // Оптимизация: пагинация
    @Query("SELECT u FROM User u")
    Page<User> findAllUsers(Pageable pageable);
    
    // Оптимизация: batch операции
    @Modifying
    @Query("UPDATE User u SET u.lastLogin = :lastLogin WHERE u.id IN :ids")
    int updateLastLogin(@Param("ids") List<Long> ids, @Param("lastLogin") LocalDateTime lastLogin);
}

3. Infrastructure Level

# Оптимизация на уровне инфраструктуры
apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
      - name: user-service
        image: user-service:latest
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
        env:
        - name: JAVA_OPTS
          value: "-Xms512m -Xmx1g -XX:+UseG1GC"