• 请不要在回答技术问题时复制粘贴 AI 生成的内容
rizon
V2EX  ›  程序员

Spring 项目如何实现可以拆开部署也可以合并成一个 web 项目部署

  •  
  •   rizon ·
    othorizon · Apr 23, 2020 · 5113 views
    This topic created in 2219 days ago, the information mentioned may be changed or developed.

    我们有几个 spring 服务,期望实现的效果是:

    在某些客户方,我们把这几个服务作为一个 web 服务来部署。

    在某些客户方,我们把服务拆分成多个 web 服务来部署。

    有什么好的实现办法吗?

    Supplement 1  ·  Apr 23, 2020
    再有就是 怎么合并上下文了?
    分开部署时每个 web 项目有自己的上下文配置(context-path),合并起来后怎么处理呢
    27 replies    2020-04-27 10:42:19 +08:00
    rizon
        1
    rizon  
    OP
       Apr 23, 2020
    木有人吗? 果然是太奇葩了吗,,但是现实就是如此啊,生活总比小说敢演
    wky809982944
        2
    wky809982944  
       Apr 23, 2020
    如果是 SpringCloud,父 maven 打成一个 jar 和每个 maven 分别打 jar,或者再进一步,根据业务打成不同的 docker 镜像(随便说的,才大三)
    rizon
        3
    rizon  
    OP
       Apr 23, 2020
    @wky809982944 #2 你说的这种打 jar 的方式在考虑,但是具体操作起来 有点麻烦,没找到可行的方案
    0x666666
        4
    0x666666  
       Apr 23, 2020
    @rizon 上家公司就是用 Spring cloud, 每个服务一个 jar 包,然后通过 docker+k8s 部署
    rizon
        5
    rizon  
    OP
       Apr 23, 2020
    @0x666666 #4 这是分开部署没什么问题。现在的问题是,需要能把多个 jar 包合并成一个 web 服务来部署
    wky809982944
        6
    wky809982944  
       Apr 23, 2020
    @rizon 打 jar 应该不麻烦吧,mvn package clean 就行,一个 maven 模块对应一个微服务对应一个 jar 包,根据业务需要组装对应的 jar 包为 docker 镜像就行了,不同的客户对应不同的 Git 分支写不同的 jekins 脚本然后部署到 k8s 上
    wky809982944
        7
    wky809982944  
       Apr 23, 2020
    @rizon 一个 docker 镜像能对应多个 jar 包,没毛病啊
    gz911122
        8
    gz911122  
       Apr 23, 2020
    @rizon 一个 docker 里面塞多个 jar 包完事 ,反正从外面看上去是一个不就得了
    louis2003
        9
    louis2003  
       Apr 23, 2020
    多个部署好了 用 nginx 转发不就好了 都是多个部署 ,或者前面加一个 gateway 配置一下路径转发。
    louis2003
        10
    louis2003  
       Apr 23, 2020
    其他的方式肯定要修改蛮多的。
    wky809982944
        11
    wky809982944  
       Apr 23, 2020
    @gz911122 说实话不太符合 docker 的设计原则,docker 不能当虚拟机用,一个 docker 最好还是对应一个微服务,非要合在一起还是打成一个 jar 靠谱,当然用是能用
    rizon
        12
    rizon  
    OP
       Apr 23, 2020
    @wky809982944 #7
    @gz911122 #8
    @louis2003 #9

    那不行,需要实现的是合并成一个 jar 包。。作为一个 spring 服务来启动。
    odirus
        13
    odirus  
       Apr 23, 2020
    要不每个微服务打包成两种?一种是 jar 、一种是 war,需要合并的话就把多个 war 包丢到一个 Tomcat 里面
    yalin
        15
    yalin  
       Apr 23, 2020
    假装微服务?
    NoKey
        16
    NoKey  
       Apr 23, 2020
    个人感觉,看能不能从工程上下手,把整个工程改成多个子工程,然后在 maven 上进行配置,通过配置某个关键字进去,打包成整体或者打包成分开的,找个 maven 高手来问问看可行不
    gemini767
        17
    gemini767  
       Apr 23, 2020
    我的思路是重构 业务代码分模块 多模块部署就是每一个模块一个 main 打 jar
    单模块部署就是单独建一个 main 模块,把之前多模块全部依赖进来,合并一个 main 打 jar

    理论上这样改冻最小 只是剥离出入口函数和业务耦合部分
    hengyunabc
        18
    hengyunabc  
       Apr 23, 2020
    用 spring boot 是可以做到的,不过对代码的控制要求有点高。要灵活运用各种 `@Configuration` 来组织 service web 配置,可以参考 spring boot 官方的项目: https://github.com/spring-io/initializr,它的各种模块都是独立的。
    xyooyx
        19
    xyooyx  
       Apr 23, 2020
    把模块打进 jar 然后自定义一个类加载器按需求加载模块
    guyeu
        20
    guyeu  
       Apr 23, 2020
    我们也有这个需求,实现方式是一个 maven 模块,按包划分子模块,每个子模块有单独的 SpringBootApplication 主类,单独启可以单独启子模块的 SpringBootApplication 主类,合并启的话 springboot 原生支持的,SpringApplication.run 有一个重载可以传入多个主类。
    guyeu
        21
    guyeu  
       Apr 23, 2020
    当然同样的原理,分成 maven 子模块也可以。
    wangxiaoaer
        22
    wangxiaoaer  
       Apr 23, 2020
    app-1:jar
    app-2:jar
    app-3:jar

    app-1-release:war <--app-1.jar
    app-2-release:war <--app-2.jar
    app-3-release:war <--app-3.jar

    app-all-release:war <-- app-1.jar,app-2.jar,app-3.jar

    maven 的话一共 7 个 module,需要哪个打包哪个
    rizon
        23
    rizon  
    OP
       Apr 23, 2020
    @guyeu #20 怎么解决 web 的上下文问题?每个独立部署的时候 有自己的 context-path 合并之后 上下文怎么办?
    SaltedFish12138
        24
    SaltedFish12138  
       Apr 23, 2020
    我觉得,从大的方向上来说,你要在变化的客户需求之前,保证自己牢固的项目基础。如果可能,尽量以外部工具和设置满足客户差异化的部署需求。

    就楼主的实际情况来分析:
    1. 做成微服务,至于各模块要拆开为不同的项目,还是 subproject 或者 module 就随意了
    2. 用 docker 部署, 每个微服务不同的 dockerfile (实现多服务部署);再做一个 dockerfile,把所有微服务集成到一个 docker image 里(实现一个服务部署)(诚如楼主所言,不太符合 docker 设计原则,但客户需求千奇百怪,咱也得灵活运用工具不是)
    3. 多服务部署时,使用 docker compose 维护依赖和各容器间环境变量的关系。单服务的环境变量和上下文就很随意了,用 docker 设置还是 Spring 配置文件就看自己需求了
    guyeu
        25
    guyeu  
       Apr 23, 2020
    @rizon #23 一个应用可以有多个上下文的。
    rizon
        26
    rizon  
    OP
       Apr 27, 2020
    @guyeu #25 额 Spring 配置文件里的 contextpath 不就只有一个吗?
    guyeu
        27
    guyeu  
       Apr 27, 2020
    @rizon #26 一份配置文件对应一个 FileSystemXmlApplicationContext 或 ClassPathXmlApplicationContext,然而是可以有多个的,以 ApplicationContext 作为关键词搜一下吧。。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1137 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 409ms · UTC 18:13 · PVG 02:13 · LAX 11:13 · JFK 14:13
    ♥ Do have faith in what you're doing.