Systemstart und -herunterfahren
Übersicht
PlantPulse läuft als Docker Compose Stack. Start / Herunterfahren / Neustart werden zentral über die gemeinsamen Verben in /opt/kopens/plantpulse-platform-docker/bin/ verwaltet, und die Abhängigkeitsreihenfolge zwischen den Containern wird automatisch durch depends_on von compose angewendet — der Betreiber muss sich nicht um die Reihenfolge kümmern.
Bei up.sh und restart.sh bedeutet 0 nicht „der Befehl war erfolgreich", sondern „jetzt einsatzbereit". Bei der Zugangsdaten-Rotation am 2026-08-14 kam es zu einem Vorfall, bei dem man nur „gestartet" sah und zum nächsten Schritt überging, während ein Broker noch nicht hochgefahren war und der Prozess dort hängen blieb — daraufhin wurden beide Verben so geändert, dass sie warten, bis alles bereit ist.
status.sh ist anders — 0 = normal / 2 = abnormal.
Empfohlene Betriebsbefehle (Zusammenfassung)
cd /opt/kopens/plantpulse-platform-docker/bin
./up.sh # 기동 (멱등) — 준비될 때까지 대기. 0 = 준비 완료
./down.sh # 안전 종료 (의존 순서의 역순, 상태 보존)
./restart.sh # graceful drain → 정지 → 기동 → 준비 대기
./status.sh # 서비스 / health / 볼륨 요약. 0 = 정상 / 2 = 비정상
./ops-check.sh # 헬스 + 최근 critical log
./logs.sh [서비스] # 로그 보기 — 1회 출력, -f 로 따라가기 (인자 없으면 전체)
./stack-verify-boot.sh # 스택 전체 준비 판정
./doctor.sh # 진단 tarball (시스템 변경 없음)
Alle Verben unterstützen --help. Die alten Namen (stack-run.sh · stack-stop.sh · stack-bash.sh · stack-update.sh · stack-remove.sh) funktionieren weiterhin.
| Umgebungsvariable | Standardwert | Bedeutung |
|---|---|---|
PP_READY_TIMEOUT | 900 | Obergrenze der Wartezeit auf Bereitschaft (Sekunden) |
PP_READY_INTERVAL | 15 | Prüfintervall (Sekunden) |
PP_WAIT=0 | — | Es wird nicht gewartet. 0 bedeutet in diesem Fall nicht Bereitschaft |
Startreihenfolge (automatisch)
Zwischen Containern
depends_on von compose hält die Reihenfolge mit der service_healthy-Bedingung ein — es wird nicht auf „Prozess läuft", sondern auf „einsatzbereit" gewartet. Diese Reihenfolge ist nicht willkürlich, sondern übernimmt exakt die Startreihenfolge des Applikations-Orchestrators.
Die letzten vier (warehouse · opcua · aasx · ha) haben untereinander keine Reihenfolge.
Innerhalb des Datalake-Containers
Die Infrastrukturkomponenten starten innerhalb des einen Containers plantpulse-datalake ebenfalls wieder der Reihe nach.
| Reihenfolge | Bereich | Hauptkomponenten | Repräsentative Ports |
|---|---|---|---|
| 1 | Storage | Cassandra, PostgreSQL, Valkey, MinIO | 9042 / 5432 / 6379 / 9000 |
| 2 | Analyse | Spark, Hive, Kyuubi, Gravitino | 7077 / 9083 / 10000 / 19001 |
| 3 | Zeitreihe | TSE Engine, UI | 7800 / 3000 |
| 4 | Messaging | Kafka, MQTT | 9092 / 1883 |
| 5 | Workflow | Temporal, Kestra | 7233 / 8233 / 8380 |
| 6 | Verarbeitung | CEP, Data Gateway, SQL, Monitor | 7400 / 5500 / 4000 / 4950 |
Der Prozessstart selbst dauert 3–5 Minuten (JVM-Warmup), aber bei einer Neuinstallation dauert es aufgrund der Cassandra-Schema-Migration und Stabilisierung 15–18 Minuten, bis alle Komponenten stabil sind.
Messwerte (2026-08-31, 32 vCPU / 128GiB): Datalake 217 Sekunden, Webserver 316 Sekunden. Ein Neustart mit bereits vorhandenen Daten ist deutlich schneller.
Herunterfahrreihenfolge
cd /opt/kopens/plantpulse-platform-docker/bin
./down.sh
Die Reihenfolge muss nicht manuell eingehalten werden. Da compose in umgekehrter Abhängigkeitsreihenfolge stoppt, wird zuerst die datenschreibende Seite (Apps) gestoppt und zuletzt der Datalake. Jeder Container hat eine großzügige Stoppfrist (stop_grace_period) — beim Datalake 180 Sekunden —, damit Cassandra Zeit hat, die Memtables zu flushen.
Die Volumes (pp-data · pp-temp · pp-backup · pp-security · pp-proxy-certs) bleiben unabhängig von Stopp oder Entfernen immer erhalten.
docker kill oder ein erzwungenes Herunterfahren des Hosts nichtNicht geflushte Memtable-Daten von Cassandra können dadurch verloren gehen. Verwenden Sie unbedingt ./down.sh. Wenn ein Container bereits nicht mehr reagiert, folgen Sie dem Notfallverfahren.
Neustart
Kompletter Neustart
cd /opt/kopens/plantpulse-platform-docker/bin
./restart.sh
- (Falls laufend) Anfrage eines graceful drain an den Datalake
- Stopp des gesamten Stacks in umgekehrter Abhängigkeitsreihenfolge
- Erneuter Start in der Reihenfolge
depends_on - Warten, bis bereit — bei Exit-Code
0ist der Zustand einsatzbereit
Wird verwendet bei Änderungen an bin/env.sh, Änderungen von Locale/Zeitzone, Behebung vorübergehender Probleme sowie regelmäßigen Neustarts.
Neustart nur einer einzelnen App
Da die sechs Apps jeweils in eigenen Containern laufen, bleiben die übrigen Apps und die Infrastruktur unangetastet, wenn nur dieser eine Container neu gestartet wird. Dies ist einer der Gründe, warum die Container getrennt wurden.
cd /opt/kopens/plantpulse-platform-docker
docker compose -f compose/docker-compose.yml restart plantpulse-server-web
docker compose restart hält die Abhängigkeitsreihenfolge nicht einWenn mehrere Apps gemeinsam wiederbelebt werden müssen, ist es sicherer, den gesamten Stack mit ./restart.sh neu zu starten.
Neustart nur der Infrastrukturkomponenten
./shell.sh # 데이터레이크 진입
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd restart storage
exit
Die verfügbaren Skripte sind pd restart storage · pd restart analytics · pd restart messaging · pd restart timeseries · pd restart workflow · pd restart cep · pd restart data-gateway · pd restart sql · restart-monitor.sh. Details finden Sie im Startleitfaden.
Statusprüfung
Kurzzusammenfassung
./status.sh # 0 = 정상 / 2 = 비정상
Es gibt fünf Kriterien, nach denen status.sh einen Zustand als abnormal einstuft.
| Beurteilung | Inhalt |
|---|---|
| Dienstliste kann nicht gelesen werden | compose-Auflösung fehlgeschlagen oder kein Docker-Zugriff |
| Ein von compose deklarierter Dienst hat keinen Container | nicht gestartet |
Dauerhafter Container ist nicht running | Einmalig laufende Container (plantpulse-certs) sind ausgenommen |
Health eines Dauercontainers ist unhealthy | starting / none gelten als Beurteilung ausstehend |
| Health-API meldet nicht OK | Probe innerhalb des Datalake |
Volumes und conf werden nur gemeldet, fließen aber nicht in den Exit-Code ein — da bei einer auf zwei Knoten getrennten Installation (PP_TIER=APP) das Fehlen einzelner Elemente normal ist.
Exited (0) eines Einmalcontainers bedeutet Erfolgplantpulse-certs erstellt Zertifikate und beendet sich danach selbst. Da compose den Healthcheck dieses Containers explizit deaktiviert hat (healthcheck: disable), bleibt das Health-Feld leer — würde man einem Einmalcontainer einen Health-Probe verpassen, würde ein „normal funktionierender Container" für immer als unhealthy erscheinen, und jeder müsste sich diese eine Ausnahme merken. status.sh und ops-check.sh beurteilen nur diesen Container anhand des Exit-Codes — betrachten Sie ihn bei manueller Prüfung ebenso.
Containerprüfung
docker ps # 여덟 개가 (healthy), certs 는 Exited (0)
docker stats --no-stream # 컨테이너별 CPU / 메모리
Healthcheck-API
# 호스트 / 외부에서 — 4950 이 publish 되어 있습니다
curl -kfsS https://<server-ip>:4950/api/health | jq
# 컨테이너 안에서 — 어떤 구성에서도 동작합니다
docker exec plantpulse-datalake curl -kfsS https://127.0.0.1:4950/api/health | jq
Der Wert von "status" ist nur einer von OK · WARN · FAIL, und OK/WARN liegen im Normalbereich.
Konsole und Health-API werden über beide Ports bereitgestellt — 4950 (HTTPS) und 4949 (Klartext-HTTP). Es ist dieselbe Konsole und dieselbe API, nur das Schema unterscheidet sich. 4949 leitet nicht mehr auf 4950 um.
4949 ist Klartext — Login-Passwörter und Session-Cookies fließen unverschlüsselt. In nicht vertrauenswürdigen Netzwerken verwenden Sie 4950. 4949 ist eine Option für Umgebungen, in denen Warnungen wegen selbstsignierter Zertifikate den Betreiber tatsächlich behindern.
Logprüfung
./logs.sh # 여덟 컨테이너를 시간순으로 한 화면에
./logs.sh plantpulse-server-web -n 200 # 특정 컨테이너
./logs.sh cassandra # 데이터레이크 안 컴포넌트 로그 파일
./logs.sh --list # 볼 수 있는 대상 전체
./logs.sh -f plantpulse-proxy # 계속 따라가기 (Ctrl-C 로 종료)
Standardmäßig werden die letzten N Zeilen (Standard 200) ausgegeben, danach ist Schluss. Zum Mitverfolgen fügen Sie -f hinzu.
Konfiguration des automatischen Starts
Es ist keine gesonderte Konfiguration erforderlich. Dauerhafte Container sind in compose als restart: always deklariert, sodass sie beim Hochfahren des Docker-Daemons auch nach einem Host-Neustart automatisch mitstarten. Einmalige Container (plantpulse-certs) sind restart: "no" und laufen daher nicht erneut — da sonst neue Zertifikate ausgestellt würden.
Zu prüfen ist lediglich der automatische Start des Docker-Daemons.
systemctl is-enabled docker # enabled 여야 합니다
sudo systemctl enable docker # 아니라면
Ein Host-Neustart ist der einzige Weg, bei dem die depends_on-Reihenfolge nicht angewendet wird — da alles gleichzeitig hochfährt, kann der Healthcheck des Proxy kurzzeitig fehlschlagen, bis der Webserver bereit ist (gemessenes Maximum 316 Sekunden). Da das Wiederholungsbudget auf 360 Sekunden eingestellt ist und Docker Container wegen unhealthy nicht neu startet, handelt es sich um einen von selbst behebbaren vorübergehenden Zustand.
Notfallverfahren
Web-Konsole reagiert nicht
cd /opt/kopens/plantpulse-platform-docker/bin
# 1. 어느 컨테이너가 문제인가
./status.sh
# 2. 프록시와 웹 서버 로그
./logs.sh plantpulse-proxy -n 100
./logs.sh plantpulse-server-web -n 200
# 3. 웹 서버만 재시작 (인프라는 유지)
cd /opt/kopens/plantpulse-platform-docker
docker compose -f compose/docker-compose.yml restart plantpulse-server-web
# 4. 회복되지 않으면 진단 번들
bin/doctor.sh
Der Healthcheck des Proxy prüft nur sich selbst + Erreichbarkeit des Upstream (der Gesundheitszustand des Backends wird durch den eigenen Healthcheck des Webservers beurteilt). Wenn der Proxy grün ist, aber nichts angezeigt wird, prüfen Sie plantpulse-server-web.
OOM (Out Of Memory) aufgetreten
# 1. 어느 컨테이너가 OOM 인가
docker inspect plantpulse-server-web --format '{{.State.OOMKilled}} {{.State.ExitCode}} {{.RestartCount}}'
# 2. 호스트 커널 로그
dmesg | grep -i "out of memory\|oom"
# 3. 컨테이너별 사용량
docker stats --no-stream
Jeder Container hat einen eigenen Grenzwert — der Datalake DOCKER_DATALAKE_MEMORY (Standard 80G), die Apps DOCKER_SERVER_MEMORY · DOCKER_BATCH_MEMORY usw. (Umgebungsvariablen). Nach Anpassung der Werte mit ./restart.sh übernehmen.
Jeder App einen eigenen mem_limit zuzuweisen, ist der primäre Zweck der Containertrennung. Selbst wenn eine App an ihre Grenze stößt, bleiben Infrastruktur und andere Apps am Leben.
DB-Verbindungsfehler
Alle Datenbanken befinden sich innerhalb von plantpulse-datalake.
cd /opt/kopens/plantpulse-platform-docker/bin
./shell.sh # 데이터레이크 진입
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node psql # PostgreSQL
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node cql # Cassandra
/opt/kopens/plantpulse-platform/plantpulse-datalake-cli/bin/pd node status # Cassandra 링 상태
Um nur die Infrastruktur wiederzubeleben, verwenden Sie pd restart storage innerhalb des Containers, falls das nicht hilft ./restart.sh auf dem Host.
Bei Verdacht auf Datenkorruption
cd /opt/kopens/plantpulse-platform-docker/bin
./down.sh # 즉시 정지 (추가 손상 방지)
ls -lh /data1/pp-backup/docker-volume/ # 최신 백업 확인
./doctor.sh # 진단 번들 (데이터를 임의로 수정하지 마세요)
Bitte senden Sie das erzeugte Tarball an webmaster@kopens.com.
Betriebs-Checkliste
Tägliche Prüfung
| Prüfpunkt | Befehl / Prüfmethode | Normalkriterium |
|---|---|---|
| Gesamtstatus der Dienste | ./status.sh | Exit-Code 0 |
| Betriebs-Health | ./ops-check.sh | keine kritischen Log-Einträge |
| Health-API | curl -kfsS https://<server-ip>:4950/api/health | status ist OK oder WARN |
| Container | docker ps | acht (healthy), certs ist Exited (0) |
| Festplattennutzung | df -h /data1 | Auslastung unter 80% |
| Container-Ressourcen | docker stats --no-stream | ausreichend Spielraum gegenüber Grenzwerten |
| Cassandra-Status | pd node status innerhalb des Containers | alle Knoten UN (Up/Normal) |
Wöchentliche Prüfung
| Prüfpunkt | Befehl / Prüfmethode | Normalkriterium |
|---|---|---|
| Cassandra Compaction | pd node compactionstats innerhalb des Containers | keine übermäßig anstehenden Aufgaben |
| Cassandra-Tabellen | pd node table-stats innerhalb des Containers | kein abnormales Wachstum |
| Kafka Topics / Lag | pd node topic innerhalb des Containers | Anzahl verzögerter Nachrichten im Normalbereich |
| Backup-Prüfung | ls -lh /data1/pp-backup/docker-volume/ | gültiges Backup vorhanden |
| Docker-Nutzung | docker system df | keine Ansammlung ungenutzter Images |
| Logvolumen | du -sh /opt/kopens/plantpulse-platform-docker/logs | kein abnormales Wachstum |
| Sicherheitsupdates | Prüfung auf OS-Paket-Updates | keine bekannten Schwachstellen |
Binäre (native) Umgebung
Der folgende Inhalt bleibt für bestehende Systeme, die mit binärer Installation aufgebaut wurden, erhalten. Da die aktuelle Auslieferung ausschließlich den oben beschriebenen Docker Compose Stack umfasst, verwenden Sie die folgenden Verfahren (systemd-Dienst, Windows-Dienst, einzelner Prozessstart) nicht in einer Containerumgebung.
In der binären Umgebung befinden sich die Betriebsskripte in /opt/kopens/plantpulse-platform/plantpulse-startup/ — start-daemon.sh · stop.sh · restart.sh · status.sh · kill.sh · log-viewer.sh. Details finden Sie unter Binäre Installation.
Linux-Start (systemd)
Falls ein systemd-Dienst registriert ist, kann mit folgendem Befehl gestartet werden.
# 1. 스토리지 서비스 시작
sudo systemctl start plantpulse-postgresql
sudo systemctl start plantpulse-redis
sudo systemctl start plantpulse-cassandra
# Cassandra가 완전히 시작될 때까지 대기 (약 30~60초)
until cqlsh 127.0.0.1 -e "DESCRIBE KEYSPACES" > /dev/null 2>&1; do
echo "Cassandra 시작 대기 중..."
sleep 5
done
echo "Cassandra 시작 완료"
# 2. 메시징 서비스 시작
sudo systemctl start plantpulse-kafka
sudo systemctl start plantpulse-mqtt
# 3. 엔진 서비스 시작
sudo systemctl start plantpulse-timeseries
sudo systemctl start plantpulse-cep
# 4. 웹서버 시작
sudo systemctl start plantpulse-server
# 5. 에이전트 시작
sudo systemctl start plantpulse-agent
Manueller Linux-Start
Wenn kein systemd verwendet wird, können die Startskripte der einzelnen Module direkt ausgeführt werden.
# 스토리지
/opt/kopens/plantpulse-platform/plantpulse-storage/db/postgres/bin/pg_ctl start -D /opt/kopens/plantpulse-platform/plantpulse-storage/db/postgres/data
/opt/kopens/plantpulse-platform/plantpulse-storage/db/valkey/bin/valkey-server /opt/kopens/plantpulse-platform/plantpulse-storage/db/valkey/conf/valkey.conf &
/opt/kopens/plantpulse-platform/plantpulse-storage/db/cassandra/bin/cassandra
# 메시징
/opt/kopens/plantpulse-platform/plantpulse-messaging/kafka/bin/kafka-server-start.sh -daemon /opt/kopens/plantpulse-platform/plantpulse-messaging/kafka/config/server.properties
/opt/kopens/plantpulse-platform/plantpulse-messaging/mqtt/bin/startup.sh
# 엔진
/opt/kopens/plantpulse-platform/plantpulse-timeseries/bin/startup.sh
/opt/kopens/plantpulse-platform/plantpulse-cep/bin/startup.sh
# 웹서버
/opt/kopens/plantpulse-platform/plantpulse-server/bin/startup.sh
# 에이전트
/opt/kopens/plantpulse-platform/plantpulse-plugin/opc-ua/bin/startup.sh
Startskript (mit Abhängigkeitsprüfung)
Nachfolgend ein Beispielskript, das Abhängigkeiten prüft und die Dienste nacheinander startet.
#!/bin/bash
# plantpulse-start-all.sh - 전체 플랫폼 시작 스크립트
KOPENS_HOME="/opt/kopens"
LOG_FILE="/var/log/plantpulse/startup.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
wait_for_port() {
local host=$1 port=$2 timeout=${3:-60}
local elapsed=0
while ! nc -z "$host" "$port" 2>/dev/null; do
if [ $elapsed -ge $timeout ]; then
log "ERROR: $host:$port 연결 타임아웃 (${timeout}초)"
return 1
fi
sleep 2
elapsed=$((elapsed + 2))
done
log "OK: $host:$port 연결 확인"
return 0
}
# 1. PostgreSQL
log "PostgreSQL 시작 중..."
sudo systemctl start plantpulse-postgresql
wait_for_port 127.0.0.1 5432 30 || exit 1
# 2. Redis
log "Redis 시작 중..."
sudo systemctl start plantpulse-redis
wait_for_port 127.0.0.1 6379 15 || exit 1
# 3. Cassandra
log "Cassandra 시작 중..."
sudo systemctl start plantpulse-cassandra
wait_for_port 127.0.0.1 9042 120 || exit 1
# 4. Kafka & MQTT
log "Kafka 시작 중..."
sudo systemctl start plantpulse-kafka
wait_for_port 127.0.0.1 9092 30 || exit 1
log "MQTT 시작 중..."
sudo systemctl start plantpulse-mqtt
wait_for_port 127.0.0.1 1883 15 || exit 1
# 5. TSE
log "시계열 엔진 시작 중..."
sudo systemctl start plantpulse-timeseries
wait_for_port 127.0.0.1 7800 30 || exit 1
# 6. CEP
log "CEP 엔진 시작 중..."
sudo systemctl start plantpulse-cep
wait_for_port 127.0.0.1 7400 30 || exit 1
# 7. 웹서버
log "PlantPulse 웹서버 시작 중..."
sudo systemctl start plantpulse-server
wait_for_port 127.0.0.1 80 60 || exit 1
# 8. OPC Agent
log "OPC Agent 시작 중..."
sudo systemctl start plantpulse-agent
wait_for_port 127.0.0.1 60000 30 || exit 1
log "전체 플랫폼 시작 완료"
Windows-Start
Windows-Dienst
Wenn in der Windows-Umgebung als Dienst registriert, kann der Start über den Dienstmanager (services.msc) oder die Eingabeaufforderung erfolgen.
# 서비스 시작 (관리자 권한 PowerShell)
Start-Service PlantPulse-PostgreSQL
Start-Service PlantPulse-Redis
Start-Service PlantPulse-Cassandra
Start-Service PlantPulse-Kafka
Start-Service PlantPulse-MQTT
Start-Service PlantPulse-TSE
Start-Service PlantPulse-CEP
Start-Service PlantPulse-Server
Start-Service PlantPulse-Agent
Start über Batch-Datei
@echo off
REM plantpulse-start-all.bat - 전체 시작 배치 파일
echo [%date% %time%] PostgreSQL 시작 중...
net start PlantPulse-PostgreSQL
timeout /t 10 /nobreak > nul
echo [%date% %time%] Redis 시작 중...
net start PlantPulse-Redis
timeout /t 5 /nobreak > nul
echo [%date% %time%] Cassandra 시작 중...
net start PlantPulse-Cassandra
timeout /t 60 /nobreak > nul
echo [%date% %time%] Kafka 시작 중...
net start PlantPulse-Kafka
timeout /t 10 /nobreak > nul
echo [%date% %time%] MQTT 시작 중...
net start PlantPulse-MQTT
timeout /t 5 /nobreak > nul
echo [%date% %time%] 시계열 엔진 시작 중...
net start PlantPulse-TSE
timeout /t 10 /nobreak > nul
echo [%date% %time%] CEP 시작 중...
net start PlantPulse-CEP
timeout /t 10 /nobreak > nul
echo [%date% %time%] 웹서버 시작 중...
net start PlantPulse-Server
timeout /t 30 /nobreak > nul
echo [%date% %time%] OPC Agent 시작 중...
net start PlantPulse-Agent
timeout /t 10 /nobreak > nul
echo [%date% %time%] 전체 시작 완료
pause
Herunterfahrreihenfolge
Das Herunterfahren muss in umgekehrter Reihenfolge zum Start erfolgen. Zuerst werden die datenerfassenden Agenten heruntergefahren, zuletzt die Datenbank.
| Reihenfolge | Dienst | Beschreibung |
|---|---|---|
| 1 | OPC Agent | Stopp der Datenerfassung |
| 2 | PlantPulse-Webserver (Tomcat) | Stopp des Webdienstes |
| 3 | CEP | Stopp der Ereignisverarbeitung |
| 4 | TSE | Stopp der Zeitreihen-Engine |
| 5 | MQ (Kafka / MQTT) | Stopp des Message-Brokers |
| 6 | Cassandra | Stopp der Zeitreihen-DB |
| 7 | Redis (Valkey) | Stopp des Caches |
| 8 | PostgreSQL | Stopp der Meta-DB |
Achtung: Wird Cassandra vor den anderen Diensten heruntergefahren, können noch nicht geflushte Memtable-Daten verloren gehen. Beenden Sie unbedingt zuerst Agent und Webserver, um Schreibvorgänge zu stoppen, bevor Sie Cassandra herunterfahren. Vor dem Herunterfahren von Cassandra wird empfohlen, mit dem Befehl
nodetool draindie Memtables zwangsweise zu flushen.
Linux-Herunterfahrbefehle
# 1. 에이전트 종료
sudo systemctl stop plantpulse-agent
# 2. 웹서버 종료
sudo systemctl stop plantpulse-server
# 3. 엔진 종료
sudo systemctl stop plantpulse-cep
sudo systemctl stop plantpulse-timeseries
# 4. 메시징 종료
sudo systemctl stop plantpulse-mqtt
sudo systemctl stop plantpulse-kafka
# 5. Cassandra 안전 종료 (Memtable 플러시 후 종료)
/opt/kopens/plantpulse-platform/plantpulse-storage/db/cassandra/bin/nodetool drain
sudo systemctl stop plantpulse-cassandra
# 6. Redis 종료
sudo systemctl stop plantpulse-redis
# 7. PostgreSQL 종료
sudo systemctl stop plantpulse-postgresql
Windows-Herunterfahrbefehle
# 역순으로 서비스 중지 (관리자 권한 PowerShell)
Stop-Service PlantPulse-Agent
Stop-Service PlantPulse-Server
Stop-Service PlantPulse-CEP
Stop-Service PlantPulse-TSE
Stop-Service PlantPulse-MQTT
Stop-Service PlantPulse-Kafka
Stop-Service PlantPulse-Cassandra
Stop-Service PlantPulse-Redis
Stop-Service PlantPulse-PostgreSQL
@echo off
REM plantpulse-stop-all.bat - 전체 종료 배치 파일
echo [%date% %time%] OPC Agent 종료 중...
net stop PlantPulse-Agent
timeout /t 5 /nobreak > nul
echo [%date% %time%] 웹서버 종료 중...
net stop PlantPulse-Server
timeout /t 10 /nobreak > nul
echo [%date% %time%] CEP 종료 중...
net stop PlantPulse-CEP
timeout /t 5 /nobreak > nul
echo [%date% %time%] 시계열 엔진 종료 중...
net stop PlantPulse-TSE
timeout /t 5 /nobreak > nul
echo [%date% %time%] MQTT 종료 중...
net stop PlantPulse-MQTT
timeout /t 5 /nobreak > nul
echo [%date% %time%] Kafka 종료 중...
net stop PlantPulse-Kafka
timeout /t 10 /nobreak > nul
echo [%date% %time%] Cassandra 종료 중...
net stop PlantPulse-Cassandra
timeout /t 30 /nobreak > nul
echo [%date% %time%] Redis 종료 중...
net stop PlantPulse-Redis
timeout /t 5 /nobreak > nul
echo [%date% %time%] PostgreSQL 종료 중...
net stop PlantPulse-PostgreSQL
timeout /t 10 /nobreak > nul
echo [%date% %time%] 전체 종료 완료
pause
Neustart
Normaler Neustart
Um die gesamte Plattform neu zu starten, führen Sie erst das Herunterfahren, dann den Start durch.
# 전체 종료 (역순)
sudo systemctl stop plantpulse-agent
sudo systemctl stop plantpulse-server
sudo systemctl stop plantpulse-cep
sudo systemctl stop plantpulse-timeseries
sudo systemctl stop plantpulse-mqtt
sudo systemctl stop plantpulse-kafka
/opt/kopens/plantpulse-platform/plantpulse-storage/db/cassandra/bin/nodetool drain
sudo systemctl stop plantpulse-cassandra
sudo systemctl stop plantpulse-redis
sudo systemctl stop plantpulse-postgresql
# 전체 시작 (정순)
sudo systemctl start plantpulse-postgresql
sudo systemctl start plantpulse-redis
sudo systemctl start plantpulse-cassandra
sleep 60 # Cassandra 시작 대기
sudo systemctl start plantpulse-kafka
sudo systemctl start plantpulse-mqtt
sudo systemctl start plantpulse-timeseries
sudo systemctl start plantpulse-cep
sudo systemctl start plantpulse-server
sudo systemctl start plantpulse-agent
Rolling Restart (unterbrechungsfreier Neustart)
In Clusterumgebungen kann ein Rolling Restart durchgeführt werden, bei dem die Knoten nacheinander ohne Dienstunterbrechung neu gestartet werden.
#!/bin/bash
# rolling-restart.sh - 클러스터 Rolling Restart
# 사용법: ./rolling-restart.sh node1 node2 node3
NODES=("$@")
for NODE in "${NODES[@]}"; do
echo "=== $NODE 재시작 시작 ==="
# 1. 로드밸런서에서 노드 제거
echo "$NODE 로드밸런서에서 제거 중..."
# curl -X POST http://loadbalancer/api/remove-node -d "node=$NODE"
# 2. 연결 드레인 대기 (기존 요청 처리 완료 대기)
echo "기존 연결 드레인 대기 (30초)..."
sleep 30
# 3. 서비스 재시작
echo "$NODE 서비스 재시작 중..."
ssh "$NODE" "sudo systemctl restart plantpulse-server"
# 4. 헬스체크 통과 대기
echo "$NODE 헬스체크 대기 중..."
until ssh "$NODE" "curl -sf http://localhost/api/v5/ping > /dev/null 2>&1"; do
sleep 5
done
# 5. 로드밸런서에 노드 재등록
echo "$NODE 로드밸런서에 재등록 중..."
# curl -X POST http://loadbalancer/api/add-node -d "node=$NODE"
echo "=== $NODE 재시작 완료 ==="
echo "다음 노드 진행 전 안정화 대기 (60초)..."
sleep 60
done
echo "Rolling Restart 완료"
Hinweis: Rolling Restart wird auf den Webserver (Tomcat) angewendet. Für den Rolling Restart des Cassandra-Clusters führen Sie nach
nodetool draindie Knoten nacheinander neu gestartet durch.
Statusprüfung
Prozessprüfung
# 전체 PlantPulse 관련 프로세스 확인
ps aux | grep plantpulse
# 특정 서비스 프로세스 확인
ps aux | grep plantpulse-server
ps aux | grep cassandra
ps aux | grep kafka
Portprüfung
# 핵심 포트 한 번에 확인
for port in 5432 6379 9042 9092 1883 7800 7400 80 60000; do
if nc -z 127.0.0.1 $port 2>/dev/null; then
echo "OK: 포트 $port 열림"
else
echo "FAIL: 포트 $port 닫힘"
fi
done
Healthcheck-API
Der PlantPulse-Webserver stellt einen Healthcheck über den Endpunkt /api/v5/ping bereit.
# 기본 헬스체크
curl -sf http://localhost/api/v5/ping
# 응답: {"status":"OK","timestamp":1709884800000}
# HTTP 상태 코드만 확인
curl -sf -o /dev/null -w "%{http_code}" http://localhost/api/v5/ping
# 200이면 정상
Logprüfung
# PlantPulse 웹서버 로그
tail -f /opt/kopens/plantpulse-platform/plantpulse-server/logs/system.log
# Cassandra 로그
tail -f /opt/kopens/plantpulse-platform/plantpulse-storage/db/cassandra/logs/system.log
# Kafka 로그
tail -f /opt/kopens/plantpulse-platform/plantpulse-messaging/kafka/logs/server.log
# 에이전트 로그
tail -f /opt/kopens/plantpulse-platform/plantpulse-plugin/opc-ua/logs/agent.log
# 시작 시 에러 로그만 필터링
grep -i "error\|exception\|fail" /opt/kopens/plantpulse-platform/plantpulse-server/logs/system.log | tail -20
JVM-Statusprüfung
# Java 프로세스 목록 확인
jps -lv
# PlantPulse 서버 힙 메모리 확인
jstat -gc $(pgrep -f plantpulse-server) 1000 5
# GC 로그 확인
tail -f /opt/kopens/plantpulse-platform/plantpulse-server/logs/gc.log
# 스레드 덤프 (문제 진단 시)
jstack $(pgrep -f plantpulse-server) > /tmp/thread-dump-$(date +%Y%m%d%H%M%S).txt
Status des systemd-Dienstes
# 전체 PlantPulse 서비스 상태 확인
systemctl list-units 'plantpulse-*' --all
# 특정 서비스 상세 상태
sudo systemctl status plantpulse-server
sudo systemctl status plantpulse-cassandra
Konfiguration des automatischen Starts
Linux (systemd enable)
Konfiguration, damit der Dienst beim Booten des Servers automatisch startet.
# 자동 시작 활성화
sudo systemctl enable plantpulse-postgresql
sudo systemctl enable plantpulse-redis
sudo systemctl enable plantpulse-cassandra
sudo systemctl enable plantpulse-kafka
sudo systemctl enable plantpulse-mqtt
sudo systemctl enable plantpulse-timeseries
sudo systemctl enable plantpulse-cep
sudo systemctl enable plantpulse-server
sudo systemctl enable plantpulse-agent
# 자동 시작 상태 확인
systemctl list-unit-files 'plantpulse-*' | grep enabled
Hinweis: Wenn Sie in der systemd-Unit-Datei die Direktive
After=verwenden, um Abhängigkeiten in der Startreihenfolge zwischen Diensten festzulegen, werden diese auch beim Booten in der richtigen Reihenfolge gestartet. Beispiel:[Unit]Description=PlantPulse ServerAfter=plantpulse-postgresql.service plantpulse-redis.service plantpulse-cassandra.serviceRequires=plantpulse-postgresql.service plantpulse-redis.service[Service]Type=forkingUser=kopensExecStart=/opt/kopens/plantpulse-platform/plantpulse-server/bin/startup.shExecStop=/opt/kopens/plantpulse-platform/plantpulse-server/bin/shutdown.shRestart=on-failureRestartSec=10[Install]WantedBy=multi-user.target
Automatischer Start des Windows-Dienstes
# 서비스 자동 시작 설정
Set-Service -Name "PlantPulse-PostgreSQL" -StartupType Automatic
Set-Service -Name "PlantPulse-Redis" -StartupType Automatic
Set-Service -Name "PlantPulse-Cassandra" -StartupType Automatic
Set-Service -Name "PlantPulse-Kafka" -StartupType Automatic
Set-Service -Name "PlantPulse-Server" -StartupType Automatic
Set-Service -Name "PlantPulse-Agent" -StartupType Automatic
# 자동 시작 상태 확인
Get-Service PlantPulse-* | Select-Object Name, StartType, Status
Notfallverfahren
Server reagiert nicht
Wenn der Webserver nicht reagiert, gehen Sie in folgender Reihenfolge vor.
# 1. 헬스체크 확인
curl -sf --connect-timeout 5 http://localhost/api/v5/ping
echo "HTTP 응답 코드: $?"
# 2. 프로세스 상태 확인
ps aux | grep plantpulse-server
# 3. 포트 점유 확인
ss -tlnp | grep ':80'
# 4. 스레드 덤프 (행(hang) 의심 시)
jstack $(pgrep -f plantpulse-server) > /tmp/thread-dump-$(date +%Y%m%d%H%M%S).txt
# 5. GC 상태 확인
jstat -gcutil $(pgrep -f plantpulse-server) 1000 3
# 6. 웹서버만 재시작 (다른 서비스는 유지)
sudo systemctl restart plantpulse-server
# 7. 재시작 후 헬스체크 확인
sleep 30
curl -sf http://localhost/api/v5/ping
OOM (Out Of Memory) aufgetreten
# 1. OOM 발생 확인
dmesg | grep -i "out of memory\|oom"
# 2. 힙 덤프 확인 (자동 생성된 경우)
ls -la /opt/kopens/plantpulse-platform/plantpulse-server/logs/heapdump*
# 3. 메모리 사용량 확인
free -h
ps aux --sort=-%mem | head -10
# 4. JVM 힙 크기 조정 (catalina.sh 또는 setenv.sh)
# JAVA_OPTS="-Xms4g -Xmx8g -XX:+HeapDumpOnOutOfMemoryError"
# 설정 변경 후 재시작
sudo systemctl restart plantpulse-server
DB-Verbindungsfehler
# 1. PostgreSQL 연결 확인
psql -h 127.0.0.1 -U plantpulse -d plantpulse -c "SELECT 1"
# 2. Cassandra 연결 확인
cqlsh 127.0.0.1 -e "DESCRIBE KEYSPACES"
# 3. Redis 연결 확인
redis-cli -h 127.0.0.1 ping
# 4. 연결 수 확인 (PostgreSQL)
psql -h 127.0.0.1 -U plantpulse -d plantpulse -c "SELECT count(*) FROM pg_stat_activity"
# 5. DB 서비스 재시작 (필요 시)
# 주의: DB 재시작 전 반드시 웹서버와 에이전트를 먼저 종료해 주세요
sudo systemctl stop plantpulse-agent
sudo systemctl stop plantpulse-server
sudo systemctl restart plantpulse-postgresql
sudo systemctl start plantpulse-server
sudo systemctl start plantpulse-agent
Betriebs-Checkliste
Tägliche Prüfung
| Prüfpunkt | Befehl / Prüfmethode | Normalkriterium |
|---|---|---|
| Gesamtstatus der Dienste | systemctl list-units 'plantpulse-*' | alle Dienste active (running) |
| Prüfung der Kernports | Portprüfskript (siehe oben) | alle Ports geöffnet |
| Healthcheck-API | curl http://localhost/api/v5/ping | HTTP 200, Status OK |
| Festplattennutzung | df -h | Auslastung unter 80% |
| Speichernutzung | free -h | Auslastung unter 85% |
| Fehlerprotokolle | grep ERROR plantpulse.log | tail -20 | keine wiederkehrenden Fehler |
| Cassandra-Status | nodetool status | alle Knoten UN (Up/Normal) |
Wöchentliche Prüfung
| Prüfpunkt | Befehl / Prüfmethode | Normalkriterium |
|---|---|---|
| Cassandra Compaction | nodetool compactionstats | keine übermäßig anstehenden Aufgaben |
| PostgreSQL-Statistik | Abfrage von pg_stat_activity | keine übermäßigen Idle-Verbindungen |
| Kafka Consumer Lag | kafka-consumer-groups.sh --describe | Anzahl verzögerter Nachrichten im Normalbereich |
| JVM-GC-Statistik | jstat -gcutil | niedrige Häufigkeit von Full GC |
| Backup-Prüfung | Prüfung der letzten Backup-Dateien | gültiges Backup vorhanden |
| Logdateivolumen | du -sh */logs/ | kein abnormales Wachstum |
| Sicherheitsupdates | Prüfung auf OS-Paket-Updates | keine bekannten Schwachstellen |