← Назад к вопросам

Производишь ли деплой правок кода при изменении в приложении

1.0 Junior🔥 161 комментариев
#Docker, Kubernetes и DevOps#Soft Skills и карьера

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Производишь ли деплой правок кода при изменении в приложении

Краткий ответ

Да, правки кода требуют деплоя в production, но процесс зависит от архитектуры, типа изменений и используемой стратегии доставки. Это не просто скопировать .jar файл - это полный цикл с тестированием, контролем версий и мониторингом.

1. Процесс деплоя: общий цикл

Этапы разработки → production

Кодирование → Commit → Pull Request → Code Review → 
Testing (Unit, Integration, E2E) → Merge → CI/CD Pipeline → 
Build → Artifact Repository → Staging → Smoke Tests → 
Production Deployment → Monitoring → Rollback (если нужно)

2. CI/CD Pipeline для Java приложения

Пример с Jenkins + Docker

// Jenkinsfile - весь процесс деплоя автоматизирован
pipeline {
    agent any
    
    environment {
        REGISTRY = 'docker.io'
        IMAGE_NAME = 'myapp'
        VERSION = "${BUILD_NUMBER}"
        DOCKER_TAG = "${REGISTRY}/${IMAGE_NAME}:${VERSION}"
    }
    
    stages {
        stage('Checkout') {
            steps {
                // Получить код из Git
                checkout scm
            }
        }
        
        stage('Build') {
            steps {
                script {
                    sh '''
                        ./mvnw clean package -DskipTests
                    '''
                }
            }
        }
        
        stage('Test') {
            steps {
                script {
                    sh '''
                        ./mvnw test
                        ./mvnw verify
                    '''
                }
            }
        }
        
        stage('Docker Build') {
            steps {
                script {
                    sh '''
                        docker build -t ${DOCKER_TAG} .
                        docker push ${DOCKER_TAG}
                    '''
                }
            }
        }
        
        stage('Deploy to Staging') {
            steps {
                script {
                    sh '''
                        kubectl set image deployment/myapp-staging \\
                        myapp-staging=${DOCKER_TAG} -n staging
                    '''
                }
            }
        }
        
        stage('Smoke Tests') {
            steps {
                script {
                    sh '''
                        curl -f http://staging.myapp.com/health || exit 1
                    '''
                }
            }
        }
        
        stage('Approve for Production') {
            when {
                branch 'main'
            }
            steps {
                input 'Deploy to Production?'
            }
        }
        
        stage('Deploy to Production') {
            when {
                branch 'main'
            }
            steps {
                script {
                    sh '''
                        kubectl set image deployment/myapp-prod \\
                        myapp-prod=${DOCKER_TAG} -n production \\
                        --record
                    '''
                }
            }
        }
        
        stage('Monitor') {
            steps {
                script {
                    sh '''
                        # Проверить метрики и логи
                        sleep 60
                        ./check_health.sh
                    '''
                }
            }
        }
    }
    
    post {
        failure {
            // Откат при ошибке
            script {
                sh 'kubectl rollout undo deployment/myapp-prod -n production'
            }
        }
    }
}

3. Типы деплоев в зависимости от изменений

Hot Reload (без перезагрузки JVM)

// Для development окружения - Spring DevTools
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

// pom.xml
// <dependency>
//     <groupId>org.springframework.boot</groupId>
//     <artifactId>spring-boot-devtools</artifactId>
//     <optional>true</optional>
// </dependency>

// При сохранении файла DevTools перезагружает контекст приложения
// Это НЕ требует перестартка, но работает ТОЛЬКО в development

Blue-Green Deployment

// Две идентичные версии приложения
public class DeploymentStrategy {
    /*
     * Blue (текущая production версия)
     * Green (новая версия)
     * 
     * 1. Деплоим новую версию на Green
     * 2. Запускаем тесты
     * 3. Переводим трафик с Blue на Green (instant switch)
     * 4. Blue остаётся backup для быстрого откката
     * 
     * Минусы нет downtime, моментальный откат
     */
}

Canary Deployment

#!/bin/bash
# 10% трафика на новую версию, остальное на старую

kubectl set image deployment/myapp-canary myapp=myapp:new-version

# Постепенно увеличиваем процент
kubectl patch service myapp -p \
  '{"spec":{"selector":{"version":"canary"}}}' \
  --type merge

# Мониторим метрики ошибок
sleep 5m

