メインコンテンツまでスキップ

plantpulse-server (ウェブコンソール + IIoT エンジン)

役割

プラットフォームの顔であり頭脳に当たるコアモジュールです。オペレータが見るウェブコンソール、外部システムが呼び出すREST API、そして産業データを実際に処理するIIoTエンジンが、すべてこのひとつのモジュール内で動作します。

項目
モジュール名plantpulse-server
コンテナplantpulse-server-web (独立イメージ、独立コンテナ)
コンテナ内パス/opt/kopens/plantpulse-platform/plantpulse-server/
ユーザーアクセス80 / 443plantpulse-proxy が受け取り、このコンテナへ転送します
管理コンソール7443 (HTTPS、plantpulse-datalake がpublish)
ホストポートなし — プロキシの背後でのみ動作します
メモリ上限DOCKER_SERVER_MEMORY デフォルト 16g / ヒープ DOCKER_SERVER_HEAP デフォルト 12g
ランタイムApache Tomcat 9 + Java 21
スループット毎秒40,000メッセージ (36スレッドパイプライン)
このコンテナはホストポートを開きません

ユーザートラフィックは常にplantpulse-proxy(80/443)を通ります。そのためバックエンドが移動したり名前が変わっても、ユーザー・設備設定に手を加える必要がありません。コンテナの状態はbin/status.shで、ログはbin/logs.sh plantpulse-server-webで確認します。

責務範囲

ディレクトリ構造

plantpulse-server/
├── config/ # 서버 관리 설정 (외부화 — 배포해도 유지)
│ ├── plantpulse-engine.properties # IIoT 엔진 튜닝
│ ├── plantpulse-storage.properties # DB 연결
│ ├── plantpulse-mq.properties # 메시징 연결
│ ├── plantpulse-mail.properties # SMTP
│ ├── plantpulse-ai.properties # AI 게이트웨이
│ └── log4j2.xml # 로깅 설정 (자가 시딩 — 최초 기동 시 생성)
├── bin/
│ ├── start.sh
│ ├── stop.sh
│ └── log-viewer.sh
├── logs/
│ └── system.log
├── path/ # 경로 매핑
└── server/ # 내장 Tomcat
├── conf/
│ ├── server.xml # 커넥터 / 포트
│ ├── context.xml # 컨텍스트 / 데이터소스
│ ├── catalina.properties
│ ├── logging.properties
│ ├── tomcat-users.xml
│ ├── web.xml
│ └── Catalina/localhost/
│ └── ROOT.xml # 컨텍스트 설정 (sessionCookieName 등)
└── webapps/
├── ROOT.war # 웹 애플리케이션 (WAR 통배포)
└── ROOT/ # Tomcat 이 unpack 한 디렉토리 (수정 금지)

デプロイ方式: ウェブアプリはserver/webapps/ROOT.war 置き換え方式でデプロイされます (WAR一括配布、切り替え実施中)。既存のapp/plantpulse-server-web explodedディレクトリ方式は廃止予定であり、server.xml のContextdocBase オーバーライドは削除されました。ROOT/ 内部のファイルを直接編集するとデプロイ時に消去されるため、設定変更は常にconfig/ で行います。

主要設定ファイル

設定ファイルはモジュールのconfig/ ディレクトリにあり、サーバーは-Dpp.conf.dir${catalina.base}/../config → クラスパス(フォールバック) の順で探索します。外部設定がロードされると、起動ログにProperties loaded from external conf: が出力されます。

application.properties は廃止されました (2026.06)。テーマ / ホームページなどコンソール動作設定はコンソールのシステム > 設定管理 (mm_config テーブル)で管理し、alarm.duplicate.check.minutesplantpulse-engine.properties に移行されました。

plantpulse-engine.properties

IIoTエンジンパイプラインのチューニング。

項目デフォルト値説明
engine.pipeline.threads36並列処理スレッド数
engine.pipeline.ratelimit40000毎秒最大メッセージ数
engine.pipeline.batch.size1000バッチ束サイズ
engine.pipeline.queue.size1200000キュー容量
engine.dedup.enabledtrue重複排除有効化

