首页
斐讯设备
疯言疯语
系统运维
编程语言
网站建设
友情连接
推荐
autojs
Search
1
charles破解注册码(含windows和mac)最新安装教程「亲测有效」
57 阅读
2
aris常用命令收集
32 阅读
3
【N1和Armbian】一、N1刷Linux系统armbian
31 阅读
4
docker更新现有容器为自动重启
28 阅读
5
[上]JAVA学习系列模块九第五章186.对象数组_基本使用
26 阅读
登录
Search
标签搜索
JAVA
JAVA学习系列
docker
Linux
js
N1
git
模块二
模块一
端口
模块五
数据库
模块九
模块四
镜像
模块三
模块六
MySQL
百度网盘
nginx
DaiMaFengZi
累计撰写
591
篇文章
累计收到
10
条评论
首页
栏目
斐讯设备
疯言疯语
系统运维
编程语言
网站建设
页面
友情连接
推荐
autojs
搜索到
214
篇与
的结果
2026-08-13
达梦数据库 dexp/dimp 实战指南:模式克隆、REMAP_SCHEMA 与特殊字符踩坑记录
达梦数据库 dexp/dimp 实战指南:模式克隆、REMAP_SCHEMA 与特殊字符踩坑记录在日常的数据库运维和开发测试中,我们经常需要对某个模式(Schema)进行完整备份,或者将其"克隆"一份用于测试环境。在达梦数据库(DMDB)中,dexp(逻辑导出)和 dimp(逻辑导入)是完成这项工作的利器。本文将结合实战经验,分享如何使用 dexp/dimp 进行模式导出与重命名导入(REMAP_SCHEMA),并记录一个由密码特殊字符引发的"导出 0 张表"的隐蔽 Bug。一、核心踩坑:密码中的 .. 导致导出 0 张表诡异的现象在使用 dexp 导出 V5_EAM 模式时,命令行执行后瞬间结束,日志中显示:[WARNING]invalid object:V5_EAM export total 0 TABLE schema[V5_EAM] export terminate.....查询 DBA_TABLES 确认该模式下明明有 218 张表,但导出结果却是 0。根因分析经过排查,发现该数据库 SYSDBA 用户的密码为 woshimima..(末尾包含连续的两个点 ..)。当在命令行直接拼接连接串时:# 错误示范 ./dexp USERID=SYSDBA/woshimima..@localhost:5236 SCHEMAS=V5_EAM ...连续点号 .. 在 Shell 解析或 dexp 内部参数解析时,被错误地识别为路径跳转或特殊指令,导致 dexp 内部验证 Schema 属主时发生异常,从而跳过了所有对象的导出。解决方案方案 A(推荐):使用交互式密码输入不在命令行中明文传递密码,执行命令后根据提示输入:./dexp USERID=SYSDBA@localhost:5236 SCHEMAS=V5_EAM FILE=... LOG=...方案 B:使用单引号包裹整个 USERID利用单引号屏蔽 Shell 的特殊字符解析:./dimp 'USERID=SYSDBA/woshimima..@localhost:5236' ...二、实战:导出模式 (dexp)确认连接方式后,执行完整的模式导出。建议加上 PARALLEL 参数提升导出速度。cd /data/dmdbms/bin/ ./dexp USERID=SYSDBA@localhost:5236 \ SCHEMAS=V5_EAM \ FILE=/data/dmexport/V5_EAM.dmp \ LOG=/data/dmexport/V5_EAM_export.log \ PARALLEL=4执行后按提示输入密码。看到 terminate export success without warning 即代表完美导出。三、实战:导入并重命名模式 (dimp + REMAP_SCHEMA)很多时候,我们导出的数据是为了在同一实例下建立一份测试副本。这时就需要用到 REMAP_SCHEMA 参数,将源模式的数据导入到目标模式中。⚠️ 核心注意点:目标模式必须提前创建dimp 的 REMAP_SCHEMA 不会自动创建目标模式!如果目标模式不存在,导入会直接报错。Step 1:创建目标模式/data/dmdbms/bin/disql SYSDBA@localhost:5236 -e "CREATE SCHEMA V5_EAM_TEST_0813;"Step 2:执行导入cd /data/dmdbms/bin/ ./dimp USERID=SYSDBA@localhost:5236 \ FILE=/data/dmexport/V5_EAM.dmp \ LOG=/data/dmexport/V5_EAM_TEST_0813.log \ REMAP_SCHEMA=V5_EAM:V5_EAM_TEST_0813 \ TABLE_PARALLEL=4参数解析:REMAP_SCHEMA=源模式:目标模式。此操作对源模式 V5_EAM 是只读的,绝对不会影响原数据。四、总结密码安全与兼容性:强烈建议使用交互式密码输入来调用 dexp/dimp,既能避免密码泄露在 history 中,又能完美规避特殊字符(如 @、..、# 等)导致的解析 Bug。REMAP_SCHEMA 前置条件:永远记得在导入前,先 CREATE SCHEMA 目标模式。数据完整性:导入完成后,务必通过 SELECT COUNT(*) FROM DBA_TABLES WHERE OWNER='目标模式'; 核对表数量,确保数据无损迁移。💻 第二部分:自动化交互式 Shell 脚本将以下代码保存为 dm_migrate.sh,赋予执行权限(chmod +x dm_migrate.sh)后运行。脚本包含了环境检查、交互式菜单、密码隐藏输入和自动创建 Schema 等完善功能。脚本修正说明(发布前已订正):原稿在 Markdown 渲染中丢失了部分语法符号,已在此处还原/修正:还原变量符号 ${VAR}(原稿误为 {VAR});还原颜色转义 \033(原稿误为 033);修正命令替换 $(...) 与退出码 $?;disql 检查/建模式语句改用 双引号包裹密码(user/"pass"@host:port),与文章主旨一致,规避 .. 等特殊字符被解析的坑。#!/bin/bash # ============================================================================== # 达梦数据库 dexp/dimp 交互式迁移脚本 # 作者: DBA 运维助手 # 描述: 支持模式导出、模式重命名导入(REMAP_SCHEMA),自动处理前置校验 # ============================================================================== # ================= 基础配置区 (可根据实际环境修改) ================= DM_BIN_DIR="/data/dmdbms/bin" # 达梦 bin 目录路径 EXPORT_BASE_DIR="/data/dmexport" # 导出文件默认存放目录 DEFAULT_HOST="localhost" # 默认数据库 IP DEFAULT_PORT="5236" # 默认数据库端口 DEFAULT_USER="SYSDBA" # 默认执行用户 # ===================================================================== # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 检查达梦工具是否存在 check_env() { if [ ! -f "${DM_BIN_DIR}/dexp" ] || [ ! -f "${DM_BIN_DIR}/dimp" ]; then echo -e "${RED}[ERROR] 未找到 dexp 或 dimp 工具,请检查 DM_BIN_DIR 配置: ${DM_BIN_DIR}${NC}" exit 1 fi mkdir -p "${EXPORT_BASE_DIR}" } # 获取数据库连接参数 get_db_conn() { read -p "请输入数据库 IP [默认 ${DEFAULT_HOST}]: " DB_HOST DB_HOST=${DB_HOST:-$DEFAULT_HOST} read -p "请输入数据库端口 [默认 ${DEFAULT_PORT}]: " DB_PORT DB_PORT=${DB_PORT:-$DEFAULT_PORT} read -p "请输入数据库用户名 [默认 ${DEFAULT_USER}]: " DB_USER DB_USER=${DB_USER:-$DEFAULT_USER} echo -n "请输入 ${DB_USER} 的密码 (输入时不可见): " read -s DB_PASS echo "" if [ -z "${DB_PASS}" ]; then echo -e "${RED}[ERROR] 密码不能为空!${NC}" exit 1 fi # dexp/dimp:用单引号包裹整个 USERID,防止密码中的特殊字符(如 .. @ #)被 Shell 解析 CONN_STR="'USERID=${DB_USER}/${DB_PASS}@${DB_HOST}:${DB_PORT}'" # disql:用双引号包裹密码(达梦语法 user/"pass"@host:port),同样规避特殊字符 DISQL_CONN="${DB_USER}/\"${DB_PASS}\"@${DB_HOST}:${DB_PORT}" } # 导出模式 do_export() { echo -e "\n${BLUE}========== 模式导出 (dexp) ==========${NC}" get_db_conn read -p "请输入要导出的源模式名 (如 V5_EAM): " SRC_SCHEMA if [ -z "${SRC_SCHEMA}" ]; then echo -e "${RED}[ERROR] 模式名不能为空!${NC}" return fi TIMESTAMP=$(date +%Y%m%d_%H%M%S) DMP_FILE="${EXPORT_BASE_DIR}/${SRC_SCHEMA}_${TIMESTAMP}.dmp" LOG_FILE="${EXPORT_BASE_DIR}/${SRC_SCHEMA}_${TIMESTAMP}_exp.log" echo -e "${YELLOW}[INFO] 开始导出 ${SRC_SCHEMA} 到 ${DMP_FILE} ...${NC}" # 使用 eval 执行带有单引号的连接串(去掉外层单引号后整体作为一个参数传给 dexp) eval "${DM_BIN_DIR}/dexp ${CONN_STR} SCHEMAS=${SRC_SCHEMA} FILE=${DMP_FILE} LOG=${LOG_FILE} PARALLEL=4" if [ $? -eq 0 ]; then echo -e "${GREEN}[SUCCESS] 导出完成!请检查日志: ${LOG_FILE}${NC}" else echo -e "${RED}[ERROR] 导出失败,请查看日志排查原因: ${LOG_FILE}${NC}" fi } # 导入模式 do_import() { echo -e "\n${BLUE}========== 模式导入 (dimp + REMAP) ==========${NC}" get_db_conn read -p "请输入 DMP 文件绝对路径: " DMP_FILE if [ ! -f "${DMP_FILE}" ]; then echo -e "${RED}[ERROR] 文件不存在: ${DMP_FILE}${NC}" return fi read -p "请输入 DMP 文件中的源模式名 (如 V5_EAM): " SRC_SCHEMA read -p "请输入要导入的目标模式名 (如 V5_EAM_TEST_0813): " DEST_SCHEMA if [ -z "${SRC_SCHEMA}" ] || [ -z "${DEST_SCHEMA}" ]; then echo -e "${RED}[ERROR] 模式名不能为空!${NC}" return fi # 检查目标模式是否存在,不存在则提示创建 echo -e "${YELLOW}[INFO] 检查目标模式 ${DEST_SCHEMA} 是否存在...${NC}" CHECK_SQL="SELECT COUNT(*) FROM DBA_USERS WHERE USERNAME='${DEST_SCHEMA}';" # 使用 disql 检查(密码用双引号包裹,规避特殊字符) USER_EXISTS=$(echo "${CHECK_SQL}" | ${DM_BIN_DIR}/disql ${DISQL_CONN} -e 2>/dev/null | grep -oE '[0-9]+' | head -1) if [ "${USER_EXISTS}" != "1" ]; then echo -e "${YELLOW}[WARNING] 目标模式 ${DEST_SCHEMA} 不存在!dimp 不会自动创建模式。${NC}" read -p "是否立即通过 SYSDBA 创建该模式? (y/n): " CREATE_CHOICE if [[ "${CREATE_CHOICE}" =~ ^[Yy] ]]; then ${DM_BIN_DIR}/disql ${DISQL_CONN} -e "CREATE SCHEMA ${DEST_SCHEMA};" if [ $? -eq 0 ]; then echo -e "${GREEN}[SUCCESS] 模式 ${DEST_SCHEMA} 创建成功!${NC}" else echo -e "${RED}[ERROR] 模式创建失败,请检查权限或名称是否合法。${NC}" return fi else echo -e "${RED}[INFO] 取消导入。请先手动创建目标模式。${NC}" return fi fi TIMESTAMP=$(date +%Y%m%d_%H%M%S) LOG_FILE="${EXPORT_BASE_DIR}/${DEST_SCHEMA}_${TIMESTAMP}_imp.log" echo -e "${YELLOW}[INFO] 开始导入 ${SRC_SCHEMA} -> ${DEST_SCHEMA} ...${NC}" eval "${DM_BIN_DIR}/dimp ${CONN_STR} FILE=${DMP_FILE} LOG=${LOG_FILE} REMAP_SCHEMA=${SRC_SCHEMA}:${DEST_SCHEMA} TABLE_PARALLEL=4" if [ $? -eq 0 ]; then echo -e "${GREEN}[SUCCESS] 导入完成!请检查日志: ${LOG_FILE}${NC}" else echo -e "${RED}[ERROR] 导入出现异常,请查看日志排查原因: ${LOG_FILE}${NC}" fi } # 主菜单 main_menu() { check_env while true; do echo -e "\n${GREEN}========================================${NC}" echo -e "${GREEN} 达梦数据库 dexp/dimp 迁移工具箱${NC}" echo -e "${GREEN}========================================${NC}" echo "1. 导出模式 (Export Schema)" echo "2. 导入模式 (Import & REMAP_SCHEMA)" echo "0. 退出" echo -e "${GREEN}----------------------------------------${NC}" read -p "请选择操作 [0-2]: " CHOICE case ${CHOICE} in 1) do_export ;; 2) do_import ;; 0) echo -e "${BLUE}再见!${NC}"; exit 0 ;; *) echo -e "${RED}[ERROR] 无效的选择,请重新输入。${NC}" ;; esac done } # 执行主菜单 main_menu💡 脚本使用指南创建脚本文件:vi /data/dm_migrate.sh粘贴上述代码并保存。赋予执行权限:chmod +x /data/dm_migrate.sh运行脚本:./dm_migrate.sh脚本亮点隐藏密码输入:使用 read -s,密码不会在屏幕上显示,也不会留在命令历史中。自动处理特殊字符:脚本内部自动对 dexp/dimp 用单引号包裹连接串('USERID=...')、对 disql 用双引号包裹密码(user/"pass"@host:port),完美解决你之前遇到的 .. 密码解析 Bug。智能校验:在选择导入时,脚本会自动调用 disql 检查目标模式是否存在。如果不存在,会主动询问并帮你创建,避免了 dimp 因找不到目标 Schema 而报错的问题。自动命名:导出文件和日志自动加上 年月日_时分秒 时间戳,防止覆盖历史备份。
2026年08月13日
2 阅读
0 评论
0 点赞
2026-08-10
银河麒麟系统 OpenSSH 升级至 10.x 实战避坑指南
银河麒麟系统 OpenSSH 升级至 10.x 实战避坑指南⚠️ 核心警告(操作前必读)绝对不要关闭当前的 SSH 连接窗口! 必须保留一个已登录的旧会话作为“救生艇”,直到新终端测试连接成功为止,否则一旦配置错误将导致服务器失联。银河麒麟特性: 在重启 SSH 服务前必须执行 systemctl daemon-reload,否则会出现服务状态异常或配置不生效的提示。PAM 认证模块变更: 从 OpenSSH 10 以下版本升级,必须修改 PAM 加密模块配置(pam_stack.so 已被废弃),这是导致“密码正确却提示 Failed password”的通用致命错误。第一步:升级前准备与备份在操作前,务必备份当前的 SSH 配置文件,以便在出现问题时快速回滚。# 备份 sshd 配置文件 sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F) # 进入 RPM 包所在目录(假设放在 /root/openssh/) cd /root/openssh/第二步:执行 RPM 升级使用 rpm 命令直接进行升级安装:sudo rpm -Uvh openssh-*.rpm第三步:修复 Host Key 权限(必做)OpenSSH 10.x 对安全性要求极高,如果主机密钥(Host Key)权限过于宽松,sshd 将直接拒绝启动。执行以下命令修正权限和属主:# 1. 确保私钥权限为 600 chmod 600 /etc/ssh/ssh_host_rsa_key chmod 600 /etc/ssh/ssh_host_ecdsa_key chmod 600 /etc/ssh/ssh_host_ed25519_key # 2. 确保对应的公钥权限为 644 chmod 644 /etc/ssh/ssh_host_rsa_key.pub chmod 644 /etc/ssh/ssh_host_ecdsa_key.pub chmod 644 /etc/ssh/ssh_host_ed25519_key.pub # 3. 确保属主正确 chown root:root /etc/ssh/ssh_host_*_key /etc/ssh/ssh_host_*_key.pub第四步:清理废弃配置项 (sshd_config)OpenSSH 10 彻底移除了对 SSHv1 协议及相关古老加密算法的支持。旧配置文件中的某些选项会导致 sshd 报错。💡 避坑经验:报错提示的行号(如 155行、157行)并不固定。不要盲目按行号删除,一定要用 sshd -t 命令动态查看报错。# 测试配置文件是否有语法错误或废弃选项 sudo sshd -t常见报错及修复方法:报错 1: /etc/ssh/sshd_config line 157: Deprecated option RhostsRSAAuthenticationsudo sed -i '/^RhostsRSAAuthentication/d' /etc/ssh/sshd_config报错 2: /etc/ssh/sshd_config line 155: Deprecated option RSAAuthenticationsudo sed -i '/^RSAAuthentication/d' /etc/ssh/sshd_config修复后,再次执行 sudo sshd -t,如果没有任何输出,则说明配置文件已完全合法。第五步:重载配置与启动服务(麒麟系统关键步)在银河麒麟系统中,由于 systemd 单元文件或 init 脚本发生了变更,必须重载 daemon 配置。# 1. 重载 systemd 管理器配置(银河麒麟必做!) sudo systemctl daemon-reload # 2. 启动/重启 sshd 服务 sudo systemctl restart sshd.service # 3. 查看服务运行状态 sudo systemctl status sshd.service确认状态为 active (running) 且 22 端口正常监听。第六步:修复 PAM 认证模块(🔥 核心重点)这是从 10 以下版本升级必须修改的部分!旧版系统使用 pam_stack.so,而该模块在现代系统中已被移除。如果不修复,查看日志(journalctl -xeu sshd)会看到 PAM unable to dlopen(/usr/lib64/security/pam_stack.so),导致即使密码正确也无法登录。# 1. 备份旧的 PAM 配置 sudo cp /etc/pam.d/sshd /etc/pam.d/sshd.bak.$(date +%F) # 2. 写入 OpenSSH 10 兼容的标准 PAM 配置 sudo tee /etc/pam.d/sshd << 'EOF' #%PAM-1.0 auth required pam_sepermit.so auth substack password-auth auth include postlogin account required pam_nologin.so account include password-auth password include password-auth session required pam_selinux.so close session required pam_loginuid.so session optional pam_keyinit.so force revoke session include password-auth session include postlogin session required pam_selinux.so open env_params EOF第七步:最终验证1. 验证版本:ssh -V预期输出应包含 OpenSSH_10.x 字样。2. 验证连接(关键):新开一个终端窗口,尝试 SSH 登录服务器。如果能成功输入密码并进入系统 $\rightarrow$ 升级成功。如果提示 Permission denied 或连接断开 $\rightarrow$ 立即回到保留的旧终端窗口,检查 /etc/pam.d/sshd 内容是否写入正确,或恢复备份文件。📝 总结与排错心得关于报错行号: sshd -t 报出的行号只是参考,核心是看它提示 Deprecated option 后面的参数名,用 sed 精准删除即可。关于通用错误: pam_stack.so 缺失是跨大版本升级的“通用错误”,只要是从低版本升到 10.x,这个 PAM 配置文件必须替换。关于 systemctl 警告: 如果启动时提示 Warning: The unit file... changed on disk,不要慌,这只是提醒你执行 systemctl daemon-reload,执行后重启服务即可消除。底线原则: 只要不关闭老的 SSH 会话,哪怕配置改错了、服务起不来,你依然有权限在旧窗口里把备份文件还原,从容救场。
2026年08月10日
3 阅读
0 评论
0 点赞
2026-07-29
N1盒子安装FnOS,服务优化记录--持续更新
可停用服务:插 4G 网卡无法上网。(插网线无影响) sudo systemctl disable ModemManager.service AI 计算管理服务 sudo systemctl disable ai_manager.service # 停止不必要的网络服务 sudo systemctl disable avahi.service sudo systemctl disable avahi-daemon.service # 停止文件监控(利于硬盘休眠) sudo systemctl disable trim_file_monitor.service #仅用于加入 Windows AD 域。家庭 NAS 不需要。 sudo systemctl disable --now winbind.service #Open vSwitch。除非你在 N1 上跑复杂的软路由(如 OpenWrt 旁路由模式)并需要 VLAN 隔离,否则纯 NAS 模式用不到。 sudo systemctl disable --now ovs-vswitchd.service sudo systemctl disable --now ovsdb-server.service #pNFS 块布局映射。这是企业级 NFS 集群用的,单机 NAS 用不到。 sudo systemctl disable --now nfs-blkmap.service #电源管理。N1 没有电池,且 USB 硬盘的休眠由飞牛自带的 trim_diskpowerd 控制,不依赖 upower。 sudo systemctl disable --now upower.service #关闭 Open vSwitch N1单网口NAS不需要OVS虚拟交换: sudo systemctl stop openvswitch-switch sudo systemctl disable openvswitch-switch停用会出现问题服务: WebDAV 服务:停止了,相册无法启动 sudo systemctl enable cloud_storage_dav.service考虑停用的服务:# 停止缩略图和媒体服务(最占 CPU) sudo systemctl status auto_thumbnailer.service sudo systemctl status mediasrv.service sudo systemctl status imagesrv.service
2026年07月29日
9 阅读
0 评论
0 点赞
2026-07-24
Ungoogled Chromium Binaries 离线部署实战指南
Ungoogled Chromium Binaries 离线部署实战指南—— 跨发行版、多架构服务器环境下的"绿色版"精准获取与使用1. 为什么选择 Ungoogled Chromium Binaries?在离线、多发行版(EulerOS / Kylin / Ubuntu)、多版本且混合架构(x86_64 + ARM64)的服务器环境中部署 Chrome,官方 .deb/.rpm 包因对 glibc、NSS、GTK 等系统库的严格版本锁定而完全不可用。Ungoogled Chromium Binaries 是 ungoogled-software/ungoogled-chromium 主仓库官方推荐的预编译二进制分发页面。它专门解决了以下核心痛点:零/低系统依赖:Portable(便携)版本静态链接了大部分运行时库,不绑定特定版本的 glibc,真正实现"解压即用"。双架构全覆盖:同时提供 x86_64 和 aarch64 (ARM64) 构建,完美适配信创鲲鹏/飞腾及传统 Intel/AMD 服务器。去 Google 化:移除了所有 Google 私有服务、追踪器和 API 依赖,符合内网及信创环境的安全合规要求。免 Root 权限:无需系统级安装,普通用户即可运行,避免污染宿主系统环境。⚠️ 安全声明该页面的二进制由社区贡献者构建,非可重现构建(non-reproducible)。若用于高安全合规环境,建议在隔离环境中自行从源码审计构建。对于一般内网服务器自动化、渲染、截图等场景,此方案是当前兼容性最优解。2. 读懂下载页:没有搜索框,如何找到"绿色版"?很多用户首次打开该页面时会困惑:没有搜索框,也没有"绿色版/安装版"的中文标签。这是因为该页面遵循开源社区惯例,按 平台 + 架构 + 构建类型 分类。你需要建立以下概念映射:页面表格中的名称实际含义对应 Windows 概念是否推荐离线多系统环境Portable Linux 64-bit解压后直接运行的 tar.xz 包,自带依赖库✅ 真·绿色版强烈推荐Linux AppImage 64-bit自包含的 .AppImage 单文件✅ 绿色版推荐(仅 x86_64)Portable Linux 64-bit (musl)针对 Alpine/Void 等轻量系统的静态构建✅ 超级绿色版老旧系统兜底Debian/Ubuntu (unportable).deb 包,需 dpkg 安装,强依赖系统库❌ 安装版绝对不要用Fedora/RHEL (unportable).rpm 包,需 rpm 安装,强依赖系统库❌ 安装版绝对不要用💡 核心原则只认准 Portable 和 AppImage 字样。凡是带有 unportable、.deb、.rpm 后缀的,一律跳过。快速定位技巧页面为静态生成,无搜索功能。请使用浏览器 Ctrl+F 搜索以下关键词:x86_64 绿色版 → 搜索 Portable Linux 64-bitARM64 绿色版 → 搜索 Portable Linux 64-bit ARM 或 aarch64自包含单文件 → 搜索 AppImage3. 下载与离线部署全流程第一步:联网机下载访问 Ungoogled Chromium Binaries在表格中找到目标架构对应的 Portable 行,点击版本号链接(如 150.0.7871.128-1),跳转至 GitHub Release 页面。下载对应文件:目标架构文件名示例x86_64ungoogled-chromium-150.0.7871.128-1-linux-portable.tar.xzARM64ungoogled-chromium-150.0.7871.128-1-linux-arm64-portable.tar.xz务必同时下载中文字体(离线服务器无 CJK 字体必然乱码):wget https://github.com/notofonts/noto-cjk/raw/main/Sans/SubsetOTF/SC/NotoSansSC-Regular.otf第二步:离线服务器部署将下载的文件通过 U 盘或内网传输至目标服务器后执行:# 1. 创建目录并解压(无需 root) mkdir -p /opt/chromium tar -xf ungoogled-chromium-*-portable.tar.xz -C /opt/chromium --strip-components=1 # 2. 放置字体 mkdir -p /opt/chromium/fonts cp NotoSansSC-Regular.otf /opt/chromium/fonts/ # 3. 赋予执行权限 chmod +x /opt/chromium/chrome # 4. 验证动态链接库完整性(应全部显示 found 或 static) ldd /opt/chromium/chrome第三步:运行测试/opt/chromium/chrome \ --headless=new \ --no-sandbox \ --disable-gpu \ --disable-dev-shm-usage \ --font-path=/opt/chromium/fonts \ --screenshot=/tmp/test.png \ https://example.com确认 /tmp/test.png 生成且中文渲染正常,即部署成功。4. 多架构统一启动脚本(生产环境推荐)在混合架构集群中,建议封装 wrapper 脚本自动适配,屏蔽底层差异:#!/bin/bash # /usr/local/bin/chrome-headless ARCH=$(uname -m) CHROME_DIR="/opt/chromium" FONT_DIR="${CHROME_DIR}/fonts" case "$ARCH" in x86_64) CHROME_BIN="${CHROME_DIR}/chrome-x86_64" ;; aarch64) CHROME_BIN="${CHROME_DIR}/chrome-aarch64" # ARM64 二进制缺失时回退到容器 if [ ! -f "$CHROME_BIN" ]; then exec docker run --rm \ -v "${FONT_DIR}:/usr/share/fonts/custom:ro" \ zenika/alpine-chrome \ --headless=new --no-sandbox --disable-gpu \ --disable-dev-shm-usage \ --font-path=/usr/share/fonts/custom \ "$@" fi ;; *) echo "Unsupported architecture: $ARCH" >&2 exit 1 ;; esac exec "$CHROME_BIN" \ --headless=new \ --no-sandbox \ --disable-gpu \ --disable-dev-shm-usage \ --font-path="$FONT_DIR" \ "$@"调用方式统一为:chrome-headless --screenshot=/tmp/output.png https://example.com5. 常见问题速查表问题现象根因解决方案GLIBC_2.xx not found宿主机 glibc 版本过低换用 musl Portable 构建,或使用容器方案中文显示方块/乱码缺少 CJK 字体添加 --font-path 指向 Noto Sans SC 或文泉驿字体Out of memory / 崩溃/dev/shm 空间不足必须加 --disable-dev-shm-usageRunning as root without --no-sandboxroot 用户运行加 --no-sandbox(容器内或 root 下必需)ARM64 无可用 Portable 构建社区未覆盖该架构使用 zenika/alpine-chrome ARM64 容器镜像替代ldd 显示大量 not foundPortable 版仍依赖少量系统库安装缺失基础库(如 libnss3),或换用完全静态构建6. 参考链接二进制下载页:https://ungoogled-software.github.io/ungoogled-chromium-binaries/主仓库(源码/补丁):https://github.com/ungoogled-software/ungoogled-chromium容器替代方案:https://hub.docker.com/r/zenika/alpine-chromeCJK 字体下载:https://github.com/notofonts/noto-cjk
2026年07月24日
8 阅读
0 评论
0 点赞
2026-07-17
Nginx平滑升级离线编译与零停机热替换完整手册
Nginx 1.30.4 离线编译与零停机热替换完整手册⚠️ 前置条件确认当前身份:root旧版 Nginx 前缀:/usr/local/nginx编译依赖:gcc、make、pcre-devel、zlib-devel、openssl-devel 等必须已在离线环境中提前安装。若未安装,需先通过 rpm/deb 包离线安装依赖,否则 ./configure 会失败。📥 第一阶段:获取源码与解压1. 下载 Nginx 1.30.4 源码包在有网络的机器上下载后,通过 U盘/SCP 等方式传入服务器 /home/zjgzwyjsadmin/ 目录:# 在联网机器执行示例 wget https://nginx.org/download/nginx-1.30.4.tar.gz2. 解压并进入源码目录cd /home/nginx-1.30.4 tar -zxvf nginx-1.30.4.tar.gz cd nginx-1.30.4路径约定后续所有命令均假设源码位于 /home/nginx-1.30.4。若您实际路径不同,请全局替换。🔧 第二阶段:编译构建(仅编译,不安装)1. 提取旧版编译参数OLD_ARGS= $ (nginx -V 2>&1 | grep "configure arguments:" | sed 's/configure arguments: //') echo "📋 旧版参数: $ OLD_ARGS"2. 配置编译选项# 使用旧版参数确保模块完全兼容 ./configure $ OLD_ARGS3. 编译生成新二进制# 利用多核加速编译,绝不执行 make install! make -j $ (nproc)4. 编译后双重验证(必做)# 验证1:参数一致性(注意 -- 分隔符防止 grep 误解析) ./objs/nginx -V 2>&1 | grep "configure arguments:" | grep -F -- " $ OLD_ARGS" \ && echo "✅ 编译参数一致" || { echo "❌ 参数不一致,停止!"; exit 1; } # 验证2:新二进制能正确解析现有配置 ./objs/nginx -t # 期望输出: syntax is ok / test is successful只有两个验证均通过,才能继续。 若失败,检查 $OLD_ARGS 完整性或重新 make clean && make。🔒 第三阶段:全量备份(不可跳过)BACKUP_TIME= $ (date +%Y%m%d_%H%M%S) NGINX_BIN= $ (which nginx) # 备份二进制 cp " $ NGINX_BIN" " $ {NGINX_BIN}.bak. $ {BACKUP_TIME}" # 备份配置目录 cp -a /usr/local/nginx/conf "/usr/local/nginx/conf.bak. $ {BACKUP_TIME}" echo "✅ 备份完成:" ls -lh " $ {NGINX_BIN}.bak. $ {BACKUP_TIME}" ls -ld "/usr/local/nginx/conf.bak. $ {BACKUP_TIME}"🔄 第四阶段:零停机热替换执行💡 原理:USR2 启动新 Master → 新 Worker 接管新请求 → WINCH 优雅关闭旧 Worker→ QUIT 退出旧 Master。全程无连接中断。# 确保在源码目录下 cd /home/zjgzwyjsadmin/nginx-1.30.4 NGINX_BIN= $ (which nginx) # 步骤1:覆盖二进制(旧进程在内存中运行,不受磁盘影响) cp ./objs/nginx " $ NGINX_BIN" # 步骤2:启动新 Master 进程 kill -USR2 $ (cat /usr/local/nginx/logs/nginx.pid) sleep 3 # 步骤3:确认双 Master 共存(必须看到两行 master) ps aux | grep "[n]ginx: master" # 步骤4:优雅关闭旧 Worker kill -WINCH $ (cat /usr/local/nginx/logs/nginx.pid.oldbin) # 步骤5:业务健康检查(关键决策点!) curl -sI http://localhost | head -3 tail -20 /usr/local/nginx/logs/error.log | grep -E "emerg|crit|alert" # ✅ 正常 → 继续步骤6 # ❌ 异常 → 立即执行下方【紧急回滚预案】 # 步骤6:彻底退出旧 Master kill -QUIT $ (cat /usr/local/nginx/logs/nginx.pid.oldbin) # 步骤7:最终版本确认 nginx -v # 期望输出: nginx version: nginx/1.30.4✅ 第五阶段:升级后验证矩阵检查项命令合格标准版本号nginx -vnginx/1.30.4进程唯一性`ps aux \grep "[n]ginx: master" \wc -l`输出 1配置语法nginx -ttest is successful错误日志tail -20 /usr/local/nginx/logs/error.log无新增 emerg/crit业务响应curl -sI http://localhostHTTP 2xx/3xx监听端口`ss -tlnp \grep nginx`所有预期端口 LISTEN🔙 紧急回滚预案(30秒内恢复)仅在第四阶段步骤5健康检查失败时执行:NGINX_BIN= $ (which nginx) # ⚠️ 将下方时间戳替换为第三阶段输出的实际 BACKUP_TIME BACKUP_TIME="YYYYMMDD_HHMMSS" # 1. 终止新进程组 kill -QUIT $ (cat /usr/local/nginx/logs/nginx.pid) 2>/dev/null # 2. 恢复旧二进制 cp " $ {NGINX_BIN}.bak. $ {BACKUP_TIME}" " $ NGINX_BIN" # 3. 重启旧版本 nginx -t && nginx # 4. 验证回滚成功 nginx -v && curl -sI http://localhost⚠️ Root 环境安全警告SELinux:若启用,覆盖二进制后必须执行 restorecon -v "$NGINX_BIN",否则新 Master 无法绑定端口。WINCH 耐心等待:WebSocket/大文件下载等长连接可能导致旧 Worker 持续数分钟。用 watch -n1 'ps aux | grep "[n]ginx: worker"' 监控,绝不要 kill -9。PID 路径:以上命令假设 PID 在 /usr/local/nginx/logs/nginx.pid。若不同,通过 nginx -V 2>&1 | grep -oP '(?<=--pid-path=)\S+' 获取实际路径并全局替换。操作窗口:尽管零停机,仍建议在业务低峰期执行。离线依赖:若 ./configure 报错缺少库,需在离线环境中提前准备好对应的 devel 包(如 pcre2-devel、zlib-devel、openssl-devel)并通过 rpm -ivh 或 dpkg -i 安装。
2026年07月17日
14 阅读
0 评论
0 点赞
2026-05-20
NGINX 零停机平滑升级全流程实操指南
一、 概述在生产环境下,升级 NGINX 二进制文件通常面临一个挑战:如何升级而不需要停止服务(零停机)?NGINX 通过一套精巧的信号量(Signals)机制实现了平滑升级。其核心原理是:启动一个新的主进程(Master Process)接管监听端口,让旧进程在处理完现有请求后优雅退出,从而实现无缝切换。二、 升级前置准备与环境摸底在升级之前,必须确保新版本的编译参数与当前运行的版本完全一致,否则会导致启动失败或功能缺失。1. 查询当前版本及编译参数# 查看当前版本号 nginx -v # 查看详细编译参数 (极其重要,升级时必须使用相同的参数) nginx -V记录项: 重点记录 configure arguments 之后的所有内容(如 --prefix=/usr/local/nginx)。2. 确认二进制文件路径与 PID# 确认 nginx 可执行文件路径 which nginx # 确认当前运行的主进程 PID ps aux | grep nginx 记录项: 记录 master process 的 PID。3. 配置文件语法检查在任何操作前,确保当前配置文件没有语法错误。nginx -t三、 新版本编译准备核心原则:只编译→→不安装。 严禁直接执行 make install,因为这会覆盖您生产环境的配置文件。1. 下载并解压wget http://nginx.org/download/nginx-x.x.x.tar.gz tar -zxvf nginx-x.x.x.tar.gz cd nginx-x.x.x2. 配置与编译使用第一阶段记录的编译参数进行配置:# 使用之前 nginx -V 记录的参数 ./configure --prefix=/usr/local/nginx [其他参数...] # 编译生成二进制文件 make编译完成后,新的二进制文件位于 objs/nginx。四、 执行平滑升级(核心步骤)步骤 1:二进制文件替换由于 Linux 内核禁止覆盖正在运行的二进制文件(会报 Text file busy),我们必须使用 mv 命令通过改变 inode 的方式进行替换。 # 1. 备份旧文件 cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak # 2. 使用 mv 替换新文件 (绕过 Text file busy) mv objs/nginx /usr/local/nginx/sbin/nginx # 3. (可选) 如果系统中有快捷路径 /usr/local/bin/nginx,请同步更新 cp /usr/local/nginx/sbin/nginx /usr/local/bin/nginx步骤 2:启动新主进程 (USR2)向旧主进程发送 USR2 信号,通知其启动新版本的二进制进程。 kill -USR2 <旧MasterPID> 状态: 此时,旧主进程和新主进程同时存在,它们共同监听端口,但新请求将开始分发给新进程。 步骤 3:优雅停止旧工作进程 (WINCH) 向旧主进程发送 WINCH 信号,通知旧的工作进程(Worker Processes)在处理完当前请求后立即退出。 code Bash kill -WINCH <旧MasterPID> 状态: 此时,所有新流量已全部由新版本进程处理。步骤 4:业务验证(关键环节) 在彻底删除旧版本前,必须进行全方位验证: 本地验证: curl -I http://127.0.0.1:端口 外部验证: telnet IP 端口 或 浏览器访问。 日志验证: tail -f /usr/local/nginx/logs/error.log 检查是否有 [emerg] 报错。 ### 步骤 5:彻底关闭旧主进程 (QUIT) 确认业务运行稳定后,关闭不再需要的旧主进程。 ```text kill -QUIT ``` 五、 异常处理与回滚方案 1. 怎么回滚? 如果在 步骤 3 之后发现新版本运行异常,可以通过以下指令将流量瞬间切回旧版本: code Bash # 向新主进程发送 WINCH 信号,让新 worker 退出 kill -WINCH # 此时流量会自动切回尚未关闭的旧 worker 进程 2. 常见坑点排查 ```text Text file busy: 不要用 cp 覆盖运行中的文件,必须用 mv。 版本显示不一致: 如果 nginx -v 显示旧版而 ps 显示新版,说明 /usr/local/bin/nginx 和 /usr/local/nginx/sbin/nginx 两者不一致,请同步覆盖。 Telnet 不通: 若 curl 内部通但外部不通,请检查防火墙(Firewalld/Security Group)策略,这通常与 NGINX 升级无关,而是网络层波动。 ``` 六、 总结流程图 备份→→编译→→mv替换→→USR2(启动新版)→→WINCH(切流量)→→验证→→QUIT(删旧版)
2026年05月20日
15 阅读
0 评论
0 点赞
2026-04-13
2026 最新实战:在单卡 48GB GPU 上部署 Qwen3.5-35B-A3B MoE 模型(vLLM + Open WebUI 完整指南)
一、为什么选择 Qwen3.5-35B-A3B?Qwen3.5-35B-A3B 是阿里通义千问团队于 2026 年初发布的 混合专家(MoE)模型,具备以下优势:小体积,大能力:总参数量 35B,但每次推理仅激活约 3B 参数,显存占用远低于同级别 Dense 模型。超长上下文:原生支持 262,144 tokens,轻松处理长文档、代码库。开源免费:采用 Apache 2.0 协议,可商用,权重已在 ModelScope 魔搭社区 公开。性能卓越:在多项基准测试中超越前代 Qwen3-235B-A22B,推理成本更低。对于拥有 单张 48GB GPU(如 A6000、RTX 6000 Ada)的用户,它是目前能本地部署的 最强 MoE 模型。二、环境配置(无需虚拟环境,全局安装即可)重要提示:经大量用户反馈,vLLM 与 Open WebUI 必须在同一 Python 环境中运行,否则会出现模块缺失或 API 不兼容问题。因此,直接使用全局环境是最简单可靠的方案。# 升级 pip(避免旧版 pip 的编译问题) pip install --upgrade pip #安装魔塔社区的包 pip install modelscope # 安装 vLLM(自动匹配 CUDA 版本) pip install vllm # 安装 FlashAttention(加速注意力计算) pip install flash-attn --no-build-isolation # 安装webui聊天界面 pip install open-webui三、单卡部署:Qwen3.5-35B-A3B 快速启动1. 下载模型(以 Qwen3.5-35B-A3B 为例)#模型下载 from modelscope import snapshot_download model_dir = snapshot_download('Qwen3.5-35B-A3B',cache_dir='./')四、单卡部署:启动 vLLM 服务vllm serve ./Qwen3.5-35B-A3B \ --dtype bfloat16 \ --port 5000 \ --max_model_len 262144 \ --gpu_memory_utilization 0.85参数详解(针对 MoE 模型优化):参数推荐值说明--dtypebfloat16MoE 模型必须用 bfloat16,auto 可能导致精度下降--port5000API 服务端口(可自定义)--max_model_len262144启用模型最大上下文长度(爆显存时可降至 131072)--gpu_memory_utilization0.8548GB 显存安全值(若爆显存,逐步降至 0.8 → 0.75)显存占用参考(48GB GPU):上下文 262K:~41GB上下文 131K:~38GB上下文 65K:~35GB五、集成 Open WebUI(图形化聊天界面)# 启用网络加速(AutoDL 用户必备) source /etc/network_turbo # 设置环境变量(关键!) export HF_ENDPOINT=https://hf-mirror.com # Hugging Face 镜像加速 export ENABLE_OLLAMA_API=False # 禁用 Ollama 兼容层 export OPENAI_API_BASE_URL=http://127.0.0.1:5000/v1 # 指向 vLLM API export DEFAULT_MODELS="Qwen3.5-35B-A3B" # 必须与模型文件夹名一致 # 启动 WebUI(默认端口 8080,此处改为 6006) open-webui serve --port 6006访问界面浏览器打开:👉 http://你的服务器IP:6006六、多卡部署(扩展参考)注意:Qwen3.5-35B-A3B 仅支持张量并行(Tensor Parallelism),不支持流水线并行。# 2 卡示例(如 2×A6000) vllm serve ./Qwen3.5-35B-A3B \ --dtype bfloat16 \ --port 5000 \ --tensor-parallel-size 2 \ --gpu_memory_utilization 0.8 \ --max_model_len 262144并行策略:--tensor-parallel-size N:必须等于 GPU 数量(如 2 卡设为 2)。不要设置 --pipeline-parallel-size:MoE 模型不兼容。七、OpenAI 格式 API 调用启动兼容 API 服务(等效于 vllm serve)python -m vllm.entrypoints.openai.api_server \ --served-model-name Qwen3.5-35B-A3B \ --model ./Qwen3.5-35B-A3B \ --dtype bfloat16 \ --port 5000 \ --max_model_len 262144 \ --gpu_memory_utilization 0.85Python 调用示例from openai import OpenAI client = OpenAI( base_url="http://localhost:5000/v1", api_key="not-needed" ) response = client.chat.completions.create( model="Qwen3.5-35B-A3B", messages=[{"role": "user", "content": "请用 262K 上下文分析以下代码库..."}], max_tokens=500 ) print(response.choices[0].message.content)
2026年04月13日
24 阅读
0 评论
0 点赞
2026-04-04
【N1安装飞牛之日志】斐讯N1日志内容不显示的问题
前言日志应用空白一片,无东西显示。修复方案使用root登录SSH,或者切换到rootapt update sudo apt-get -o Dpkg::Options::="--force-overwrite" install -y rsyslog这个命令的关键在于 -o Dpkg::Options::="--force-overwrite",它允许 rsyslog 覆盖 trim 包中已有的同名配置文件。会让您输入Y或者N 这个就看个人了。我是输入的都是N安装完成后启动应用systemctl start rsyslog systemctl status rsyslog可选覆盖掉配置在终端shell中,以root用户执行以下复制命令(请根据自己的上传路径修改命令)cp /vol1/1000/文件分享/rsyslog.conf /etc/ mkdir -p /etc/rsyslog.d cp /vol1/1000/文件分享/avahi-daemon.conf /etc/rsyslog.d/{cloud title="蓝奏网盘" type="lz" url="https://daimafengzi.lanzout.com/iCQlv3mf11be" password=""/}{cloud title="百度网盘" type="bd" url="https://pan.baidu.com/s/1JcvWscfj3jC6bk2MJfTuxg?pwd=yqjz" password="yqjz"/}
2026年04月04日
16 阅读
0 评论
0 点赞
1
2
...
27