用 Bash 脚本 + expdp 实现 Oracle 定时备份与异地传输
Oracle 数据库的备份要能兜底,光在数据库服务器上留一份还不够:本地盘挂了、机器没了,备份也就没了。这篇文章记录一套完整的做法——用 expdp 定时导出数据库,脚本负责压缩打包,再通过 OpenResty 搭的接收接口把备份传到另一台服务器上。 准备工作 数据库连接信息:能连上要备份的 Oracle 库,且账号有足够的权限执行备份。 备份目录:选一个空间足够的目录存备份文件。 压缩工具:备份完成后要压缩,确认装了 gzip 或 zip 之类工具。 创建 Oracle 目录对象expdp 的导出位置由 Oracle 的 DIRECTORY 对象决定,先在数据库里建一个指向备份目录的对象: 1CREATE DIRECTORY dumpdir AS '/path/to/backup/directory'; 目录路径要真实存在,且 Oracle 用户有写权限。 备份脚本新建 backup_script.sh,内容如下: 1234567891011121314151617181920212223242526272829303132333435363738394...
容器技术解析:原理、优势与虚拟机的区别
每个把应用从测试机搬到生产服务器的运维都遇到过同一件事:明明跑得好好的程序,换个环境就报错——缺库、版本不对、配置路径变了。容器就是冲着这个问题来的。这篇讲清容器是什么、解决什么矛盾、和虚拟机的区别在哪,以及什么场景不该用它。 容器是什么:把应用装进集装箱海运里,集装箱的功劳是把形状各异的货物标准化:不管里面装什么,箱子对外尺寸一致,码头吊机、货轮、卡车都能通用。容器对应用干的是同一件事。 容器是一种轻量级的软件打包技术:把应用程序连同它的全部依赖(代码、运行时、库、环境变量)打成一个标准单元,在任何环境里行为一致。 它比传统虚拟机轻的根本原因在运行时机制:容器直接使用主机操作系统的内核,自己不带内核;虚拟机则要带一整套操作系统。这个差异是后面所有对比的源头。 这不是概念推断,随手可验:分别用 Rocky Linux 9 和 Debian 12 两个镜像起容器,uname -r 打出的是同一个内核版本——镜像换了发行版,内核没换,因为它来自宿主机;再进容器找 /boot,里面连内核文件都没有。 内核之上,容器靠两组内核机制撑起”隔离”:namespace 让每个容器只看得到自己...
Nginx Round-Robin 负载均衡:默认策略的实测与边界
Nginx 做反向代理时,多个后端怎么分流量是最先要回答的问题。Round-Robin(轮询)是最基础的答案:请求按顺序逐个分给后端,分完一轮再从头来。它还是 Nginx 的默认策略——upstream 块里不写任何负载均衡指令时,用的就是轮询,简单到容易被当成”理所当然不看第二眼”的东西。但轮询在什么分布下才均匀、后端宕机时流量怎么走,值得实测一遍再说。 本文按配置实战组织:先交代实验环境,然后实测轮询序列、加权分布、宕机转移三个关键行为,最后给一组容易写错的配置对比。所有输出均为 nginx/1.31.5 实跑结果。 实验环境所有实例在单个容器里可复现:nginx/1.31.5(docker 镜像 nginx:alpine),用三个 server 块监听 8081/8082/8083 模拟三台后端(分别返回 backend1/2/3),80 端口反代 upstream;access_log 记录 $upstream_addr 观察每笔请求实际落在哪台后端。判断”流量分给了谁”,猜是没有用的——这个变量给出的是确定答案...
用 Nginx split_clients 模块做 A/B 测试与灰度发布
新首页设计到底比旧的好不好?新功能敢不敢直接全量上?A/B 测试和灰度发布都是同一个问题的不同问法:怎么把流量按比例、稳定地分成几组。Nginx 的 split_clients 模块(ngx_http_split_clients_module)在接入层就把这件事办了——对用户特征做哈希,按百分比切分流量,不需要应用代码参与。 本文按配置实战组织:先交代实验环境,再实测三件事——分组是否稳定、比例是否可信、调整比例会发生什么。所有输出均为 nginx/1.31.5 实跑结果。 使用场景 A/B 测试:两个版本的页面各分一半流量,比较转化率和用户反馈,看哪个版本更有效。 灰度发布:先给小比例用户放出新功能,观察没有问题再逐步放大,控制发布风险。 按用户特征路由:根据 IP、User-Agent 等特征把特定用户群路由到不同的后端或版本。 三个场景共享同一个前提:分组依据能从请求里直接拿到——IP、User-Agent、Header、Cookie 值都行,split_clients 只是负责”拿这个特征切比例”。需要按登录身份分组的,把用户 ID 放进 ...
Nginx map 模块实战:用变量映射替代 if 分支
写 Nginx 配置时经常遇到这种事:同一个变量在不同取值下要做不同处理,如果用一堆 if 去分支,配置会迅速变得难读——而且 Nginx 的 if 在 location 里声名狼藉(IfIsEvil),行为处处是坑。map 模块就是为这种场景准备的:根据一个变量的值映射出另一个变量的值,映射表集中写在 map 块里,逻辑一目了然。 这篇用 nginx/1.31.5 容器实测四组典型用法:静态查表、正则映射、灰度分流、hostnames 通配,全部配置都跑过验证。 实验环境 nginx/1.31.5(nginx:alpine 容器,容器内 curl 自测) 验证方法:map 的结果变量直接用 return 200 回显(重定向场景用回显代替真实 301,避免循环跳转干扰观察) 核心机制一句话map 定义在 http 层,把”源变量 → 结果变量”的映射做成一张表;结果是惰性求值的——不是每次请求都遍历全表,而是请求真正用到结果变量时才计算一次,内部用哈希组织,性能开销很小。 实例一:静态映射——按 URL 查表重定向原文场景:根据 $uri 计算重定向目标。...
用 Nginx secure_link 模块实现防盗链和临时链接
有些资源不能裸奔在公网上:付费下载的文件、限时分享的压缩包,都需要”拿着有效凭证才能访问”。Nginx 的 secure_link 模块(ngx_http_secure_link_module)用 URL 签名实现这一点——请求带上了正确签名和未过期的有效期参数才放行,否则直接拒掉。签名对不对、过期判定怎么走,光看文档容易想当然,本文全部实测。 按配置实战组织:先交代实验环境与签名生成,再验证放行、过期、无签名、篡改、换源五种请求的实际走向。所有输出均为 nginx/1.31.5 实跑结果。 实验环境 nginx/1.31.5(docker 镜像 nginx:alpine,nginx -V 确认自带 --with-http_secure_link_module); 受保护文件 /usr/share/nginx/html/private.zip(内容 SECRET); 签名由后端脚本生成——本实验用一段 Python 扮演(真实可跑): 1234567import hashlib, base64, timeexpires = int(time.time()) ...
Nginx Referer 防盗链实战:valid_referers 四种请求实测
别人家的页面直接 <img> 标签挂着你的图片,流量账单算在你头上——这就是盗链。HTTP 请求头里的 Referer 记录了请求是从哪个页面跳转来的,Nginx 的 Referer 模块(ngx_http_referer_module)利用这个字段判断请求来源,既能做防盗链,也能把来源信息记进日志做流量分析。 核心机制一句话:valid_referers 列出合法来源,不匹配的请求会让内置变量 $invalid_referer 变成非空,配合 if 拒绝即可。 本文在 nginx:alpine 容器里把带 Referer、不带 Referer、空头、盗链头四种请求各跑一遍,每种都有实拍结果,最后把一个流传很广的错误写法实跑给你看。 实验环境与机制前提 nginx:alpine 官方镜像,版本 nginx/1.31.5,referer 模块为内置标准模块,无需额外编译参数; 请求在容器内自发自收,用 curl 的 -H 手工构造 Referer 头。 先说清楚 Referer 的可信度:浏览器从页面 A 跳到页面 B 时,请求 B 资源通常会带上 Refe...
Nginx addition 模块:把子请求内容拼进主响应
页面里经常有广告位、页脚、推荐位这类由独立接口提供的小片段,如果让浏览器再发请求去取,请求数和后端压力都会跟着涨。Nginx 的 addition 模块给了另一种思路:在 Nginx 层把子请求的响应体插到主响应的前面或后面,客户端一次请求拿到完整内容。这篇在 nginx:1.28 容器里把它的配置、边界和一个流传很广的过时写法实跑一遍。 实验环境 Docker 容器 nginx:1.28-alpine(nginx/1.28.3,2026-09 实测)。 官方镜像编译时带了 addition 模块(nginx -V 可见 --with-http_addition_module),但注意:这是可选模块,不是所有发行版包都默认带上,部署前先确认。 准备三个文件:main.html(主文档)、banner.html(横幅)、footer.html(页脚)。 核心机制一句话addition 是个过滤模块:响应经过 Nginx 时,它按配置向子请求(add_before_body / add_after_body 指定的 URI)再发起一次内部请求,把子请求的响应体插...
用 Nginx sub_filter 在响应返回前替换内容
后端代码不方便改,但响应里的某个域名、某个敏感词必须换掉——这种活最适合交给 Nginx 的 sub 模块(ngx_http_sub_module):在响应返回给客户端之前,把内容里的指定字符串替换掉。反代场景下做域名迁移、链接改写、敏感词过滤,都不用碰后端一行代码。但”只换了第一处”、”JSON 不生效”、”开了压缩就失灵”这三个高频翻车点,都是配置默认值埋的,值得实测一遍看清楚。 本文按配置实战组织:先交代实验环境,再依次实测替换次数、内容类型、压缩三个默认行为。所有输出均为 nginx/1.31.5 实跑结果(官方镜像默认编译了 sub 模块,nginx -V 可查)。 能做什么 动态修改响应内容:替换响应中的特定字符串,比如敏感词、旧的资源地址,后端服务完全不用改。 链接改写:响应里出现的旧 URL 字符串(如 http://old.example.com)统一换成新地址,实现迁移期的平滑过渡。 注入公共片段:拿高频出现的标记当锚点,比如把 </body> 替换成 <script src="/stats.js"><...
Nginx Concat 模块:安装与合并静态资源
页面引用十几个 CSS/JS 文件,浏览器就得发十几个请求——Concat 模块让服务器端把多个文件合成一个响应返回,请求数和网络延迟都降下来。它是阿里 Tengine 系的第三方模块,官方 Nginx 不带,这篇按原文的安装思路在容器里实编译一遍,再把它真正的用法(?? URL 合并)、类型约束和超限保护逐个实测。 安装:第三方模块要走 –add-moduleConcat 不在官方发行版里,安装就是”取源码、编译进 Nginx”四步(以下在 Alpine 容器实测通过,模块仓库 alibaba/nginx-http-concat,Nginx 1.28.0): 1234git clone https://github.com/alibaba/nginx-http-concat.gitcd nginx-1.28.0./configure --add-module=/path/to/nginx-http-concatmake && make install 注:原文写的仓库地址 alibaba/ngx_http_concat_module 实测...