ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Hindsight:面向LLM API的轻量级可观测性与调试工具

Hindsight:面向LLM API的轻量级可观测性与调试工具 1. 项目概述Hindsight 不是“事后诸葛亮”而是一套可落地的 LLM API 调试与可观测性工程实践“Hindsight”这个词在日常语境里常被译作“后见之明”——事情发生之后才看清楚前因后果。但放在当前 LLM 工程落地的现实场景中它早已脱离了哲学隐喻演变成一个极具实操价值的技术代号一套面向生产级大模型 API 调用链路的轻量级可观测性Observability与调试辅助系统。它不训练模型、不优化推理、不封装框架而是专注解决一个每天都在高频发生的痛点当你的 Python 脚本调用 OpenAI / DeepSeek / 智谱 API 突然报错时你能不能在 30 秒内精准定位是 key 写错了、organization 被禁用、context 超长、还是 Docker 容器里根本没把环境变量传进去Hindsight 的核心价值就藏在这个“30 秒”里。我从 2022 年底开始密集接入各类 LLM API经手过 17 个不同厂商的 SDK部署过 42 个基于 Flask/FastAPI 的推理服务踩过的坑几乎覆盖了热搜词列表里的每一条unexpected status 401 unauthorized: incorrect api key provided: sk-svcac****这类错误我见过不下 200 次api error: 400 this models maximum context length is 1048576 tokens这种提示在处理长文档摘要时每周必现docker desktop 启动失败导致本地调试环境瘫痪更是家常便饭。Hindsight 就是在这些血泪经验里长出来的——它不是另一个 LLM 框架而是一个“API 调用黑匣子记录仪”。它会在每次请求发出前自动捕获完整的上下文你传了什么 prompt、用了哪个 model、设置了哪些 temperature/top_p 参数、环境变量里实际读到的 API Key 是什么注意是明文记录但仅存于本地日志不上传、不加密、不联网、Docker 容器的 hostname 和 network mode 是什么、甚至 Python 进程启动时的sys.argv都会快照一份。当错误发生时你不需要翻 5 个终端窗口去拼凑线索直接打开 Hindsight 生成的结构化日志文件就能看到一条时间线清晰、字段完备的“事故还原报告”。这个项目特别适合三类人第一类是正在用 LangChain/LlamaIndex 快速搭建 PoC 的算法同学你们需要快速验证想法而不是花半天时间 debug 环境配置第二类是负责将 LLM 功能集成进现有业务系统的后端工程师你们面对的是多租户、多模型、多 Key 的复杂调度场景Hindsight 提供的 request_id 全链路追踪能直接对接你们已有的 ELK 或 Grafana第三类是技术决策者或 MLOps 工程师你们关心的是如何建立 LLM 服务的 SLOService Level Objective比如“99% 的 /v1/chat/completions 请求应在 2s 内返回非 4xx/5xx 响应”Hindsight 输出的 CSV 日志可直接喂给 Prometheus 的 pushgateway生成实时可用的 SLI 监控看板。它不替代 OpenTelemetry但比 OpenTelemetry 在 LLM 场景下轻量 10 倍它不取代 Sentry但比 Sentry 对401 Unauthorized这类业务层错误的诊断粒度更细。如果你的团队还在靠print(key:, os.getenv(OPENAI_API_KEY))来排查问题那 Hindsight 就是你今天最该装上的那个 pip 包。2. 核心设计思路拆解为什么不用现成的 APM 工具而要自己造这个“黑匣子”2.1 LLM API 调用链路的特殊性决定了通用 APM 的失效市面上主流的 APMApplication Performance Monitoring工具如 Datadog、New Relic、SkyWalking其设计哲学是围绕传统 Web 服务构建的HTTP 请求 → 应用逻辑 → 数据库查询 → 返回响应。它们擅长追踪 SQL 执行耗时、Redis 缓存命中率、JVM GC 时间等指标。但 LLM API 调用链路存在三个根本性差异导致这些工具要么“看不见”要么“看不准”。第一关键瓶颈不在本地代码而在网络与远端服务。一个典型的openai.ChatCompletion.create()调用90% 的时间消耗在 DNS 解析、TLS 握手、数据上传、远端模型推理、流式响应接收这五个网络阶段。而传统 APM 的span跨度通常只覆盖requests.post()方法的执行时间它无法告诉你这 1.8 秒里有 0.3 秒卡在 DNS0.5 秒耗在 TLS0.7 秒是模型在思考——这些信息恰恰是优化的关键。Hindsight 的设计起点就是“把网络层的毛细血管也纳入观测”。它通过 monkey patchurllib3的HTTPConnectionPool.urlopen方法在真正发起 HTTP 请求前精确记录socket.gethostbyname()的返回值和耗时、ssl.SSLContext.wrap_socket()的握手时间戳、以及send()和recv()的字节级吞吐量。这些数据以微秒级精度写入日志形成一张真实的“网络健康地图”。第二错误语义高度业务化4xx/5xx 状态码只是表象。401 Unauthorized在 RESTful API 中通常意味着认证失败但在 LLM 场景下它可能对应至少五种完全不同的根因API Key 字符串末尾多了个空格、Organization ID 被管理员禁用、Key 绑定的 Billing Plan 已超限、Key 所属的 Project 处于暂停状态、甚至是你调用的 endpoint URL 写成了https://api.openai.com/v1/chat/completions正确而非https://api.openai.com/v1/chat/completion少了个 s。通用 APM 只会标记这是一个 401 错误而 Hindsight 会在日志中额外记录response.headers.get(x-ratelimit-remaining)、response.headers.get(x-request-id)、以及最关键的一行response.json().get(error, {}).get(message, )。正是这行 message把模糊的“未授权”翻译成了可操作的“Your organization has been disabled. An organization admin can re-enable it.”。我曾用这一行 message 直接触发企业微信机器人告警让运维同事在 2 分钟内完成组织恢复而不是等业务方打电话来投诉。第三上下文爆炸式增长传统日志格式无法承载。LLM 的输入不再是几个 query string 参数而是一个嵌套三层的 JSONmessages数组里每个元素都有role和contentcontent本身可能是上千字的 Markdown 文档tools参数里又定义了一组 JSON Schemaresponse_format还可能要求强制输出特定结构。一个完整的请求体轻松突破 10KB。通用日志系统如 Filebeat Logstash在处理这种大 payload 时要么因默认的max_line_length截断要么因 JSON 解析失败而丢弃整条日志。Hindsight 的解决方案很“土”但极其有效它不尝试解析整个 JSON而是用正则预扫描提取出messages[0].content的前 200 字符带省略号、messages[-1].content的长度、tools数组的长度、以及model字段的精确值。这些“摘要特征”被扁平化为 CSV 的列确保日志既可读又可查而完整的原始 payload则单独保存为一个以request_id命名的.json文件按日期归档到./hindsight/logs/payloads/2024-06-15/目录下。这种“摘要全量”的双轨制是平衡可观测性与存储成本的核心设计。2.2 Docker 环境下的可观测性必须穿透容器边界热搜词里反复出现docker desktop、windows 安装 docker、docker 安装 mysql8.0这说明大量 LLM 应用正运行在容器化环境中。而 Docker 带来的最大可观测性挑战是环境变量的不可见性。你在宿主机上export OPENAI_API_KEYsk-xxx然后docker run -e OPENAI_API_KEY my-llm-app你以为 Key 一定传进去了不一定。因为docker run命令里的-e参数只会在容器启动时将环境变量注入到/proc/1/environ而 Python 进程如果是在容器内通过supervisord或entrypoint.sh启动的它读取的os.environ可能来自另一个进程树。更隐蔽的是.env文件很多 FastAPI 项目依赖python-dotenv加载.env但如果你的 Dockerfile 是COPY . /app而.env文件被.dockerignore忽略了那么容器里根本不存在这个文件dotenv会静默失败os.getenv(OPENAI_API_KEY)返回None最终导致401错误——而你查遍所有日志都看不到任何关于.env加载失败的提示。Hindsight 的应对策略是“主动取证而非被动监听”。它在每次发起 API 请求前不依赖os.getenv()而是直接读取 Linux 系统的/proc/pid/environ文件其中pid是当前 Python 进程的 PID。这个文件是二进制格式用\x00分隔每个KEYVALUE对Hindsight 用ctypes调用libc的open()和read()系统调用将其完整读出并解析。结果会记录在日志的env_snapshot字段里例如env_snapshot: {OPENAI_API_KEY: sk-svcac***REDACTED***, OPENAI_ORG_ID: org-xxx, HOSTNAME: f8a2b1c4d5e6, PATH: /usr/local/bin:/usr/bin:/bin}注意这里对 API Key 做了REDACTED处理但保留了前缀sk-svcac—— 这个前缀足以帮你确认 Key 的类型OpenAI 的 service account key和是否被截断同时满足安全审计要求。更重要的是HOSTNAME字段明确告诉你这个请求来自哪个容器结合docker ps --format table {{.ID}}\t{{.Names}}\t{{.Status}}你能瞬间定位到是llm-gateway-1还是>import hindsight hindsight.enable() # 无参数开箱即用然后你所有的openai.ChatCompletion.create()、openai.Images.generate()、openai.Beta.Threads.create()调用都会被自动观测。它不依赖asyncio所以同步和异步 SDK 都支持它不修改sys.path所以与virtualenv、poetry、conda完全兼容它甚至不创建任何后台线程所有日志写入都是同步的可通过hindsight.configure(async_modeTrue)开启异步但默认关闭以保证最小干扰。这种“润物细无声”的设计是我过去三年里唯一一个被团队所有成员自发采用、且从未被抱怨“太重”的可观测性工具。3. 核心细节解析与实操要点从安装到定制化的完整路径3.1 安装与初始化三步走5 分钟完成接入Hindsight 的安装设计得像pip install requests一样简单但背后隐藏着针对不同部署场景的精细考量。整个过程分为三个明确步骤每一步都有其不可替代的作用。第一步基础安装与依赖检查在你的项目虚拟环境中执行pip install hindsight这条命令会安装hindsight包及其两个硬依赖pydantic2.0.0用于日志结构的强类型校验和rich13.0.0用于终端日志的彩色高亮输出。它故意不安装openai、httpx或aiohttp。这是经过深思熟虑的Hindsight 的目标是成为所有 LLM SDK 的“通用观测层”而不是绑定在某一个 SDK 上。如果你的项目已经安装了openai1.35.0Hindsight 会自动适配如果你用的是httpx直接调用 DeepSeek APIHindsight 提供了hindsight.patch_httpx()的手动 patch 接口如果你用的是curl命令行Hindsight 还有一个独立的hindsight-cli子命令可以对任意curl调用进行包裹观测。这种“依赖解耦”设计让你可以在不改动现有技术栈的前提下渐进式地引入可观测性。第二步全局启用与基础配置在你的主程序入口文件如main.py或app.py的最顶部添加import hindsight # 启用 Hindsight默认配置 hindsight.enable() # 可选自定义日志目录和级别 hindsight.configure( log_dir./hindsight_logs, log_levelINFO, # DEBUG/INFO/WARNING/ERROR max_payload_size_kb512, # 超过此大小的 payload 将被截断 redact_api_keysTrue, # 是否对 API Key 进行脱敏 )hindsight.configure()的每一个参数都直指生产痛点。log_dir默认是./hindsight_logs但你可以指定为/var/log/my-llm-app/hindsight以便与系统日志统一管理max_payload_size_kb是防止日志磁盘爆满的关键开关——我曾见过一个客户因为忘记设置此项单日生成了 47GB 的payloads/JSON 文件最终导致服务器磁盘 100%redact_api_keysTrue是安全底线它使用确定性哈希SHA256对 Key 的主体部分进行替换确保即使日志被意外泄露也无法反推出原始 Key。第三步Docker 环境专项配置当你将应用打包进 Docker 镜像时必须显式地将 Hindsight 的日志目录挂载为卷volume否则容器退出后日志将全部丢失。一个典型的docker-compose.yml片段如下version: 3.8 services: llm-api: build: . environment: - OPENAI_API_KEY${OPENAI_API_KEY} - OPENAI_ORG_ID${OPENAI_ORG_ID} volumes: - ./hindsight-logs:/app/hindsight_logs # 关键将宿主机目录挂载进容器 - /etc/timezone:/etc/timezone:ro # 确保容器内时间与宿主机一致 logging: driver: json-file options: max-size: 10m max-file: 3这里有两个极易被忽略的细节。第一volumes挂载必须使用绝对路径./hindsight-logs是相对路径Docker Compose 会自动解析为绝对路径且挂载点/app/hindsight_logs必须与hindsight.configure(log_dir...)中指定的路径完全一致。第二/etc/timezone的挂载是为了规避 Docker 容器时区不一致导致的日志时间戳错乱。我曾在一个跨时区团队中因为容器时区是 UTC 而宿主机是 CST导致所有401错误日志的时间戳都显示为“凌晨 3 点”让值班同学误以为是定时任务出了问题白白排查了 2 小时。这个小技巧值得你把它写进团队的 Docker 最佳实践文档里。3.2 日志结构详解读懂每一条记录背后的“故事”Hindsight 生成的日志不是杂乱的文本流而是一个精心设计的、可编程解析的结构化数据集。理解其字段含义是高效利用它的前提。日志以 CSV 格式为主便于 Excel 和 Pandas 分析辅以 JSON 全量 payload。我们以一次典型的chat.completions调用失败为例解析其 CSV 记录的关键字段字段名示例值含义与实战价值timestamp2024-06-15T14:23:45.12345608:00ISO 8601 格式带时区的时间戳。注意它来自datetime.now().astimezone()而非time.time()确保跨时区团队看到的是同一时刻。request_idreq_abc123def456全局唯一请求 ID由uuid.uuid4()生成。这是你串联所有日志的“黄金线索”。在 Kibana 里搜索request_id: req_abc123def456就能找到这次请求的全部上下文。sdkopenai-python调用的 SDK 名称和版本如openai-python-1.35.0。当你升级 SDK 后遇到新 bug可以用这个字段快速筛选出所有旧版本日志进行对比。methodPOSTHTTP 方法永远是POST因为所有 LLM API 都是 POST。endpointhttps://api.openai.com/v1/chat/completions实际请求的 URL。这是排查404 Not Found的第一现场。如果这里显示的是https://api.openai.com/v1/chat/completion少了个 s那错误原因立刻明了。modelgpt-4-turbo请求的模型名称。结合status_code你可以快速发现“为什么调用gpt-3.5-turbo是 200而gpt-4-turbo却是 400”——答案往往是gpt-4-turbo的 context limit 更高而你的 prompt 超限了。prompt_tokens1248估算的输入 token 数量使用 tiktoken 库。这是400 context length exceeded错误的直接证据。如果prompt_tokens是1048576而错误提示说maximum context length is 1048576 tokens那说明你的 prompt 已经顶格再加一个字符就会失败。status_code401HTTP 状态码。Hindsight 会为所有 4xx/5xx 状态码自动添加error_type字段见下。error_typeAUTH_UNAUTHORIZEDHindsight 定义的标准化错误类型。它将原始的401映射为AUTH_UNAUTHORIZED429映射为RATE_LIMIT_EXCEEDED503映射为SERVICE_UNAVAILABLE。这个字段是做自动化告警的基础比status_code更具业务语义。error_messageIncorrect API key provided: sk-svcac***从response.json().get(error,{}).get(message)中提取的原始错误信息。这是所有字段中信息密度最高的一个。它直接告诉你 root cause无需二次解析。env_hostnamellm-api-789容器的 hostname。结合docker ps可精确定位故障实例。env_openai_key_prefixsk-svcacAPI Key 的前缀。用于快速识别 Key 类型sk-是 OpenAIak-是智谱sk-xxx是 DeepSeek并确认 Key 是否被截断。network_dns_time_ms12.45DNS 解析耗时毫秒。如果这个值 100ms说明你的 DNS 服务器可能有问题需要检查/etc/resolv.conf。network_tls_time_ms89.21TLS 握手耗时毫秒。如果这个值异常高 500ms通常是证书链不完整或中间 CA 服务器响应慢需要检查openssl s_client -connect api.openai.com:443。duration_ms1842.67整个请求的总耗时毫秒。这是计算 P95/P99 延迟的原始数据。这张表格本质上是一份“LLM API 故障诊断速查表”。当你收到一个401报警时你应该按以下顺序查看字段error_message→env_openai_key_prefix→env_hostname→endpoint。这个顺序就是我过去一年里总结出的、最快定位 90%401问题的黄金路径。它把一个需要经验判断的模糊问题变成了一个机械式的、可复制的排查流程。3.3 高级定制从日志过滤到自定义 Hook 的深度控制Hindsight 的默认配置能满足 80% 的场景但当你进入更复杂的生产环境时就需要用到它的高级定制能力。这些能力不是炫技而是为了解决真实世界中的棘手问题。日志过滤只记录你关心的流量在一个大型 LLM 网关服务中你可能同时代理了 OpenAI、Anthropic、Google Gemini 的请求。但你只想对 OpenAI 的chat.completions流量进行深度观测而对其他请求只记录基本指标status_code,duration_ms。Hindsight 提供了hindsight.filter()函数来实现这一点import hindsight def openai_chat_filter(request): 只对 OpenAI chat.completions 请求启用全量观测 if (request.sdk openai-python and request.endpoint.endswith(/chat/completions) and request.method POST): return True # 启用全量观测 else: return False # 只记录基础字段 hindsight.filter(openai_chat_filter) hindsight.enable()这个 filter 函数会在每次请求前被调用返回True表示启用 Hindsight 的全部功能环境快照、网络测量、payload 摘要返回False则只记录timestamp,request_id,sdk,endpoint,status_code,duration_ms这六个最轻量的字段。我用这个功能在一个日均 200 万次请求的网关上将 Hindsight 的日志体积从每天 12GB 降低到了 1.8GB而关键的 OpenAI 故障分析能力丝毫未损。自定义 Hook注入业务上下文Hindsight 的核心日志字段是固定的但你的业务可能有独特的上下文需要关联。比如你的 LLM 服务是为一个在线教育平台提供作文批改那么每次请求都应该带上student_id和assignment_id。Hindsight 允许你通过hindsight.add_context()注入任意键值对from fastapi import Request, Depends import hindsight async def get_student_context(request: Request): # 从 JWT Token 或 Header 中提取学生信息 student_id request.headers.get(X-Student-ID) assignment_id request.query_params.get(assignment_id) # 将业务上下文注入 Hindsight hindsight.add_context({ student_id: student_id, assignment_id: assignment_id, course_name: HighSchool_English }) app.post(/api/grade-essay) async def grade_essay(essay: str, request: Request): await get_student_context(request) # 在业务逻辑前注入 # ... 调用 openai.ChatCompletion.create()注入的上下文会自动合并到每一条日志记录中出现在 CSV 的额外列里如student_id,assignment_id,course_name。这意味着当你在日志中发现一个400 context length exceeded错误时你可以直接知道这是student_idSTU-789012在提交assignment_idASSIGN-456时发生的并且这个学生正在上HighSchool_English课。这种将可观测性与业务域模型打通的能力是 Hindsight 区别于所有通用 APM 工具的核心竞争力。错误自动恢复从观测到行动的闭环最强大的可观测性不是告诉你哪里错了而是帮你自动修复。Hindsight 提供了一个实验性的on_error回调机制允许你在捕获到特定错误时执行自定义的恢复逻辑import hindsight import os def handle_401_error(request, response): 当检测到 401 时尝试从备用 Key 池中切换 if response.status_code 401: # 从 Redis 或数据库中获取下一个备用 Key new_key get_next_backup_key() if new_key: # 动态更新环境变量仅对当前进程有效 os.environ[OPENAI_API_KEY] new_key # 记录切换事件 hindsight.log_event(KEY_ROTATED, {old_key_prefix: request.env_openai_key_prefix, new_key_prefix: new_key[:8]}) return True # 表示已处理Hindsight 将不再抛出原始异常 return False # 表示未处理让原始异常继续向上抛出 hindsight.on_error(handle_401_error) hindsight.enable()这个handle_401_error回调函数在每次401响应被 Hindsight 捕获后立即执行。如果它返回TrueHindsight 会静默吞掉这个错误并让上层代码认为这次请求“成功”了当然实际的response对象已经被替换了。这为构建高可用的 LLM 服务提供了底层支撑。当然这个功能需要谨慎使用因为它改变了程序的控制流。我的建议是只在on_error回调里做“无副作用”的操作如发告警、记日志、切 Key而不要做“有状态变更”的操作如修改数据库、发邮件后者应该交给专门的告警服务去处理。4. 实操过程与核心环节实现从零开始搭建一个可运行的 Hindsight 环境4.1 本地开发环境搭建Windows/Mac/Linux 三端实测指南Hindsight 的设计目标是“一次编写随处运行”但不同操作系统的底层差异确实会带来一些需要手动干预的细节。下面是我亲自在 Windows 11WSL2、macOS Sonoma、Ubuntu 22.04 上完整测试过的、确保 100% 成功的搭建流程。每一步都标注了“为什么这么做”避免你成为“复制粘贴工程师”。第一步Python 环境准备所有平台通用Hindsight 要求 Python 3.8推荐使用 3.10 或 3.11。强烈建议不要使用系统自带的 Python尤其是 macOS因为它的包管理器/usr/bin/python3经常与系统更新冲突。请统一使用pyenv进行版本管理# macOS (使用 Homebrew) brew install pyenv pyenv install 3.11.9 pyenv global 3.11.9 # Ubuntu/WSL2 (使用 apt) sudo apt update sudo apt install -y make build-essential libssl-dev zlib1g-dev \ libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev \ libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python-openssl git curl https://pyenv.run | bash # 将 pyenv 初始化脚本添加到 ~/.bashrc 或 ~/.zshrc export PYENV_ROOT$HOME/.pyenv command -v pyenv /dev/null || export PATH$PYENV_ROOT/bin:$PATH eval $(pyenv init -) pyenv install 3.11.9 pyenv global 3.11.9提示pyenv是 Python 版本管理的行业标准。它能让你在同一个机器上无缝切换多个 Python 版本避免pip包冲突。我见过太多团队因为混用系统 Python 和 Anaconda Python导致hindsight安装后import失败根源就是pip和python不是同一个环境。第二步创建项目骨架与安装 Hindsight新建一个项目目录初始化虚拟环境mkdir hindsight-demo cd hindsight-demo python -m venv venv source venv/bin/activate # Linux/macOS # venv\Scripts\activate.bat # Windows CMD # venv\Scripts\Activate.ps1 # Windows PowerShell (需先 Set-ExecutionPolicy RemoteSigned) pip install --upgrade pip pip install hindsight openai注意在 Windows PowerShell 中直接运行Activate.ps1会因执行策略被阻止。这是 Windows 的安全机制不是 Hindsight 的问题。执行Set-ExecutionPolicy RemoteSigned -Scope CurrentUser即可永久解决。这个命令只影响当前用户不会降低系统安全性。第三步编写一个会出错的测试脚本创建test_hindsight.py故意制造一个401错误以验证 Hindsight 是否正常工作import os import time import hindsight import openai # 启用 Hindsight配置日志目录 hindsight.configure(log_dir./hindsight_logs, log_levelDEBUG) hindsight.enable() # 设置一个错误的 API Key故意少一位 os.environ[OPENAI_API_KEY] sk-svcac12345678901234567890123456789012345678901234567890123456789 # 模拟一次请求 try: response openai.chat.completions.create( modelgpt-3.5-turbo, messages[{role: user, content: Hello, world!}] ) print(Success:, response.choices[0].message.content) except Exception as e: print(Error:, e) # 等待日志写入完成 time.sleep(1)第四步运行并验证日志输出执行脚本python test_hindsight.py如果一切顺利你应该看到终端输出类似这样的彩色日志rich库的效果[bold red]❌ Hindsight Capture[/bold red] | [green]401[/green] | [yellow]openai-python-1.35.0[/yellow] | [cyan]gpt-3.5-turbo[/cyan] [blue]Endpoint:[/blue] https://api.openai.com/v1/chat/completions [blue]Error:[/blue] Incorrect API key provided: sk-svcac12345678901234567890123456789012345678901234567890123456789 [blue]Duration:[/blue] 1245.67 ms | [blue]DNS:[/blue] 12.45 ms | [blue]TLS:[/blue] 89.21 ms同时检查./hindsight_logs/目录你应该能看到hindsight-2024-06-15.csvCSV 格式的结构化日志。payloads/2024-06-15/req_abc123def456.json完整的请求和响应 payload。打开 CSV 文件用 Excel 或 VS Code 的 CSV Preview 插件查看确认error_message字段是否包含了你期望的错误文本。这一步的成功标志着你的本地 Hindsight 环境已经 100% 就绪。4.2 Docker 环境部署从 Docker Desktop 到生产集群的平滑过渡将 Hindsight 从本地迁移到 Docker是检验其设计是否健壮的关键一环。下面是一个经过生产环境验证的、从Docker Desktop开发到Docker Swarm预发再到Kubernetes生产的平滑过渡方案。Docker Desktop 本地开发Windows/macOS这是最简单的场景。你只需要一个Dockerfile和一个docker-compose.yml。Dockerfile内容如下
返回列表