单台机器运行多Quarkus实例及OSGI向Quarkus迁移问题咨询
迁移方案合理性说明
你规划的将OSGi bundle逐个迁移为独立Quarkus实例的方案是标准的微服务迁移路径,不存在认知偏差:
- Quarkus本身是面向单服务设计的应用开发框架,和Apache Karaf这种承载多应用组件的容器定位完全不同,本身就不提供「单实例承载多服务」的能力,所以每个微服务对应一个独立Quarkus实例、单独做配置是正确的实现方式。
- 如果觉得逐个配置太繁琐,可以通过Quarkus内置的统一配置中心扩展解决,比如对接Consul配置中心、云厂商托管的配置服务(AWS Parameter Store、GCP Secret Manager),公共配置统一维护,不需要每个实例单独写重复配置。
- 不要求必须和原有OSGi bundle 1:1对应,可以先将频繁更新、有独立扩缩容需求的bundle拆成独立服务,底层公共依赖类的bundle可以先抽为公共JAR包被多个服务依赖,减少迁移成本。
服务发现实现方案
Quarkus已经内置了全场景的服务发现支持,不需要额外做复杂开发:
- 如果后续部署到AWS、GCP的Kubernetes服务,直接用Kubernetes原生的Service DNS即可实现服务发现,引入
quarkus-kubernetes扩展后框架会自动生成服务部署、服务发现的相关配置,开箱即用。 - 如果是虚拟机部署场景,可以引入
quarkus-consul-config或者quarkus-eureka-client扩展,简单配置注册中心地址即可自动完成服务注册、发现的全流程。
跨服务直接调用类方法的实现方案
微服务架构下所有服务运行在独立进程中,默认无法直接跨进程调用对方内部类方法,你在OSGi中可以直接调用是因为所有bundle运行在同一个JVM进程中,两种架构的底层逻辑不同。如果确实有类似调用需求,有两种可选方案:
- 抽离公共SDK:将服务B的对外接口、公共类封装为独立的JAR包,同时提供本地实现封装和REST/gRPC客户端封装,服务A依赖该JAR包即可像调用本地方法一样调用服务B的能力。如果对性能要求极高,可以直接将服务B的实现打包进服务A,但是该方案会失去独立扩缩容、独立部署的优势,仅适合对延迟极其敏感的场景。
- 使用RPC框架替代REST:引入Quarkus官方支持的gRPC扩展,服务B定义好gRPC接口之后,服务A引入自动生成的客户端存根,调用语法和调用本地方法完全一致,同时跨进程调用的性能远高于REST,兼顾微服务的隔离性和调用便捷性。
迁移初期建议优先用gRPC做跨服务调用,不要为了沿用原有直接调用的习惯强行把多个服务的实现打包到同一个实例中,避免后期又要重新拆分。
内容的提问来源于stack exchange,提问作者Hans Blafoo
相关产品推荐
相关产品推荐

