Pinpoint 3.1.1 Docker Compose 部署指南
用 Docker Compose 在单台 Linux 服务器从零部署 Pinpoint 3.1.1 全链路监控(Web 控制台+数据收集器+HBase 存储+Agent 探针+示例应用),覆盖镜像选型、首启时序、数据持久化、环境变量表、等价 docker run 与 9 类排障实录,全部命令实测通过。
Pinpoint 3.1.1 Docker Compose 部署指南
目标:用 Docker Compose 在一台 Linux 服务器上从零部署一套可用的 Pinpoint 3.1.1 全链路监控环境(Web 控制台 + 数据收集器 + HBase 存储 + Agent 探针 + 示例应用),完成数据持久化、参数说明与部署后验证。整套流程已在 Ubuntu 22.04.4 LTS(Docker 29.8.1 + Compose v5.5.1)实测通过,文中所有命令与回显均来自真实部署过程。
一、环境信息
本章列出本次部署实测所用的软硬件环境与网络规划,读者可对照自己的服务器评估是否满足条件。
- 操作系统:Ubuntu 22.04.4 LTS(x86_64)
- 硬件:12 vCPU / 31GB 内存(实测整套服务常驻内存约 3.4GB,4C8G 的机器即可跑通本方案)
- Docker 版本:Docker version 29.8.1, build 4a63305
- Compose 版本:Docker Compose version v5.5.1(
docker composev2 插件语法) - Pinpoint 版本:3.1.1(官方
pinpointdocker系列镜像,2026-10-02 发布,与 GitHub v3.1.1 Release 对应) - 内置组件版本:HBase 2.2.6(hbase 服务内置)、ZooKeeper 3.4.13、MySQL 8.0(实测拉取为 8.0.46)、Redis 7.0.14
- 部署目录:
/opt/pinpoint - 服务端口规划:
8148→ Web 控制台(容器内 8080)、8149→ HBase Master UI(容器内 16010)、8150→ 示例应用(容器内 8080)、8151→ MySQL(容器内 3306) - Compose 项目名:
pinpoint-311-stack;自定义网络pinpoint-311-net(10.89.70.0/24),collector 固定 IP10.89.70.30
二、镜像选型说明
Pinpoint 官方在 Docker Hub 的 pinpointdocker 组织下为每个组件发布独立镜像,版本 tag 与 GitHub Release 一一对应。本章给出本方案选用的镜像清单与取舍理由。
| 服务 | 镜像 | 版本 | 角色说明 |
|---|---|---|---|
| zoo1 / zoo2 / zoo3 | zookeeper | 3.4.13 | ZooKeeper 三节点,collector/web 集群注册(CLUSTER_ENABLE) |
| pinpoint-hbase | pinpointdocker/pinpoint-hbase | 3.1.1 | 内置 HBase 2.2.6 + Pinpoint 全部表结构初始化脚本,链路数据存储 |
| pinpoint-mysql | mysql | 8.0 | 仅存 Web 元数据(用户组/告警规则/任务表),实测拉取为 8.0.46 |
| pinpoint-web | pinpointdocker/pinpoint-web | 3.1.1 | Web 控制台(Spring Boot + 前端 SPA),查询 HBase 展示拓扑/调用栈 |
| pinpoint-collector | pinpointdocker/pinpoint-collector | 3.1.1 | gRPC 数据收集器(9991/9992/9993),接收 Agent 上报写 HBase |
| pinpoint-agent | pinpointdocker/pinpoint-agent | 3.1.1 | 探针安装目录(本身不跑业务),通过共享卷提供给应用挂载 |
| pinpoint-quickstart | pinpointdocker/pinpoint-quickstart | latest | 官方示例应用(Tomcat 8 + JDK 8 testapp),用于开箱验证,生产可不部署 |
| redis | redis | 7.0.14 | web/collector 的缓存(实测配置 --maxmemory 128mb --maxmemory-policy allkeys-lru) |
选型要点解读:
- 版本对齐:Pinpoint 3.1.x 的 Agent 与 Collector 强耦合(官方兼容矩阵:3.1.x agent 仅兼容 3.1.x collector),四个 pinpointdocker 镜像必须统一用
3.1.1,不要混用 3.0.x; - 裁剪说明:官方 pinpoint-docker 仓库的 docker-compose.yml 是含 flink×2、batch、pinot、kafka 等 13+ 服务的「全家桶」,本方案裁剪为 8 类 10 个服务(3×ZooKeeper + HBase + MySQL + Web + Collector + Agent + 示例应用 + Redis),去掉实时流聚合(flink)与告警批处理(batch)等重依赖,保留「探针 → 收集 → 存储 → 展示」最小可用链路;
- 仓库状态:官方 pinpoint-docker 仓库已归档不再维护(官方生产建议转向 pinpoint-kubernetes),但镜像仍在 Docker Hub 随新版本持续发布,Compose 路径作为单机部署依然可用;
- metric 变体:如需 OpenTelemetry 指标接入,collector/web 需改用
3.1.1-metric变体镜像并外接 OTLP 通道,默认链路不含,本文不展开。
三、前置条件
部署前需逐项确认硬件资源、软件版本与端口占用,避免启动中途失败。
3.1 硬件与资源
最低 4 vCPU / 8GB 内存 / 40GB 磁盘。整套服务启动后的实际资源占用(实测 docker stats --no-stream 输出):
NAME MEM USAGE / LIMITS CPU %
pinpoint-311-web 575.8MiB / 31.3GiB 0.53%
pinpoint-311-collector 783.6MiB / 31.3GiB 1.99%
pinpoint-311-quickstart 440.2MiB / 31.3GiB 0.06%
pinpoint-311-agent 1.625MiB / 31.3GiB 0.00%
pinpoint-311-hbase 1.108GiB / 31.3GiB 2.14%
pinpoint-311-redis 3.297MiB / 31.3GiB 0.07%
pinpoint-311-mysql 372.6MiB / 31.3GiB 0.33%
pinpoint-311-zoo2 47.36MiB / 31.3GiB 0.10%
pinpoint-311-zoo1 42.39MiB / 31.3GiB 0.06%
pinpoint-311-zoo3 42.21MiB / 31.3GiB 0.06%
合计约 3.4GB 常驻内存,其中 HBase 约 1.1GB、collector 约 0.8GB 是大头。8GB 内存机器部署后余量已不多,不要再在这台机器上压测大并发。
3.2 软件检查
docker --version
实测回显:
Docker version 29.8.1, build 4a63305
docker compose version
实测回显:
Docker Compose version v5.5.1
需要 Docker Engine 与 Compose v2 插件(docker compose 子命令形态)。若机器上只有老版独立二进制 docker-compose(v1),把本文所有 docker compose 替换为 docker-compose 亦可,但建议升级。
3.3 端口检查
确认 8148/8149/8150/8151 四个宿主端口未被占用(无输出即空闲,被占用则需修改 compose 里的映射端口):
ss -ltn | grep -E ':(8148|8149|8150|8151)'
本机部署完成后该命令的实测输出(此时端口已被本栈占用,属预期):
LISTEN 0 4096 0.0.0.0:8148 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:8149 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:8150 0.0.0.0:*
LISTEN 0 4096 0.0.0.0:8151 0.0.0.0:*
3.4 网段规划
compose 显式声明了自定义网桥网段 10.89.70.0/24,并给 collector 固定 IP 10.89.70.30(固定 IP 是为了外部微服务上的 Agent 能长期指向 collector 地址)。部署前确认该网段与现有 Docker 网络不冲突:
docker network ls
实测回显(部署后,pinpoint-311-net 已在列;若输出中已有其他网络占用了 10.89.70.x 网段,需同步修改 compose 中 subnet 与 collector 的 ipv4_address):
c873b82bb85f pinpoint-311-net bridge local
四、部署步骤
本章从建目录开始,到全套服务启动、数据落库、拓扑出图为止,逐步执行。
4.1 创建部署目录
mkdir -p /opt/pinpoint/initdb
cd /opt/pinpoint
最终目录结构:
/opt/pinpoint/
├── docker-compose.yml # 编排文件(4.3)
└── initdb/ # MySQL 首次初始化脚本(4.2)
├── CreateTableStatement-mysql.sql
└── SpringBatchJobRepositorySchema-mysql.sql
4.2 准备 MySQL 初始化脚本
Pinpoint 的 Web 控制台需要 MySQL 里有用户组(user_group)、告警规则(alarm_rule)等元数据表,以及 Spring Batch 任务表。这两个建表脚本来自官方 pinpoint-docker 仓库 pinpoint-mysql/init-docker-files/ 目录,首次启动时由 MySQL 官方镜像的 /docker-entrypoint-initdb.d 机制自动执行(仅数据卷为空时执行一次)。
将以下内容保存为 /opt/pinpoint/initdb/CreateTableStatement-mysql.sql:
-- DROP TABLE user_group;
-- DROP TABLE user_group_member;
-- DROP TABLE puser;
-- DROP TABLE alarm_rule;
CREATE TABLE `user_group` (
`number` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`id` VARCHAR(30) NOT NULL,
PRIMARY KEY (`number`)
);
ALTER TABLE user_group ADD UNIQUE KEY id_idx (id);
CREATE TABLE `user_group_member` (
`number` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_group_id` VARCHAR(30) NOT NULL,
`member_id` VARCHAR(30) NOT NULL,
PRIMARY KEY (`number`)
);
ALTER TABLE user_group_member ADD UNIQUE KEY user_group_id_member_id_idx (`user_group_id`,`member_id`);
CREATE TABLE `puser` (
`number` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` VARCHAR(30) NOT NULL,
`name` VARCHAR(150) NOT NULL,
`department` VARCHAR(150) NOT NULL,
`phone_country_code` int(10) NOT NULL DEFAULT '0',
`phonenumber` VARCHAR(100),
`email` VARCHAR(100),
PRIMARY KEY (`number`)
);
ALTER TABLE puser ADD UNIQUE KEY user_id_idx (`user_id`);
CREATE TABLE `alarm_rule` (
`rule_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`application_id` VARCHAR(30) NOT NULL,
`service_type` VARCHAR(30) NOT NULL,
`checker_name` VARCHAR(50) NOT NULL,
`threshold` INT(10) DEFAULT NULL,
`user_group_id` VARCHAR(30) NOT NULL,
`sms_send` CHAR(1) DEFAULT NULL,
`email_send` CHAR(1) DEFAULT NULL,
`webhook_send` CHAR(1) DEFAULT NULL,
`notes` VARCHAR(100) DEFAULT NULL,
PRIMARY KEY (`rule_id`)
);
ALTER TABLE alarm_rule ADD INDEX application_id_checker_name_user_group_id_idx (application_id, user_group_id, checker_name);
CREATE TABLE `alarm_history` (
`history_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`rule_id` INT(10) UNSIGNED NOT NULL,
`application_id` VARCHAR(30) NOT NULL,
`checker_name` VARCHAR(50) NOT NULL,
`detected` CHAR(1) DEFAULT NULL,
`sequence_count` INT(10),
`timing_count` INT(10),
PRIMARY KEY (`history_id`)
);
ALTER TABLE alarm_history ADD INDEX application_id_checker_name_idx (application_id, checker_name);
CREATE TABLE `agent_statistics` (
`agent_count` INT(10) UNSIGNED NOT NULL,
`date_val`DATETIME NOT NULL,
PRIMARY KEY (`date_val`)
);
CREATE TABLE `webhook` (
`webhook_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`alias` VARCHAR(256) NULL,
`url` VARCHAR(256) NOT NULL,
`application_id` VARCHAR(127) NULL,
`service_name` VARCHAR(127) NULL,
PRIMARY KEY (`webhook_id`)
);
CREATE TABLE `webhook_send` (
`webhook_send_info_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`webhook_id` INT UNSIGNED NOT NULL,
`rule_id` INT UNSIGNED NOT NULL,
PRIMARY KEY (`webhook_send_info_id`)
);
将以下内容保存为 /opt/pinpoint/initdb/SpringBatchJobRepositorySchema-mysql.sql:
-- DROP TABLE IF EXISTS BATCH_STEP_EXECUTION_CONTEXT;
-- DROP TABLE IF EXISTS BATCH_JOB_EXECUTION_CONTEXT;
-- DROP TABLE IF EXISTS BATCH_STEP_EXECUTION;
-- DROP TABLE IF EXISTS BATCH_JOB_EXECUTION_PARAMS;
-- DROP TABLE IF EXISTS BATCH_JOB_EXECUTION;
-- DROP TABLE IF EXISTS BATCH_JOB_INSTANCE;
-- DROP TABLE IF EXISTS BATCH_STEP_EXECUTION_SEQ;
-- DROP TABLE IF EXISTS BATCH_JOB_EXECUTION_SEQ;
-- DROP TABLE IF EXISTS BATCH_JOB_SEQ;
CREATE TABLE BATCH_JOB_INSTANCE (
JOB_INSTANCE_ID BIGINT NOT NULL PRIMARY KEY ,
VERSION BIGINT ,
JOB_NAME VARCHAR(100) NOT NULL,
JOB_KEY VARCHAR(32) NOT NULL,
constraint JOB_INST_UN unique (JOB_NAME, JOB_KEY)
) ENGINE=InnoDB;
CREATE TABLE BATCH_JOB_EXECUTION (
JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY ,
VERSION BIGINT ,
JOB_INSTANCE_ID BIGINT NOT NULL,
CREATE_TIME DATETIME(6) NOT NULL,
START_TIME DATETIME(6) DEFAULT NULL ,
END_TIME DATETIME(6) DEFAULT NULL ,
STATUS VARCHAR(10) ,
EXIT_CODE VARCHAR(2500) ,
EXIT_MESSAGE VARCHAR(2500) ,
LAST_UPDATED DATETIME(6),
constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID)
references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)
) ENGINE=InnoDB;
CREATE TABLE BATCH_JOB_EXECUTION_PARAMS (
JOB_EXECUTION_ID BIGINT NOT NULL ,
PARAMETER_NAME VARCHAR(100) NOT NULL ,
PARAMETER_TYPE VARCHAR(100) NOT NULL ,
PARAMETER_VALUE VARCHAR(2500) ,
IDENTIFYING CHAR(1) NOT NULL ,
constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ENGINE=InnoDB;
CREATE TABLE BATCH_STEP_EXECUTION (
STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY ,
VERSION BIGINT NOT NULL,
STEP_NAME VARCHAR(100) NOT NULL,
JOB_EXECUTION_ID BIGINT NOT NULL,
CREATE_TIME DATETIME(6) NOT NULL,
START_TIME DATETIME(6) DEFAULT NULL ,
END_TIME DATETIME(6) DEFAULT NULL ,
STATUS VARCHAR(10) ,
COMMIT_COUNT BIGINT ,
READ_COUNT BIGINT ,
FILTER_COUNT BIGINT ,
WRITE_COUNT BIGINT ,
READ_SKIP_COUNT BIGINT ,
WRITE_SKIP_COUNT BIGINT ,
PROCESS_SKIP_COUNT BIGINT ,
ROLLBACK_COUNT BIGINT ,
EXIT_CODE VARCHAR(2500) ,
EXIT_MESSAGE VARCHAR(2500) ,
LAST_UPDATED DATETIME(6),
constraint JOB_EXEC_STEP_FK foreign key (STEP_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ENGINE=InnoDB;
CREATE TABLE BATCH_STEP_EXECUTION_CONTEXT (
STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY,
SHORT_CONTEXT VARCHAR(2500) NOT NULL,
SERIALIZED_CONTEXT TEXT ,
constraint STEP_EXEC_CTX_FK foreign key (STEP_EXECUTION_ID)
references BATCH_STEP_EXECUTION(STEP_EXECUTION_ID)
) ENGINE=InnoDB;
CREATE TABLE BATCH_JOB_EXECUTION_CONTEXT (
JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY,
SHORT_CONTEXT VARCHAR(2500) NOT NULL,
SERIALIZED_CONTEXT TEXT ,
constraint JOB_EXEC_CTX_FK foreign key (JOB_EXECUTION_ID)
references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ENGINE=InnoDB;
CREATE TABLE BATCH_STEP_EXECUTION_SEQ (
ID BIGINT NOT NULL,
UNIQUE_KEY CHAR(1) NOT NULL,
constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
) ENGINE=InnoDB;
INSERT INTO BATCH_STEP_EXECUTION_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_STEP_EXECUTION_SEQ);
CREATE TABLE BATCH_JOB_EXECUTION_SEQ (
ID BIGINT NOT NULL,
UNIQUE_KEY CHAR(1) NOT NULL,
constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
) ENGINE=InnoDB;
INSERT INTO BATCH_JOB_EXECUTION_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_JOB_EXECUTION_SEQ);
CREATE TABLE BATCH_JOB_SEQ (
ID BIGINT NOT NULL,
UNIQUE_KEY CHAR(1) NOT NULL,
constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
) ENGINE=InnoDB;
INSERT INTO BATCH_JOB_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_JOB_SEQ);
⚠️ 注意:
BATCH_STEP_EXECUTION表的外键引用是BATCH_STEP_EXECUTION.STEP_EXECUTION_ID(官方脚本原文如此),MySQL 8.0 执行时不会报错,属于官方脚本自身的写法,保持原样即可。
4.3 编写 docker-compose.yml
将以下内容保存为 /opt/pinpoint/docker-compose.yml(与官方 compose 的差异:裁掉 flink/batch/pinot/kafka、ZooKeeper 显式三节点、collector 固定 IP、JVM 堆统一压到 256–512MB):
name: pinpoint-311-stack
services:
zoo1:
container_name: pinpoint-311-zoo1
image: zookeeper:3.4.13
restart: always
hostname: zoo1
expose:
- "2181"
- "2888"
- "3888"
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=0.0.0.0:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
JVMFLAGS: -Xms128m -Xmx256m
networks:
- pinpoint
zoo2:
container_name: pinpoint-311-zoo2
image: zookeeper:3.4.13
restart: always
hostname: zoo2
expose:
- "2181"
- "2888"
- "3888"
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=0.0.0.0:2888:3888 server.3=zoo3:2888:3888
JVMFLAGS: -Xms128m -Xmx256m
networks:
- pinpoint
zoo3:
container_name: pinpoint-311-zoo3
image: zookeeper:3.4.13
restart: always
hostname: zoo3
expose:
- "2181"
- "2888"
- "3888"
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=0.0.0.0:2888:3888
JVMFLAGS: -Xms128m -Xmx256m
networks:
- pinpoint
pinpoint-hbase:
container_name: pinpoint-311-hbase
image: "pinpointdocker/pinpoint-hbase:3.1.1"
networks:
- pinpoint
environment:
- HBASE_HEAPSIZE=512m
- AGENTINFO_TTL=31536000
- AGENTSTATV2_TTL=5184000
- APPSTATAGGRE_TTL=5184000
- APPINDEX_TTL=31536000
- AGENTLIFECYCLE_TTL=5184000
- AGENTEVENT_TTL=5184000
- STRINGMETADATA_TTL=15552000
- APIMETADATA_TTL=31536000
- SQLMETADATA_TTL=15552000
- TRACEV2_TTL=5184000
- APPTRACEINDEX_TTL=5184000
- APPMAPSTATCALLERV2_TTL=5184000
- APPMAPSTATCALLEV2_TTL=5184000
- APPMAPSTATSELFV2_TTL=5184000
- HOSTAPPMAPV2_TTL=5184000
volumes:
- hbase_data:/home/pinpoint/hbase
- /home/pinpoint/zookeeper
ports:
- "8149:16010"
restart: always
depends_on:
- zoo1
- zoo2
- zoo3
pinpoint-mysql:
container_name: pinpoint-311-mysql
image: mysql:8.0
restart: "no"
hostname: pinpoint-mysql
ports:
- "8151:3306"
environment:
- MYSQL_ROOT_PASSWORD=q1w2e3r4
- MYSQL_USER=admin
- MYSQL_PASSWORD=q1w2e3r4
- MYSQL_DATABASE=pinpoint
volumes:
- ./initdb:/docker-entrypoint-initdb.d:ro
- mysql_data:/var/lib/mysql
networks:
- pinpoint
pinpoint-web:
container_name: pinpoint-311-web
image: "pinpointdocker/pinpoint-web:3.1.1"
depends_on:
- pinpoint-hbase
- pinpoint-mysql
- zoo1
- redis
restart: always
ports:
- "8148:8080"
environment:
- WEB_SERVER_PORT=8080
- SPRING_PROFILES_ACTIVE=release
- PINPOINT_ZOOKEEPER_ADDRESS=zoo1
- CLUSTER_ENABLE=true
- ADMIN_PASSWORD=q1w2e3r4
- CONFIG_SENDUSAGE=false
- LOGGING_LEVEL_ROOT=INFO
- CONFIG_SHOW_APPLICATIONSTAT=true
- JDBC_DRIVERCLASSNAME=com.mysql.jdbc.Driver
- JDBC_URL=jdbc:mysql://pinpoint-mysql:3306/pinpoint?characterEncoding=UTF-8
- JDBC_USERNAME=admin
- JDBC_PASSWORD=q1w2e3r4
- SPRING_DATASOURCE_HIKARI_JDBCURL=jdbc:mysql://pinpoint-mysql:3306/pinpoint?characterEncoding=UTF-8
- SPRING_DATASOURCE_HIKARI_USERNAME=admin
- SPRING_DATASOURCE_HIKARI_PASSWORD=q1w2e3r4
- SPRING_METADATASOURCE_HIKARI_JDBCURL=jdbc:mysql://pinpoint-mysql:3306/pinpoint?characterEncoding=UTF-8
- SPRING_METADATASOURCE_HIKARI_USERNAME=admin
- SPRING_METADATASOURCE_HIKARI_PASSWORD=q1w2e3r4
- SPRING_DATA_REDIS_HOST=pinpoint-311-redis
- SPRING_DATA_REDIS_PORT=6379
- SPRING_DATA_REDIS_USERNAME=default
- SPRING_DATA_REDIS_PASSWORD=
- JAVA_TOOL_OPTIONS=-Xms256m -Xmx512m
networks:
- pinpoint
pinpoint-collector:
container_name: pinpoint-311-collector
image: "pinpointdocker/pinpoint-collector:3.1.1"
depends_on:
- pinpoint-hbase
- zoo1
- redis
restart: always
environment:
- SPRING_PROFILES_ACTIVE=release
- PINPOINT_ZOOKEEPER_ADDRESS=zoo1
- CLUSTER_ENABLE=true
- LOGGING_LEVEL_ROOT=INFO
- FLINK_CLUSTER_ENABLE=false
- SPRING_DATASOURCE_HIKARI_JDBCURL=jdbc:mysql://pinpoint-mysql:3306/pinpoint?characterEncoding=UTF-8
- SPRING_DATASOURCE_HIKARI_USERNAME=admin
- SPRING_DATASOURCE_HIKARI_PASSWORD=q1w2e3r4
- SPRING_DATA_REDIS_HOST=pinpoint-311-redis
- SPRING_DATA_REDIS_PORT=6379
- SPRING_DATA_REDIS_USERNAME=default
- SPRING_DATA_REDIS_PASSWORD=
- JAVA_TOOL_OPTIONS=-Xms256m -Xmx512m
networks:
pinpoint:
ipv4_address: 10.89.70.30
pinpoint-agent:
container_name: pinpoint-311-agent
image: "pinpointdocker/pinpoint-agent:3.1.1"
restart: unless-stopped
networks:
- pinpoint
volumes:
- data-volume:/pinpoint-agent
environment:
- SPRING_PROFILES=release
- COLLECTOR_IP=pinpoint-311-collector
- PROFILER_TRANSPORT_MODULE=GRPC
- PROFILER_TRANSPORT_AGENT_COLLECTOR_PORT=9991
- PROFILER_TRANSPORT_METADATA_COLLECTOR_PORT=9991
- PROFILER_TRANSPORT_STAT_COLLECTOR_PORT=9992
- PROFILER_TRANSPORT_SPAN_COLLECTOR_PORT=9993
- COLLECTOR_TCP_PORT=9994
- COLLECTOR_STAT_PORT=9995
- COLLECTOR_SPAN_PORT=9996
- PROFILER_SAMPLING_TYPE=COUNTING
- PROFILER_SAMPLING_COUNTING_SAMPLING_RATE=1
- PROFILER_SAMPLING_PERCENT_SAMPLING_RATE=100
- PROFILER_SAMPLING_NEW_THROUGHPUT=0
- PROFILER_SAMPLING_CONTINUE_THROUGHPUT=0
- AGENT_DEBUG_LEVEL=INFO
depends_on:
- pinpoint-collector
pinpoint-quickstart:
container_name: pinpoint-311-quickstart
image: "pinpointdocker/pinpoint-quickstart:latest"
ports:
- "8150:8080"
volumes:
- data-volume:/pinpoint-agent
environment:
JAVA_OPTS: "-Xms256m -Xmx512m -javaagent:/pinpoint-agent/pinpoint-bootstrap.jar -Dpinpoint.agentId=app-in-docker -Dpinpoint.applicationName=quickapp -Dpinpoint.profiler.profiles.active=release"
networks:
- pinpoint
depends_on:
- pinpoint-agent
redis:
container_name: pinpoint-311-redis
image: redis:7.0.14
restart: always
hostname: pinpoint-redis
command: ["redis-server", "--maxmemory", "128mb", "--maxmemory-policy", "allkeys-lru"]
networks:
- pinpoint
volumes:
data-volume:
mysql_data:
hbase_data:
networks:
pinpoint:
name: pinpoint-311-net
driver: bridge
ipam:
config:
- subnet: 10.89.70.0/24
关键设计逐项说明:
name: pinpoint-311-stack:显式指定 Compose 项目名,三个数据卷会命名为pinpoint-311-stack_*,便于识别与清理;zoo1/zoo2/zoo3:三节点 ZooKeeper,ZOO_SERVERS里每个节点把自己写成0.0.0.0、其余写主机名;JVMFLAGS把堆压到 256MB;pinpoint-hbase:HBASE_HEAPSIZE=512m控制 HBase JVM 堆;15 个*_TTL环境变量控制各 HBase 表的数据保留秒数(详见第五章与官方脚本);数据卷挂载在/home/pinpoint/hbase(HBase rootdir);pinpoint-mysql:restart: "no"——MySQL 只存元数据,官方便不自动重启,日常靠 compose 拉起;./initdb挂载到/docker-entrypoint-initdb.d,首次初始化时自动建表;pinpoint-web/pinpoint-collector:JAVA_TOOL_OPTIONS=-Xms256m -Xmx512m控制 JVM 堆(两服务是 Java 17 应用);collector 通过ipv4_address固定为10.89.70.30;pinpoint-agent:本身不运行业务,仅作为探针文件目录,通过data-volume共享卷把/pinpoint-agent提供给应用容器挂载;configure-agent.sh启动时会把这里的环境变量写进探针配置文件;pinpoint-quickstart:官方示例应用,通过共享卷拿到探针并以-javaagent:/pinpoint-agent/pinpoint-bootstrap.jar启动,-Dpinpoint.agentId=app-in-docker -Dpinpoint.applicationName=quickapp决定它在拓扑里的应用名。生产接入真实应用时不需要这个服务。
4.4 启动全套服务
cd /opt/pinpoint && docker compose up -d
首次启动实测回显(镜像已提前拉取时不再出现 pull 过程;首次拉取镜像约 1–2GB,视带宽需等待):
Volume pinpoint-311-stack_hbase_data Creating
Volume pinpoint-311-stack_hbase_data Creating
Volume pinpoint-311-stack_data-volume Creating
Volume pinpoint-311-stack_data-volume Creating
Volume pinpoint-311-stack_mysql_data Creating
Network pinpoint-311-net Creating
Network pinpoint-311-net Creating
Volume pinpoint-311-stack_mysql_data Creating
Volume pinpoint-311-stack_data-volume Created
Volume pinpoint-311-stack_data-volume Created
Volume pinpoint-311-stack_hbase_data Created
Volume pinpoint-311-stack_hbase_data Created
Volume pinpoint-311-stack_mysql_data Created
Volume pinpoint-311-stack_mysql_data Created
Network pinpoint-311-net Created
Network pinpoint-311-net Created
Container pinpoint-311-zoo3 Creating
Container pinpoint-311-zoo1 Creating
Container pinpoint-311-zoo2 Creating
Container pinpoint-311-redis Creating
Container pinpoint-311-mysql Creating
Container pinpoint-311-zoo3 Created
Container pinpoint-311-zoo1 Created
Container pinpoint-311-mysql Created
Container pinpoint-311-redis Created
Container pinpoint-311-zoo2 Created
Container pinpoint-311-hbase Creating
Container pinpoint-311-hbase Created
Container pinpoint-311-web Creating
Container pinpoint-311-collector Creating
Container pinpoint-311-web Created
Container pinpoint-311-collector Created
Container pinpoint-311-agent Creating
Container pinpoint-311-agent Created
Container pinpoint-311-quickstart Creating
Container pinpoint-311-quickstart Created
Container pinpoint-311-zoo1 Starting
Container pinpoint-311-redis Starting
Container pinpoint-311-zoo2 Starting
Container pinpoint-311-zoo3 Starting
Container pinpoint-311-mysql Starting
Container pinpoint-311-zoo1 Started
Container pinpoint-311-redis Started
Container pinpoint-311-zoo2 Started
Container pinpoint-311-zoo3 Started
Container pinpoint-311-hbase Starting
Container pinpoint-311-mysql Started
Container pinpoint-311-hbase Started
Container pinpoint-311-collector Starting
Container pinpoint-311-web Starting
Container pinpoint-311-collector Started
Container pinpoint-311-agent Starting
Container pinpoint-311-web Started
Container pinpoint-311-agent Started
Container pinpoint-311-quickstart Starting
Container pinpoint-311-quickstart Started
💡 说明:
up -d命令本身几秒内返回,但后台就绪需要约 8 分钟——collector 是整条链路里最慢的一环(详见 4.5)。不要看到命令返回就访问页面下结论。
4.5 启动过程与就绪时序
各服务的就绪顺序由内部初始化逻辑决定,实测时间线如下(以 docker compose up -d 为 T+0,读各服务启动日志时间戳归纳):
| 时刻 | 组件 | 实测事件 |
|---|---|---|
| T+0 | zoo1/zoo2/zoo3 | ZooKeeper 集群起成员选举,几秒内就绪 |
| T+0 起 | pinpoint-mysql | 初始化数据目录(mysqld 8.0.46 initializing → Database files initialized),随后执行 initdb 两个建表脚本 |
| T+0 起 | pinpoint-hbase | 容器入口执行 initialize-hbase.sh:start-hbase.sh(起 HMaster/HRegionServer)→ configure-hbase.sh(按 TTL 环境变量 sed 生成建表脚本)→ check-table.sh(表不存在则等 15 秒后用 hbase shell hbase-create.hbase 建 22 张表) |
| T+4min | pinpoint-quickstart / pinpoint-agent | 示例应用 Tomcat 带 -javaagent 起动,探针开始向 collector 上报(此时 collector 未就绪会先失败,属预期,见常见问题 Q1) |
| T+4min 起 | pinpoint-web | Spring Boot 启动并连 MySQL/Redis/ZooKeeper |
| T+8min | pinpoint-collector | 进程内 HBase Warmup(逐表预热 region)完成后,gRPC 三个 receiver 同时 bind:9991/9992/9993(bindaddress 0.0.0.0),此后 Agent 上报才真正可用 |
hbase 服务的初始化链路(容器入口命令实测为 /bin/sh -c /usr/local/bin/initialize-hbase.sh && tail -f /dev/null)中,TTL 的生效方式值得注意:configure-hbase.sh 会把 15 个 *_TTL 环境变量逐表 sed 进 hbase-create.hbase/hbase-update-ttl.hbase,只在建表时生效;表已存在时改 TTL 环境变量不会作用到老表,需进 HBase shell 手工 alter(见第七章)。
4.6 验证部署结果
第一步:确认全部服务在跑。
cd /opt/pinpoint && docker compose ps
实测回显:
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
pinpoint-311-agent pinpointdocker/pinpoint-agent:3.1.1 "/usr/local/bin/conf…" pinpoint-agent 5 minutes ago Up 5 minutes
pinpoint-311-collector pinpointdocker/pinpoint-collector:3.1.1 "java -cp @/app/jib-…" pinpoint-collector 5 minutes ago Up 5 minutes
pinpoint-311-hbase pinpointdocker/pinpoint-hbase:3.1.1 "/bin/sh -c '/usr/lo…" pinpoint-hbase 5 minutes ago Up 5 minutes 0.0.0.0:8149->16010/tcp, [::]:8149->16010/tcp
pinpoint-311-mysql mysql:8.0 "docker-entrypoint.s…" pinpoint-mysql 5 minutes ago Up 5 minutes 33060/tcp, 0.0.0.0:8151->3306/tcp, [::]:8151->3306/tcp
pinpoint-311-quickstart pinpointdocker/pinpoint-quickstart:latest "catalina.sh run" pinpoint-quickstart 5 minutes ago Up 5 minutes 0.0.0.0:8150->8080/tcp, [::]:8150->8080/tcp
pinpoint-311-redis redis:7.0.14 "docker-entrypoint.s…" redis 5 minutes ago Up 5 minutes 6379/tcp
pinpoint-311-web pinpointdocker/pinpoint-web:3.1.1 "java -cp @/app/jib-…" pinpoint-web 5 minutes ago Up 5 minutes 0.0.0.0:8148->8080/tcp, [::]:8148->8080/tcp
pinpoint-311-zoo1 zookeeper:3.4.13 "/docker-entrypoint.…" zoo1 5 minutes ago Up 5 minutes 2181/tcp, 2888/tcp, 3888/tcp
pinpoint-311-zoo2 zookeeper:3.4.13 "/docker-entrypoint.…" zoo2 5 minutes ago Up 5 minutes 2181/tcp, 2888/tcp, 3888/tcp
pinpoint-311-zoo3 zookeeper:3.4.13 "/docker-entrypoint.…" zoo3 5 minutes ago Up 5 minutes 2181/tcp, 2888/tcp, 3888/tcp
第二步:确认 Web 控制台可访问。
curl -I http://localhost:8148/
实测回显(HTTP 200 即正常;首次启动约 4–5 分钟后才可访问):
HTTP/1.1 200
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Cache-Control: no-cache
浏览器打开 http://<服务器IP>:8148/ 即进入 Pinpoint 控制台。
第三步:确认示例应用可访问并制造流量。
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8150/index.html
实测回显:
200
请求示例应用的慢请求端点,制造一条约 3 秒的调用记录(该端点是官方示例特意提供的演示端点):
time curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8150/sleep3.pinpoint
实测回显:
200
real 0m3.05s
user 0m0.00s
sys 0m0.00s
第四步:确认 HBase 表已建成。
docker compose exec pinpoint-hbase /opt/hbase/hbase-2.2.6/bin/hbase shell
进入 HBase shell 后执行 status 与 list,实测回显:
hbase(main):001:0> status
1 active master, 0 backup masters, 1 servers, 0 dead, 1908.0000 average load
hbase(main):002:0> list
TABLE
AgentEvent
AgentId
AgentInfo
AgentLifeCycle
ApiMetaData
Application
ApplicationIndex
ApplicationMapStatisticsCallee_Ver2
ApplicationMapStatisticsCaller_Ver2
ApplicationMapStatisticsSelf_Ver2
ApplicationTraceIndex
HostApplicationMap_Ver2
MapAgentSelf
MapAppHost
MapAppIn
MapAppOut
MapAppSelf
SqlMetaData_Ver2
SqlUidMetaData
StringMetaData
TraceIndex
TraceV2
22 row(s)
22 张 Pinpoint 表齐全即存储层就绪。输入 exit 退出 HBase shell。
第五步:确认 Agent 已注册、拓扑出图。
等 collector 就绪、示例应用有流量后(首启约 8–10 分钟),查询注册的应用列表:
curl -s http://localhost:8148/api/applications
实测回显:
[{"applicationName":"quickapp","serviceType":"TOMCAT","code":1010}]
能查到 quickapp 即 Agent→Collector→HBase→Web 全链路贯通。此时浏览器打开 Web 控制台,在左上角应用下拉框选 quickapp、时间范围选最近 5 分钟并点搜索,拓扑图出现 USER → quickapp 两个节点即为部署成功。
⚠️ 注意:若
curl /api/applications返回[],多半是 collector 尚未就绪或示例应用还没有过流量——先打一次http://localhost:8150/sleep3.pinpoint再等 30 秒重试。若始终为空,按第十一章 Q1/Q2 排查。
五、数据持久化说明
Pinpoint 的数据分三处落盘,全部使用 Compose 命名卷,docker compose down(不带 -v)不会丢数据:
| 卷名 | 挂载点 | 内容 | 对应服务 |
|---|---|---|---|
pinpoint-311-stack_hbase_data | /home/pinpoint/hbase | 全部链路数据(HBase rootdir,22 张表) | pinpoint-hbase |
pinpoint-311-stack_mysql_data | /var/lib/mysql | Web 元数据(用户组/告警规则/Spring Batch 表) | pinpoint-mysql |
pinpoint-311-stack_data-volume | /pinpoint-agent | 探针文件目录(agent 服务写入、示例应用只读挂载) | pinpoint-agent / pinpoint-quickstart |
验证卷的实测回显:
docker volume inspect pinpoint-311-stack_hbase_data --format '{{.Name}} -> {{.Mountpoint}}'
pinpoint-311-stack_hbase_data -> /var/lib/docker/volumes/pinpoint-311-stack_hbase_data/_data
要点说明:
- HBase 是唯一链路存储:拓扑、调用栈、散点数据全部在
hbase_data卷里,备份优先级最高;HBase 数据目录在容器内是/home/pinpoint/hbase(rootdir),不是 HBase 安装目录/opt/hbase; - initdb 只在首次生效:
./initdb以只读方式挂进 MySQL 的/docker-entrypoint-initdb.d,仅在mysql_data卷为空时执行;已有数据卷时新增 SQL 不会重跑; - 探针目录共享:
data-volume是 agent 与 quickstart 之间的桥梁——agent 服务的入口脚本把配置好的探针文件写进卷,应用容器挂同一个卷并以-javaagent挂载。自研应用接入时同样只需挂这个卷(或直接把/pinpoint-agent目录拷到应用机器); - 备份方式:HBase 数据可用
docker run --rm -v pinpoint-311-stack_hbase_data:/data -v /opt/pinpoint/backup:/backup ubuntu tar czf /backup/hbase_data-$(date +%F).tar.gz /data打快照(需先docker compose stop pinpoint-hbase pinpoint-web pinpoint-collector保证一致性,备完再start);MySQL 可用mysqldump常规备份。
六、环境变量表
本方案全部参数通过 compose 的 environment: 注入。按服务列出实测使用的变量、取值与说明(「镜像默认值」列来自镜像内配置文件的实测值)。
6.1 pinpoint-web
| 环境变量 | 本方案取值 | 镜像默认值 | 说明 |
|---|---|---|---|
| WEB_SERVER_PORT | 8080 | 8080 | Web 服务监听端口(容器内) |
| SPRING_PROFILES_ACTIVE | release | release | Spring 配置集(local/release 两套,决定读哪个 profiles 目录) |
| PINPOINT_ZOOKEEPER_ADDRESS | zoo1 | zoo1 | ZooKeeper 地址,多个用逗号分隔 |
| CLUSTER_ENABLE | true | false | 是否向 ZooKeeper 注册集群信息(Web 端实时 Active Thread 图依赖它) |
| ADMIN_PASSWORD | q1w2e3r4 | admin | 管理口令(映射到 pinpoint-web-root.properties 的 admin.password;见第十一章 Q8 关于登录开关的说明) |
| CONFIG_SENDUSAGE | false | true | 是否发送使用统计(映射 config.sendUsage) |
| CONFIG_SHOW_APPLICATIONSTAT | true | false | 是否在拓扑节点上展示应用统计(映射 config.show.applicationStat) |
| LOGGING_LEVEL_ROOT | INFO | INFO | 根日志级别 |
| JDBC_DRIVERCLASSNAME | com.mysql.jdbc.Driver | 同左 | JDBC 驱动类 |
| JDBC_URL | jdbc:mysql://pinpoint-mysql:3306/pinpoint?characterEncoding=UTF-8 | — | 元数据库连接串 |
| JDBC_USERNAME / JDBC_PASSWORD | admin / q1w2e3r4 | — | 元数据库账号 |
| SPRING_DATASOURCE_HIKARI_JDBCURL / USERNAME / PASSWORD | 同 JDBC_* | — | Spring Boot HikariCP 主数据源(Spring 原生前缀,优先级更高) |
| SPRING_METADATASOURCE_HIKARI_* | 同上 | — | 元数据专用 HikariCP 数据源 |
| SPRING_DATA_REDIS_HOST / PORT / USERNAME / PASSWORD | pinpoint-311-redis / 6379 / default / 空 | — | Redis 连接信息 |
| JAVA_TOOL_OPTIONS | -Xms256m -Xmx512m | 无 | JVM 堆(-Xms/-Xmx 建议控制在 256–512MB 起步) |
6.2 pinpoint-collector
| 环境变量 | 本方案取值 | 说明 |
|---|---|---|
| SPRING_PROFILES_ACTIVE | release | Spring 配置集 |
| PINPOINT_ZOOKEEPER_ADDRESS | zoo1 | ZooKeeper 地址 |
| CLUSTER_ENABLE | true | collector 也向 ZooKeeper 注册(与 Web 同集群才能实时联动) |
| FLINK_CLUSTER_ENABLE | false | 实时流聚合开关,本方案未部署 flink,必须关掉 |
| SPRING_DATASOURCE_HIKARI_JDBCURL / USERNAME / PASSWORD | 指向 pinpoint-mysql | 元数据库(与 Web 同库) |
| SPRING_DATA_REDIS_HOST / PORT / USERNAME / PASSWORD | pinpoint-311-redis / 6379 / default / 空 | Redis 连接 |
| JAVA_TOOL_OPTIONS | -Xms256m -Xmx512m | JVM 堆 |
| LOGGING_LEVEL_ROOT | INFO | 根日志级别 |
gRPC 监听端口(9991/9992/9993)与 SSL 端口(9441/9442/9443)未在 compose 覆盖,使用镜像默认值,实测启动日志:collector.receiver.grpc.agent.bindaddress.ip=0.0.0.0 / port=9991,stat 9992、span 9993。
6.3 pinpoint-agent
agent 镜像的入口脚本 configure-agent.sh 会把这些环境变量 sed 进探针配置文件(/pinpoint-agent/pinpoint-root.config 与 /pinpoint-agent/profiles/{local,release}/pinpoint.config):
| 环境变量 | 本方案取值 | 说明 |
|---|---|---|
| SPRING_PROFILES | release | 决定写 profiles/release/pinpoint.config |
| COLLECTOR_IP | pinpoint-311-collector | collector 地址(容器网络内可用服务名;跨机部署写 IP) |
| PROFILER_TRANSPORT_MODULE | GRPC | Agent→Collector 传输协议(GRPC/THRIFT,3.x 用 GRPC) |
| PROFILER_TRANSPORT_AGENT_COLLECTOR_PORT | 9991 | gRPC Agent 通道端口 |
| PROFILER_TRANSPORT_METADATA_COLLECTOR_PORT | 9991 | gRPC 元数据通道端口 |
| PROFILER_TRANSPORT_STAT_COLLECTOR_PORT | 9992 | gRPC 统计通道端口 |
| PROFILER_TRANSPORT_SPAN_COLLECTOR_PORT | 9993 | gRPC Span 通道端口 |
| COLLECTOR_TCP_PORT / COLLECTOR_STAT_PORT / COLLECTOR_SPAN_PORT | 9994 / 9995 / 9996 | THRIFT 模式端口(GRPC 模式不生效,保留默认即可) |
| PROFILER_SAMPLING_TYPE | COUNTING | 采样类型(COUNTING 按每 N 笔采 1 笔 / PERCENT 按百分比 / THROUGHPUT 按吞吐) |
| PROFILER_SAMPLING_COUNTING_SAMPLING_RATE | 1 | 每 1 笔采 1 笔(全量采样;生产建议 10–50) |
| PROFILER_SAMPLING_PERCENT_SAMPLING_RATE | 100 | 百分比采样的采样率 |
| PROFILER_SAMPLING_NEW_THROUGHPUT / CONTINUE_THROUGHPUT | 0 / 0 | 吞吐采样阈值,0 表示不启用 |
| AGENT_DEBUG_LEVEL | INFO | 探针日志级别 |
6.4 pinpoint-hbase
| 环境变量 | 本方案取值(秒) | 说明 |
|---|---|---|
| HBASE_HEAPSIZE | 512m | HBase JVM 堆(脚本据此设置 -Xmx) |
| AGENTINFO_TTL | 31536000(365 天) | AgentInfo/AgentId/应用索引类表保留期 |
| APPINDEX_TTL | 31536000(365 天) | ApplicationIndex 保留期 |
| APIMETADATA_TTL | 31536000(365 天) | API 元数据保留期 |
| TRACEV2_TTL | 5184000(60 天) | 调用链明细保留期 |
| APPTRACEINDEX_TTL | 5184000(60 天) | 调用链索引保留期 |
| APPMAPSTATCALLERV2_TTL / APPMAPSTATCALLEV2_TTL / APPMAPSTATSELFV2_TTL | 5184000(60 天) | 拓扑统计三表保留期 |
| AGENTSTATV2_TTL | 5184000(60 天) | Agent JVM 统计保留期 |
| AGENTEVENT_TTL / AGENTLIFECYCLE_TTL | 5184000(60 天) | Agent 事件/生命周期保留期 |
| APPSTATAGGRE_TTL | 5184000(60 天) | 应用统计聚合保留期 |
| HOSTAPPMAPV2_TTL | 5184000(60 天) | 主机-应用映射保留期 |
| STRINGMETADATA_TTL / SQLMETADATA_TTL | 15552000(180 天) | 字符串/SQL 元数据保留期 |
6.5 zookeeper / mysql / redis
| 服务 | 环境变量/参数 | 取值 | 说明 |
|---|---|---|---|
| zoo1–zoo3 | ZOO_MY_ID | 1/2/3 | 节点 ID,三节点分别为 1、2、3 |
| zoo1–zoo3 | ZOO_SERVERS | 见 compose | 成员列表,自己写 0.0.0.0、同伴写主机名 |
| zoo1–zoo3 | JVMFLAGS | -Xms128m -Xmx256m | ZooKeeper JVM 堆 |
| pinpoint-mysql | MYSQL_ROOT_PASSWORD | q1w2e3r4 | root 口令(示例环境) |
| pinpoint-mysql | MYSQL_USER / MYSQL_PASSWORD | admin / q1w2e3r4 | 业务账号 |
| pinpoint-mysql | MYSQL_DATABASE | pinpoint | 初始库名 |
| redis | command 参数 | --maxmemory 128mb --maxmemory-policy allkeys-lru | 内存上限与淘汰策略 |
七、配置参数说明
环境变量只覆盖了高频参数。三类服务的完整配置文件在镜像内的位置与修改方式如下(参数级逐项解析见本专栏《Pinpoint 3.1.1 配置参数详解》)。
Web(容器内 /app/resources/):application.yml(Spring 主配置)、pinpoint-web-root.properties(admin.password、config.sendUsage、config.show.applicationStat、websocket.allowedOrigins 等)、hbase-root.properties(HBase 连接)、profiles/{local,release}/{hbase.properties,pinpoint-web.properties}。环境变量(如 ADMIN_PASSWORD)的优先级高于 properties 文件。
Collector(容器内 /app/resources/):application.yml、pinpoint-collector-root.properties(基础配置)、pinpoint-collector-grpc-root.properties(gRPC 监听端口与 bindaddress)、hbase-root.properties。默认 gRPC 监听 0.0.0.0:9991/9992/9993,跨机部署无需改 bindaddress,只需放行防火墙。
Agent(/pinpoint-agent/ 目录):pinpoint-root.config(传输端口等全局项)与 profiles/{local,release}/pinpoint.config(collector 地址、采样率等)。两种改法:改 compose 环境变量重建(推荐,幂等);或直接改 data-volume 卷里的配置文件后重启应用。
TTL 类参数:只在建表时经 configure-hbase.sh 写进建表脚本。首启后修改 TTL 环境变量对已存在的表无效,需进 HBase shell 执行 alter '表名', {TTL => '秒数'},或删卷重建。
⚠️ 注意:JVM 堆相关只有三个入口——web/collector 的
JAVA_TOOL_OPTIONS、hbase 的HBASE_HEAPSIZE、示例应用的JAVA_OPTS。修改后必须验证实际生效值(方法见第九章与配置详解篇)。
八、配置文件挂载
镜像内置配置开箱即用;如需深度定制(改日志策略、HBase 连接、页面行为),用 volumes 把宿主机配置文件覆盖进容器。挂载点与容器内路径对照:
| 服务 | 容器内路径 | 建议宿主机路径 | 用途 |
|---|---|---|---|
| pinpoint-web | /app/resources/log4j2-spring.xml | ./conf/web/log4j2-spring.xml | Web 日志策略 |
| pinpoint-web | /app/resources/pinpoint-web-root.properties | ./conf/web/pinpoint-web-root.properties | Web 行为参数 |
| pinpoint-collector | /app/resources/pinpoint-collector-grpc-root.properties | ./conf/collector/pinpoint-collector-grpc-root.properties | gRPC 监听参数 |
| pinpoint-collector | /app/resources/log4j2-spring.xml | ./conf/collector/log4j2-spring.xml | 收集器日志策略 |
| pinpoint-agent | /pinpoint-agent/pinpoint-root.config | ./conf/agent/pinpoint-root.config | 探针全局配置 |
操作方式:先从镜像里拷出原文件作为底稿,修改后在对应服务的 volumes: 段加一行挂载,再 docker compose up -d 重建该服务。以 Web 的日志配置为例:
# 从镜像中拷出原文件作为修改底稿
docker compose cp pinpoint-web:/app/resources/log4j2-spring.xml ./conf/web/log4j2-spring.xml
然后在 pinpoint-web 服务下增加挂载(相对 compose 文件所在目录):
volumes:
- ./conf/web/log4j2-spring.xml:/app/resources/log4j2-spring.xml:ro
docker compose up -d pinpoint-web
说明::ro 表示容器内只读,防止服务改写宿主机文件;挂载 properties 类文件前务必确认其中键名拼写,Spring 启动对未知键不报错但会静默忽略。
九、等价 docker run
不使用 Compose 时,以下命令与 compose 定义一一等价,可用于逐个手工拉起(按依赖顺序执行;pinpoint-311-net 网络需先创建)。生产仍建议用 Compose 统一管理。
1. 创建网络与数据卷:
docker network create --driver bridge \
--subnet 10.89.70.0/24 pinpoint-311-net
docker volume create pinpoint-311-stack_hbase_data
docker volume create pinpoint-311-stack_mysql_data
docker volume create pinpoint-311-stack_data-volume
2. ZooKeeper 三节点(zoo2/zoo3 同理,替换 MY_ID 与 ZOO_SERVERS 自身项):
docker run -d --name pinpoint-311-zoo1 --hostname zoo1 \
--network pinpoint-311-net --restart always \
-e ZOO_MY_ID=1 \
-e ZOO_SERVERS="server.1=0.0.0.0:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888" \
-e JVMFLAGS="-Xms128m -Xmx256m" zookeeper:3.4.13
3. MySQL:
docker run -d --name pinpoint-311-mysql --hostname pinpoint-mysql \
--network pinpoint-311-net -p 8151:3306 \
-v /opt/pinpoint/initdb:/docker-entrypoint-initdb.d:ro \
-v pinpoint-311-stack_mysql_data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=q1w2e3r4 \
-e MYSQL_USER=admin -e MYSQL_PASSWORD=q1w2e3r4 \
-e MYSQL_DATABASE=pinpoint mysql:8.0
4. Redis:
docker run -d --name pinpoint-311-redis --hostname pinpoint-redis \
--network pinpoint-311-net --restart always \
redis:7.0.14 redis-server --maxmemory 128mb --maxmemory-policy allkeys-lru
5. HBase(含全部 TTL 变量,此处节选关键变量,完整清单同 compose 第四章):
docker run -d --name pinpoint-311-hbase \
--network pinpoint-311-net --restart always \
-v pinpoint-311-stack_hbase_data:/home/pinpoint/hbase \
-p 8149:16010 \
-e HBASE_HEAPSIZE=512m \
-e AGENTINFO_TTL=31536000 -e APPINDEX_TTL=31536000 \
-e TRACEV2_TTL=5184000 -e APPTRACEINDEX_TTL=5184000 \
-e APPMAPSTATCALLERV2_TTL=5184000 -e APPMAPSTATCALLEV2_TTL=5184000 \
-e APPMAPSTATSELFV2_TTL=5184000 -e AGENTSTATV2_TTL=5184000 \
-e AGENTEVENT_TTL=5184000 -e AGENTLIFECYCLE_TTL=5184000 \
-e APPSTATAGGRE_TTL=5184000 -e HOSTAPPMAPV2_TTL=5184000 \
-e STRINGMETADATA_TTL=15552000 -e SQLMETADATA_TTL=15552000 \
-e APIMETADATA_TTL=31536000 \
pinpointdocker/pinpoint-hbase:3.1.1
6. Collector(固定 IP):
docker run -d --name pinpoint-311-collector \
--network pinpoint-311-net --ip 10.89.70.30 --restart always \
-e SPRING_PROFILES_ACTIVE=release \
-e PINPOINT_ZOOKEEPER_ADDRESS=zoo1 \
-e CLUSTER_ENABLE=true -e FLINK_CLUSTER_ENABLE=false \
-e SPRING_DATASOURCE_HIKARI_JDBCURL="jdbc:mysql://pinpoint-mysql:3306/pinpoint?characterEncoding=UTF-8" \
-e SPRING_DATASOURCE_HIKARI_USERNAME=admin \
-e SPRING_DATASOURCE_HIKARI_PASSWORD=q1w2e3r4 \
-e SPRING_DATA_REDIS_HOST=pinpoint-311-redis \
-e SPRING_DATA_REDIS_PORT=6379 \
-e JAVA_TOOL_OPTIONS="-Xms256m -Xmx512m" \
pinpointdocker/pinpoint-collector:3.1.1
7. Web:
docker run -d --name pinpoint-311-web \
--network pinpoint-311-net --restart always \
-p 8148:8080 \
-e SPRING_PROFILES_ACTIVE=release \
-e PINPOINT_ZOOKEEPER_ADDRESS=zoo1 \
-e CLUSTER_ENABLE=true \
-e ADMIN_PASSWORD=q1w2e3r4 \
-e CONFIG_SENDUSAGE=false \
-e CONFIG_SHOW_APPLICATIONSTAT=true \
-e JDBC_DRIVERCLASSNAME=com.mysql.jdbc.Driver \
-e JDBC_URL="jdbc:mysql://pinpoint-mysql:3306/pinpoint?characterEncoding=UTF-8" \
-e JDBC_USERNAME=admin -e JDBC_PASSWORD=q1w2e3r4 \
-e SPRING_DATASOURCE_HIKARI_JDBCURL="jdbc:mysql://pinpoint-mysql:3306/pinpoint?characterEncoding=UTF-8" \
-e SPRING_DATASOURCE_HIKARI_USERNAME=admin \
-e SPRING_DATASOURCE_HIKARI_PASSWORD=q1w2e3r4 \
-e SPRING_DATA_REDIS_HOST=pinpoint-311-redis \
-e SPRING_DATA_REDIS_PORT=6379 \
-e JAVA_TOOL_OPTIONS="-Xms256m -Xmx512m" \
pinpointdocker/pinpoint-web:3.1.1
8. Agent 目录与应用挂载(以示例应用为例):
docker run -d --name pinpoint-311-agent \
--network pinpoint-311-net --restart unless-stopped \
-v pinpoint-311-stack_data-volume:/pinpoint-agent \
-e SPRING_PROFILES=release \
-e COLLECTOR_IP=10.89.70.30 \
-e PROFILER_TRANSPORT_MODULE=GRPC \
-e PROFILER_SAMPLING_TYPE=COUNTING \
-e PROFILER_SAMPLING_COUNTING_SAMPLING_RATE=1 \
pinpointdocker/pinpoint-agent:3.1.1
docker run -d --name pinpoint-311-quickstart \
--network pinpoint-311-net -p 8150:8080 \
-v pinpoint-311-stack_data-volume:/pinpoint-agent \
-e JAVA_OPTS="-Xms256m -Xmx512m -javaagent:/pinpoint-agent/pinpoint-bootstrap.jar -Dpinpoint.agentId=app-in-docker -Dpinpoint.applicationName=quickapp -Dpinpoint.profiler.profiles.active=release" \
pinpointdocker/pinpoint-quickstart:latest
要点:跨机接入真实应用时,COLLECTOR_IP 写 collector 所在宿主机的外网 IP 并放行 9991/9992/9993 三个 TCP 端口;应用侧只需挂载探针目录并加 -javaagent 与 -Dpinpoint.* 启动参数。
十、常用运维命令
以下命令均在部署目录 /opt/pinpoint 下执行。
查看服务状态(实测回显见 4.6 第一步):
docker compose ps
查看实时日志(-f 跟踪、--tail 限定行数,排障首选):
docker compose logs --tail 50 pinpoint-collector
docker compose logs -f pinpoint-web
collector 就绪的标志性日志(实测):进程内 HBase Warmup 结束后出现 grpcAgentReceiver/grpcSpanReceiver/grpcStatReceiver 依次 Start、9991/9992/9993 bind 完成。
停止单个服务(实测回显):
docker compose stop pinpoint-web
Container pinpoint-311-web Stopping
Container pinpoint-311-web Stopped
启动单个服务(实测回显):
docker compose start pinpoint-web
Container pinpoint-311-web Starting
Container pinpoint-311-web Started
确认状态:
docker ps --format '{{.Names}} {{.Status}}' | grep pinpoint-311-web
pinpoint-311-web Up 3 seconds
进入容器排查(以 HBase shell 为例,实测回显见 4.6 第四步):
docker compose exec pinpoint-hbase /opt/hbase/hbase-2.2.6/bin/hbase shell
整体启停:
docker compose stop # 全部停止(保留数据卷)
docker compose start # 全部启动
docker compose restart pinpoint-collector # 重启单个服务
docker compose down # 删除容器与网络,保留数据卷
docker compose down -v # 连同数据卷一起删除(链路数据清零,慎用)
⚠️ 注意:HBase/collector 每次冷启动都要走 Warmup 与建表检查,整个链路从 stop 到再次可用约需 3–5 分钟,web 页面短暂报「HBase 连接失败」属正常,不要急着重建。
十一、常见问题
以下问题均来自本次部署的实际排障记录,含错误现象、定位过程与结论。
11.1 Agent 日志大量 Connection refused,数据上报失败
现象:示例应用启动日志(docker compose logs pinpoint-quickstart)刷 AgentInfoSender 告警,实测关键行:
[ nfoSender-Timer] WARN c.n.p.p.AgentInfoSender -- Failed to send agentInfo={objectName='ObjectNameV1{agentId='app-in-docker', agentName='app-in-docker', applicationName='quickapp'}', ... serverType=TOMCAT, jvmVersion='1.8.0_402', agentVersion='3.1.1', ...}
io.grpc.StatusRuntimeException: UNAVAILABLE: io exception
Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: pinpoint-311-collector/10.89.70.30:9991
原因与结论:Agent 比 collector 先就绪(示例应用 T+4min 起、collector gRPC bind 在 T+8min),上报落空。Agent 会周期性重试,collector 就绪后自动恢复,无需处理;确认恢复可用 curl -s "http://localhost:8148/api/v1/agents?applicationName=quickapp&from=<开始毫秒>&to=<当前毫秒>" 看 state.code=100(Running)。
11.2 collector 迟迟不能收数
现象:其余服务几分钟就绪,collector 始终「在启动」。
原因与结论:collector 启动时要做进程内 HBase Warmup(逐表预热 region,日志可见 Warmup for hbase table ... AgentEvent regionSize:1),完成后才 bind gRPC 9991/9992/9993。实测全程约 8 分钟,是整条链路最慢的一环。判断标准:日志出现 grpcAgentReceiver/grpcSpanReceiver/grpcStatReceiver Start 即就绪;在 8 分钟内反复重启 collector 只会更慢。
11.3 Web 拓扑图为空
现象:控制台选 quickapp 查询,拓扑空白;web 日志实测:
agentIdEntry not found. application:DEFAULT(0)/quickapp(SPRING_BOOT:1210)
Building empty application map
原因与结论:查询时间窗内数据尚未落库(Agent 注册 + 首批 Span 写入有延迟)。先对示例应用打几次流量(curl http://localhost:8150/sleep3.pinpoint),等 1–2 分钟再查。若仍为空,检查应用下拉框选的应用名与时间范围。
11.4 用 SPRING_BOOT 查询拓扑/数据为空
现象:手工调 API 时按 SPRING_BOOT 传参查不到任何数据。
原因与结论:这是 Pinpoint 的经典陷阱——serviceType 由探针按运行环境自动识别,不由应用名决定。本环境示例应用虽是 Spring 风格,但跑在独立 Tomcat 里,注册为 TOMCAT(1010)。实测确认:
$ curl -s http://localhost:8148/api/applications
[{"applicationName":"quickapp","serviceType":"TOMCAT","code":1010}]
查询一律先以 /api/applications 返回的 serviceType/code 为准,不要臆测 SPRING_BOOT(1210)。
11.5 GET /api/servermap 返回 404
现象:按老文档调 GET /api/servermap 得 404(No static resource)。
原因与结论:3.1.x 的正确路径是 /api/servermap/serverMap(前端资源同理走 /api/servermap/serviceMap)。完整可用的查询(实测):
curl -s "http://localhost:8148/api/servermap/serverMap?serviceName=DEFAULT&applicationName=quickapp&serviceTypeName=TOMCAT&serviceTypeCode=1010&from=1792713840000&to=1792717440000&callerRange=1&calleeRange=1&bidirectional=false&wasOnly=false"
返回 applicationMapData 下的 nodeDataArray(USER、quickapp 两节点)与 linkDataArray(一条链路)。时间参数为 epoch 毫秒,窗口不能超过 2 天(见 11.7)。
11.6 /api/servermap/serviceMap 报 Service map is not enabled
现象:调 serviceMap 端点返回异常,collector/web 日志实测:
[AOP] ERROR MapController.getServiceMapData execution time:0ms param:[ApplicationForm{serviceName='DEFAULT', applicationName='quickapp', ...}] error:Service map is not enabled
java.lang.UnsupportedOperationException: Service map is not enabled
原因与结论:serviceMap 是 3.1 的新版服务地图特性,需专门的功能开关与数据链路支撑,默认 compose 镜像未启用,属预期限制。日常拓扑用 /api/servermap/serverMap 即可。
11.7 查询窗口超过 2 天报错或被截断
原因与结论:Web 启动日志实测 serverMapPeriodMax=2(单位天),拓扑查询窗口上限 2 天;可选档位实测为 serverMapPeriodInterval=[5m, 20m, 1h, 3h, 6h, 12h, 1d, 2d]。查更久远数据需分段查询。
11.8 JDK17 反射告警刷屏
现象:web/collector 启动日志出现:
java.lang.reflect.InaccessibleObjectException: Unable to make static boolean java.nio.Bits.unaligned() accessible: module java.base does not "opens java.nio" to unnamed module
原因与结论:3.1.x 服务端运行在 Java 17 上,部分老依赖的反射调用触发的模块系统告警,实测不影响功能,可忽略;强迫症可在 JAVA_TOOL_OPTIONS 里追加 --add-opens java.base/java.nio=ALL-UNNAMED 消除。
11.9 登录开关设置了却不生效(405)
现象:给 web 加 PINPOINT_MODULES_WEB_LOGIN=basic-login 并重建后,POST /login 返回 405 Method Not Allowed,启动日志也没有登录模块安装记录(对照:Webhook 模块启用时会打印 Install WebhookModule)。
原因与结论:实测(镜像内自带 pinpoint-basic-login-3.1.1.jar,JWT 过滤器在,GET /login 返回 200)该 compose 环境变量在 3.1.1 官方镜像中未生效,Web 一直以无登录状态运行,ADMIN_PASSWORD 不会真正启用认证。生产部署请勿裸奔:在 Pinpoint 前置一层 Nginx 反向代理做 Basic Auth/IP 白名单,这是当前 Compose 形态下最可靠的访问控制方式。
11.10 端口/网段冲突
现象:up -d 报端口被占用或网段重叠。
原因与结论:改 compose 中 ports: 左侧宿主端口,或改 subnet/ipv4_address 换一个空闲网段( collector 固定 IP 要与新网段同段,且 agent 侧 COLLECTOR_IP 若写的是 IP 需同步更新)。
十二、参考链接
- 官方主仓库:https://github.com/pinpoint-apm/pinpoint
- 官方 Docker 仓库(已归档,compose 参考):https://github.com/pinpoint-apm/pinpoint-docker
- Docker Hub 镜像:https://hub.docker.com/r/pinpointdocker/pinpoint-hbase
- 官方文档站:https://pinpoint-apm.gitbook.io/pinpoint
- 官方 Kubernetes 部署(生产推荐):https://github.com/pinpoint-apm/pinpoint-kubernetes
- 本站系列:《Pinpoint 3.1.1 介绍与选型指南》(版本背景、架构与选型对比)