ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Oracle ORDS 安装与 AutoREST:数据库表变 REST 接口

Oracle ORDS 安装与 AutoREST:数据库表变 REST 接口 1. ORDS 到底是什么为什么我不用自写接口层前年接了一个门店库存看板的外包活数据全在客户机房那台 Oracle 19c 上前端是两个人在写的 Vue 页面。客户明确说不想再维护一套 Java 后端能少一层就少一层。我当时的思路很简单既然 Oracle 自己带了一套能把表直接暴露成 HTTP 接口的东西那就别自己造轮子了。这套东西就是Oracle ORDSOracle REST Data Services一个纯 Java 写的中间件装在数据库服务器或者任意一台能连通数据库的机器上跑起来之后你在数据库里敲几条 PL/SQL表就变成了带分页、筛选、排序的 REST 接口前端拿到 URL 直接就能查。ORDS 解决的核心痛点是数据到接口之间的那一段胶水代码。传统做法是后端写 Controller、写 Service、写 DTO、写分页插件一张表至少几十行代码改个字段还要重新打包发版。ORDS 把这层变成了数据库里的一行配置ORDS.ENABLE_OBJECT(...)执行完接口就上线了字段改了接口自动跟着变。它适合三类人一是手上有 Oracle 但缺后端人力的团队二是做内部工具、报表、看板接口只读为主、并发不高的场景三是已经在用 APEX 的团队因为 ORDS 本来就是 APEX 的运行容器顺手就能把 REST 服务一起开了。1.1 从需求倒推为什么选 ORDS 而不是自己写接口我评估方案时列了三条硬指标交付周期、运维成本、查询能力。自己写 Spring Boot 那一套光环境搭建、分页封装、权限校验、部署流水线一周打底而且上线之后多了一个要盯的进程。用 ORDS从下载到第一个接口能访问熟练的话两小时内搞定中间不用写一行 Java。但 ORDS 不是万能的这里得说实话。它擅长的是以表为中心的 CRUD 和查询一旦业务逻辑复杂到需要跨十几张表做计算、需要调用外部服务、需要事务编排ORDS 就会很别扭。我的判断标准是如果这个接口用一句 SQL 能表达出来就用 ORDS如果需要一段业务代码就别硬塞。后来这个项目里简单查询全走 ORDS 的 AutoREST两张报表用 ORDS 的自定义 Handler 包了一段复杂 SQL剩下一个对接第三方支付回调的逻辑还是老老实实写了个小服务。混合用谁也不耽误谁。还有一个容易忽略的点ORDS 返回的是标准 JSON字段名默认就是列名的小写形式前端不用做任何映射转换。这一点比我见过的一些自研框架友好太多那些框架动不动就要在 DTO 上加注解改名字改一次要重新发版。1.2 三种运行形态独立模式、Tomcat、WebLogicORDS 有三种跑法这个必须提前定因为它决定了后面装什么、配什么。第一种是独立模式StandaloneORDS 的 war 包里内置了 Jettyjava -jar ords.war standalone一条命令就起来了不依赖任何外部容器。这是我最常用的方式尤其是在客户那种机房就一台机器、不想再装中间件的环境里独立模式省事到极致。缺点是它本身不做集群要扛高并发得在前面挂 Nginx 或者多实例加负载均衡。第二种是部署到 Tomcat把ords.war丢进webapps目录靠 Tomcat 管生命周期。适合已经有 Tomcat 运维体系的团队日志、监控、启停脚本都是现成的。但要注意 JDK 版本和 Servlet 规范版本得对得上我见过有人把新版 ORDS 丢进 Tomcat 7 里启动直接报类找不到。第三种是WebLogic企业级环境里常见配置最重但和 Oracle 自家的认证、集群能力结合得最好。我个人的选择顺序是单机小项目走独立模式中型项目走 Tomcat 或者独立模式加 Nginx只有客户强制要求才上 WebLogic。原因很实际——独立模式的配置文件就一个standalone.properties出问题的时候你一眼能看完WebLogic 出问题光日志目录就够你找半天。1.3 JDK 与数据库版本先对齐再动手这一段是踩过坑才写的。ORDS 对 JDK 版本有明确要求而且要求不算低。21.x 系列的 ORDS 大部分版本 JDK 8 和 JDK 11 都能跑22.x 之后官方基本要求 JDK 11 起步再往上的版本更推荐 JDK 17。我手上有一台老机器系统里留着的是很早以前的 JRE 7当时图省事直接拿它去启动新版 ORDS结果连解压后的类都加载不了报的是UnsupportedClassVersionError。后来换了 OpenJDK 11 才正常。所以装之前先执行java -version看清楚主版本号。如果机器上同时存在多个 JDK不要去改系统默认的JAVA_HOME那可能影响别的服务。正确做法是在启动脚本里直接写绝对路径比如/usr/lib/jvm/java-11-openjdk/bin/java -jar ords.war standalone这样互不干扰。数据库版本这边也要对一下。ORDS 支持的数据库版本有个下限新版 ORDS 一般要求 12.1 以上如果你手里是 11.2.0.4 的老库尽量配 21.x 这类稍早的 ORDS 版本。另外一个容易翻车的点是 Oracle 19c19c 默认是多租户架构一个 CDB 下面挂一个 PDB你连数据库时写的 service name 必须是 PDB 的那个不能写 CDB 的。我就是在这上面卡过一次ORDS 装完启动报连不上查了半天监听日志最后发现是连接串里写的 service name 指向了根容器。2. 装之前要盘清楚的环境与账号很多人装 ORDS 装到一半卡住八成不是 ORDS 本身的问题而是前置条件没清。我现在的习惯是动手之前先列一张清单把每一项都在命令行里验证一遍验证不过就不往下走。2.1 数据库侧service name、监听与 CDB/PDB第一步是确认数据库能连上这个动作听起来废话但真的有人跳过。在数据库服务器上用lsnrctl status看一眼监听状态重点看输出的Service xxx has 1 instance(s)那一行这里的xxx就是你后面要填进 ORDS 的 service name。如果监听里压根没有你要用的那个服务名说明数据库实例没注册上先解决这个再谈 ORDS。我遇到过的几类典型症状列一下方便对照现象大概率原因处理方向客户端报 ORA-12514监听里没有该 service name检查 PDB 是否 openlsnrctl status确认服务注册客户端报 ORA-28547连接方式与监听配置不匹配确认用的是 EZConnect 还是 tnsnames路径别混用本地 tnsping 通、远程不通防火墙或监听只绑了 127.0.0.1检查listener.ora的 HOST开放 1521 端口能连 CDB 连不上 PDBservice name 写错容器用 PDB 的 service name而不是 SID这里特别说一下 ORA-28547。它出现的场景很杂有的人本机用 Navicat 连得好好的换到服务器上跑 ORDS 就连不上最后发现是两边走的连接路径不一样——一个走 tnsnames 别名一个走 EZConnect 直连。ORDS 的安装向导里连接类型那一项选basic就是直接填主机端口服务名选tns就是走TNS_ADMIN目录下的配置文件。我的建议是除非你们公司有统一维护的 tnsnames否则一律用basic少一层配置少一层错。另外如果你的数据库是 19c 的 CDB/PDB 架构还要确认 PDB 处于 READ WRITE 状态SELECT name, open_mode FROM v$pdbs;如果显示MOUNTED先ALTER PLUGGABLE DATABASE xxx OPEN;。2.2 账号与权限DBA 装一次之后用 schema 自己开ORDS 的安装过程要做两件事一是创建 ORDS 自己的元数据 schema默认叫ORDS_METADATA和公共用户ORDS_PUBLIC_USER二是把配置写进数据库。这两件事都需要比较高的权限所以安装阶段我会直接用 DBA 账号装完之后日常就不再用了。注意ORDS_METADATA 是 ORDS 自己的地盘别往里面塞业务表也别手工改它的数据升级的时候会出问题。安装完成之后真正启用某个业务 schema 的 REST 服务时就不一定需要 DBA 了。执行的账号有两种选择一种是用该 schema 自己的用户登录去执行ORDS.ENABLE_SCHEMA另一种是用 DBA 带上p_schema参数指定目标。我一般选后者因为很多时候业务 schema 的密码不在我手上。这里有个细节ORDS.ENABLE_SCHEMA这个包在安装完 ORDS 之后是全局可见的不管你登录哪个 schema 都能调。但反过来如果安装步骤没走完或者安装过程中滚了回滚你会发现这个包压根不存在执行报ORA-06550之类的编译错误。所以永远先确认安装成功再去 enable。2.3 目录、端口与内存规划目录规划这一块我吃过亏。早期我图省事直接在/root下面解压运行后来机器重装配置文件全丢重新配了一遍。现在固定用一套目录结构/opt/ords/ # ORDS 主目录放 ords.war /opt/ords/conf/ # 配置目录configdir放参数和日志配置 /opt/ords/logs/ # 日志 /opt/ords/standalone/ # 独立模式运行时生成的目录解压的时候用unzip ords-xx.x.x.zip -d /opt/ords解压完里面会有一个ords.war和一堆文档。真正要用的是那个 war 包。端口方面ORDS 独立模式默认监听 8080。这个端口很容易和别的东西撞我一般先netstat -tlnp | grep 8080看一眼被占了就换个 8090 之类的。数据库那边的 1521 也要确认从 ORDS 所在机器能通可以用telnet 数据库IP 1521或者nc -vz 数据库IP 1521快速验证。内存上ORDS 本身不重给它 1G 到 2G 堆内存足够应付内部系统的量级。我会在启动参数里显式写-Xms512m -Xmx2048m避免默认值太小导致频繁 GC。这个数字不是拍脑袋来的ORDS 的 JDBC 连接池默认最大 10 个连接每个连接加上游标、结果集缓冲一个连接大概占几 MB10 个连接也就几十 MB剩下的堆空间主要给 JSON 序列化和响应缓冲用。2G 对绝大多数内部系统是够的除非你要一次返回几十万行——那种需求本来就不该用 REST 接口干。3. ORDS 安装实操从解压到第一次启动准备工作做完正式进入安装。ORDS 的安装方式有两种交互式的install命令和基于参数文件的静默安装。两种我都在不同场景下用过下面分别说。3.1 下载包与目录布局ORDS 的安装包是一个 zip下载完解压。不建议在生产机器上现下我一般是本地下好再用 scp 传上去避免服务器没有外网出口、卡在下载环节。传上去之后mkdir -p /opt/ords/conf cd /opt/ords unzip ords-23.2.0.185.1746.zip ls -l解压出来你会看到ords.war、examples、doc、params这些内容。params目录里放着参数文件的模板做静默安装的时候可以直接拿它改。3.2 交互式 install advanced 每一条问题怎么答第一次装我建议走交互式看着每一行提示理解 ORDS 到底要什么信息。命令是java -jar ords.war install advanced它会依次问你这些问题我按实际填法说明指定配置目录问你配置放哪里。填/opt/ords/conf。这个目录会存ords_params.properties、standalone.properties、logging.properties后面所有调整基本都在这里。数据库连接类型选项里有basic和tns。选basic。主机名、端口、服务名分别是数据库 IP、1521、第 2.1 节确认过的 service name。这三个填错是最常见的翻车点。是否使用 SSL 连接数据库内网一般不启用除非你们数据库配了 TCPS 且下发过钱包。数据库管理员账号与密码填 DBA。这一步 ORDS 会用它创建元数据 schema。默认表空间与临时表空间直接回车用默认的SYSDBA建议值即可除非你们有专门的表空间规范。是否安装示例 REST 模块选不安装。示例模块只是为了演示生产环境装了还得删。APEX 静态资源目录如果你用 APEX填 APEX images 的物理路径不用的话填一个空目录或者直接跳过。这一步跳过不影响 ORDS 本身提供 REST 服务很多人以为不填就装不了其实不是。密码设定会给ORDS_PUBLIC_USER之类的账号设密码设一个强密码并记下来。跑完之后ORDS 会往数据库里写元数据屏幕上会打印每一步的进度。看到最后提示成功说明安装这一关过了。提示整个安装过程如果中途中断数据库里可能残留一半的 ORDS_METADATA 对象。重新安装前先确认 schema 状态必要时先卸载干净再装别强行覆盖安装。3.3 参数文件静默安装第二次装、或者要在多台机器上批量装的时候交互式就太慢了。这时用参数文件db.connectionTypebasic db.hostname192.168.10.20 db.port1521 db.servicenameorclpdb1 db.sid db.usernamesystem db.passwordYourStrongPwd feature.sdwtrue写到/opt/ords/conf/ords_params.properties里然后java -jar ords.war install --parameter-file /opt/ords/conf/ords_params.properties参数文件的好处是它本身就是一份配置文档换机器的时候改几行就能复用比在对话框里回答二十个问题可靠得多。注意密码写明文的问题生产环境这个文件的权限要给到 600属主限制成运行 ORDS 的那个账号。3.4 启动 standalone 与 systemd 托管安装完成后第一次启动cd /opt/ords java -jar ords.war standalone --configdir /opt/ords/conf看到类似Starting Servlet Engine和后面的端口监听信息就说明起来了。默认访问地址是http://主机IP:8080/ords/浏览器打开如果能看到一个欢迎页或者 404 但响应头是 ORDS 发的说明服务正常。不过没人会天天开着终端敲这条命令一定要托管成系统服务。我用 systemd[Unit] DescriptionOracle REST Data Services Afternetwork.target [Service] Typesimple Useroracle EnvironmentJAVA_HOME/usr/lib/jvm/java-11-openjdk WorkingDirectory/opt/ords ExecStart/usr/lib/jvm/java-11-openjdk/bin/java -Xms512m -Xmx2048m -jar /opt/ords/ords.war standalone --configdir /opt/ords/conf Restarton-failure RestartSec10 StandardOutputappend:/opt/ords/logs/ords.out StandardErrorappend:/opt/ords/logs/ords.err [Install] WantedBymulti-user.target写成文件丢到/etc/systemd/system/ords.service然后systemctl daemon-reload systemctl enable --now ords。以后重启机器它自己就起来了日志也落在固定位置排查问题不用再翻终端历史。有个坑要提醒独立模式默认把standalone.properties生成在当前工作目录下的standalone子目录里如果你不显式指定--configdir而启动目录又变了ORDS 会以为自己是第一次运行重新问你一遍配置。这就是为什么我在 ExecStart 里坚持写死--configdir。4. 启用 REST 数据服务让表变成 URL服务跑起来了但这时候你访问http://主机:8080/ords/是看不到任何业务数据的因为还没有任何 schema 被启用。这一步是 ORDS 的核心操作也是最容易出认知偏差的地方——很多人以为装完 ORDS 就自动有接口了其实还得手动开。4.1 ENABLE_SCHEMA给 schema 开一张门牌启用 schema 的本质是给这个 schema 分配一段 URL 路径。写法BEGIN ORDS.ENABLE_SCHEMA( p_enabled TRUE, p_schema HR, p_url_mapping_type BASE_PATH, p_url_mapping_pattern hr, p_auto_rest_auth FALSE ); COMMIT; END; /逐参数解释一下这几个参数都有讲究p_enabled传 TRUE 是启用传 FALSE 是关闭。临时下线一个 schema 的接口时直接把这里改成 FALSE 重跑一遍就行不用碰 ORDS 进程。p_schema是数据库里的用户名大小写按实际对象名来一般是大写。p_url_mapping_type固定写BASE_PATH表示这个 schema 的接口挂在路径根下。p_url_mapping_pattern是 URL 里那一段比如填hr接口路径就是/ords/hr/...。这个值必须全局唯一两个 schema 抢同一个 pattern 会报错。我见过有人图省事全填 schema 名结果两个环境搬迁的时候撞了排查了半天。p_auto_rest_auth决定这个 schema 下自动生成的接口默认是否需要认证。开发阶段图快可以设 FALSE上线前务必改成 TRUE或者对具体对象单独设置权限。这一条是安全底线后面还会展开说。执行完之后如果一切正常访问http://主机:8080/ords/hr/会返回一个描述该 schema REST 服务清单的 JSON说明门牌挂好了。4.2 AutoREST 打开对象5 分钟出一个查询接口schema 启用之后还要告诉 ORDS 哪些表可以被访问。这就是 AutoRESTBEGIN ORDS.ENABLE_OBJECT( p_enabled TRUE, p_schema HR, p_object EMPLOYEES, p_object_type TABLE, p_object_alias employees, p_auto_rest_auth FALSE ); COMMIT; END; /跑完这条接口就活了http://主机:8080/ords/hr/employees/。p_object_type除了 TABLE还支持 VIEW 和PROCEDURE。视图这一项很实用——如果你的业务逻辑需要多表关联可以先把关联结果做成视图再用 ORDS 把视图暴露出去既复用了 SQL 又不用写 Handler。p_object_alias是 URL 里显示的名字不填默认取表名的小写。建议显式填一是好记二是表名里如果有下划线或者缩写别名可以让 URL 更干净。返回的数据结构长这样{ items: [ { employee_id: 100, last_name: King, salary: 24000 } ], hasMore: true, limit: 25, offset: 0, count: 25 }items是数据hasMore告诉前端还有没有下一页limit和offset是本次的分页参数count是本页条数。前端拿这个结构直接写分页组件就行不用额外约定。4.3 查询语法分页、筛选、排序、字段裁剪AutoREST 生成的不只是一个查询地址它内置了一套查询参数这几个参数用熟了能省掉大量自定义接口。常用的有四类分页?limit50offset100。默认每页 25 行。这里要注意ORDS 侧对单次请求返回的行数有一个上限保护你传一个特别大的 limit 也会被截断hasMore会告诉你还有数据。所以前端做无限滚动的时候一定要根据hasMore判断而不是根据count是否小于 limit。筛选?q{salary:{$gt:10000},last_name:{$like:S%}}。支持的比较操作符有$eq、$gt、$lt、$gte、$lte、$like、$in等等。多个条件之间是 AND 关系。排序?orderbyhire_date:desc,salary:asc。冒号后面是方向多个字段用逗号分隔。老一点的 ORDS 版本可能是空格分隔如果冒号写法不生效翻一下你们那个版本的文档。字段裁剪?fieldsemployee_id,last_name,salary。这个参数在移动端特别有用能显著减小响应体。我做过一个场景一张宽表 40 多个字段前端列表页只需要 6 个加上 fields 之后响应体从 200KB 降到 30KB 以内弱网环境下的体验差别非常明显。4.4 自定义 HandlerAutoREST 不够用时怎么办AutoREST 只能做单表或者单视图的 CURD。一旦遇到需要传参数做复杂计算、需要一次返回多段结果、需要写操作的业务逻辑就得上自定义模块。思路是把一段 PL/SQL 或者 SQL 包成一个 HTTP HandlerBEGIN ORDS.DEFINE_MODULE( p_module_name report.api, p_base_path /report/, p_items_per_page 0, p_status PUBLISHED ); ORDS.DEFINE_TEMPLATE( p_module_name report.api, p_pattern summary/:dept_id ); ORDS.DEFINE_HANDLER( p_module_name report.api, p_pattern summary/:dept_id, p_method GET, p_source_type json/query, p_source SELECT department_id, COUNT(*) total, SUM(salary) amount FROM employees WHERE department_id :dept_id GROUP BY department_id ); COMMIT; END; /这里的:dept_id是路径参数p_source_type选json/query表示把这个查询结果直接序列化成 JSON 返回。除了json/query还有plsql/block执行一段 PL/SQL、json/query的更新变体等等。plsql/block的口子最大你可以在里面写任意的 PL/SQL包括调用存储过程、写日志、做校验。我的经验是能用json/query就别用plsql/block。因为json/query本质还是一条 SQL执行计划清晰、性能可预测plsql/block里写多了逻辑这段代码就变成了没人管的数据库里的黑盒改起来比 Java 代码还痛苦。4.5 认证与跨域别让数据库裸奔在公网上前面演示用的都是p_auto_rest_auth FALSE那是为了先跑通。生产环境的顺序应该是反过来的先按TRUE配好认证再放行必要的接口。ORDS 支持的认证方式里最常用的是 OAuth2 的 client credentials 模式适合服务端到服务端的调用BEGIN OAUTH.CREATE_CLIENT( p_name portal_client, p_grant_type client_credentials, p_owner HR, p_description 内部看板调用, p_support_email opsexample.com, p_privilege_names ); OAUTH.GRANT_CLIENT_ROLE( p_client_name portal_client, p_role_name oracle.dbtools.role.autorest.HR.EMPLOYEES ); COMMIT; END; /拿到 client_id 和 client_secret 之后前端先换 token再用 token 调接口。不同大版本的 ORDS 里这组包名略有差异21c 之后部分场景用的是ORDS.CREATE_OAUTH_CLIENT动手前先DESC一下确认包存在。这一点我踩过照着一篇旧博客敲了半天报包不存在换了包名立刻就好。如果是浏览器直接调接口还要处理跨域。ORDS 的模块定义里有p_origins_allowed参数可以配 CORS 白名单但我不太喜欢在 ORDS 里配因为它的 CORS 支持相对简单。更省事的做法是在前面挂一层 Nginx统一加响应头location /ords/ { proxy_pass http://127.0.0.1:8080/ords/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; add_header Access-Control-Allow-Origin https://dashboard.example.com always; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS always; add_header Access-Control-Allow-Headers Authorization,Content-Type always; if ($request_method OPTIONS) { return 204; } }多一层 Nginx 还有个附带好处TLS 证书、限流、访问日志、IP 白名单都能在这一层做ORDS 本身就不用直接暴露在业务网里了。5. 出问题怎么办故障速查与排查思路ORDS 出问题的表现有时候很像但根因可能完全在不同的层。我总结了一套从下往上的排查顺序先看数据库能不能连再看 ORDS 进程在不在最后看 URL 和权限对不对。下面按阶段分开讲。5.1 启动阶段的报错报错关键字含义处理办法UnsupportedClassVersionErrorJDK 版本太低换 JDK 11 或 17启动脚本写绝对路径Address already in use端口被占netstat -tlnp找到占用进程换端口Configuration not found找不到配置启动时显式加--configdir参数Unable to obtain JDBC connection连不上数据库检查 service name、监听、防火墙ORA-01031 insufficient privileges安装账号权限不足用 DBA 账号重新执行安装这几条里Unable to obtain JDBC connection出现的频率最高但它的根因又最分散。我的排查顺序是先在 ORDS 机器上telnet 数据库IP 1521看端口通不通通了再用 SQL*Plus 从同一台机器用同样的连接串连一次确认账号密码和 service name 没错都对但 ORDS 还是连不上就去看ords_params.properties里到底写的是什么经常是手工改文件的时候把 service name 改错了却忘了重装。5.2 连不上数据库的几类典型症状有一类问题特别隐蔽ORDS 服务启动的时候一切正常日志也没报错但一访问接口就 500日志里才抛连接异常。这种情况说明 ORDS 启动时拿到了连接后面池子里的连接失效了。常见原因是数据库那边做过重启、或者网络中间有设备把空闲连接掐断了。处理办法是调整连接池参数在standalone.properties里加上jdbc.InitialLimit3 jdbc.MinLimit1 jdbc.MaxLimit15 jdbc.InactivityTimeout1800 jdbc.AbortOnConnectionExceptiontrue jdbc.ValidateConnectionOnBorrowtrueValidateConnectionOnBorrow这一项是关键它让 ORDS 在每次从池子里取连接时先探活失效的连接会被丢弃重建。代价是每次取连接多一次轻量往返对内部系统的并发量来说完全可以接受。MaxLimit从默认的 10 调到 15是因为我发现并发查询稍微一多请求就会排在池子外面等调大一点能明显改善。5.3 接口层 404/401/500 的区分方法HTTP 状态码其实是很好的线索只是很多人不去看。我的对照表状态码常见原因快速验证404schema 没启用、别名不对、路径大小写错访问/ords/根路径看 schema 是否出现在清单里401该对象要求认证但请求没带 token检查p_auto_rest_auth的取值或确认 token 是否过期403认证通过但没授权该对象确认 client 是否被授予了oracle.dbtools.role.autorest.SCHEMA.OBJECT角色400查询参数语法错误多半是q里的 JSON 写错了括号引号挨个对500服务器端异常翻 ORDS 日志看具体的 ORA- 错误码排查 404 的时候有个小技巧先访问/ords/ORDS 会返回当前实例下所有已启用的 schema 清单。如果目标 schema 不在清单里那问题一定在ENABLE_SCHEMA这一步跟表、跟权限都没关系。这样能一下子把范围缩小一半比盲猜快得多。至于 500日志是唯一可靠的信息源。ORDS 的日志在配置目录下的logs文件夹独立模式的运行时输出也会打到你重定向的ords.out里。看到 500 就去搜ORA-开头的行数据库抛出来的原始错误一般都在那。6. 上线前后的一些取舍与经验前面都是怎么做这一节讲讲我最后怎么选的这些判断没有标准答案但都是从实际项目里磨出来的。6.1 连接池和 JVM 参数怎么给连接池大小这个事我的经验公式是MaxLimit不要超过数据库允许的最大会话数除以 ORDS 实例数的三分之一。比如数据库processes参数是 300除了应用本身还要留给其他系统我一般给单个 ORDS 实例的MaxLimit在 15 到 25 之间。给太大没有意义因为查询本身很快瓶颈通常不在连接数上给太小就会出现请求排队表现为接口偶发变慢。JVM 堆内存方面-Xms和-Xmx我建议设成一样大。这样 JVM 启动时就申请到位避免运行期反复扩容带来的停顿。我一般用-Xms1g -Xmx2g除非监控到 GC 频繁否则不去动它。真要调优先加-XX:PrintGCDetails之类的参数收集一段时间的日志看数据说话别凭感觉改。6.2 安全上最低要做的几件事这份清单我每次上线前都会过一遍第一p_auto_rest_auth全部改成 TRUE只对确需公开的个别对象单独放开。改的时候注意已经启用的对象也要单独改一遍因为 schema 级别的开关只影响之后新启用的对象。第二ORDS 不要直接监听在 0.0.0.0 上暴露到公网。让它只听本机前面挂 Nginx 做 TLS 终结和访问控制。如果确实要跨机访问至少配一个 IP 白名单。第三数据库账号用最小权限。别用 SYS 或者 SYSTEM 去跑业务接口给一个只有 SELECT 权限的账号专门用于只读接口。写接口如果需要也单独开一个账号。第四把ords_params.properties的文件权限收紧。这个文件里有 DBA 密码的明文权限给 600属主是运行账号。这条看起来琐碎但审计的时候经常被挑出来。第五监控 ORDS 进程。最简单的方式是配一个健康检查 URL比如直接请求/ords/根路径返回 200 就算活着。我用 systemd 的Restarton-failure加上一个定时 curl 告警成本很低但能第一时间发现服务挂了。6.3 备份、升级和多环境同步ORDS 的配置其实分两部分一部分是磁盘上的文件ords_params.properties、standalone.properties、logging.properties另一部分在数据库里schema 启用信息、模块定义、权限。搬迁到一个新环境的时候磁盘文件直接拷过去数据库里的那部分就得重新执行一遍 PL/SQL 脚本。我的做法是把所有ENABLE_SCHEMA、ENABLE_OBJECT、DEFINE_MODULE的语句都写进一个ords-config.sql文件跟着项目代码一起进版本库。这样新环境部署的时候装完 ORDS 直接跑这个脚本配置就全部还原了。比手工敲一遍可靠也比导出数据库对象简单。升级 ORDS 的时候要留个心眼新版 ORDS 的安装过程会自动升级数据库里的ORDS_METADATA这个动作是有版本方向的升上去之后一般没法直接降回来。所以升级前一定要在测试环境先跑一遍验证所有接口正常再动生产。另外升级前把配置目录整个打包备份一份出问题能快速回退到旧版本加旧配置虽然数据库里的元数据降不回来但至少服务能先恢复。还有一点是我被坑过的多个环境开发、测试、生产如果共用同一个数据库实例的不同 schemaURL 前缀一定要区分开否则p_url_mapping_pattern很容易撞。现在我的命名习惯是项目_环境_业务域比如crm_dev_order虽然长了点但从来没出过冲突。这个习惯看着不起眼等你有五六个环境的时候就知道有多值了。
返回列表