开源密钥管理器VSV:一个加密文件搞定多环境密钥管理

news2026/5/12 21:33:10
1. 项目概述一个面向开发者的加密密钥管理器最近在折腾一个内部项目需要管理不同环境开发、测试、生产的数据库密码、API密钥这些敏感信息。一开始图省事直接写在了.env文件里结果在代码评审时被同事一眼看到场面一度十分尴尬。后来也试过一些云端的密钥管理服务功能是强大但要么太贵要么配置复杂还得担心服务商的可靠性。就在我纠结的时候发现了一个叫 Victory‘s Secrets简称 VSV的开源项目它的理念一下子打动了我一个加密文件搞定所有密钥管理无需任何外部依赖。简单来说VSV 是一个为开发者和中小团队设计的加密密钥管理器。它的核心思想非常极客把你所有的密钥Secrets——比如数据库连接串、第三方服务的 Token、内部 API 的密钥——都加密打包进一个单一的.vsv文件里。这个文件就是你的“保险库”。你可以像对待普通代码一样把它提交到 Git 仓库进行版本管理可以把它扔到任何一台 HTTPS 服务器上作为远程保险库在 Docker 或 Kubernetes 环境里直接把它挂载为卷Volume就行。整个过程中完全不需要连接任何额外的密钥管理服务或数据库真正做到了“拎包入住”开箱即用。我花了些时间深入研究它的源码和设计发现它绝不是一个简单的“加密版.env文件”。从底层的加密算法选型到面向开发流程的 CLI 工具链再到为生产环境准备的守护进程Agent模式设计得非常周全。接下来我就结合自己的实际使用和代码阅读心得把这个项目的里里外外、从原理到实操给大家拆解明白。2. 核心设计思路与安全架构拆解2.1 为什么是“一个文件”哲学在深入技术细节前我们先聊聊 VSV 最根本的设计哲学“一个文件”。这听起来简单背后却解决了一系列实际问题。首先它极大地简化了部署和协作。传统的密钥管理方案无论是使用环境变量文件.env、云服务商提供的密钥管理服务还是自建的 HashiCorp Vault你都需要在应用部署时配置相应的访问权限、网络策略或客户端。而 VSV 只需要一个文件。在 CI/CD 流水线中你只需要在构建或部署步骤里确保能访问到这个加密的.vsv文件并提供解密密码即可。在团队协作中新成员拉取代码库后如果已经共享了加密文件和解密密码通过安全渠道他立刻就能获得所有环境的密钥无需等待权限审批或学习复杂的客户端配置。其次它实现了状态的可追溯和可版本化。密钥并不是一成不变的数据库密码可能会轮换API 密钥可能会更新。当这些变更被记录在一个加密文件里并提交到 Git 后你就拥有了完整的变更历史。你可以清晰地看到某年某月某日是谁因为什么原因通过 Commit 信息修改了生产环境的某个密钥。这比在某个黑盒管理界面上点一下“更新”要透明和可靠得多。最后它赋予了部署环境极大的灵活性。这个文件可以放在任何地方本地开发文件就在项目根目录。Git 仓库作为二进制文件提交虽然 Git 对二进制文件 diff 不友好但我们是加密的本来也看不到内容。静态文件服务器你可以把这个文件放到任何支持 HTTPS 的静态托管服务如 AWS S3、Cloudflare R2、甚至 GitHub Releases上。应用运行时通过 HTTPS 下载并解密。关键点在于服务器只能看到一堆加密的、无意义的字节完全不知道里面是什么。容器卷在 Docker 或 K8s 中直接将这个文件作为 ConfigMap 或 Secret 挂载进容器。这种“文件即接口”的设计让密钥管理的基础设施成本降到了几乎为零。2.2 加密与密钥派生如何锁住你的秘密安全是密钥管理器的生命线。VSV 在加密层面的选择非常扎实和现代没有使用任何冷门或过时的算法。1. 加密算法AES-256-GCMVSV 使用AES-256-GCM模式对文件内容进行加密。这里有几个关键词AES-256这是目前公认安全、高效的对称加密算法256位密钥长度在可预见的未来都是安全的。GCM 模式全称 Galois/Counter Mode。这不仅仅是一个加密模式它同时提供了认证加密功能。这意味着它不仅能防止内容被窃听机密性还能防止密文在传输或存储过程中被篡改完整性。如果加密文件被人恶意修改了一个字节解密时会直接失败报错而不是解出一堆乱码这非常重要。2. 密钥派生Argon2id用户的密码通常不够强不能直接用作加密密钥。这里就需要一个“密钥派生函数”KDF把用户输入的密码可能很弱转换成一个强壮的、固定长度的加密密钥。VSV 选择了Argon2id这是目前密码哈希竞赛PHC的冠军算法被公认为抵御 GPU、ASIC 等硬件破解攻击的最佳选择之一。VSV 使用的参数是内存消耗 256MB迭代次数 8。这个参数设置很有讲究256MB 内存这使得攻击者如果想用显卡GPU进行暴力破解需要为每个猜测的密码分配大量显存极大拖慢破解速度提高攻击成本。8 次迭代在保证安全强度的前提下这是一个对日常使用比较友好的性能折中点。派生一次密钥可能需要几百毫秒用户能感知到但不会觉得卡顿而对于需要尝试数十亿次密码的攻击者来说这个延迟就是灾难。3. 密钥的生命周期永不落盘这是 VSV 安全设计中非常关键的一环用户的原始密码和最终用于加密的 CryptoKey永远不会以任何形式写入磁盘。用户输入密码。使用 Argon2id 派生出一个中间密钥材料。在内存中通过 Web Crypto APINode.js 环境生成一个CryptoKey对象。这个 Key 对象可以被标记为non-extractable不可提取意味着即使恶意代码拿到了这个 Key 对象也无法从中读出原始的密钥字节。所有加密解密操作都通过这个CryptoKey对象在内存中进行。当进程结束或用户主动锁定保险库这个 Key 对象就从内存中消失了。注意这意味着你必须妥善保管好你的主密码。VSV 没有“忘记密码”的功能。一旦丢失密码那个.vsv加密文件就成了一堆永远无法解开的乱码。建议使用 1Password、Bitwarden 等密码管理器来管理你的 VSV 主密码。2.3 多环境与组织结构设计一个真实的项目通常有development开发、staging预发布、production生产等多个环境每个环境的密钥值是不同的。VSV 采用了一种直观的树状结构来组织密钥服务 (service) - 环境 (environment) - 字段 (field)例如你可以这样设置# 设置开发环境的数据库主机 vsv set db.host localhost -e dev # 设置生产环境的数据库主机另一个值 vsv set db.host prod-db.cluster.amazonaws.com -e prod # 设置一个所有环境共享的 API 密钥不指定 -e vsv set payment.api_key sk_live_xxxxxx在加密文件中数据实际上是以一种结构化的方式存储的例如 JSON但对外呈现的是这种点分隔的路径式访问非常清晰。这种设计让密钥管理不再是一团乱麻而是有了清晰的命名空间也便于在 CI/CD 中按环境进行校验和注入。3. 核心工具链详解与实战操作VSV 不是一个孤立的库它提供了一整套从开发到生产、从命令行到图形界面的工具链。理解并熟练使用这些工具是发挥其威力的关键。3.1 CLI开发者的瑞士军刀CLI 是 VSV 最核心的交互方式覆盖了 80% 的日常操作。安装非常简单作为一个全局工具使用npm install -g vsv # 或者更推荐在项目中使用 npx避免全局污染 npx vsv --help初始化与基础操作首先我们需要创建一个加密的保险库文件。# 在当前目录初始化一个名为 secrets.vsv 的保险库文件 # 命令会提示你输入并确认主密码 vsv init -f secrets.vsv执行后会生成一个secrets.vsv文件。用文本编辑器打开它你会看到类似U2FsdGVkX1...这样的一长串 Base64 编码的加密数据除此之外什么也看不懂。接下来开始添加密钥。假设我们有一个后端服务需要数据库和 Redis 的配置。# 添加开发环境配置。--create 参数表示如果路径不存在则自动创建。 vsv set db.host localhost -e dev --create -f secrets.vsv vsv set db.port 5432 -e dev -f secrets.vsv vsv set db.name myapp_dev -e dev -f secrets.vsv vsv set db.password dev_password_123 -e dev -f secrets.vsv vsv set redis.url redis://localhost:6379 -e dev -f secrets.vsv # 添加生产环境配置值不同 vsv set db.host production-db.rds.amazonaws.com -e prod --create -f secrets.vsv vsv set db.port 5432 -e prod -f secrets.vsv ...你可以通过vsv list命令查看所有已存储的密钥路径。密钥注入与动态执行这是 VSV 非常酷的一个功能vsv run。它允许你直接启动一个进程并将指定环境的密钥作为环境变量注入到该进程中。# 使用开发环境的密钥启动 Node.js 应用 vsv run -e dev -f secrets.vsv -- node server.js # 在脚本中你可以像往常一样通过 process.env 访问这些变量 # 例如server.js 里可以直接用 process.env.DB_HOST这个命令背后VSV 会先解密文件然后根据你定义的模板或默认规则将密钥转换为环境变量最后 spawn 一个新的子进程并将这些变量注入其环境。子进程完全感知不到 VSV 的存在它只是发现自己运行时环境变量已经齐备了。环境文件生成虽然vsv run很方便但很多传统应用或脚本还是依赖.env文件。VSV 可以动态生成它。 首先你需要一个模板文件比如.env.template# .env.template DB_HOST{{ db.host }} DB_PORT{{ db.port }} DB_NAME{{ db.name }} REDIS_URL{{ redis.url }} API_KEY{{ payment.api_key }}注意{{ ... }}是占位符对应 VSV 中的密钥路径。然后使用命令生成vsv template .env.template -e dev -o .env.dev这会生成一个内容如下的.env.dev文件DB_HOSTlocalhost DB_PORT5432 DB_NAMEmyapp_dev REDIS_URLredis://localhost:6379 API_KEYsk_live_xxxxxx你可以把这个生成步骤放在应用启动脚本或 Docker 容器的启动入口中实现密钥的运行时渲染。3.2 Agent 守护进程生产环境的稳定基石在开发时每次操作都输入密码没问题但在生产环境的自动化脚本或长时间运行的服务中反复解密文件既不安全密码可能出现在进程参数中也低效。为此VSV 提供了Agent守护进程模式。Agent 的工作原理启动用户用密码启动 AgentAgent 在内存中解密并加载整个保险库持有一个解密的密钥上下文。监听Agent 启动一个 Unix Domain Socket在 Linux/macOS 上或 Named Pipe在 Windows 上并监听这个 Socket。通信后续所有的vsv get、vsv run等命令不再直接操作文件而是作为客户端通过这个 Socket 向 Agent 发送请求。响应Agent 利用内存中的密钥上下文处理请求如查询某个值、渲染模板并将结果返回给客户端。安全Socket 文件的权限被设置为0600即只有启动 Agent 的用户自己可以读写其他用户无法访问。实操使用 Agent# 1. 启动 Agent 守护进程。 # -d 参数表示以守护进程daemon模式运行即后台运行。 # 命令会提示输入密码成功后 Agent 就在后台运行了。 vsv agent start -f secrets.vsv -e prod -d # 2. 现在所有后续命令都无需指定 -f 文件和密码了。 # 它们会自动连接到本地的 Agent Socket 进行操作。 vsv get db.host # 直接获取生产环境的 db.host vsv run -- node server.js # 使用生产环境密钥启动服务 # 3. 查看 Agent 状态 vsv agent status # 4. 停止 Agent vsv agent stop为什么 Agent 模式更适合生产环境密码隔离密码只在启动 Agent 时输入一次之后不再出现。在 Docker 中你可以在容器启动的初始化脚本中启动 Agent密码可以通过VSV_PASSWORD环境变量传入确保该环境变量仅对初始化脚本可见之后应用进程完全通过 Socket 通信接触不到密码。性能避免了每次操作都进行昂贵的 Argon2id 密钥派生和文件解密对于频繁访问密钥的应用如每次请求都需要 API Key 的微服务性能提升显著。集中管理多个进程可以共享同一个 Agent 提供的密钥上下文。3.3 SDK在代码中直接集成对于更复杂的应用你可能需要在运行时动态读取密钥而不是仅仅通过环境变量。VSV 提供了 TypeScript/JavaScript SDK。方式一直接操作保险库文件适用于脚本、CLI 工具等一次性任务。import { vault } from vsv; async function main() { // 打开保险库文件需要提供密码可以从环境变量读取 await vault.open(./secrets.vsv, process.env.VSV_PASSWORD!); // 获取特定环境的密钥 const dbHost vault.get(db.host, prod); const apiKey vault.get(payment.api_key); // 获取全局密钥 console.log(Database host: ${dbHost}); // 使用完毕后可以关闭清除内存中的密钥 vault.close(); } main().catch(console.error);方式二连接 Agent适用于长时间运行的服务与 Agent 模式搭配是绝配。import { createClient } from vsv/client; async function bootstrapApp() { // 创建连接到本地 Agent Socket 的客户端 // 默认会尝试连接 VSV 默认的 Socket 路径无需配置 const client createClient(); try { // 通过 Agent 获取密钥无需密码 const dbConfig { host: await client.get(db.host, prod), port: await client.get(db.port, prod), name: await client.get(db.name, prod), password: await client.get(db.password, prod), }; console.log(Database config loaded via Agent:, dbConfig); // 使用配置连接数据库... } catch (error) { console.error(Failed to connect to VSV agent. Is it running?, error); process.exit(1); } } bootstrapApp();SDK 的方式给了你最大的灵活性可以将密钥管理无缝集成到你的应用初始化逻辑中。3.4 桌面应用给非命令行用户一个界面不是所有团队成员都习惯命令行。VSV 还提供了一个基于 Electron 的桌面图形界面应用。这对于项目经理、测试人员或需要偶尔查看某个密钥值的开发者来说非常友好。桌面应用的核心安全原则与 CLI 一致密钥明文只存在于应用的内存和渲染进程的严格隔离区域中永远不会暴露给 DOM 或泄露到剪贴板除非用户明确复制且应用实现了剪贴板自动清空。应用通常还会在窗口失去焦点时启用隐私遮罩防止他人窥屏。4. 集成到现代开发与部署流水线一个工具再好如果不能融入现有的 CI/CD 流程价值就大打折扣。VSV 在这方面考虑得很周到。4.1 在 CI 中校验密钥预检门禁在代码合并或部署前检查生产环境的密钥是否已正确设置且格式有效是一个很好的实践。这可以避免将缺少关键配置的代码部署上线。# GitHub Actions 示例 name: Test and Lint on: [push, pull_request] jobs: secrets-check: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Check Production Secrets run: npx vsv check -e prod -f secrets.vsv env: # 将 VSV 主密码存储在 GitHub Secrets 中变量名为 VSV_PASSWORD VSV_PASSWORD: ${{ secrets.VSV_PASSWORD }}vsv check命令会尝试解密文件并验证指定环境这里是prod下所有必需的密钥是否都存在且非空。如果校验失败CI 流程会中止从而阻止有问题的代码进入下一阶段。4.2 在 Docker 容器中使用在 Docker 化部署中你有几种选择将加密文件作为构建上下文在 Dockerfile 中 COPY 进去。不推荐因为这会让加密文件留在镜像层中虽然内容是加密的但增加了镜像体积和潜在的攻击面。运行时挂载这是推荐的方式。在docker run或 Docker Compose 中将宿主机上的secrets.vsv文件作为卷Volume挂载到容器内的特定路径。# docker-compose.yml version: 3.8 services: app: build: . volumes: - ./secrets.vsv:/app/secrets.vsv:ro # 只读挂载 environment: - VSV_PASSWORD_FILE/run/secrets/vsv_password # 从 Docker Secret 读取密码 # 在 entrypoint.sh 中启动 vsv agent 或直接使用 vsv run使用 Docker Secrets对于密码可以使用docker secret create创建然后在 Compose 文件中引用它会以文件形式挂载到容器的/run/secrets/目录下。VSV 支持通过VSV_PASSWORD_FILE环境变量指定密码文件路径非常安全。4.3 在 Kubernetes 中部署Kubernetes 的原生资源Secret虽然可以用来存储密钥但它是 Base64 编码而非加密的有权限的人可以直接看到。VSV 提供了一个更安全的中间方案。方案A使用 VSV 文件作为 ConfigMap将secrets.vsv整个加密文件创建为 ConfigMap。kubectl create configmap app-secrets-vault --from-filesecrets.vsv然后在 Pod 中挂载这个 ConfigMap。密码可以通过 Kubernetes Secret 来提供同样Secret 是 Base64但至少和业务配置分开了。apiVersion: v1 kind: Pod metadata: name: my-app spec: containers: - name: app image: my-app:latest volumeMounts: - name: vault-config mountPath: /etc/vsv readOnly: true - name: vault-password mountPath: /etc/vsv-password readOnly: true env: - name: VSV_PASSWORD_FILE value: /etc/vsv-password/password volumes: - name: vault-config configMap: name: app-secrets-vault - name: vault-password secret: secretName: vsv-main-password items: - key: password path: password在应用的启动命令中使用vsv run或启动vsv agent。方案B远程保险库Remote Vault这是更优雅和安全的方式。将加密的secrets.vsv文件托管在一个内部的 HTTPS 文件服务器上比如用 Nginx 托管一个静态文件。你的 Kubernetes 应用只需要知道这个文件的 URL 和密码即可。env: - name: VSV_VAULT_URL value: https://internal-fileserver.company.com/secrets/production.vsv - name: VSV_PASSWORD valueFrom: secretKeyRef: name: vsv-secrets key: masterPassword应用启动时VSV SDK 或 CLI 会从VSV_VAULT_URL下载加密文件然后用密码解密。这样做的好处是密钥文件与镜像解耦更新密钥无需重新构建和部署镜像只需替换服务器上的文件。访问控制可以通过 HTTPS 服务器的认证机制如客户端证书、IP 白名单来控制谁可以下载这个文件。审计文件服务器的访问日志就是你的密钥文件访问审计日志。5. 实战心得与避坑指南在实际项目中使用 VSV 一段时间后我积累了一些经验教训也遇到并解决了一些典型问题。5.1 密码管理与备份策略问题主密码丢了怎么办.vsv文件损坏了怎么办心得密码必须用密码管理器保存这是铁律。1Password、Bitwarden 等工具是管理 VSV 主密码的最佳场所。可以考虑创建一个“紧急访问”或“共享保险库”在团队核心成员间共享这个主密码。定期备份加密文件虽然文件在 Git 里但建议定期如每周将最新的secrets.vsv文件单独备份到另一个安全的离线位置。Git 仓库有可能被误操作清空历史。使用--create参数在vsv set时养成使用--create的习惯。如果路径不存在比如你打错了字它会创建一个空值而不是报错退出。这有助于通过后续的vsv check发现配置缺失而不是在运行时才崩溃。5.2 团队协作流程问题新成员加入或者有密钥需要更新如何安全地同步建议流程初始化由项目负责人用vsv init创建初始加密文件并设置好主密码。共享密码通过安全的线下渠道如当面告知、使用已建立的 PGP 加密邮件将主密码告知需要访问的团队成员。切勿通过 Slack、微信等在线聊天工具发送。文件共享将secrets.vsv文件提交到 Git 仓库的一个特定目录如infra/secrets/。确保.gitignore不会忽略它。密钥更新更新者拉取最新代码在本地用vsv set修改密钥。使用vsv check验证修改无误。提交secrets.vsv文件的变更到 Git并附上清晰的 Commit 信息如 “Update production Stripe API key”。其他成员拉取代码后自动获得最新的密钥文件。他们不需要知道新密码因为加密文件用的是同一个主密码。5.3 常见错误与排查错误Error: Decryption failed可能原因 1密码错误。这是最常见的原因。仔细检查输入注意大小写和特殊字符。如果从环境变量传入检查变量名是否正确值前后是否有空格或换行符。可能原因 2加密文件损坏。如果文件在传输或存储过程中出现比特错误解密也会失败。尝试从备份或 Git 历史中恢复一个版本。排查命令可以尝试用vsv view --metadata -f secrets.vsv如果项目有该命令查看文件头信息确认文件格式是否正确。错误Error: Socket connection refused(Agent 模式)可能原因 1Agent 没有启动。运行vsv agent status检查。可能原因 2Agent 已崩溃或异常退出。检查系统日志或使用ps aux | grep vsv查看进程是否存在。尝试vsv agent stop后再vsv agent start。可能原因 3Socket 文件权限问题。在某些系统上如果以不同用户身份运行命令可能无法访问属于另一个用户的 Socket 文件权限为 0600。确保使用同一用户。性能问题启动或操作缓慢可能原因Argon2id 密钥派生是故意设计成耗资源的。256MB 内存和 8 次迭代在性能较弱的机器如低配 CI Runner或容器中可能感觉明显。优化建议在 CI 中考虑缓存解密后的上下文如果安全策略允许而不是每次 job 都重新派生密钥。在生产环境务必使用 Agent 模式。一次派生长期使用。如果确实需要调整可以查阅 VSV 的源码看是否支持通过环境变量降低 Argon2id 参数注意这会降低安全性请谨慎评估。5.4 安全增强建议定期轮换主密码虽然麻烦但这是安全最佳实践。流程是用旧密码打开保险库立即用vsv change-password命令如果提供或创建一个新文件并迁移所有密钥然后彻底删除旧文件。限制.vsv文件的访问权限在服务器上确保secrets.vsv文件的权限是600仅所有者可读写。审计日志VSV 本身不记录访问日志。对于高安全场景可以考虑如果使用远程保险库分析 HTTPS 服务器的访问日志。在调用 VSV SDK 的代码中加入关键密钥访问的日志注意切勿日志记录密钥值本身只记录访问了哪个路径。结合云厂商的 KMS对于顶级安全需求可以将 VSV 的主密码本身加密后存储。例如使用 AWS KMS 或 Google Cloud KMS 加密你的 VSV 主密码应用启动时先调用 KMS 解密出主密码再用它来打开 VSV 保险库。这样VSV 主密码也不以明文形式存在了。6. 总结与项目展望Victory‘s Secrets 这个项目在我看来精准地击中了一个痛点在追求简单、可控和安全的平衡点上为开发者和中小团队提供了一个近乎完美的解决方案。它没有去和 HashiCorp Vault 这样的企业级巨无霸竞争分布式、高可用、复杂策略管理的功能而是牢牢抓住了“一个文件”这个核心抽象把单机场景下的密钥管理做到了极致。从技术选型上看AES-256-GCM 和 Argon2id 的组合是当前密码学实践中的“黄金标准”体现了作者对安全性的深刻理解。从工具链设计上看CLI、Agent、SDK、Desktop App 的覆盖满足了从自动化脚本到图形化操作的所有需求体现了优秀的开发者体验思维。从集成友好度上看对 CI/CD、Docker、Kubernetes 的天然支持让它能轻松融入现代开发流程。当然它也有其边界。它不适合需要成百上千个微服务共享密钥、需要动态生成临时密钥、需要精细到“某个服务只能读某个路径”这种复杂权限模型的超大规模场景。但对于绝大多数创业公司、内部项目、开源应用以及中小型企业的产品来说它的能力已经绰绰有余甚至过剩。我个人在几个项目中采用 VSV 后最直观的感受是“心静了”。再也不用在部署文档里写“请先在服务器上创建如下环境变量”再也不用担心.env.example文件里不小心留下了真实密钥再也不用在团队群里问“谁有生产环境的那个 API Key”。一切关于秘密的信息都被收敛到了一个加密文件里并通过 Git 进行版本化和协作。这种简洁和秩序对于研发效率和安全性的提升是实实在在的。最后如果你正在被各种密钥管理问题困扰不妨花上半小时按照上面的快速开始试试 Victory‘s Secrets。它可能不会是你技术栈中最闪耀的那个组件但很可能会成为你最信赖、最省心的那一块基石。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2607273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…