Pinpoint 3.1.1 Docker Compose 部署指南

用 Docker Compose 在单台 Linux 服务器从零部署 Pinpoint 3.1.1 全链路监控(Web 控制台+数据收集器+HBase 存储+Agent 探针+示例应用),覆盖镜像选型、首启时序、数据持久化、环境变量表、等价 docker run 与 9 类排障实录,全部命令实测通过。

PinpointPinpoint应用监控可观测性2026/10/23

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 compose v2 插件语法)
  • 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 固定 IP 10.89.70.30

二、镜像选型说明

Pinpoint 官方在 Docker Hub 的 pinpointdocker 组织下为每个组件发布独立镜像,版本 tag 与 GitHub Release 一一对应。本章给出本方案选用的镜像清单与取舍理由。

服务镜像版本角色说明
zoo1 / zoo2 / zoo3zookeeper3.4.13ZooKeeper 三节点,collector/web 集群注册(CLUSTER_ENABLE)
pinpoint-hbasepinpointdocker/pinpoint-hbase3.1.1内置 HBase 2.2.6 + Pinpoint 全部表结构初始化脚本,链路数据存储
pinpoint-mysqlmysql8.0仅存 Web 元数据(用户组/告警规则/任务表),实测拉取为 8.0.46
pinpoint-webpinpointdocker/pinpoint-web3.1.1Web 控制台(Spring Boot + 前端 SPA),查询 HBase 展示拓扑/调用栈
pinpoint-collectorpinpointdocker/pinpoint-collector3.1.1gRPC 数据收集器(9991/9992/9993),接收 Agent 上报写 HBase
pinpoint-agentpinpointdocker/pinpoint-agent3.1.1探针安装目录(本身不跑业务),通过共享卷提供给应用挂载
pinpoint-quickstartpinpointdocker/pinpoint-quickstartlatest官方示例应用(Tomcat 8 + JDK 8 testapp),用于开箱验证,生产可不部署
redisredis7.0.14web/collector 的缓存(实测配置 --maxmemory 128mb --maxmemory-policy allkeys-lru)

选型要点解读:

  1. 版本对齐:Pinpoint 3.1.x 的 Agent 与 Collector 强耦合(官方兼容矩阵:3.1.x agent 仅兼容 3.1.x collector),四个 pinpointdocker 镜像必须统一用 3.1.1,不要混用 3.0.x;
  2. 裁剪说明:官方 pinpoint-docker 仓库的 docker-compose.yml 是含 flink×2、batch、pinot、kafka 等 13+ 服务的「全家桶」,本方案裁剪为 8 类 10 个服务(3×ZooKeeper + HBase + MySQL + Web + Collector + Agent + 示例应用 + Redis),去掉实时流聚合(flink)与告警批处理(batch)等重依赖,保留「探针 → 收集 → 存储 → 展示」最小可用链路;
  3. 仓库状态:官方 pinpoint-docker 仓库已归档不再维护(官方生产建议转向 pinpoint-kubernetes),但镜像仍在 Docker Hub 随新版本持续发布,Compose 路径作为单机部署依然可用;
  4. 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

