拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

OpenMRS Standalone 2.3.1部署实战:从解压到MySQL切换与避坑

OpenMRS Standalone 2.3.1部署实战:从解压到MySQL切换与避坑 简介OpenMRS 2.3.1 独立版是一份面向医疗机构、医疗信息化开发者及运维人员的开源电子病历系统部署包。它旨在帮助用户在资源有限的环境中快速搭建可定制的病历管理平台涵盖患者登记、病史记录、诊断报告、处方与实验室结果管理等核心功能。压缩包内共15个文件以properties与xml配置文件、jar/war程序包、sh启动脚本及zip格式的演示/空数据库为主整体大小约394.68MB独立运行版免去了复杂服务器配置附带的README与启动脚本可引导完成基础配置webapps与Tomcat目录则提供了可直接运行的完整环境。空数据库与演示数据库便于初始化测试政策文件和配置模板可辅助理解系统默认策略模块化设计与多语言界面也有助于在不同规模和区域的机构中灵活部署。已有588人学习下载适合需要评估、部署或二次开发OpenMRS的团队参考。1. 拿到 openmrs-standalone-2.3.1 这个 zip别急着解压先搞清楚它能救什么急OpenMRS standalone 2.3.1 的 zip 包本质上是一个自带运行时、解压即用的开源企业电子病历系统适合需要离线演示、快速搭测试环境或在一台没有外网的内网机器上起病历系统的场景。很多团队第一次接触它是把 OpenMRS 当作一套“能直接跑起来的开源 HIS 前端”来评估——它确实做到了一个 zip 里同时打包了 Tomcat 中间件、H2 数据库和 OpenMRS 平台本体省去手工配 servlet 容器的过程。这篇笔记从解压开始讲到换 MySQL、做备份和排障读完你能把这个 zip 变成一台能长期服务的实例也能知道 2.3.1 的边界在哪、什么时候不该硬上。2. Standalone 发行版与源码包的根本差异为什么要用 zip 起 OpenMRS2.1 Standalone 不是简化版而是“被预先组装好的生产候选”OpenMRS 官方除了提供 war 包和源码仓库还会发布 standalone 发行版。常见做法是把 OpenMRS Core、参考应用模块和必要的依赖模块一起打进一个可执行 jar再配上一个 Tomcat 的内嵌版本。2.3.1 这个版本号对应的是 OpenMRS Platform 2.3.x 时期的 standalone 构建它和源码包的最大区别是源码包要你自己装 Maven、MySQL、Tomcat再编译模块standalone 则把这些步骤全部提前做完你拿到的是一个“黑匣子”——至少第一次启动前你不需要知道它的模块装配细节。这个设计目的很直接让医院信息科的同事、没有 Java 背景的实施人员也能把系统拉起来。zip 里那个 openmrs-standalone.jar 是入口它负责启动内嵌 Tomcat、初始化 H2 连接池、加载模块目录里的所有 omod 模块。如果你把它理解成“一个可以取代 Tomcat MySQL OpenMRS 部署目录三件套的组装体”后续调参就有方向了。2.2 压成 zip 的原因跨平台分发和离线安装2.3.1 时代的 standalone 构建没有用安装向导而是选择打 zip这有几个实际好处。第一zip 在 Windows 和 Linux 下都能解压不需要管理员权限解压到用户目录就能跑第二zip 天然适合离线分发医院内网环境经常不允许访问 Maven 中央仓库zip 包内已经带了核心模块不需要联网下载依赖第三zip 方便做版本管理——你想回退到 2.3.0解压另一个包、改一下数据目录就可以切换。要注意的是这个 zip 起到的只是“运输容器”作用它内部的 openmrs-standalone.jar 才是真正的程序。解压后你会看到 conf、modules、webapp 几个目录conf 里放 runtime.properties 等配置文件modules 里是 omod 模块包webapp 是解包后的前端静态资源。第一次启动后home 目录下会多出一个 openmrs 数据目录H2 的库文件和 runtime 日志都写在那里。2.3 2.3.1 能做什么、不能做什么评估边界OpenMRS 2.3.1 是 2.x 系列中相对成熟的一个小版本支持患者登记、临床就诊记录、处方、报表和用户权限管理参考应用界面也能正常使用。但 standalone 默认用的是 H2 数据库H2 适合单机、演示和测试不适合多科室并发写入而且 standalone 的模块加载方式和源码部署略有不同如果你要引入第三方 omod需要验证它和 2.3.1 的 API 兼容性。我对它的定位是评估期、开发环境和培训环境的最佳选择生产环境务必换成 MySQL见第 4 章。提示2.3.1 的 standalone 包对 Java 版本有硬性要求Java 8 是安全区间。不要看到是 2.x 就觉得 Java 11 也能跑遇到过几次因为默认 JDK 版本太高导致启动失败的案例具体原因放在第 5 章排查。3. 在 Windows 和 Linux 上跑通 OpenMRS Standalone最小可执行清单3.1 环境准备先过 Java 和端口两道关部署前最容易被忽略的是 Java 环境。OpenMRS 2.3.1 依赖 Java 8超过这个版本内嵌 Tomcat 的类加载器可能抛 NoClassDefFoundError 或 UnsupportedClassVersionError。我一般会在命令行先确认版本然后检查 8080 端口是否被占用java -version # 期望输出包含 1.8 或 8u例如 java version 1.8.0_202 # 检查端口占用Linux ss -tlnp | grep 8080 # 检查端口占用Windows PowerShell netstat -ano | findstr 8080这里只看两件事一是 java 命令是否指向 JDK 8二是 8080 是否空闲。如果你机器上装了多个 JDK建议显式设置 JAVA_HOME让它指向 JDK 8 的安装路径。standalone 的启动脚本会优先读取 JAVA_HOME其次才在 PATH 里找 java。端口如果被其他服务占用OpenMRS 的 Tomcat 会启动失败但日志可能只显示“Port busy”不会提示是谁占用。3.2 解压 zip 并启动Windows 双击与 Linux 命令行拿到 openmrs-standalone-2.3.1 zip 后先解压到不含中文和空格路径的目录避免 Tomcat 的资源路径解析出问题。Windows 下常见的做法是解压到 D:\openmrs-standalone-2.3.1然后双击 openmrs-standalone.bat。Linux 下这样启动cd /opt/openmrs-standalone-2.3.1 chmod x openmrs-standalone.sh ./openmrs-standalone.sh脚本会启动内嵌 Tomcat打开浏览器访问http://localhost:8080/openmrs进入初始化向导。首次启动时间比较长main 方法里会创建 H2 数据库、加载所有模块并初始化核心数据这个过程在三到五分钟内都算正常不要中途关掉终端。完成之后浏览器会自动跳转到管理员创建页面输入用户名、密码、姓名系统才会真正进入可用状态。3.3 Windows 下后台静默启动避免关了终端就断双击 bat 启动的进程会绑定在终端窗口上窗口一关服务就停。Windows 上想让 OpenMRS 一直跑有几种做法。第一写一个简单的 vbs 脚本用隐藏窗口的方式调用 bat第二用 WinSW 这类工具把 standalone 包装成 Windows 服务第三种是我用得比较多的方式——直接把启动脚本塞进计划任务的“用户登录时”触发器再把程序设为开机自动登录。对于评估环境来说第三种最简单也方便手动停止。Linux 服务器上更推荐用 systemd 托管下面是我常用的服务单元配置注意替换实际路径和用户sudo tee /etc/systemd/system/openmrs.service /dev/null EOF [Unit] DescriptionOpenMRS Standalone 2.3.1 Afternetwork.target [Service] Typesimple Useropenmrs WorkingDirectory/opt/openmrs-standalone-2.3.1 ExecStart/usr/bin/java -jar /opt/openmrs-standalone-2.3.1/openmrs-standalone.jar Restarton-failure RestartSec10 [Install] WantedBymulti-user.target EOF sudo systemctl daemon-reload sudo systemctl enable --now openmrs这里的 Typesimple 适合 standalone jar 直接前台运行的场景。ExecStart 里没有写 -Xmx 之类的 JVM 参数是因为 standalone 的启动脚本里默认有内存设置如果你用 systemd 直启 jar内存参数要自己加建议写成-Xms512m -Xmx2g避免容器因为内存限制被杀掉。Restarton-failure 能在程序抛异常退出时自动拉起但如果是端口被占或者数据库文件损坏导致的退出无限重启只会刷日志排查时记得先journalctl -u openmrs -n 100看真实原因。3.4 初始化数据库和第一个管理员账号访问初始化向导后系统会让你选择安装方式常见选择是“安装参考应用”这是 OpenMRS 2.3.1 时期默认推荐的界面。接下来填写数据库配置如果只是本地评估保留 H2 的默认选项即可如果要接 MySQL这一步就要动手改参数具体见第 4 章。数据库初始化完成后创建超级管理员账号账号名建议用 admin 而不是 doctor 之类因为后续装模块、管理权限都需要管理员角色。整个初始化过程在 H2 模式下很快MySQL 模式下取决于网络和磁盘但一般不超过十分钟。完成后登录系统会进入 OpenMRS 的仪表盘到这里最小可执行集就算跑通了。接下来要做的不是急着录患者而是先确认日志里的关键信息数据目录在哪、运行模式是 H2 还是 MySQL、模块加载是否全部 success。4. 从演示到生产把 Standalone 的 H2 换成 MySQL并做好备份4.1 为什么必须换 MySQLH2 的边界与并发问题H2 是 OpenMRS standalone 内置的嵌入式数据库零配置、单文件存储对演示和开发极其友好。但它的并发写能力有限多科室同时录入患者、开处方时H2 的行锁竞争会导致界面卡顿而且 H2 的数据文件依赖文件锁进程异常退出后可能留下锁文件导致下次启动失败。生产级 OpenMRS 需要 MySQL 或 MariaDB 承载核心数据这也是官方文档明确建议的走向。换库不是把 zip 删了再装一遍standalone 通过 conf/runtime.properties 里的连接参数来决定连哪个库。把 H2 切换成 MySQL 的常见做法是先准备好一个 MySQL 实例和空库再修改 runtime.properties把连接 URL、用户名、密码指向 MySQL。注意这个切换不会自动迁移已有 H2 数据如果 H2 里已经有测试数据需要先用导出工具把数据倒出来再导入 MySQL。4.2 配置 MySQL 连接参数与建立数据库先在 MySQL 里建库和账号再给 OpenMRS 足够的权限。我习惯单独建一个账号不用 rootCREATE DATABASE openmrs CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER openmrslocalhost IDENTIFIED BY StrongPassword; GRANT ALL PRIVILEGES ON openmrs.* TO openmrslocalhost; FLUSH PRIVILEGES;字符集选 utf8mb4 是必要的OpenMRS 里会存多语言文本和患者姓名utf8mb4 能覆盖表情符号和生僻字避免写入报错。如果 MySQL 版本比较老没有 utf8mb4也可以用 utf8但 MySQL 8 环境下建议直接用 utf8mb4。接下来修改 runtime.properties文件位置在解压目录的 conf 文件夹里。没有这个文件的话第一次启动后会自动生成。关键行如下# OpenMRS runtime properties connection.urljdbc:mysql://localhost:3306/openmrs?useSSLfalsecharacterEncodingUTF-8 connection.usernameopenmrs connection.passwordStrongPassword connection.driver_classcom.mysql.jdbc.Driver改完保存重启 OpenMRS。standalone 检测到连接配置变了会认为是新部署重新执行数据库初始化脚本——所以这一步要在 H2 数据还没积累出重要内容时做。初始化完成后登录系统验证几个基础页面患者登记、搜索、仪表盘报表。如果页面能正常打开但录入患者保存不了重点看 MySQL 的字符集和 SQL 模式特别是 ONLY_FULL_GROUP_BY 可能导致一些统计查询失败。4.3 固化配置把 runtime.properties 纳入版本管理runtime.properties 是整个 standalone 实例最核心的配置文件里面不仅有数据库连接还有模块路径、数据目录、scheduler 是否启用等开关。多实例部署时我一般会把 conf 目录复制一份作为模板修改连接参数后分发给各台机器避免每台机器靠记忆手工改。注意以下几点一是数据目录和模块目录的路径使用绝对路径二是不要把密码写死到公开仓库三是 Windows 路径和 Linux 路径的写法不要混用。application_data_directory/var/lib/openmrs module.repository_folder/opt/openmrs-standalone-2.3.1/modulesapplication_data_directory 控制着 H2 数据文件或一些本地文件的落盘位置。如果你的机器有独立数据盘把这个目录挂过去后续备份就只需要打这一个目录的包非常省事。很多实施团队容易忽略这个字段导致数据散落在 home 目录下备份时漏掉。4.4 备份与恢复最便宜的安全网是定时压缩数据目录OpenMRS 生产实例的备份逃不开两件事数据库备份和数据目录备份。MySQL 备份用 mysqldump注意加上单事务参数避免锁表数据目录备份则直接打包 application_data_directory 指向的目录里面包含上传的图片、文档等附件。备份命令如下# 数据库备份 mysqldump -u openmrs -pStrongPassword --single-transaction --routines --triggers openmrs openmrs_$(date %Y%m%d).sql # 数据目录备份 tar -czf openmrs_data_$(date %Y%m%d).tar.gz /var/lib/openmrs恢复时先停服务再倒库登录 MySQL 执行 source 导入备份的 SQL然后解压数据目录到原位置最后启动 OpenMRS。这个流程里有几个容易翻车的点如果 source 导入时遇到外键顺序问题可以在备份时加上--no-create-db用默认库导入如果数据目录压缩时文件正在被写入会导致附件损坏备份前要保证服务停止或者文件处于一致状态。定时备份可以交给 cron 或计划任务保留七天轮换足够。4.5 用反向代理补上 HTTPS 和域名访问standalone 默认只监听 8080 的 HTTP生产环境不可能直接暴露。常见做法是前面挂 Nginx 做 TLS 终止把 /openmrs 路径反代到本地 8080。这个配置需要注意 cookie 的 Secure 属性否则 HTTPS 下登录会掉会话。我的最小配置长这样server { listen 443 ssl; server_name emr.example.com; ssl_certificate /etc/nginx/ssl/emr.crt; ssl_certificate_key /etc/nginx/ssl/emr.key; location /openmrs { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cookie_path /openmrs /openmrs; } }proxy_cookie_path 这一行很容易漏掉不写的话 OpenMRS 设置 JSESSIONID 时只认原始路径浏览器存了 cookie 也发不出来表现为“能打开登录页登录后立刻回到登录页”。这属于典型的部署层次问题不是 OpenMRS 本身 bug排查时第一时间看浏览器开发者工具里的 cookie 路径。5. 避坑指南OpenMRS Standalone 2.3.1 最常见的 5 个翻车点5.1 启动闪退日志只有一行报错Java 版本不匹配现象双击 bat 或执行 sh 后进程立刻退出终端里只剩一行UnsupportedClassVersionError或者干脆没有输出。原因系统默认 Java 版本高于 82.3.1 的内嵌 Tomcat 编译字节码版本是 JDK 8。解决显式设置 JAVA_HOME 指向 JDK 8再启动。export JAVA_HOME/usr/lib/jvm/java-8-openjdk-amd64 export PATH$JAVA_HOME/bin:$PATH ./openmrs-standalone.sh如果机器上确实没有 JDK 8装一个不会影响其他应用standalone 进程是独立 JVM不修改全局配置也行。这个坑是最常见的八成启动失败都源于此。线上排查顺序我建议是先 java -version再看日志最后才怀疑代码包本身。5.2 端口被占用导致 Tomcat 启动中止把监听地址改成 127.0.0.1现象日志显示Port 8080 already in use服务起不来。原因本机已有应用占用 8080或者 OpenMRS 被系统当作单实例重复启动了。解决要么停掉占用的进程要么改 OpenMRS 的端口。修改方式是在 runtime.properties 里增加一行server.port8081重启即可。注意如果改用 8081访问路径变成http://localhost:8081/openmrsNginx 反代配置也要跟着改。5.3 解压 zip 时文件损坏或路径过长先用压缩软件测试完整性现象解压 openmrs-standalone-2.3.1.zip 时提示 CRC 校验错误或者解压到一半报文件路径太长。原因下载过程丢包导致 zip 损坏Windows 解压到深层次目录时路径字段超过限制。解决先用 7-Zip 打开看看能否正常列出内容再解压路径重命名成一个短目录例如 D:\openmrs。看热词里提到 zip 伪加密和 zip 解压问题记住一个原则zip 不是可靠的长期存储介质下载完第一件事是做完整性校验哪怕是核对文件大小也好过解压到一半才报错。5.4 H2 残留锁文件导致重启失败删除 .lock.db 文件现象服务被 kill 后再次启动报Database may be already in use。原因H2 在数据目录里生成了带 lock 的文件进程异常退出没有释放。解决停掉所有 java 进程删除数据目录里的.lock.db文件再启动。这个方法只对 H2 有效MySQL 模式不会出现这问题。如果你已经把数据切到了 MySQL这段直接跳过。5.5 登录后立即登出反向代理的 cookie 与 HTTPS 设置现象在 HTTPS 地址下输入用户名密码浏览器转一圈又回到登录页没有任何报错。原因Nginx 反代没设置 proxy_cookie_path或者没有传 X-Forwarded-Proto 导致 OpenMRS 的会话 cookie 被视为不安全。解决按 4.5 的配置补上 proxy_cookie_path如果还不行检查浏览器 Application 面板里 cookie 的 Secure 标记是否被正确移除。这个问题在 standalone 直连时不会出现只在加了反代之后冒出来所以遇到时要第一时间怀疑是中间层而不是 OpenMRS 本体。提示遇到 5.5 类似的情况别急着重启服务先开浏览器开发者工具看请求和 cookie能省一半时间。6. 进阶用法用多实例配置与自动化健康检查提高部署交付效率部署 OpenMRS 到第二台机器时你会发现自己手动点初始化向导其实是在浪费时间。我现在的做法是把 runtime.properties 做成一式两份一份是 H2 演示模板一份是 MySQL 生产模板里面把 application_data_directory、模块路径、连接池大小都提前写好新环境只要改 IP 和密码就能拉起来。这是整个 standalone 工作流里最值得投入的一步能显著减少实施交付的重复劳动。验证部署是否健康有个很朴素的方法写一个脚本定时请求http://localhost:8080/openmrs/ms/emrapi/patient这个接口带管理员 Basic Auth检查 HTTP 200 和响应体长度。返回 200 且内容非空说明 Tomcat 和模块都活着如果返回 503说明基本上下文没起来再去看日志找模块加载失败点。下面是一个最小健康检查脚本#!/bin/bash AUTH$(echo -n admin:yourpassword | base64) STATUS$(curl -s -o /dev/null -w %{http_code} -H Authorization: Basic $AUTH \ http://localhost:8080/openmrs/ms/emrapi/patient) if [ $STATUS 200 ]; then echo OpenMRS healthy else echo OpenMRS down, status$STATUS fi这个 bash 脚本可以放进 cron每分钟跑一次配合告警可以达到最基本的可用性监控。如果你不想用管理员密码在脚本里做 Basic Auth也可以给监控单独开一个低权限账号只开放查看权限更安全。我的习惯是监控账号和日常账号分开防止脚本泄露密码后波及整个系统。最后一个技巧升级 standalone 版本前一定先把 conf 目录和 application_data_directory 整个备份下来。OpenMRS 的模块机制很灵活但灵活的另一面是有可能不向后兼容升级后旧模块和新平台版本冲突而加载失败。留着旧版本压缩包和数据备份就是给自己留一张后悔药回退时解压旧包、替换 conf、启动十分钟内恢复原状。这句话不是空话是我在 2.x 系列上真实花费过一晚上的教训。希望这些边界和细节能帮你在自己的 OpenMRS 部署上少走一段弯路。本文还有配套的精品资源点击获取
返回列表