当前位置: 首页 > news >正文

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最需要先甩掉的是配置,还是整个模块?

http://www.jsqmd.com/news/1342317/

相关文章:

  • LFM2.5-2.6B工具调用完全指南:从函数定义到多轮对话实现
  • SAP OData技术解析与应用实践
  • 在线面试准备指南:设备调试与环境布置全解析
  • Punctuator2未来展望:从学术研究到工业应用的路线图
  • COLMAP-Free 3DGS震撼登场:告别传统三维重建繁琐流程,零基础也能轻松上手!
  • react-native-youtube-iframe Props全解析:定制你的视频播放器
  • Windows命令行高效运维:核心技巧与实战脚本
  • AI 渗透的组织变革:怎么设计一个 AI 时代的红队 / 蓝队 / 紫队?
  • OpenNews MCP安全配置指南:如何保护你的API Token和数据安全
  • anydoc开发指南:如何为这个高性能文档转换库贡献代码
  • 2026年跑了4家门店对比,说说南昌大空间火锅
  • GitHub用户画像分析利器:GitStalk高级搜索与数据可视化教程
  • 逻辑回归原理与Python实战:从基础到应用
  • CasADi与Matlab实现车辆轨迹跟踪MPC控制
  • 2026年最佳免费IP库:gh_mirrors/ipd/IP_database评测
  • 终极优化:License_Plate_Detection_Pytorch如何实现80ms/帧的实时处理能力
  • 从理论到实践:Software-Engineering-In-Arabic架构模式CQRS与分层架构
  • UE5动态摄像机进阶:Spring Arm防穿模与平滑优化实战
  • Chronos-2-Synth vs 传统模型:为什么合成数据训练的时间序列模型更强大?
  • Windows7命令行用户管理实战技巧
  • 如何用Pyechonest获取歌曲 tempo、energy 和 valence 特征?完整教程
  • ADR配置文件详解:定制企业级AI安全监控策略的终极指南
  • 2026年8月无锡GEO推荐公司评测报告:谁表现突出?|本土AI搜索优化服务商实力横向对比选型参考 - wxxwlm
  • Node.js开发者必看:anydoc绑定库快速上手指南
  • 翻了5份课程手册,终于搞懂新能源EMBA的真实差别
  • 从0到1掌握kanana-2-3b-instruct-8bit:超简单MLX量化模型使用教程
  • VirtualDesktop高级技巧:实现窗口自动分配与多桌面协同工作流
  • 从配置到调试:lsp-java + dap-mode实现Emacs全流程Java开发
  • 笔记二十一:Agentic RL 从入门到精通——训练能自己动手干活的 AI 智能体
  • OpenAI MCP 混用密钥泄露实录:边界超时让私钥暴露 12 分钟