plantpulse-server (ウェブコンソール + IIoT エンジン)
役割
プラットフォームの顔であり頭脳に当たるコアモジュールです。オペレータが見るウェブコンソール、外部システムが呼び出すREST API、そして産業データを実際に処理するIIoTエンジンが、すべてこのひとつのモジュール内で動作します。
| 項目 | 値 |
|---|---|
| モジュール名 | plantpulse-server |
| コンテナ | plantpulse-server-web (独立イメージ、独立コンテナ) |
| コンテナ内パス | /opt/kopens/plantpulse-platform/plantpulse-server/ |
| ユーザーアクセス | 80 / 443 — plantpulse-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-webexplodedディレクトリ方式は廃止予定であり、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.minutesはplantpulse-engine.propertiesに移行されました。
plantpulse-engine.properties
IIoTエンジンパイプラインのチューニング。
| 項目 | デフォルト値 | 説明 |
|---|---|---|
engine.pipeline.threads | 36 | 並列処理スレッド数 |
engine.pipeline.ratelimit | 40000 | 毎秒最大メッセージ数 |
engine.pipeline.batch.size | 1000 | バッチ束サイズ |
engine.pipeline.queue.size | 1200000 | キュー容量 |
engine.dedup.enabled | true | 重複排除有効化 |
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 catalina | server/logs/catalina.out | Tomcat標準出力 |
| アクセスログ | server/logs/localhost_access_log.YYYY-MM-DD.txt | HTTPリクエストログ |
| エンジンログ | logs/engine.log | IIoTエンジン処理詳細 |
| スロークエリ | logs/slow.log | 200ms以上のクエリ |
ログレベル変更 — ロギング設定(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 を調整します。大規模同時接続環境では以下を推奨します。
| 同時接続数 | maxThreads | acceptCount |
|---|---|---|
| ~ 100 | 200 | 100 |
| ~ 500 | 500 | 200 |
| 500+ | 1000 | 500 |
IIoTエンジンスループット
plantpulse-engine.properties のengine.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.conf のnofile を65535以上に |
| コンソール応答が遅い | DBスロークエリ | PostgreSQL slow queryログ、Valkey キャッシュ命中率を確認 |
| ログイン無限ループ | セッション / クッキー問題 | ブラウザキャッシュ削除、server/conf/Catalina/localhost/ROOT.xml のsessionCookieName を確認 |
| 502 / 504 (リバースプロキシ) | バックエンド応答タイムアウト | nginxproxy_read_timeout を上向き |
| WebSocket途切れ | ファイアウォールアイドルタイムアウト | ファイアウォールタイムアウト > 60s、tomcat.websocket.session.timeout を調整 |
詳細な診断はトラブルシューティングページを参照してください。
セキュリティチェックリスト
- デフォルト admin パスワード変更 (
admin / admin123!) -
tomcat-users.xmlのmanagerアカウント削除または強力なパスワード -
server.xmlのshutdown port (7000)への外部アクセス遮断 - HTTPS証明書適用 (
prepare-ssl.sh結果または外部CA) - X-Frame-Options / CSP / HSTS ヘッダ設定確認
- API Bearer Token を運用vaultに保存
-
config/プロパティファイルのデバッグオプション無効化と権限制限 (chmod 600)
詳細なセキュリティ設定はセキュリティ設定ページを参照してください。