plantpulse-storage.properties

データストア接続。

# Cassandra
cassandra.host=${PP_CASSANDRA_HOST}
cassandra.port=${PP_CASSANDRA_PORT}
cassandra.keyspace=${PP_KEYSPACE}
cassandra.user=${PP_CASSANDRA_USER}
cassandra.password=${PP_CASSANDRA_PASSWORD}

# PostgreSQL (Spring DataSource)
postgres.url=jdbc:postgresql://${PP_POSTGRES_HOST}:${PP_POSTGRES_PORT}/${PP_DB_NAME}
postgres.user=${PP_PG_USER}
postgres.password=${PP_PG_PASSWORD}

# Valkey
redis.host=${PP_REDIS_HOST}
redis.port=${PP_REDIS_PORT}
redis.password=${PP_REDIS_PASSWORD}

このアプリは設定をレンダリングしません。 コンテナに分離された後、ウェブサーバーはデータレイクの設定レンダラーなしで起動し、3ヶ所から値を読みます — ① オペレータが置いた外部ファイル → ② WARに内装されたデフォルト値 → ③ composeが渡した環境変数。3つのうち環境変数が内装デフォルト値をオーバーライドします。

そのためアプリが見る値の定義源はcompose/docker-compose.yml 唯一つです。データレイク側だけにあり、composeにない名前はこのアプリに届きません — データレイク側だけで識別子を変更したサイトでアプリ5個が旧名を使い続けた事故がそれです(2026-08-29)。

ウェブアプリ内部(server/webapps/ROOT/)のファイルは編集しないでください — デプロイ時に消去されます。

server/conf/server.xml

Tomcatコネクタ設定。ポート変更 / TLS / 圧縮 / スレッドプール。

<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
maxThreads="500"
acceptCount="200"
URIEncoding="UTF-8"
compression="on"
compressibleMimeType="text/html,text/css,application/json,application/javascript" />

<Connector port="443" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
SSLEnabled="true"
maxThreads="500"
sslEnabledProtocols="TLSv1.3,TLSv1.2">
<SSLHostConfig>
<Certificate certificateKeystoreFile="/var/security/plantpulse/server.jks"
certificateKeystorePassword="${PP_TLS_KEYSTORE_PASSWORD}" />
</SSLHostConfig>
</Connector>

運用コマンド

ホストから — コンテナ単位

コンテナを再起動するのはすなわちこのモジュールの再起動です。インフラと他のアプリは影響を受けません。

cd /opt/kopens/plantpulse-platform-docker

# 서버만 재시작
docker compose -f compose/docker-compose.yml restart plantpulse-server-web

# 상태 · 로그
bin/status.sh
bin/logs.sh plantpulse-server-web -n 200

コンテナ内へ入る

cd /opt/kopens/plantpulse-platform-docker/bin
./shell.sh plantpulse-server-web
データレイクのrestart-server.sh では再起動されません

そのスクリプトは各アプリの独自コンテナ内からそのモジュールのランチャーを呼ぶ薄い委譲です。データレイクコンテナにはウェブサーバー実行ファイルがないため、「モジュールが見つからない」エラーで終了します。上記のコンテナ単位の再起動を使用してください。

ホットリロード (再起動なしで設定を反映)

一部の設定はコンソールのシステム > 設定管理 メニューからホットリロードが可能です。config/ のプロパティファイルやserver.xml などの起動時設定は再起動が必要です。

ログ

ログパス内容
メインログlogs/system.logアプリケーションロジック、エラー
Tomcat catalinaserver/logs/catalina.outTomcat標準出力
アクセスログserver/logs/localhost_access_log.YYYY-MM-DD.txtHTTPリクエストログ
エンジンログlogs/engine.logIIoTエンジン処理詳細
スロークエリlogs/slow.log200ms以上のクエリ

ログレベル変更 — ロギング設定(log4j2.xml)はモジュールconfig/ に外部化されています (自己シーディング: 初回起動時にWARデフォルト値がconfig/log4j2.xml にコピーされ、適用時に起動ログにLogging reconfigured from external conf: 出力):