if curl -f http://myapp.com/metrics | grep -q 'error_rate < 1%'; then
    # Откатить старую версию
    kubectl delete deployment myapp-stable
else
    # Откатить новую версию
    kubectl rollout undo deployment/myapp-canary
fi

4. Rolling Update

# kubernetes deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Один pod с новой версией
      maxUnavailable: 0  # Ноль старых pods (без downtime)
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:v2.0.1
        readinessProbe:  # Проверка перед добавлением в балансировщик
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 5

5. Database Migrations во время деплоя

// Flyway для миграций
// src/main/resources/db/migration/V1__Initial_schema.sql

// Spring Boot автоматически применит миграции при старте
@Configuration
public class DatabaseConfiguration {
    @Bean
    public Flyway flyway(DataSource dataSource) {
        Flyway flyway = Flyway.configure()
            .dataSource(dataSource)
            .locations("classpath:db/migration")
            .baselineOnMigrate(true)
            .load();
        flyway.migrate();  // Применить миграции
        return flyway;
    }
}

Правила для миграций

-- ✅ ХОРОШО - совместимо с старой версией
ALTER TABLE users ADD COLUMN email VARCHAR(255);

-- ✅ ХОРОШО - миграция вперёд-назад
ALTER TABLE users RENAME COLUMN phone TO phone_number;

-- ❌ ПЛОХО - удаление поля может сломать старый код
ALTER TABLE users DROP COLUMN phone;

-- ❌ ПЛОХО - обязательное поле без значения по умолчанию
ALTER TABLE users ADD COLUMN status VARCHAR(50) NOT NULL;

-- ✅ ПРАВИЛЬНО
ALTER TABLE users ADD COLUMN status VARCHAR(50) DEFAULT 'active';

6. Версионирование и Artifacts

// pom.xml - semantic versioning
<version>2.1.0</version>

// В коде - версию можно получить
@Component
public class VersionInfo {
    @Value("${project.version}")
    private String version;
    
    @GetMapping("/version")
    public String getVersion() {
        return version;
    }
}

// Artifacts хранятся в Nexus/Artifactory
// myapp-2.1.0.jar
// myapp-2.1.0-SNAPSHOT.jar (development)

7. Zero-Downtime Deployment

// Graceful shutdown
@Configuration
public class ShutdownConfiguration {
    @Bean
    public GracefulShutdown gracefulShutdown() {
        return new GracefulShutdown();
    }
}

public class GracefulShutdown {
    public void shutdown() {
        // 1. Убрать из балансировщика
        deregisterFromLoadBalancer();
        
        // 2. Дать время активным запросам завершиться
        Thread.sleep(30000);  // 30 секунд
        
        // 3. Закрыть connection pools
        closeConnections();
        
        // 4. Остановить JVM
        System.exit(0);
    }
}

8. Мониторинг после деплоя

// Метрики для проверки здоровья
@RestController
@RequestMapping("/actuator")
public class HealthController {
    @GetMapping("/health")
    public HealthStatus health() {
        return new HealthStatus(
            "UP",
            DatabaseStatus.OK,
            CacheStatus.OK,
            ExternalServiceStatus.OK
        );
    }
}

// Логирование изменений
@RestController
public class DeploymentInfoController {
    @GetMapping("/deploy-info")
    public DeploymentInfo getInfo() {
        return new DeploymentInfo(
            "2.1.0",
            "2024-03-22T10:30:00Z",
            "john.doe",
            "Fix critical bug in payment processing"
        );
    }
}

Практический процесс в реальной компании

  1. Code Review - все изменения проверяются коллегами
  2. Merge в main - только после одобрения
  3. CI/CD запускается автоматически
  4. Деплой в staging - тестовое окружение
  5. Smoke tests - базовые проверки
  6. Manual approval - DevOps одобряет production деплой
  7. Production deployment - через Kubernetes/Docker
  8. Мониторинг и логи - 24/7 наблюдение
  9. Rollback - если что-то пошло не так

Ключевые моменты

  • Деплой - это не копирование файлов, а полный цикл
  • Стратегии: Blue-Green, Canary, Rolling Update
  • База данных: миграции должны быть совместимы с обеими версиями
  • Откат должен быть быстрым (не более 5 минут)
  • Мониторинг - самая важная часть
  • Zero-downtime - стандарт для production
  • Каждый деплой должен быть воспроизводим и документирован