关键设计逐项说明:

  1. name: pinpoint-311-stack:显式指定 Compose 项目名,三个数据卷会命名为 pinpoint-311-stack_*,便于识别与清理;
  2. zoo1/zoo2/zoo3:三节点 ZooKeeper,ZOO_SERVERS 里每个节点把自己写成 0.0.0.0、其余写主机名;JVMFLAGS 把堆压到 256MB;
  3. pinpoint-hbase:HBASE_HEAPSIZE=512m 控制 HBase JVM 堆;15 个 *_TTL 环境变量控制各 HBase 表的数据保留秒数(详见第五章与官方脚本);数据卷挂载在 /home/pinpoint/hbase(HBase rootdir);
  4. pinpoint-mysql:restart: "no"——MySQL 只存元数据,官方便不自动重启,日常靠 compose 拉起;./initdb 挂载到 /docker-entrypoint-initdb.d,首次初始化时自动建表;
  5. pinpoint-web / pinpoint-collector:JAVA_TOOL_OPTIONS=-Xms256m -Xmx512m 控制 JVM 堆(两服务是 Java 17 应用);collector 通过 ipv4_address 固定为 10.89.70.30;
  6. pinpoint-agent:本身不运行业务,仅作为探针文件目录,通过 data-volume 共享卷把 /pinpoint-agent 提供给应用容器挂载;configure-agent.sh 启动时会把这里的环境变量写进探针配置文件;
  7. 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+0zoo1/zoo2/zoo3ZooKeeper 集群起成员选举,几秒内就绪
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+4minpinpoint-quickstart / pinpoint-agent示例应用 Tomcat 带 -javaagent 起动,探针开始向 collector 上报(此时 collector 未就绪会先失败,属预期,见常见问题 Q1)
T+4min 起pinpoint-webSpring Boot 启动并连 MySQL/Redis/ZooKeeper
T+8minpinpoint-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/mysqlWeb 元数据(用户组/告警规则/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

要点说明:

  1. HBase 是唯一链路存储:拓扑、调用栈、散点数据全部在 hbase_data 卷里,备份优先级最高;HBase 数据目录在容器内是 /home/pinpoint/hbase(rootdir),不是 HBase 安装目录 /opt/hbase;
  2. initdb 只在首次生效:./initdb 以只读方式挂进 MySQL 的 /docker-entrypoint-initdb.d,仅在 mysql_data 卷为空时执行;已有数据卷时新增 SQL 不会重跑;
  3. 探针目录共享:data-volume 是 agent 与 quickstart 之间的桥梁——agent 服务的入口脚本把配置好的探针文件写进卷,应用容器挂同一个卷并以 -javaagent 挂载。自研应用接入时同样只需挂这个卷(或直接把 /pinpoint-agent 目录拷到应用机器);
  4. 备份方式: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_PORT80808080Web 服务监听端口(容器内)
SPRING_PROFILES_ACTIVEreleasereleaseSpring 配置集(local/release 两套,决定读哪个 profiles 目录)
PINPOINT_ZOOKEEPER_ADDRESSzoo1zoo1ZooKeeper 地址,多个用逗号分隔
CLUSTER_ENABLEtruefalse是否向 ZooKeeper 注册集群信息(Web 端实时 Active Thread 图依赖它)
ADMIN_PASSWORDq1w2e3r4admin管理口令(映射到 pinpoint-web-root.properties 的 admin.password;见第十一章 Q8 关于登录开关的说明)
CONFIG_SENDUSAGEfalsetrue是否发送使用统计(映射 config.sendUsage)
CONFIG_SHOW_APPLICATIONSTATtruefalse是否在拓扑节点上展示应用统计(映射 config.show.applicationStat)
LOGGING_LEVEL_ROOTINFOINFO根日志级别
JDBC_DRIVERCLASSNAMEcom.mysql.jdbc.Driver同左JDBC 驱动类
JDBC_URLjdbc:mysql://pinpoint-mysql:3306/pinpoint?characterEncoding=UTF-8—元数据库连接串
JDBC_USERNAME / JDBC_PASSWORDadmin / q1w2e3r4—元数据库账号
SPRING_DATASOURCE_HIKARI_JDBCURL / USERNAME / PASSWORD同 JDBC_*—Spring Boot HikariCP 主数据源(Spring 原生前缀,优先级更高)
SPRING_METADATASOURCE_HIKARI_*同上—元数据专用 HikariCP 数据源
SPRING_DATA_REDIS_HOST / PORT / USERNAME / PASSWORDpinpoint-311-redis / 6379 / default / 空—Redis 连接信息
JAVA_TOOL_OPTIONS-Xms256m -Xmx512m无JVM 堆(-Xms/-Xmx 建议控制在 256–512MB 起步)

6.2 pinpoint-collector

环境变量本方案取值说明
SPRING_PROFILES_ACTIVEreleaseSpring 配置集
PINPOINT_ZOOKEEPER_ADDRESSzoo1ZooKeeper 地址
CLUSTER_ENABLEtruecollector 也向 ZooKeeper 注册(与 Web 同集群才能实时联动)
FLINK_CLUSTER_ENABLEfalse实时流聚合开关,本方案未部署 flink,必须关掉
SPRING_DATASOURCE_HIKARI_JDBCURL / USERNAME / PASSWORD指向 pinpoint-mysql元数据库(与 Web 同库)
SPRING_DATA_REDIS_HOST / PORT / USERNAME / PASSWORDpinpoint-311-redis / 6379 / default / 空Redis 连接
JAVA_TOOL_OPTIONS-Xms256m -Xmx512mJVM 堆
LOGGING_LEVEL_ROOTINFO根日志级别

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_PROFILESrelease决定写 profiles/release/pinpoint.config
COLLECTOR_IPpinpoint-311-collectorcollector 地址(容器网络内可用服务名;跨机部署写 IP)
PROFILER_TRANSPORT_MODULEGRPCAgent→Collector 传输协议(GRPC/THRIFT,3.x 用 GRPC)
PROFILER_TRANSPORT_AGENT_COLLECTOR_PORT9991gRPC Agent 通道端口
PROFILER_TRANSPORT_METADATA_COLLECTOR_PORT9991gRPC 元数据通道端口
PROFILER_TRANSPORT_STAT_COLLECTOR_PORT9992gRPC 统计通道端口
PROFILER_TRANSPORT_SPAN_COLLECTOR_PORT9993gRPC Span 通道端口
COLLECTOR_TCP_PORT / COLLECTOR_STAT_PORT / COLLECTOR_SPAN_PORT9994 / 9995 / 9996THRIFT 模式端口(GRPC 模式不生效,保留默认即可)
PROFILER_SAMPLING_TYPECOUNTING采样类型(COUNTING 按每 N 笔采 1 笔 / PERCENT 按百分比 / THROUGHPUT 按吞吐)
PROFILER_SAMPLING_COUNTING_SAMPLING_RATE1每 1 笔采 1 笔(全量采样;生产建议 10–50)
PROFILER_SAMPLING_PERCENT_SAMPLING_RATE100百分比采样的采样率
PROFILER_SAMPLING_NEW_THROUGHPUT / CONTINUE_THROUGHPUT0 / 0吞吐采样阈值,0 表示不启用
AGENT_DEBUG_LEVELINFO探针日志级别

6.4 pinpoint-hbase

环境变量本方案取值(秒)说明
HBASE_HEAPSIZE512mHBase JVM 堆(脚本据此设置 -Xmx)
AGENTINFO_TTL31536000(365 天)AgentInfo/AgentId/应用索引类表保留期
APPINDEX_TTL31536000(365 天)ApplicationIndex 保留期
APIMETADATA_TTL31536000(365 天)API 元数据保留期
TRACEV2_TTL5184000(60 天)调用链明细保留期
APPTRACEINDEX_TTL5184000(60 天)调用链索引保留期
APPMAPSTATCALLERV2_TTL / APPMAPSTATCALLEV2_TTL / APPMAPSTATSELFV2_TTL5184000(60 天)拓扑统计三表保留期
AGENTSTATV2_TTL5184000(60 天)Agent JVM 统计保留期
AGENTEVENT_TTL / AGENTLIFECYCLE_TTL5184000(60 天)Agent 事件/生命周期保留期
APPSTATAGGRE_TTL5184000(60 天)应用统计聚合保留期
HOSTAPPMAPV2_TTL5184000(60 天)主机-应用映射保留期
STRINGMETADATA_TTL / SQLMETADATA_TTL15552000(180 天)字符串/SQL 元数据保留期

6.5 zookeeper / mysql / redis

服务环境变量/参数取值说明
zoo1–zoo3ZOO_MY_ID1/2/3节点 ID,三节点分别为 1、2、3
zoo1–zoo3ZOO_SERVERS见 compose成员列表,自己写 0.0.0.0、同伴写主机名
zoo1–zoo3JVMFLAGS-Xms128m -Xmx256mZooKeeper JVM 堆
pinpoint-mysqlMYSQL_ROOT_PASSWORDq1w2e3r4root 口令(示例环境)
pinpoint-mysqlMYSQL_USER / MYSQL_PASSWORDadmin / q1w2e3r4业务账号
pinpoint-mysqlMYSQL_DATABASEpinpoint初始库名
rediscommand 参数--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.xmlWeb 日志策略
pinpoint-web/app/resources/pinpoint-web-root.properties./conf/web/pinpoint-web-root.propertiesWeb 行为参数
pinpoint-collector/app/resources/pinpoint-collector-grpc-root.properties./conf/collector/pinpoint-collector-grpc-root.propertiesgRPC 监听参数
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 需同步更新)。

十二、参考链接