Zum Hauptinhalt springen

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.

Die Bedeutung von Exit-Code 0 ist unterschiedlich

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.

UmgebungsvariableStandardwertBedeutung
PP_READY_TIMEOUT900Obergrenze der Wartezeit auf Bereitschaft (Sekunden)
PP_READY_INTERVAL15Prüfintervall (Sekunden)
PP_WAIT=0Es 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.

ReihenfolgeBereichHauptkomponentenRepräsentative Ports
1StorageCassandra, PostgreSQL, Valkey, MinIO9042 / 5432 / 6379 / 9000
2AnalyseSpark, Hive, Kyuubi, Gravitino7077 / 9083 / 10000 / 19001
3ZeitreiheTSE Engine, UI7800 / 3000
4MessagingKafka, MQTT9092 / 1883
5WorkflowTemporal, Kestra7233 / 8233 / 8380
6VerarbeitungCEP, Data Gateway, SQL, Monitor7400 / 5500 / 4000 / 4950
Dauer

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.

Verwenden Sie docker kill oder ein erzwungenes Herunterfahren des Hosts nicht

Nicht 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
  1. (Falls laufend) Anfrage eines graceful drain an den Datalake
  2. Stopp des gesamten Stacks in umgekehrter Abhängigkeitsreihenfolge
  3. Erneuter Start in der Reihenfolge depends_on
  4. Warten, bis bereit — bei Exit-Code 0 ist 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 ein

Wenn 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.

BeurteilungInhalt
Dienstliste kann nicht gelesen werdencompose-Auflösung fehlgeschlagen oder kein Docker-Zugriff
Ein von compose deklarierter Dienst hat keinen Containernicht gestartet
Dauerhafter Container ist nicht runningEinmalig laufende Container (plantpulse-certs) sind ausgenommen
Health eines Dauercontainers ist unhealthystarting / none gelten als Beurteilung ausstehend
Health-API meldet nicht OKProbe 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.

Der Exited (0) eines Einmalcontainers bedeutet Erfolg

plantpulse-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.

Auch über 4949 wird dieselbe API ausgeliefert

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 # 아니라면
Direkt nach einem Neustart kann der Proxy kurzzeitig rot erscheinen

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
Wenn der Proxy grün ist, der Bildschirm aber 502 zeigt

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.

Ein OOM einer App bringt nicht das gesamte System zum Absturz

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üfpunktBefehl / PrüfmethodeNormalkriterium
Gesamtstatus der Dienste./status.shExit-Code 0
Betriebs-Health./ops-check.shkeine kritischen Log-Einträge
Health-APIcurl -kfsS https://<server-ip>:4950/api/healthstatus ist OK oder WARN
Containerdocker psacht (healthy), certs ist Exited (0)
Festplattennutzungdf -h /data1Auslastung unter 80%
Container-Ressourcendocker stats --no-streamausreichend Spielraum gegenüber Grenzwerten
Cassandra-Statuspd node status innerhalb des Containersalle Knoten UN (Up/Normal)

Wöchentliche Prüfung

PrüfpunktBefehl / PrüfmethodeNormalkriterium
Cassandra Compactionpd node compactionstats innerhalb des Containerskeine übermäßig anstehenden Aufgaben
Cassandra-Tabellenpd node table-stats innerhalb des Containerskein abnormales Wachstum
Kafka Topics / Lagpd node topic innerhalb des ContainersAnzahl verzögerter Nachrichten im Normalbereich
Backup-Prüfungls -lh /data1/pp-backup/docker-volume/gültiges Backup vorhanden
Docker-Nutzungdocker system dfkeine Ansammlung ungenutzter Images
Logvolumendu -sh /opt/kopens/plantpulse-platform-docker/logskein abnormales Wachstum
SicherheitsupdatesPrüfung auf OS-Paket-Updateskeine bekannten Schwachstellen

Binäre (native) Umgebung

Die aktuelle Version unterstützt keine binäre (native) Installation

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.

ReihenfolgeDienstBeschreibung
1OPC AgentStopp der Datenerfassung
2PlantPulse-Webserver (Tomcat)Stopp des Webdienstes
3CEPStopp der Ereignisverarbeitung
4TSEStopp der Zeitreihen-Engine
5MQ (Kafka / MQTT)Stopp des Message-Brokers
6CassandraStopp der Zeitreihen-DB
7Redis (Valkey)Stopp des Caches
8PostgreSQLStopp 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 drain die 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 drain die 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 Server
After=plantpulse-postgresql.service plantpulse-redis.service plantpulse-cassandra.service
Requires=plantpulse-postgresql.service plantpulse-redis.service

[Service]
Type=forking
User=kopens
ExecStart=/opt/kopens/plantpulse-platform/plantpulse-server/bin/startup.sh
ExecStop=/opt/kopens/plantpulse-platform/plantpulse-server/bin/shutdown.sh
Restart=on-failure
RestartSec=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üfpunktBefehl / PrüfmethodeNormalkriterium
Gesamtstatus der Dienstesystemctl list-units 'plantpulse-*'alle Dienste active (running)
Prüfung der KernportsPortprüfskript (siehe oben)alle Ports geöffnet
Healthcheck-APIcurl http://localhost/api/v5/pingHTTP 200, Status OK
Festplattennutzungdf -hAuslastung unter 80%
Speichernutzungfree -hAuslastung unter 85%
Fehlerprotokollegrep ERROR plantpulse.log | tail -20keine wiederkehrenden Fehler
Cassandra-Statusnodetool statusalle Knoten UN (Up/Normal)

Wöchentliche Prüfung

PrüfpunktBefehl / PrüfmethodeNormalkriterium
Cassandra Compactionnodetool compactionstatskeine übermäßig anstehenden Aufgaben
PostgreSQL-StatistikAbfrage von pg_stat_activitykeine übermäßigen Idle-Verbindungen
Kafka Consumer Lagkafka-consumer-groups.sh --describeAnzahl verzögerter Nachrichten im Normalbereich
JVM-GC-Statistikjstat -gcutilniedrige Häufigkeit von Full GC
Backup-PrüfungPrüfung der letzten Backup-Dateiengültiges Backup vorhanden
Logdateivolumendu -sh */logs/kein abnormales Wachstum
SicherheitsupdatesPrüfung auf OS-Paket-Updateskeine bekannten Schwachstellen