Sanic Inspector 实战指南:用独立 HTTP 服务实时管理运行中的 Worker
后端Web框架【免费下载链接】sanicAccelerate your web app development | Build fast. Run fast.项目地址https://gitcode.com/gh_mirrors/sa/sanic点击查看免费下载Sanic Inspector 是 Sanic Server 内置 Worker Manager 体系中的一项管理能力它以独立进程、独立应用、独立 socket的方式运行在你的 Sanic 实例后台让开发者通过 CLI 或 HTTP API 与运行中的应用程序交互查看实例状态、触发 worker 重载、优雅关闭全部进程、动态伸缩 worker 数量甚至注册任意自定义命令。读完本文你将掌握 Inspector 的启用方式、内置命令、自定义命令扩展、TLS 与 API Key 生产加固以及它背后与WorkerManager、multiplexer协同工作的底层原理。注意Inspector 从 v22.9 开始以有限能力引入本文内容以 v22.12 及以上版本为准。Inspector 是什么Inspector 是 Sanic 的一个可选组件只有在使用内置 Worker Manager 运行时才可用即默认的多进程运行模式。它是一个 HTTP 应用可以在你的应用程序后台可选地运行用于与运行中的实例交互。从源码结构看Inspector 的本质是一个独立的 Sanic 应用。在 sanic/worker/inspector.py 中Inspector类被设计为一个可调用对象当它被调用时会创建一个名为Inspector的 Sanic 应用并以single_processTrue的方式运行在一个独立的 socket 上# sanic/worker/inspector.py 中的核心逻辑节选 self.app Sanic(Inspector) self._setup() if run: self.app.run( hostself.host, portself.port, single_processTrue, ssl{key: self.tls_key, cert: self.tls_cert} if not isinstance(self.tls_key, Default) and not isinstance(self.tls_cert, Default) else None, )它在你的 Sanic 应用之外单独存在因此它不是跑在 Sanic 应用内部的中间件或路由而是一个分离的进程、一个分离的应用、暴露在一个分离的 socket 上默认绑定在localhost:6457只有当app.config.INSPECTOR为True时主进程Main process才会把它作为一个非 server 进程注册到 Worker Manager 中。在 sanic/mixins/startup.py 中可以看到它的注册逻辑inspector None if primary.config.INSPECTOR: ... inspector primary.inspector_class( monitor_pub, app_info, worker_state, primary.config.INSPECTOR_HOST, primary.config.INSPECTOR_PORT, primary.config.INSPECTOR_API_KEY, primary.config.INSPECTOR_TLS_KEY, primary.config.INSPECTOR_TLS_CERT, ) manager.manage(Inspector, inspector, {}, transientFalse)这里manager.manage(...)将其注册为transientFalse的 durable持久进程意味着它不会被 auto-reloader 随文件变更重启。启用 InspectorInspector 默认是关闭的。启用它有两种等价方式方式一创建应用实例时传入标志app Sanic(TestApp, inspectorTrue)方式二设置配置值app Sanic(TestApp) app.config.INSPECTOR True⚠️ 警告如果使用配置值的方式必须在主 worker 进程启动之前尽早设置。这意味着它要么是环境变量要么像上面这样在创建应用实例后立刻设置。在源码 sanic/app.py 中可以看到inspectorTrue本质上也是写入配置if inspector: self.config.INSPECTOR inspector而 sanic/config.py 中给出了所有 Inspector 相关配置的默认值INSPECTOR: False, # 是否启用 Inspector INSPECTOR_HOST: localhost, # 绑定主机 INSPECTOR_PORT: 6457, # 绑定端口 INSPECTOR_TLS_KEY: _default, # TLS 私钥路径 INSPECTOR_TLS_CERT: _default,# TLS 证书路径 INSPECTOR_API_KEY: , # API 认证密钥空表示不启用认证使用 Inspector一旦 Inspector 运行起来你可以通过两种方式访问它CLI 或直接 HTTP 访问其 Web API。通过 CLIsanic inspect通过 HTTPcurl http://localhost:6457CLI 底层就是一个 HTTP 客户端。在 sanic/cli/inspector_client.py 中InspectorClient使用 Python 标准库urllib发起请求并根据secure参数决定使用https还是http协议在 sanic/cli/app.py 中_inspector()方法负责解析sanic inspect后面的参数将 host、port、secure、raw、api_key 剥离出来剩余参数作为 action 及自定义命令参数交给InspectorClient.do(action, **kwargs)。CLI 与 HTTP 的对照关系如下CLI 命令HTTP 动作说明sanic inspectGET /显示运行中应用的基本信息sanic inspect reloadPOST /reload触发所有 server worker 的重载sanic inspect shutdownPOST /shutdown触发所有进程的关闭sanic inspect scale NPOST /scalebody{replicas: N}将 worker 数量伸缩到 NCLI 的完整参数定义于 sanic/cli/inspector.py--host, -HInspector 主机地址默认localhost--port, -pInspector 端口默认6457--secure, -s通过 TLS 加密访问 Inspector--api-key, -kInspector 认证密钥--raw输出原始响应信息不经过 MOTD 格式化子命令reload支持--zero-downtime、shutdown、scale replicas、custom自定义命令内置命令的底层实现内置命令并不是魔法而是Inspector类上的真实方法见 sanic/worker/inspector.py每个方法通过_publisher一条multiprocessing.connection.Connection向主进程的 monitor 管道发送指令消息reload发送__ALL_PROCESSES__:若带zero_downtimeTrue则发送__ALL_PROCESSES__::STARTUP_FIRST即先启动新进程、等它 ack 后再拆除旧进程实现零停机重载scale发送__SCALE__:{num_workers}由 sanic/worker/manager.py 的_handle_message解析后调用self.scale(int(...))执行真正的伸缩shutdown发送__TERMINATE__主进程收到后触发整体关闭。这些行为在 tests/worker/test_inspector.py 中有对应的测试验证例如def test_run_inspector_reload_zero_downtime(publisher, http_client): _, response http_client.post(/reload, json{zero_downtime: True}) assert response.status 200 publisher.send.assert_called_once_with(__ALL_PROCESSES__::STARTUP_FIRST) def test_run_inspector_scale(publisher, http_client): _, response http_client.post(/scale, json{replicas: 4}) assert response.status 200 publisher.send.assert_called_once_with(__SCALE__:4)注意scale的语义是伸缩到 N 个 workerWorkerManager.scale内部通过create_server()扩容、shutdown_server()缩容而不是增加 N 个。自定义命令Inspector 可以非常容易地扩展出自定义命令以及对应的 HTTP endpoint。编写自定义方法子类化Inspector类并创建任意方法。只要方法名不以_下划线开头该方法名就会成为 Inspector 上的一个新子命令from sanic import json from sanic.worker.inspector import Inspector class MyInspector(Inspector): async def something(self, *args, **kwargs): print(args) print(kwargs) app Sanic(TestApp, inspector_classMyInspector, inspectorTrue)这样会按以下通用模式暴露自定义方法CLIsanic inspect method_nameHTTPPOST /method_name从源码看HTTP 路由在_setup()中统一注册为self.app.post(/action:str)(self._action)_action通过getattr(self, action, None)查找对应方法并调用sanic/worker/inspector.py。因此任何不带下划线前缀的方法天然成为一个 endpoint。参数传递规则新方法接受什么参数取决于你打算如何使用该命令。例如上面的something方法接受所有位置参数和关键字参数。在 CLI 中位置参数和关键字参数会作为位置参数或关键字参数传递给方法。所有值都是str但有如下例外一个没有赋值的关键字参数其值为True如果参数以no-为前缀则其值为False。sanic inspect something one two three --four --no-five --six6在你的应用日志控制台你会看到(one, two, three) {four: True, five: False, six: 6}这个解析逻辑位于 sanic/cli/app.py 的_inspector()方法中--开头的参数若含则拆分为 key/value否则--no-前缀解析为False、普通标志解析为True。直接调用 API也能达到同样的效果把参数放到 JSON payload 中传给方法。唯一需要注意的是位置参数应放在{args: [...]}中curl http://localhost:6457/something \ --json {args:[one, two, three], four:true, five:false, six:6}在你的应用日志控制台你会看到(one, two, three) {four: True, five: False, six: 6}注意 HTTP 方式下 JSON 中的类型会被保留如six是整数6而 CLI 方式下所有值都是字符串如6。在生产环境使用⚠️ 危险在把 Inspector 暴露到生产环境之前请仔细考虑本节的所有选项。Inspector 是一个能触发 worker 重载、关闭、伸缩的管理接口一旦暴露在公网且未做防护任何人都可能关闭你的服务。在远程生产实例上运行 Inspector 时你可以通过以下两种方式保护 endpoint要求 TLS 加密以及要求 API Key 认证。TLS 加密为 Inspector 的 HTTP 实例启用 TLS需要传入证书和密钥的路径app.config.INSPECTOR_TLS_CERT /path/to/cert.pem app.config.INSPECTOR_TLS_KEY /path/to/key.pem配置后访问时必须使用--secure标志或使用https://协议sanic inspect --secure --hostsomewherecurl https://somewhere:6457对应地sanic/worker/inspector.py 中只有同时配置了tls_key和tls_cert时才向app.run()传入ssl参数而InspectorClient会根据secure选择httpsscheme 发起请求。API Key 认证你可以使用 Bearer Token 认证来保护 APIapp.config.INSPECTOR_API_KEY Super-Secret-200配置后访问时需要--api-key参数或携带 Bearer Token 授权头sanic inspect --api-keySuper-Secret-200curl http://localhost:6457 -H Authorization: Bearer Super-Secret-200其认证实现见 sanic/worker/inspector.pydef _authentication(self, request: Request) - None: if request.token ! self.api_key: raise Unauthorized(Bad API key)当api_key非空时_setup()会为 Inspector 应用注册on_request钩子比较请求中的 token即Authorization: Bearer头中的值与配置的密钥不一致则抛出Unauthorized。CLI 侧则在 sanic/cli/inspector_client.py 中自动附加authorization: Bearer {api_key}头。配置项总览所有 Inspector 相关配置项、默认值与说明如下默认值来源 sanic/config.py表格来源 configuration 文档配置项默认值说明INSPECTORFalse是否启用 InspectorINSPECTOR_HOSTlocalhostInspector 绑定主机INSPECTOR_PORT6457Inspector 绑定端口INSPECTOR_TLS_KEY-Inspector 的 TLS 私钥路径INSPECTOR_TLS_CERT-Inspector 的 TLS 证书路径INSPECTOR_API_KEY-Inspector 的 API 认证密钥版本演进方面v22.9 新增了INSPECTORv22.12 新增了INSPECTOR_HOST、INSPECTOR_PORT、INSPECTOR_TLS_KEY、INSPECTOR_TLS_CERT、INSPECTOR_API_KEY。更完整的配置说明可参考 Running - Configuration。与 Worker Manager 的关系Inspector 是 Worker Manager 体系中的一个内置非 server 进程与 auto-reloader 并列。Worker Manager 负责管理所有进程而 Inspector 则把 Manager 的部分能力重载、关闭、伸缩以及所有进程的运行状态通过 HTTP/CLI 暴露出来。从 manager 文档 可以看到一旦启用了 Inspectorapp.config.INSPECTOR True你就可以执行这些 CLI 命令sanic inspect reload Trigger a reload of the server workers sanic inspect shutdown Shutdown the application and all processes sanic inspect scale N Scale the number of workers to N sanic inspect custom Run a custom command要理解 Inspector 的完整能力边界需要先了解 Worker Manager 的进程模型、multiplexerapp.m、worker 状态机NONE/IDLE/STARTING/STARTED/ACKED/JOINED/TERMINATED/RESTARTING/FAILED/COMPLETED以及自定义进程的注册方式这些内容可继续阅读 Worker Manager。小结Sanic Inspector 为运行中的多进程实例提供了一条轻量的管理通道一条 CLI 命令sanic inspect或一个curl调用就能完成状态查看、worker 重载、进程关闭与数量伸缩通过子类化Inspector还能把任意业务方法暴露为自定义管理命令。在生产环境中务必组合使用 TLS 与 API Key 双保险将管理能力牢牢锁在可信网络内。赞分享后端Web框架【免费下载链接】sanicAccelerate your web app development | Build fast. Run fast.项目地址https://gitcode.com/gh_mirrors/sa/sanic点击查看免费下载相关推荐JupyterHub项目实战如何独立运行中转服务与Hub服务JupyterHub项目实战如何独立运行中转服务与Hub服务 前言 在JupyterHub的架构设计中中转服务 Proxy 扮演着至关重要的角色。它作为用户后端微服务webpack Web Worker 实战解析new Worker()/new SharedWorker() 的分包、命名与独立运行时webpack Web Worker 实战解析 new Worker / new SharedWorker 的分包、命名与独立运行时 本技术指南以仓库中的官方前端构建开发工具用 EasyOCR 搭建 LiteParse 独立 OCR 服务部署、HTTP API 与接入实战用 EasyOCR 搭建 LiteParse 独立 OCR 服务部署、HTTP API 与接入实战 LiteParse 除了内置的 Tesseract OCROCR文档上一篇解析Rust中的JSON与XML文件操作 - roadmap-retos-programacion项目实战下一篇深入解析Elixir正则表达式实战 - roadmap-retos-programacion项目案例创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考