三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Solon的E-Spi与H-Spi机制:解决fatjar部署难题,该选哪个?

Solon的E-Spi与H-Spi机制:解决fatjar部署难题,该选哪个?

【Java服务部署难题与Solon机制】

将一个Java服务打成单个fatjar发布出去后,运维想更改数据源指向,业务团队想在不重启进程的情况下下线模块,若只能选择“重新打包、整包重发”,会产生诸多不便。而Solon为解决这些问题准备了两套机制:E-Spi(体外扩展)和H-Spi(热插拔)。不过,选错机制,代价要么是灵活性,要么是稳定性。下面将详细介绍它们的使用方法和适用场景。

【共同痛点:fatjar密封难题】

fatjar部署方便,但修改困难,配置文件和业务模块都被打包在其中。E-Spi和H-Spi都能解决这一问题,但契约不同。E-Spi可将配置文件和插件jar放在fatjar外面,启动时加载进同一运行时,简单且无需额外依赖,但变更需重启;H-Spi为每个插件提供独立的ClassLoader,可在服务持续运行时启停模块,能力更强,但责任也更大。

【E-Spi:配置与模块外置方案】

E-Spi直接针对fatjar部署场景。指定一个扩展目录,启动时Solon会扫描并加载其中内容,包括.properties/.yml文件作为扩展配置,.jar/.zip文件作为插件包。具体步骤如下:

第一步 ---- 声明扩展目录:可通过配置solon.extend指定扩展目录,若加上“!”前缀,Solon会自动创建该目录。

第二步 ---- 放置文件:将相关文件放在jar旁边,如demo.jar、demo_ext/_db.properties、demo_ext/demo_user.jar、demo_ext/demo_order.jar。这样,数据源配置在jar外,运维可直接修改配置文件,无需触碰fatjar。

第三步(可选) ---- 代码加载:若想在代码中加载额外内容,内核提供了接口。底层是AppClassLoader.addJar(URL | File),体现了E-Spi的特点:一切共享,拆合随意,更新需重启,无额外依赖。同时,插件jar打包有要求,官方示例为“demo2002-external_ext”。

【H-Spi:隔离与热替换利器】

H-Spi是更强大的工具,可将业务模块开发成自包含的插件包,服务运行时可实时加载和卸载。与E-Spi的本质区别是隔离,每个插件有自己的ClassLoader、AppContext和配置,更新插件无需重启主服务,但主应用需引入solon-hotplug依赖。

ClassLoader契约:隔离是关键,类的可见性规则重要。父ClassLoader的类和资源子级可见,但子级注册的东西需在父级stop事件中注销;兄弟ClassLoader之间无法使用彼此的类和资源,需通过事件总线沟通。

start与stop方法:可热插拔的插件实现Plugin接口,start方法注册模块所需资源,stop方法必须移除注册过的所有资源,否则会泄漏。模板渲染在ClassLoader上有坑,渲染器需钉在正确的ClassLoader上。跨模块通讯靠事件总线配弱类型载荷,官方示例包为“demo1011”,插件管理可借助solon-hotplug进一步优化。

【E-Spi与H-Spi对比】

从ClassLoader、AppContext、配置共享情况,更新后是否需重启,额外依赖,侧重点,资源移除方式,跨模块通讯方式,底层机制等维度对比,E-Spi和H-Spi各有特点。

维度E-SpiH-Spi
ClassLoader / AppContext / 配置共享隔离(完全)
更新后是否需重启否(热更新)
额外依赖无(内核内置)solon-hotplug
侧重点简单体外扩展 / 改配置隔离 + 热插拔 + 管理
资源移除无需特殊处理必须在“stop”里手动移除所有注册的资源
跨模块通讯直接共享事件总线 / 弱类型数据
底层机制AppClassLoader.addJar隔离ClassLoader + “Plugin.start/stop”

【如何选择E-Spi与H-Spi】

选择时可思考“这东西必须在不重启的情况下变更吗?”若不需要,有重启窗口即可,可选择E-Spi,它能满足多数“不想重打fatjar”的场景,无额外依赖和生命周期记账负担;若需要模块变更时服务一直在线,则选择H-Spi,可获得真正的隔离和实时替换,但需遵守stop清理纪律和跨模块契约。不少团队会同时使用两者,E-Spi管外置配置,H-Spi管需热替换的模块。对于长期演进的Solon服务结构设计,建议仔细阅读官方文档。那么,你的fatjar最需要先甩掉的是配置,还是整个模块?

← 返回列表