# 웹 서버 컨테이너 안에서
cd /opt/kopens/plantpulse-platform-docker/bin
./shell.sh plantpulse-server-web
vi /opt/kopens/plantpulse-platform/plantpulse-server/config/log4j2.xml
# <Logger name="plantpulse" level="DEBUG"/> 등 수정 후 exit

# 호스트에서 그 컨테이너만 재시작
cd /opt/kopens/plantpulse-platform-docker
docker compose -f compose/docker-compose.yml restart plantpulse-server-web

外部ファイルなのでWAR再デプロイでも永続保持されます。ウェブアプリ内部(server/webapps/ROOT/WEB-INF/classes/log4j2.xml)は編集しないでください — デプロイ時に消去されます。

パフォーマンスチューニング

JVMヒープ

# server/bin/setenv.sh (없으면 생성)
export CATALINA_OPTS="-Xms16g -Xmx32g \
-XX:+UseG1GC -XX:MaxGCPauseMillis=200 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/var/log/plantpulse/heap/ \
-Xlog:gc*:file=/var/log/plantpulse/gc.log:time,uptime:filecount=10,filesize=100M"

Tomcatスレッドプール

server.xml のConnectorでmaxThreads / acceptCount を調整します。大規模同時接続環境では以下を推奨します。

同時接続数maxThreadsacceptCount
~ 100200100
~ 500500200
500+1000500

IIoTエンジンスループット

plantpulse-engine.propertiesengine.pipeline.threads をホストコア数の70~80% に設定します。メッセージ積滞時はengine.pipeline.queue.capacity も併せて上向き調整。

詳細なチューニングはパフォーマンスチューニングページを参照してください。

ヘルスチェック

# 표준 헬스체크 (익명, readiness — 엔진이 전 단계 기동을 완료(RUNNING)했을 때만 UP. 배포 자동검증 / 모니터링용)
curl -fsS http://127.0.0.1/api/health
# 준비 완료: 200 {"status":"UP","service":"plantpulse-server-web","ts":1765500000000,"checks":{"engine":"RUNNING"}}
# 기동 중: 503 {"status":"STARTING",...} / 기동 실패·중지: 503 {"status":"DEGRADED",...}

# 콘솔 ping
curl -fsS http://127.0.0.1/api/v5/ping

# 인증 필요 헬스체크
curl -fsS -u admin:admin123! http://127.0.0.1/api/v5/health

# WebSocket 핸드셰이크 확인
curl -i -N \
-H "Connection: Upgrade" -H "Upgrade: websocket" \
-H "Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==" \
-H "Sec-WebSocket-Version: 13" \
http://127.0.0.1:8000/ws

よくあるトラブル

症状原因対処
OutOfMemoryErrorヒープ不足setenv.sh-Xmx を上向き + GCログ分析
Too many open filesファイルディスクリプタ上限/etc/security/limits.confnofile を65535以上に
コンソール応答が遅いDBスロークエリPostgreSQL slow queryログ、Valkey キャッシュ命中率を確認
ログイン無限ループセッション / クッキー問題ブラウザキャッシュ削除、server/conf/Catalina/localhost/ROOT.xmlsessionCookieName を確認
502 / 504 (リバースプロキシ)バックエンド応答タイムアウトnginxproxy_read_timeout を上向き
WebSocket途切れファイアウォールアイドルタイムアウトファイアウォールタイムアウト > 60s、tomcat.websocket.session.timeout を調整

詳細な診断はトラブルシューティングページを参照してください。

セキュリティチェックリスト

  • デフォルト admin パスワード変更 (admin / admin123!)
  • tomcat-users.xml のmanagerアカウント削除または強力なパスワード
  • server.xmlshutdown port (7000) への外部アクセス遮断
  • HTTPS証明書適用 (prepare-ssl.sh 結果または外部CA)
  • X-Frame-Options / CSP / HSTS ヘッダ設定確認
  • API Bearer Token を運用vaultに保存
  • config/ プロパティファイルのデバッグオプション無効化と権限制限 (chmod 600)

詳細なセキュリティ設定はセキュリティ設定ページを参照してください。

関連ドキュメント