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 发布) |
| 主机端口 | 无 — 仅在代理后运行 |
| 内存限制 | 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}
本应用不进行配置渲染。 容器分离后,网页服务器在没有数据湖配置渲染器的情况下启动,从三个地方读取值 — ① 运营者放置的外部文件 → ② WAR 内置默认值 → ③ compose 传入的环境变量。环境变量会覆盖内置默认值。
因此此应用所见值的唯一定义来源是
compose/docker-compose.yml。仅存在于数据湖中,不在 compose 中的名称不会传到本应用 — 这导致了某些网站仅在数据湖侧更改标识符,而五个应用继续使用旧名称的事故 (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+ |
| 控制台响应缓慢 | 数据库慢查询 | 检查 PostgreSQL 慢查询日志、Valkey 缓存命中率 |
| 登录无限循环 | 会话 / Cookie 问题 | 清除浏览器缓存,检查 server/conf/Catalina/localhost/ROOT.xml 中的 sessionCookieName |
| 502 / 504 (反向代理) | 后端响应超时 | 增大 nginx proxy_read_timeout |
| WebSocket 断开 | 防火墙 idle timeout | 防火墙 timeout > 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)
详细安全设置请参考安全配置页面。