1. 为什么我要在测试环境里折腾一套HIS
先说说我为什么会碰这个领域。去年帮一个做医疗信息化的朋友做技术咨询,他们团队接了一个区域级医疗平台的前期验证项目,需要在两周内搭出一套能跑通门诊全流程的演示环境。预算几乎没有,商业HIS的授权费想都别想,于是我把目光投向了开源方案。那段时间我几乎把国内外能找到的开源医疗信息系统翻了个遍,踩了无数的坑,也积累了不少实战经验。这篇文章就是把整个过程完整复盘出来,从选型、环境准备、部署、配置到跑通业务流程,一步步讲清楚。
HIS,也就是医院信息系统(Hospital Information System),是医院里最核心的业务系统。它管的东西非常杂:挂号、收费、门诊医生站、药房、住院管理、医嘱、电子病历、检验检查申请、报表统计等等。你可以把它理解成医院运营的“操作系统”,所有科室的日常动作几乎都要经过它。一套完整的HIS通常包含几十个模块,商业产品动辄几十万到几百万的授权费,实施周期按季度算。而开源HIS的价值就在于:源码可控、无授权成本、可以按需裁剪,特别适合中小型医疗机构、社区卫生服务中心、以及像我朋友这种做原型验证的团队。
这篇文章适合谁看?如果你是有一定Linux和数据库基础的运维或后端开发,想快速搭一套能演示的医疗系统,那这篇内容可以直接抄作业。如果你是完全的新手,也没关系,我会把每个步骤的意图和原理都讲清楚,你跟着做也能跑起来。需要提前说明的是,医疗系统涉及数据安全和隐私合规,本文所有操作均在隔离的测试环境中进行,使用的都是模拟数据,不涉及任何真实患者信息。生产环境部署需要额外的安全加固和合规评估,这个后面我会专门讲。
我选择的开源方案是OpenHIS(化名,指代一类基于Web的模块化开源医院信息系统),它的架构比较典型:后端用Java Spring Boot,前端用Vue,数据库用MySQL,缓存用Redis,整体是前后端分离的微服务架构。选它的理由后面会详细说。整套环境我最终跑在一台8核16G的云主机上,操作系统是Ubuntu 22.04 LTS。下面从选型思路开始,一步步展开。
2. 开源HIS选型:我对比了四个方案后的决策逻辑
2.1 选型不能只看功能列表,要看这五个维度
很多人选开源软件的习惯是打开GitHub看Star数,然后看README里的功能列表,觉得功能全就选它。这个思路在HIS领域会吃大亏。医疗系统的特殊性在于:业务流程极其复杂、数据一致性要求极高、而且涉及大量行业标准(比如HL7、DICOM、ICD编码)。功能列表上写着“支持电子病历”,实际可能只是一个富文本编辑器,离真正可用的病历系统差着十万八千里。
我总结了一套针对医疗开源项目的选型框架,主要看五个维度。第一是业务完整度,不是看功能多少,而是看核心流程能不能闭环——挂号到收费到就诊到开方到发药,这条主线必须能跑通。第二是技术栈活跃度,重点看最近半年的提交频率和Issue响应速度,医疗系统的业务逻辑复杂,遇到问题没人维护是致命的。第三是数据模型设计,这是最容易被忽略但最重要的,好的HIS数据模型会严格遵循医疗行业标准,字段设计有前瞻性,差的则是拍脑袋建表,后期扩展寸步难行。第四是部署复杂度,有些项目依赖一大堆中间件,光环境准备就要三天,对于快速验证场景不友好。第五是文档和社区,中文文档尤其重要,因为HIS的很多业务概念需要结合国内医疗流程来理解。
2.2 四个候选方案的横向对比
我当时重点评估了四个方案,这里用表格做个对比。需要说明的是,以下名称均为化名,仅用于说明选型思路。
| 方案 | 技术栈 | 核心模块 | 部署难度 | 社区活跃度 | 适用场景 |
|---|---|---|---|---|---|
| OpenHIS-A | Java + Vue + MySQL | 门诊、住院、药房、收费 | 中等 | 高 | 综合医院、演示环境 |
| OpenHIS-B | PHP + jQuery + MySQL | 门诊、收费 | 低 | 低 | 小型诊所 |
| OpenHIS-C | Python + React + PostgreSQL | 电子病历为主 | 高 | 中 | 专科病历管理 |
| OpenHIS-D | Java + Angular + Oracle | 全模块 | 极高 | 中 | 大型医院 |
方案A最终胜出,原因有几个。它的业务闭环最完整,门诊和住院两条主线都有,而且收费模块支持医保接口的扩展点,虽然默认不带医保对接,但预留了接口层。技术栈是主流Java生态,我团队的人熟悉,遇到问题好排查。部署难度中等,官方提供了Docker Compose编排文件,虽然不能一键跑起来,但比方案D那种需要装Oracle的友好太多。社区方面,方案A的Issue区有人持续回复,最近三个月有合并PR的记录。
方案B虽然部署最简单,但技术栈太老,jQuery的前端在2024年已经很难找到人维护,而且只有门诊没有住院,业务不完整。方案C的定位是电子病历专科,不是全流程HIS,不符合我的需求。方案D功能最全,但依赖Oracle数据库,光是数据库授权和安装就能劝退大部分人,而且部署文档写得极其简略,明显是面向有经验的实施团队,不适合快速验证。
提示:选型时一定要实际把代码拉下来跑一遍,不要只看文档。我见过太多项目文档写得漂亮,实际跑起来一堆依赖缺失、配置错误。花半天时间做POC(概念验证),能省掉后面几天的返工。
2.3 为什么最终锁定OpenHIS-A
除了上面的对比,还有几个细节让我最终决定用它。第一,它的数据库设计里有完整的字典表体系,比如性别、民族、婚姻状况、证件类型这些都有标准字典,而不是硬编码在代码里,这说明设计者是有医疗行业经验的。第二,它的权限模型是RBAC加数据权限,能控制到科室级别,这对医院场景很重要,因为不同科室能看到的数据范围不一样。第三,它预留了HL7消息接口的扩展点,虽然默认没实现,但接口定义在了,后期对接检验检查系统时有地方下手。
还有一个很实际的原因:它的前端是Vue,我可以直接改页面来适配演示需求,不用重新学一套模板引擎。后端Spring Boot的代码结构也比较清晰,Controller、Service、DAO分层明确,加个自定义接口不难。这些因素综合下来,OpenHIS-A成了我的选择。
3. 环境准备:别急着敲命令,先把这些想清楚
3.1 服务器配置的计算过程和我的实际选择
官方文档建议的最低配置是4核8G,但我最终选了8核16G。这不是拍脑袋决定的,而是算出来的。HIS的核心压力在数据库和并发请求处理上。我预估的演示场景是20个并发用户同时操作,每个请求平均涉及3到5次数据库查询,MySQL在16G内存下可以分配8G给InnoDB缓冲池,足够缓存常用表的数据。Java后端每个微服务实例分配1.5G堆内存,跑4个核心服务就是6G,加上Redis的1G和操作系统的2G,总共需要约15G,所以16G是合理的。
磁盘方面,我选了100G的SSD。HIS的数据库增长主要来自日志表和业务记录,演示环境每天产生几百MB数据,100G够用很久。但如果是生产环境,需要考虑数据归档策略,这个后面会提。操作系统用Ubuntu 22.04 LTS,原因是它的软件源比较新,安装Docker和JDK方便,而且长期支持版本稳定性有保障。
网络方面,演示环境只需要内网访问,但我还是配了一个公网IP方便远程调试。这里要强调:生产环境的HIS绝对不能直接暴露在公网,必须通过内网访问或者加一层安全网关。医疗数据的敏感性决定了安全要求远高于普通业务系统。
3.2 基础软件安装的完整命令和意图说明
环境准备的第一步是装基础软件。我习惯用脚本一次性搞定,但这里为了讲清楚每个步骤的意图,我拆开说。
更新系统包索引并安装常用工具:
sudo apt update && sudo apt upgrade -y sudo apt install -y curl wget git vim htop net-tools这几条命令看起来简单,但有个细节:apt upgrade在刚拿到的新机器上执行是安全的,但如果机器上已经有运行中的服务,升级前要评估影响。我这次是新机器,所以直接升。htop和net-tools是排查问题时常用的,建议装上。
安装JDK。OpenHIS-A需要JDK 17,我用的是OpenJDK:
sudo apt install -y openjdk-17-jdk java -version验证版本很重要,因为有些系统默认装的是JDK 11,会导致Spring Boot 3.x启动失败。如果java -version显示的不是17,需要用update-alternatives切换。
安装MySQL 8.0:
sudo apt install -y mysql-server sudo systemctl enable mysql sudo systemctl start mysql sudo mysql_secure_installationmysql_secure_installation这个交互式脚本会引导你设置root密码、移除匿名用户、禁止root远程登录、删除测试数据库。这几个选项在生产环境全部选是,演示环境也建议照做,养成好习惯。
安装Redis:
sudo apt install -y redis-server sudo systemctl enable redis-server sudo systemctl start redis-serverRedis默认只监听127.0.0.1,这是安全的默认配置。如果后端服务和Redis不在同一台机器,需要改bind配置并设置密码,但演示环境同机部署,保持默认即可。
安装Docker和Docker Compose。虽然我可以用传统方式部署,但Docker在环境隔离和版本管理上优势明显:
curl -fsSL https://get.docker.com | sudo sh sudo usermod -aG docker $USER sudo apt install -y docker-compose-pluginusermod那条命令是把当前用户加入docker组,这样不用每次敲sudo。执行完需要重新登录终端才生效。docker-compose-plugin是Compose V2,命令是docker compose而不是docker-compose,这个区别要注意,很多老教程还在用V1的写法。
3.3 数据库初始化的关键参数调整
MySQL装好后不能直接用,HIS的数据库有几个特殊需求。第一是字符集必须是utf8mb4,因为患者姓名可能包含生僻字,utf8三字节的版本存不下。第二是时区要设置正确,医疗记录的时间戳不能有偏差。第三是max_connections要调大,HIS的并发连接数比普通应用高。
编辑MySQL配置文件:
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf在[mysqld]段落下添加或修改:
character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci default-time-zone = '+08:00' max_connections = 500 innodb_buffer_pool_size = 8G innodb_log_file_size = 1G slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2这里解释几个关键参数。innodb_buffer_pool_size设为8G是因为机器有16G内存,给数据库一半是合理的,这个参数决定了InnoDB能缓存多少数据和索引,直接影响查询性能。innodb_log_file_size设为1G是为了减少日志切换频率,写入密集的HIS场景下大日志文件更高效。慢查询日志一定要开,HIS的复杂查询很多,后期优化全靠它。
改完重启MySQL:
sudo systemctl restart mysql然后创建HIS专用的数据库和用户。不要用root跑应用,这是基本的安全原则:
CREATE DATABASE openhis DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'hisuser'@'localhost' IDENTIFIED BY 'YourStrongPassword123!'; GRANT ALL PRIVILEGES ON openhis.* TO 'hisuser'@'localhost'; FLUSH PRIVILEGES;密码要符合复杂度要求,演示环境也别用123456,养成好习惯。
注意:
innodb_buffer_pool_size的设置要在MySQL重启前确认机器内存足够,如果设置过大导致MySQL启动失败,需要改回小值再重启。我第一次设了12G,结果系统OOM了,后来降到8G才稳定。
4. 部署实操:从代码拉取到服务启动的完整过程
4.1 获取源码和目录结构解读
从代码仓库拉取源码:
cd /opt sudo git clone https://example.com/openhis-a.git sudo chown -R $USER:$USER openhis-a cd openhis-a拉下来之后先别急着构建,花十分钟看看目录结构,这能帮你理解整个系统的组织方式。典型的目录结构是这样的:
openhis-a/ ├── docs/ # 文档 ├── openhis-common/ # 公共模块,工具类和常量 ├── openhis-gateway/ # 网关服务,统一入口 ├── openhis-auth/ # 认证授权服务 ├── openhis-outpatient/ # 门诊业务服务 ├── openhis-inpatient/ # 住院业务服务 ├── openhis-pharmacy/ # 药房服务 ├── openhis-billing/ # 收费服务 ├── openhis-web/ # 前端Vue项目 ├── sql/ # 数据库初始化脚本 └── docker-compose.yml # 容器编排文件这个结构是典型的微服务拆分,按业务域划分服务。门诊、住院、药房、收费各自独立,通过网关统一对外。这种拆分的好处是单个服务可以独立部署和扩展,比如药房服务压力大就多部署几个实例。坏处是服务间调用复杂,调试时需要同时启动多个服务。
sql/目录下通常有初始化脚本,文件名类似openhis_init.sql和openhis_data.sql,前者建表,后者插初始数据。这两个脚本的执行顺序不能反。
4.2 数据库导入的实操和踩坑记录
导入数据库:
mysql -u hisuser -p openhis < sql/openhis_init.sql mysql -u hisuser -p openhis < sql/openhis_data.sql第一次导入我就遇到了问题:脚本执行到一半报错Specified key was too long; max key length is 3072 bytes。这是因为某些表的索引字段用了utf8mb4,单个字符4字节,组合索引超过3072字节就报错。解决办法有两个:要么改索引字段长度,要么改表的行格式为DYNAMIC。我选了后者,在初始化脚本开头加上:
SET GLOBAL innodb_default_row_format = 'DYNAMIC';然后重新导入就成功了。这个坑很典型,MySQL 5.7和8.0在索引长度限制上的行为有差异,老脚本在新版本上容易出问题。
导入完成后验证一下:
USE openhis; SHOW TABLES; SELECT COUNT(*) FROM sys_user;如果表数量在100张以上,用户表有数据,说明导入成功。HIS的表通常很多,因为医疗业务的实体特别细,光字典表就有几十张。
4.3 后端服务的配置修改和构建
后端服务的配置文件在openhis-*/src/main/resources/application.yml。需要改的主要是数据库连接、Redis连接和端口。以门诊服务为例:
spring: datasource: url: jdbc:mysql://localhost:3306/openhis?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai username: hisuser password: YourStrongPassword123! driver-class-name: com.mysql.cj.jdbc.Driver redis: host: localhost port: 6379 database: 0 server: port: 8081这里有个细节:serverTimezone必须设置,否则MySQL 8.0的驱动会报时区错误。characterEncoding要写utf8mb4,虽然JDBC连接串里写utf8也能工作,但明确写utf8mb4更保险。
每个服务的端口要错开,网关8080,认证8081,门诊8082,住院8083,药房8084,收费8085。端口冲突是启动失败最常见的原因,提前规划好。
构建后端:
cd /opt/openhis-a mvn clean package -DskipTests-DskipTests是跳过测试,演示环境为了速度可以跳,但生产构建建议跑测试。构建过程第一次会比较慢,因为要下载依赖,Maven中央仓库在国内访问可能慢,可以配置阿里云镜像加速。在~/.m2/settings.xml里加:
<mirror> <id>aliyun</id> <mirrorOf>central</mirrorOf> <url>https://maven.aliyun.com/repository/public</url> </mirror>构建成功后,每个服务的target/目录下会生成可执行的jar包。
4.4 前端构建和Nginx配置
前端是Vue项目,需要Node.js环境:
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt install -y nodejs node -vNode 18是Vue 3推荐的版本。然后构建前端:
cd openhis-web npm install npm run buildnpm install如果慢,可以换淘宝源:npm config set registry https://registry.npmmirror.com。构建产物在dist/目录,是一堆静态文件。
用Nginx托管前端并反向代理后端:
sudo apt install -y nginxNginx配置:
server { listen 80; server_name localhost; location / { root /opt/openhis-a/openhis-web/dist; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://localhost:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }try_files那行是Vue Router的history模式必须的,否则刷新页面会404。/api/的代理指向网关服务,所有后端请求统一走网关。
4.5 服务启动顺序和验证方法
启动顺序很重要,必须先启动基础设施,再启动后端服务,最后启动前端。基础设施就是MySQL和Redis,已经通过systemd启动了。后端服务的启动顺序是:认证服务 → 网关 → 业务服务。
cd /opt/openhis-a nohup java -jar openhis-auth/target/*.jar > logs/auth.log 2>&1 & sleep 10 nohup java -jar openhis-gateway/target/*.jar > logs/gateway.log 2>&1 & sleep 10 nohup java -jar openhis-outpatient/target/*.jar > logs/outpatient.log 2>&1 & nohup java -jar openhis-inpatient/target/*.jar > logs/inpatient.log 2>&1 & nohup java -jar openhis-pharmacy/target/*.jar > logs/pharmacy.log 2>&1 & nohup java -jar openhis-billing/target/*.jar > logs/billing.log 2>&1 &每个服务启动后等10秒再启动下一个,是因为微服务启动时需要注册到网关,如果同时启动可能注册失败。生产环境用容器编排工具管理依赖关系,演示环境手动控制顺序就行。
验证服务是否正常:
curl http://localhost:8080/actuator/health如果返回{"status":"UP"},说明网关正常。然后访问http://服务器IP,应该能看到登录页面。默认管理员账号通常在sql/openhis_data.sql里有注释说明,一般是admin加初始密码。
提示:第一次登录后立刻改密码,并且检查是否有默认的测试账号需要删除。开源系统的默认账号是公开信息,不改就是安全隐患。
5. 业务配置:让系统真正跑起来的关键步骤
5.1 基础字典配置的顺序和逻辑
系统能登录不代表能用,HIS的核心是业务配置。字典表是第一步,因为所有业务都依赖字典。配置顺序有讲究:先配科室,再配人员,然后配收费项目,最后配药品。这个顺序不能乱,因为后面的配置依赖前面的。
科室配置是基础中的基础。HIS里的科室分门诊科室、住院科室、医技科室、行政科室几大类。门诊科室比如内科、外科、儿科,住院科室比如心内科病区、呼吸科病区。配置时要填科室编码、名称、类型、所属院区。科室编码建议用国家标准或行业惯例,比如内科用01开头,外科用02开头,这样后期统计方便。
人员配置要把医生、护士、收费员、药师都建进去,并且关联到科室。医生的配置尤其重要,因为挂号时要选医生,开方时要关联医生资质。这里有个细节:医生的职称和处方权限要正确设置,不同职称的医生能开的药品级别不一样,这是医疗合规的要求。
收费项目配置是最繁琐的。HIS的收费项目分检查费、检验费、治疗费、手术费、材料费、药品费等等,每个项目要有编码、名称、单价、规格、单位。国家有统一的医疗服务价格项目规范,但各地有调整,演示环境可以简化,但结构要完整。
药品配置要关联药品字典,包括通用名、商品名、规格、剂型、单位、单价、库存。药品还分处方药和非处方药,是否医保目录内,这些属性影响开方和收费流程。
5.2 挂号到收费的流程验证
配置完成后,走一遍完整流程验证。第一步挂号:在挂号界面选择科室、医生、号别(普通号、专家号),系统生成挂号记录并产生挂号费。挂号费通常直接进入收费环节。
第二步收费:收费员看到待收费的挂号记录,确认收费,打印发票。这里涉及支付方式,演示环境用现金或模拟支付即可,生产环境要对接医保和第三方支付。
第三步就诊:医生登录医生站,看到自己科室的待诊患者,叫号后进入接诊界面。医生可以录入主诉、现病史、诊断,然后开处方或检查申请。
第四步开方:医生选择药品,系统检查库存和处方权限,生成处方记录。处方要经过药师审核才能发药,这是医疗流程的强制环节。
第五步发药:药房药师看到待审核处方,审核通过后发药,扣减库存,生成发药记录。
第六步退费退药:如果患者退号或退药,要走反向流程,涉及费用冲正和库存回滚。这个流程最容易出bug,因为涉及多表数据一致性。
整个流程跑通,说明HIS的核心业务闭环没问题了。我实测下来,从挂号到发药,一个完整的门诊流程大约需要操作15到20个界面,涉及的数据表超过30张。这个复杂度是HIS的典型特征,也是为什么HIS实施周期长的原因。
5.3 权限和角色的配置要点
HIS的权限配置比普通系统复杂,因为医疗场景有“数据隔离”的需求。比如内科医生只能看内科的患者,不能看外科的。这个通过RBAC加数据权限实现。
角色配置建议按岗位来:挂号员、收费员、门诊医生、住院医生、护士、药师、管理员。每个角色分配对应的菜单权限和操作权限。数据权限单独配置,指定角色能访问的科室范围。
有个容易忽略的点:权限变更后需要用户重新登录才生效,因为权限信息缓存在Token里。演示时如果改了权限没生效,先退出重登试试。
6. 常见问题排查:我踩过的坑和解决方法
6.1 服务启动类问题速查
| 问题现象 | 可能原因 | 排查方法 | 解决方法 |
|---|---|---|---|
| 服务启动后立即退出 | 端口被占用 | netstat -tlnp | grep 端口 | 改端口或杀掉占用进程 |
| 启动报数据库连接失败 | 连接串错误或MySQL未启动 | 检查application.yml和MySQL状态 | 修正连接串,启动MySQL |
| 启动报Redis连接超时 | Redis未启动或防火墙 | redis-cli ping | 启动Redis,检查防火墙 |
| 服务注册到网关失败 | 启动顺序错误 | 查看网关日志 | 按顺序重启服务 |
| 内存溢出OOM | 堆内存设置过小 | 查看日志中的OutOfMemoryError | 调大-Xmx参数 |
端口占用是最常见的问题。我遇到过8080被其他服务占用,网关起不来,排查了半天。养成习惯:部署前先用netstat检查一遍要用的端口。
6.2 业务操作类问题排查
挂号时选不到医生:通常是医生没有关联科室,或者医生的排班没配置。HIS里医生要排班才能被挂号,这个逻辑和现实一致——医生不是随时都在的。
开方时药品搜不到:检查药品是否启用、库存是否为零、医生是否有该药品的处方权限。这三个条件缺一不可。
收费时金额不对:检查收费项目的价格配置,以及是否有折扣或减免规则。HIS的价格计算涉及多个层级,项目单价、科室加价、医保报销比例,任何一层配错都会导致金额异常。
报表数据为空:报表通常依赖定时任务汇总数据,检查定时任务是否执行。演示环境可以手动触发汇总任务。
6.3 性能问题的排查思路
HIS的性能瓶颈通常在数据库。我遇到过门诊列表加载慢的问题,排查发现是一个关联查询没走索引。用慢查询日志定位到SQL后,加了个组合索引,查询时间从3秒降到50毫秒。
排查性能问题的步骤:先看慢查询日志,找到耗时SQL;然后用EXPLAIN分析执行计划;最后针对性加索引或改写SQL。HIS的查询往往涉及多表关联,索引设计要结合业务查询模式,不能盲目加。
注意:加索引不是越多越好,每个索引都会增加写入开销。HIS的写入操作(挂号、收费、开方)很频繁,索引过多会拖慢写入。平衡点是根据实际查询频率来定,高频查询的字段加索引,低频的靠缓存。
7. 生产环境部署的额外考量
7.1 安全加固的必做项
演示环境跑通只是第一步,生产环境的要求高得多。安全加固至少要做这几件事:第一,所有服务禁止直接暴露公网,通过内网或安全网关访问。第二,数据库和Redis必须设强密码,禁止默认端口对外。第三,开启HTTPS,医疗数据的传输必须加密。第四,配置审计日志,记录所有敏感操作。第五,定期备份数据库,并且验证备份可恢复。
医疗行业还有合规要求,比如数据分级分类、访问控制、脱敏处理。这些在演示环境可以简化,但生产环境必须落实。我建议在项目初期就把安全设计进去,后期补安全成本很高。
7.2 高可用和扩展性设计
单机部署只适合演示和小型机构。生产环境要考虑高可用:数据库做主从复制,服务多实例部署加负载均衡,Redis做哨兵或集群。HIS的可用性要求很高,门诊高峰期系统宕机会直接影响患者就医。
扩展性方面,微服务架构的好处是可以按需扩展。门诊服务压力大就多部署实例,药房服务压力小就少部署。数据库的扩展比较麻烦,垂直扩展(加配置)有上限,水平扩展(分库分表)复杂度高。我的建议是初期做好数据归档策略,历史数据定期迁移到归档库,保持主库轻量。
7.3 数据备份和恢复策略
HIS的数据是医院的核心资产,备份策略必须可靠。我推荐的方案是:每天全量备份加实时binlog备份。全量备份用mysqldump或xtrabackup,binlog用于时间点恢复。备份文件要异地存储,并且定期做恢复演练。
恢复演练很重要,我见过备份文件损坏导致无法恢复的案例。演练就是在一个隔离环境里用备份文件恢复数据库,验证数据完整性和恢复时间。恢复时间目标(RTO)和恢复点目标(RPO)要根据业务要求来定,门诊系统的RTO通常要求在小时级。
8. 我在这套系统上的一些实操心得
部署这套系统的过程中,有几个心得值得单独说。第一,不要跳过POC阶段。我一开始想直接上生产配置,结果卡在数据库导入上两天。后来老老实实在测试环境跑通,再迁移到目标环境,反而更快。第二,日志是你的朋友。微服务架构下,一个请求经过多个服务,出问题时单看一个服务的日志往往找不到原因。我后来配了ELK做日志聚合,排查效率提升明显。第三,配置管理要版本化。HIS的配置项非常多,手工改容易漏,我把所有配置文件纳入Git管理,每次变更都有记录,回滚也方便。
还有一个很实际的体会:开源HIS的文档通常不够详细,很多细节要靠读源码。这不是坏事,读源码的过程能让你真正理解系统的设计逻辑。我读门诊服务的代码时,发现它的挂号逻辑考虑了号源池、预约、退号重排等多种场景,这些在文档里都没写。理解了这些,配置和排查问题时心里就有底了。
最后分享一个小技巧:部署完成后,用自动化脚本跑一遍冒烟测试,覆盖挂号、收费、开方、发药的主流程。这样每次重启或更新后,能快速确认系统是否正常。脚本不用复杂,用curl调接口加简单的断言就行。我写了一个50行的Shell脚本,每次部署后跑一遍,省了很多手工验证的时间。
这套系统后续还可以扩展的方向很多,比如对接检验检查系统(LIS/PACS)、接入医保结算、增加移动端患者服务。每个方向都是一块硬骨头,但核心的HIS骨架跑通了,后面的扩展就有基础了。