# jd **Repository Path**: unihao/jd ## Basic Information - **Project Name**: jd - **Description**: 面试题库 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-10 - **Last Updated**: 2026-09-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Java 高级开发面试复习工具 面向 Java 高级开发岗位面试的**一站式复习与实战工具**。涵盖简历解析、题库管理、**AI 智能面试(Agent 驱动)**、Java 实操故障排查沙箱、学习数据统计五大模块。支持离线使用(内置模拟 AI / 纯本地引擎),也可接入 DeepSeek / OpenAI 兼容大模型获得真实智能评分。 ## 功能概览 | 模块 | 功能要点 | |------|---------| | 学习仪表盘 | 题量统计、掌握度分布、标签热力、最近面试与沙箱记录 | | **AI 智能面试** | **接入开源 interview-mock-skill 全套面试能力**:固定状态机 `INIT→RESUME_PARSE→INTERVIEWING→REPORT→END`、6 个标准 Skill 自动转 DeepSeek Function Call Tools、四维锚点评分(**分数由本地引擎算,模型只抽证据**)、低分自动 grilling 深挖、动态难度调节、复盘报告 + 学习卡。WebSocket 聊天 + REST 双通道 | | 简历解析 | 文本/PDF 导入 → AI 提取技术知识点 → 一键生成面试题草稿并导入题库 | | 题库管理 | 搜索分页、三种题型(简答/单选/多选/实操)、难度与掌握度、标签管理、**Excel 导入导出 + 模板下载** | | 模拟面试(经典) | **题库模式**:逐题作答 + AI 评分;**动态模式**:AI 追问仿真面试;温和/压力两种风格;四维度报告;低分自动入错题本;**复盘报告导出 Markdown** | | 实操沙箱 | 5 个真实故障案例(GC 泄漏/死锁/Dubbo RPC/Redis/MySQL 慢 SQL),仿真终端 + 分步引导 + AI 判定 + 报告打分;可选 Docker 真实容器执行 | | 错题本 | 面试低分题 + 手动加入的错题,折叠展示参考答案 | | AI 设置 | 提供方切换(离线模拟/DeepSeek/OpenAI 兼容)、API Key 脱敏存储、测试连接、**每日 Token 额度限制**与**用量统计面板** | > **AI 智能面试 vs 模拟面试(经典)**:前者是本次新增的 Agent 驱动主链路,规则、题库、评分、深挖全部本地化,可审计、可复现;后者是原有实现,保留但标记为 legacy,两者数据与入口完全隔离。 > 完整设计、方案评审(含对原始 6 条要求的逐条修正)与验证结果见 **[docs/agent-interview-design.md](docs/agent-interview-design.md)**。 ## 技术栈 - **后端**:Spring Boot 3.2.5 / Java 21 / MySQL 8(默认)/ SQLite(可选 profile)/ Hibernate / PDFBox / EasyExcel / docker-java / **Spring WebSocket** / **Redis(可选,缺失自动回落内存)** - **前端**:Vue 3 / Vite / Element Plus / Vue Router / Pinia / Axios / 原生 WebSocket - **AI**:可插拔架构,内置离线 Mock(9 大方向知识库),OpenAI Chat Completions 兼容协议(DeepSeek/OpenAI),失败自动降级 Mock - **Agent 智能面试**走标准 **Function Call** 协议(`tools` / `tool_calls` / `tool` 消息回灌),并带独立熔断器 - **监控**:Spring Boot Actuator + Micrometer → Prometheus 采集 → Grafana 看板(数据源与内置看板自动装配) - **部署**:Docker 多阶段构建 + Docker Compose 编排(含 MySQL / Redis / Prometheus / Grafana 全套) ## AI 智能面试的 6 个标准 Skill 后端自动读取 skill、自动生成 DeepSeek 可用的 Tools 结构,并按状态机阶段裁剪模型可见的工具: | Skill | 作用 | 谁在算 | |-------|------|--------| | `parse_resume` | 简历结构化解析(技能/项目/年限/弱项) | 模型抽语义 + **本地**校验技能是否真在简历里出现、**本地**决定出题领域 | | `get_interview_question` | 按岗位/项目/难度出题 | **全本地**(318 题题库 + 固定策略链:复习优先 → 薄弱优先 → 简历命中 → 深度递进) | | `evaluate_answer` | 四维打分与点评 | 模型只抽「原话证据 + 要点命中」,**分数由本地锚点引擎计算** | | `grilling_deep_dig` | 低分自动深挖追问(核心拷打) | 模型生成措辞 + **本地**判定触发与收敛;模型不可用时走本地模板追问 | | `adjust_difficulty` | 动态难度调节 | **全本地**(滚动均分 + 连续高低分 + 深挖锁定) | | `generate_interview_report` | 复盘报告 + 学习卡 | 分数由服务端算好,模型只组织语言;学习卡按上游规则本地生成 | **硬性规则**:禁止模型自编题目、禁止模型自行打分;一题一评;任一维 ≤2 必深挖;单次只允许一次工具调用。 详见 [docs/agent-interview-design.md](docs/agent-interview-design.md)。 ## 快速开始 ### 方式一:Docker 一键启动(推荐,Linux) ```bash git clone && cd jd docker compose up -d --build ``` 启动后访问: | 服务 | 地址 | 说明 | |------|------|------| | 前端页面 | http://localhost:8542 | 应用入口 | | 后端 API | http://127.0.0.1:8541/api/health | 健康检查(仅本机) | > 默认使用 **MySQL 8** 作为数据库(容器自带,数据持久化在 `mysql-data` 卷)。 > 本项目**不发布任何监控端口**:Prometheus / Grafana / Exporter 都由 > [nightjar](https://github.com/unihaoke/nightjar) 侧承担(接入后 Grafana 在 `http://:3000`)。 > 后端指标端点 `/actuator/prometheus` 供平台抓取,日志落 `backend-logs` 卷供平台采集。 > Redis 用于 Agent 面试的幂等与会话热态;**它不是硬依赖**——`AGENT_INTERVIEW_REDIS_ENABLED=false` 或 Redis 不可用时,后端自动回落到内存实现,面试功能不受影响。 > > **MySQL / Redis 不向宿主机发布端口**(数据面为 internal 网络)。需要临时直连请用一次性容器: > `docker compose run --rm mysql mysql -h mysql -uroot -p"$DB_PASS" interview_review` > `docker compose run --rm redis redis-cli -h redis -a "$REDIS_PASSWORD" ping` 或使用启动脚本: ```bash ./start.sh # 构建并启动 ./start.sh stop # 停止 ./start.sh restart # 重启 ./start.sh logs # 查看日志 ./start.sh clean # 停止并删除容器与数据 ``` > **以上方式永久可用**:接入 [nightjar](https://github.com/unihaoke/nightjar)(中间件智能问题解决平台) > **不需要改动本项目的任何文件**——平台在集成时用 Docker API 自己发现容器所在网络并接入 Exporter, > 日志则通过挂载 `backend-logs` 卷读取。详见「接入 nightjar」一节。 ### 方式二:本地开发模式 **后端**(需要 JDK 21 + Maven): ```bash cd backend mvn spring-boot:run # 后端启动在 8080 端口 ``` 默认激活 `mysql` profile,通过环境变量连接数据库(默认值见 `application-mysql.yml`): ```bash # 本地 MySQL 示例(默认 127.0.0.1:3306,库名 interview_review,账号 root/root) export SPRING_PROFILES_ACTIVE=mysql export DB_HOST=127.0.0.1 DB_PORT=3306 DB_NAME=interview_review DB_USER=root DB_PASS=root ``` > 首次启动会自动建表(`ddl-auto=update`),并自动初始化默认管理员账号 `admin`/`admin123` 与公共题库种子数据。 > 想免安装数据库可切换 `SPRING_PROFILES_ACTIVE=sqlite`,数据落在本地文件。 **前端**(需要 Node 18+): ```bash cd frontend npm install npm run dev # 前端启动在 5173 端口,自动代理 /api → localhost:8080 ``` 访问 http://localhost:5173 即可使用。 ### 运行端到端冒烟测试 后端启动后(`sqlite` profile 即可,**不需要**配置任何大模型——全链路会走本地降级): ```bash node scripts/smoke-agent-interview.mjs # 自定义地址:node scripts/smoke-agent-interview.mjs http://127.0.0.1:8080 ``` 覆盖 54 项断言:Tools Schema 自动生成、状态机推进、一题一评、低分必深挖、幂等、越权防护、 报告与学习卡、Markdown 导出、END 阶段约束。 ### 重新生成题库语料 ```bash python .skills-src/build-complete.py # 从完整 items.json 重建 318 题归一化语料 bash scripts/sync-interview-bank.sh # 同步到 backend/src/main/resources/ ``` > 上游 `items.json` 若需重新下载:`mvn -f .skills-src/fetch-pom.xml validate` > (借 Maven 的 JVM 出网;受限环境里 curl / node fetch 可能因 TLS 凭证失败)。 ## 项目结构 ``` jd/ ├── backend/ # Spring Boot 后端 │ ├── src/main/java/com/interview/review/ │ │ ├── agentinterview/ # 【AI 智能面试】Agent 驱动主链路 │ │ │ ├── AgentInterviewSessionService.java # 编排:鉴权/幂等/限流/持久化/导出 │ │ │ ├── cache/ # 会话缓存抽象(内存 / Redis 双实现) │ │ │ ├── config/ # 配置 + Function Call 协议 + Tools Schema 自动生成 │ │ │ ├── entity/ repository/ # 会话 / 逐轮记录 / 学习卡(独立表,不与旧链路混用) │ │ │ ├── llm/ # DeepSeek Function Call 客户端 + 熔断器 │ │ │ ├── model/ # 状态机阶段 / 四维评分 / 题目 / 报告等领域模型 │ │ │ ├── prompt/ # 固定 System Prompt + 各 skill 提示词模板 │ │ │ ├── runtime/ # 状态机 / SkillManager / 评分引擎 / 难度控制 / 上下文预算 │ │ │ ├── skill/ # 6 个标准 Skill 的本地实现 + 题库 │ │ │ └── web/ # REST + WebSocket 通道 │ │ ├── ai/ # AI 抽象层(接口/Mock/OpenAI兼容/用量服务) │ │ ├── auth/ # 注册登录/JWT/当前用户上下文 │ │ ├── common/ # 通用工具(ApiResult/异常处理/JSON工具) │ │ ├── config/ # AI 属性配置 │ │ ├── interview/ # 模拟面试(旧双模式,标记为 legacy) │ │ ├── question/ # 题库/标签/错题本 │ │ ├── resume/ # 简历解析与出题 │ │ ├── sandbox/ # 实操沙箱(仿真引擎/Docker执行器/5案例) │ │ ├── setting/ # AI 设置、用量统计、租户配置迁移 │ │ ├── stats/ # 学习仪表盘统计 │ │ └── InterviewReviewApplication.java │ ├── src/main/resources/ │ │ ├── application.yml # 配置文件(含 agent-interview.* 全套参数) │ │ ├── logback-spring.xml # 日志落盘(app.log / error.log),供 nightjar 日志 Agent 采集 │ │ ├── interview-bank.jsonl # Agent 题库语料(318 题,来自上游 skill 仓库) │ │ └── sandbox-cases/ # Docker 沙箱案例源码 │ └── Dockerfile ├── frontend/ # Vue 3 前端 │ ├── src/ │ │ ├── views/AgentInterview.vue # 【AI 智能面试】聊天界面 + 实时评分 + 报告面板 │ │ └── ... ├── docs/ │ └── agent-interview-design.md # Agent 智能面试架构设计与方案评审 ├── scripts/ │ ├── sync-interview-bank.sh # 题库语料 → 后端资源 同步 │ ├── check-nightjar-link.sh # 接入自检(容器 / 日志卷 / 日志目录挂载) │ └── smoke-agent-interview.mjs # 端到端冒烟测试(54 项断言) ├── .skills-src/ # 上游 skill 规则抽取规格 + 题库构建脚本与溯源材料 ├── .env.example # 环境变量样例(无监控/网络变量) ├── docker-compose.yml # 编排配置(三网分区:jd-edge / jd-app / jd-data) ├── start.sh # Linux 启动脚本 └── README.md ``` ### 两种结束方式 | 方式 | 入口 | 会做什么 | 不会做什么 | |---|---|---|---| | 结束并复盘 | `POST .../finish` / WS `FINISH` | 生成复盘报告、四维均分、薄弱主题、学习卡 | —— | | **直接结束(不复盘)** | `POST .../discard` / WS `DISCARD` | 仅把状态机推进到 END,保留已答题目的问答与评分 | **不调用任何大模型**、不生成报告、不写学习卡、不做难度调整 | 「直接结束」的会话在列表与详情里 `reportStatus=NONE`(`reportSkipped=true`), 前端在报告页给出明确说明;此时调用导出接口会返回可读提示而不是空文件: > 本场面试结束时选择了「直接结束,不复盘」,因此没有报告可导出。问答与评分记录仍可在会话详情里回看。 两种方式都是**幂等**的(重复调用返回既有结果,不报错)。 ## 实操沙箱案例 | 案例 | 故障类型 | 仿真命令 | 步骤 | |------|---------|---------|------| | JVM 内存泄漏排查 | GC / FullGC | jps / jstat / jcmd / jmap / jstack | 6 步 | | Java 死锁排查 | 线程死锁 | jps / jstack / 线程分析 | 5 步 | | Dubbo RPC 超时 | 服务治理 | tail / 日志分析 | 5 步 | | Redis 主从故障 | 缓存中间件 | info replication / 日志 | 5 步 | | MySQL 慢 SQL | 数据库 | slow.log / EXPLAIN / 索引 | 5 步 | ### 简历模块的行为约定 - **上传不需要大模型**:`/resumes/upload` 只做「校验文件 + 抽取文本 + 保留原始文件」,随时可用。 - **AI 解析需要大模型**:未配置 API Key(或提供方为 `mock`)时,`/analyze` 与 `/generate-questions` 返回 **code 428** 与一段可操作的中文提示,而**不会**降级到离线模拟返回假结果。 前端据此把按钮置灰并在页面顶部给出警告与「去 AI 设置」入口。 - **原始文件会保留**:PDF 上传的字节存进 `resume_file` 表,可随时按原样下载; 文本方式创建的简历没有原始文件,下载时选 `.txt`。 - **文件校验按魔数而非扩展名**:把 `.docx` 改名成 `.pdf` 会被拒绝,并提示「另存为 PDF 或改用粘贴文本」。 - 扫描件/纯图片 PDF 不做 OCR,会明确提示改用文本型 PDF 或粘贴文本。 ### 运行简历模块测试 ```bash node scripts/test-resume-upload.mjs # 24 项:上传/格式校验/下载/无模型提示/写路径锁回归/越权 ``` #### SQLite 下的一条运维须知 `analyze` 这类「先读后写」的事务若跨越大模型调用,SQLite(WAL)会抛 `SQLITE_BUSY_SNAPSHOT`——因为 AI 用量记录是在 `REQUIRES_NEW` 事务里提交的, 本事务的快照已过期。**这个错误不受 `busy_timeout` 影响**,表现为「点解析/下载时报服务器内部错误」。 本项目已从根上规避: 1. **AI 调用一律放在事务外**,落库用独立的短写事务(`KnowledgePointWriter`); 2. 写操作统一走 `DbRetry`(遇锁冲突退避重试,最终仍失败时给出「请切换到 MySQL」的明确提示); 3. SQLite 连接串开启 `WAL` 并把 `busy_timeout` 提到 15s(只能缓解等锁,快照过期靠重试)。 多用户/生产环境建议直接用 **MySQL**(`SPRING_PROFILES_ACTIVE=mysql`),SQLite 仅适合单机试用。 ## AI 配置说明 | 提供方 | 说明 | |--------|------| | 离线模拟(默认) | 内置 JVM/并发/Redis/MySQL/Dubbo 等 9 方向知识库,无需联网,所有功能可用 | | DeepSeek | 填入 API Key 即可,默认地址 `https://api.deepseek.com/v1` | | OpenAI 兼容 | 任何兼容 Chat Completions 协议的服务均可(OpenAI / vLLM / 通义 / Kimi 等) | - 调用真实 AI 失败时自动降级为模拟,不影响使用 - **每日 Token 额度**:设置页可配置每日上限(0=不限),超额后所有 AI 功能暂停,次日自动恢复 - **用量统计**:真实大模型按接口返回 usage 精确计量,离线模拟按文本长度估算 - **按用户隔离**:AI 提供方、API Key、模型、每日额度、用量记录均为**每个登录用户独立一份**,互不影响;未配置时回退系统默认值 ## Agent 智能面试配置 全部集中在 `application.yml` 的 `agent-interview.*`,每项都有安全默认值: ```yaml agent-interview: system-prompt: "" # 留空即用代码内固定 System Prompt llm: provider/base-url/api-key/model: "" # 留空 = 复用「设置」页里当前用户的 AI 配置 timeout-seconds: 45 # 对话/出题类调用超时 judge-timeout-seconds: 60 # 判官与深挖生成超时 max-retries: 1 # 仅对超时/5xx/429 重试 function-call-enabled: true # 关闭后全程走本地引擎 + 本地话术(无模型也能跑通) budget: session-tokens: 24000 # 单场累计 token 预算 prompt-tokens-per-call: 6000 # 单次 prompt 上限,超出即裁剪 recent-turns: 6 # 最近 N 轮保留原文,更早轮次压缩成摘要 limits: max-questions: 12 max-deep-dig-rounds: 3 # 单题深挖上限(上游未定义终止条件,此处为下游实现) max-active-sessions-per-user: 5 cache: redis-enabled: false # 置 true 且存在 Redis 时启用(compose 里已默认开启) bank: hot-reload: true # 题库资源变更自动重载 ``` **无模型时的行为**(默认 `provider: mock` 即此路径):简历解析、答案判官、深挖问句、报告撰写 全部降级为本地实现,面试流程完整可跑;分数会被标注「降级评分」、不计入难度调整,并在报告与聊天中披露。 接入 DeepSeek 后填入 API Key(设置页或上面四项)即可获得真实四维评分。 ### 判官不可用时的行为(降级模式) 默认 `provider: mock`(未配置真实大模型)时判官不可用,此时: - 四维分数固定为 1 分,且**不参与难度调整**,报告里明确披露「N/M 题为降级评分」; - **不按分数触发深挖**——否则「答得再好也会被连追 3 轮」,面试卡在第一题,观感像系统坏了; 只有「明确答不出 / 过于简短 / 通篇敷衍(`没细看`、`大概`…)」才深挖; - 有实质内容的回答会正常推进到下一题。 ## 数据与租户隔离 - **公共题库**:管理员维护的种子题目(scope=PUBLIC)对所有用户可见,用于模拟面试 - **个人数据**:简历、知识点、个人题库(PERSONAL)、错题本、面试记录、沙箱记录、AI 配置、AI 用量均按登录用户隔离;后端从 JWT 会话强制取用户身份进行过滤与归属校验,前端传 ID 不能越权访问他人数据 - **认证**:JWT 登录态,前端路由守卫拦截未登录访问,token 过期由后端 401 响应统一处理 ## Docker 部署架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ Host │ │ │ │ :8542 ┌───────────┐ /api/ ┌───────────────┐ │ │ ◀────▶│ Nginx │ ───────▶│ Backend :8080 │ │ │ │ (前端静态) │ │ (Spring Boot) │ │ │ └───────────┘ └───┬───────┬───┘ │ │ │ JPA │ 日志落盘 │ │ ▼ ▼ │ │ ┌────────────┐ ┌──────────────┐ │ │ │MySQL :3306 │ │backend-logs │ │ │ │(mysql-data)│ │(日志卷) │ │ │ └────────────┘ └──────┬───────┘ │ │ ┌────────────┐ │ │ │ │Redis :6379 │ │ │ │ └─────┬──────┘ │ │ │ │ │ │ │ 可选:backend 挂载 /var/run/docker.sock 启用沙箱真实容器模式 │ └────────────────────────────────┼───────────────┼─────────────────┘ │ 容器名/服务名 │ 只读挂载同一命名卷 (平台集成时自动接入 jd_data 网络) ▼ ▼ ┌────────────────────────────────────────┐ │ nightjar:Prometheus / Grafana / │ │ Exporter 容器 / 日志采集容器 / 告警诊断 │ └────────────────────────────────────────┘ ``` - 前端 Nginx 提供静态文件,`/api/` 反向代理到后端 - 网络分区:`jd-edge`(发布面)/ `jd-app`(应用面,backend 出网)/ `jd-data`(数据面,internal) - 默认 MySQL 8,数据持久化到 `mysql-data` 卷;后端在 MySQL 健康后启动 - MySQL / Redis 不发布宿主端口,仅数据面可达;后端只绑 `127.0.0.1` - **本项目不跑任何监控组件**:Prometheus / Grafana / Exporter / 日志采集全部由 nightjar 侧承担(见下节) ## 监控说明 - 后端通过 **Spring Boot Actuator + Micrometer** 暴露 Prometheus 格式指标,端点 `/actuator/prometheus` 仅暴露 `health`/`info`/`prometheus`,无需认证(在 `/api` 鉴权拦截范围之外);compose 已把后端只绑在 `127.0.0.1`,生产请继续保持不对公网开放 - 应用日志落盘到 `backend-logs` 卷:`interview-review.log`(全量)与 `error.log`(仅 ERROR),GC 日志为 `gc.log`;这是 nightjar 日志采集的**唯一来源**,请勿移除该挂载 - 自定义业务指标:`ai_tokens_total`(按 scene/provider 统计 token 消耗)、`ai_calls_total`(AI 调用次数) - 指标抓取、看板与告警均在 nightjar 的「集成中心」配置:接入后平台自动创建 Exporter 容器、 **自动发现并接入本项目的容器网络**(无需在本项目做任何网络改动),并自动生成看板与告警规则 ## 接入 nightjar(中间件智能问题解决平台) [nightjar](https://github.com/unihaoke/nightjar) 是「Redis / MySQL / Kafka / ES …」统一纳管 + 告警 + AI 诊断的中间件运维平台(Go + Vue,自带 docker-compose)。 本项目作为**被纳管对象**接入,且**监控侧零配置**:平台自己建只读账号、自己拉起 Exporter、 **自己发现并接入本项目容器所在的网络**,自带 Prometheus / Grafana / 日志采集, 本项目不新增任何监控容器、不建互联网络、不加别名、不改 compose。 > 上游仓库的完整操作指南:[`docs/GUIDE-JD-ONBOARD.md`](https://github.com/unihaoke/nightjar/blob/master/docs/GUIDE-JD-ONBOARD.md)。 ### 网络隔离模型 接入不需要把两个 compose 项目丢进同一张网,也不需要互联网络—— 平台在自己这边把 Exporter 接进本项目容器的网络上,本项目保持**三网分区**: | 网络 | internal | 成员 | 说明 | |------|----------|------|------| | `jd-edge` | 否 | frontend | 面向用户,唯一发布业务端口 | | `jd-app` | 否 | frontend ↔ backend | backend 经此出网调用大模型 | | `jd-data` | **是** | backend、mysql、redis | 数据面:**无出网、无宿主端口** | 跨栈可见面只有两个端点:平台 Exporter 访问 `interview-mysql:3306` / `interview-redis:6379` (只读指标),以及平台日志采集容器读取 `backend-logs` 卷。 nightjar 看不到 frontend / backend 的出网链路。 > 平台接入的方式:创建 Exporter 时用 Docker API 反查目标容器(按容器名/compose 服务名/网络别名) > 所在网络(这里是 `jd_jd-data`),把 Exporter 接进去。**本项目侧因此没有任何前置条件**。 > `jd-data` 保持 `internal: true`:Exporter 只借用同网络的 DNS 与端口,不参与本项目的出网。 ### 改了什么 | 文件 | 作用 | |------|------| | `docker-compose.yml` | **改造**:三网分区;MySQL / Redis 取消宿主端口映射(原为 `0.0.0.0:3306` / `:6379`);Redis 开启 `requirepass`;后端只绑 `127.0.0.1`;后端日志落盘到 `backend-logs` 卷 | | `.env.example` | 统一环境变量(`REDIS_PASSWORD` 等);**没有任何监控/网络变量** | | `backend/src/main/resources/logback-spring.xml` | 新增:`interview-review.log` 全量 + `error.log` 仅 ERROR,供平台日志采集 | | `backend/Dockerfile` | GC 日志改为 `/app/data/logs/gc.log`,落进 `backend-logs` 卷 | | `scripts/check-nightjar-link.sh` | 接入自检:业务容器运行中、日志卷非空、日志目录是命名卷 | | `start.sh` | `up` 恢复为普通启动;`check` 做接入自检 | > 网络已从 `interview-net` 拆分为 `jd-*`,已有部署请先 `docker compose down` 再启动。 ### 命令 | 目的 | 命令 | |------|------| | 启动(默认,无需为监控做任何事) | `./start.sh` 或 `docker compose up -d --build` | | 接入自检 | `./start.sh check` | | 清空数据重来 | `./start.sh clean` | > 接入前必改:`REDIS_PASSWORD` 必须非空(空口令会让 Spring 连 Redis 报 `NOAUTH`)。 > MySQL 只读监控账号**不需要**在本项目创建,由 nightjar 集成中心按需代建。 ### nightjar 平台侧 1. 部署平台并打开集成能力(脚本会自动放开 docker.sock —— 这是自动发现网络的前提): ```bash cd ./scripts/setup-jd-link.sh # 生成密钥、打开集成开关、放开 docker.sock、启动并自检 ``` 2. 打开「**集成中心**」,按被管组件新建集成(**本项目无需再改任何文件**): | 步骤 | 名称 | 地址 | 关键勾选 | |------|------|------|----------| | MySQL | `jd-mysql` | `interview-mysql:3306` | 「由平台创建只读监控账号」(填 root 凭据)+「一键拉起 Exporter」 | | Redis | `jd-redis` | `interview-redis:6379` | 「一键拉起 Exporter」(口令填 `.env` 的 `REDIS_PASSWORD`) | | 日志 | `jd-backend-logs` | 目标容器 `interview-backend` | 先「读取 docker 配置并预览」,再「创建采集容器」 | 平台会自动:建只读账号 → 起 Exporter → **发现并接入 `jd_jd-data`** → 写抓取目标与告警规则 → 出大盘。集成列表里的「待处理」会直接写明失败原因(账号不存在 / 网络不通 / DSN 非法)。 3. 平台访问地址 `http://<主机>:8000`,Grafana 为 `http://<主机>:3000`(数据源已自动配好)。 > 地址填**容器名**最稳(`interview-redis`);填 compose 服务名(`redis`)平台也会自己换算。 > 旧版需要手工填的 `Prometheus job` / `Prometheus instance` 已由平台自动写入。 ### 验证 ```bash cd ./start.sh check # 业务容器 / 日志卷 / 日志目录挂载 cd ./scripts/doctor-jd-link.sh # 平台容器 / docker.sock / 目标容器所在网络 / Exporter 网络 / 抓取 up ``` 页面侧:**统一监控**出现 `jd-redis`、`jd-mysql` 曲线;**日志告警**出现后端 ERROR 事件。 > 联动价值:本项目自带沙箱故障场景(`RedisFaultScenario` / `MySqlSlowScenario` / `GcLeakScenario` / `DeadlockScenario`)可真实制造 Redis 异常与 MySQL 慢查询,用来验证平台的告警与 AI 诊断链路,比手工造数据可靠。 ## 环境要求 | 环境 | 最低版本 | 说明 | |------|---------|------| | JDK | 21 | 后端运行时 | | Maven | 3.6+ | 后端构建(Docker 内置) | | Node | 18+ | 前端构建(Docker 内置) | | Docker | 20+ | Docker 部署方式 | | Docker Compose | 2.0+ | Docker 部署方式 | ## License MIT