← Назад к вопросам
Разворачивал ли приложение на рабочем сервере
2.0 Middle🔥 201 комментариев
#Docker, Kubernetes и DevOps#JVM и управление памятью#ORM и Hibernate
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Разворачивал ли приложение на рабочем сервере
Опыт развёртывания
Да, я имею опыт развёртывания Java приложений на рабочих серверах. Вот примеры типичных сценариев, которые я выполнял.
Пример 1: Развёртывание Spring Boot приложения на Ubuntu сервере
Шаги развёртывания:
# 1. Подключение к серверу
ssh -i /path/to/key.pem ubuntu@example.com
# 2. Установка Java (если нужна)
sudo apt-get update
sudo apt-get install openjdk-17-jdk
java -version # Проверяем версию
# 3. Создание директории приложения
sudo mkdir -p /opt/myapp
sudo chown ubuntu:ubuntu /opt/myapp
# 4. Загрузка приложения (из CI/CD или вручную)
cd /opt/myapp
wget https://releases.example.com/myapp-1.0.jar
# или скопировать файл локально:
# scp -i key.pem target/myapp-1.0.jar ubuntu@example.com:/opt/myapp/
# 5. Создание systemd сервиса
sudo nano /etc/systemd/system/myapp.service
Содержимое /etc/systemd/system/myapp.service:
[Unit]
Description=My Spring Boot Application
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/opt/myapp
# JVM параметры для оптимизации
Environment="JAVA_OPTS=-Xmx512m -Xms256m"
ExecStart=/usr/bin/java $JAVA_OPTS -jar /opt/myapp/myapp-1.0.jar
# Автозагрузка при перезагрузке сервера
Restart=always
RestartSec=5s
[Install]
WantedBy=multi-user.target
Запуск сервиса:
# Перезагружаем systemd конфигурацию
sudo systemctl daemon-reload
# Запускаем приложение
sudo systemctl start myapp
# Проверяем статус
sudo systemctl status myapp
# Разрешаем автозагрузку при перезагрузке сервера
sudo systemctl enable myapp
# Посмотреть логи
sudo journalctl -u myapp -f
Пример 2: Развёртывание с Nginx (reverse proxy)
Архитектура:
HTTP запрос (port 80/443)
|
v
Nginx (reverse proxy)
|
v
Spring Boot приложение (port 8080)
|
v
База данных
Конфигурация Nginx (/etc/nginx/sites-available/myapp):
server {
listen 80;
server_name myapp.com www.myapp.com;
# Редирект с HTTP на HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name myapp.com www.myapp.com;
# SSL сертификаты (Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/myapp.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myapp.com/privkey.pem;
# Оптимизация SSL
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Логирование
access_log /var/log/nginx/myapp_access.log;
error_log /var/log/nginx/myapp_error.log;
# Проксирование на Spring Boot приложение
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Таймауты
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
Активация конфига:
# Создаём символическую ссылку
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
# Проверяем конфигурацию
sudo nginx -t
# Перезагружаем Nginx
sudo systemctl restart nginx
# Установка SSL сертификата
sudo certbot certonly --nginx -d myapp.com -d www.myapp.com
Пример 3: Развёртывание с Docker и Docker Compose
Dockerfile приложения:
FROM openjdk:17-slim
WORKDIR /app
# Копируем JAR
COPY target/myapp-1.0.jar app.jar
# Экспортируем порт
EXPOSE 8080
# Запуск
ENTRYPOINT ["java", "-jar", "app.jar"]
Docker Compose (docker-compose.yml):
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_DB: myapp
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
myapp:
build: .
container_name: myapp
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/myapp
SPRING_DATASOURCE_USERNAME: postgres
SPRING_DATASOURCE_PASSWORD: ${DB_PASSWORD}
SPRING_JPA_HIBERNATE_DDL_AUTO: validate
ports:
- "8080:8080"
depends_on:
postgres:
condition: service_healthy
restart: always
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
nginx:
image: nginx:latest
container_name: nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- myapp
restart: always
volumes:
postgres_data:
Запуск на сервере:
# Клонируем репозиторий
git clone https://github.com/user/myapp.git
cd myapp
# Создаём .env файл
echo "DB_PASSWORD=secure_password" > .env
# Собираем приложение
mvn clean package -DskipTests
# Запускаем в фоне
docker-compose up -d
# Смотрим логи
docker-compose logs -f myapp
# Проверяем статус
docker-compose ps
Пример 4: Мониторинг и логирование в продакшене
Spring Boot конфигурация логирования (application.yml):
spring:
jpa:
hibernate:
ddl-auto: validate # ❌ Никогда не используй create/update в продакшене!
logging:
level:
root: INFO
com.myapp: DEBUG
org.springframework.web: INFO
org.hibernate.SQL: DEBUG
file:
name: /var/log/myapp/application.log
max-size: 10MB
max-history: 30
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"
management:
endpoints:
web:
exposure:
include: health,metrics,prometheus
endpoint:
health:
show-details: when-authorized
Мониторинг здоровья приложения:
# Health check
curl https://myapp.com/actuator/health
# Метрики
curl https://myapp.com/actuator/metrics
# Prometheus формат
curl https://myapp.com/actuator/prometheus
Пример 5: Обновление приложения в продакшене (Blue-Green Deploy)
# 1. Текущая версия работает на порту 8080 (Blue)
# 2. Собираем новую версию
mvn clean package -DskipTests
# 3. Запускаем на порту 8081 (Green)
java -jar target/myapp-2.0.jar --server.port=8081 &
# 4. Тестируем новую версию
curl http://localhost:8081/api/health
# 5. Если всё OK, переключаем Nginx на новую версию
# Редактируем nginx.conf:
# proxy_pass http://127.0.0.1:8081; # было 8080
sudo systemctl reload nginx
# 6. Останавливаем старую версию
kill <pid-old-app>
# 7. Откатываем обратно, если нужно:
sudo systemctl reload nginx # Переключаем на 8080
Типичные проблемы и их решение
Проблема 1: Приложение съедает всю память
Решение: Установить JVM параметры
-Xmx512m -Xms256m (максимум 512MB, минимум 256MB)
Проблема 2: Медленное выключение (graceful shutdown)
Решение: Добавить в application.yml
server.shutdown: graceful
spring.lifecycle.timeout-per-shutdown-phase: 30s
Проблема 3: БД соединения исчерпаны
Решение: Настроить connection pool
spring.datasource.hikari.maximum-pool-size: 20
spring.datasource.hikari.minimum-idle: 5
Чеклист развёртывания
- Java установлена и правильной версии
- Переменные окружения настроены (БД, API ключи)
- Логи ротируются и не заполняют диск
- SSL сертификаты установлены и не истекли
- Проверен health endpoint
- Мониторинг настроен (metrics, alerts)
- Есть план откатки (rollback strategy)
- Есть резервная копия БД перед обновлением
- Сервер имеет достаточно ресурсов (CPU, RAM, disk)
- Firewall настроен правильно
Вывод
Развёртывание Java приложений в продакшене требует:
- Понимания Linux и сетевых концепций
- Аккуратности при работе с данными
- Мониторинга и логирования для отладки проблем
- Плана откатки на случай проблем
- Документирования процесса для следующих развёртываний