V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
rizon
V2EX  ›  程序员

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

  •  
  •   rizon ·
    othorizon · 2020-04-23 16:00:33 +08:00 · 4067 次点击
    这是一个创建于 1435 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    有什么好的实现办法吗?

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

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

    理论上这样改冻最小 只是剥离出入口函数和业务耦合部分
    hengyunabc
        18
    hengyunabc  
       2020-04-23 17:46:38 +08:00
    用 spring boot 是可以做到的,不过对代码的控制要求有点高。要灵活运用各种 `@Configuration` 来组织 service web 配置,可以参考 spring boot 官方的项目: https://github.com/spring-io/initializr,它的各种模块都是独立的。
    lqw3030
        19
    lqw3030  
       2020-04-23 18:01:22 +08:00
    把模块打进 jar 然后自定义一个类加载器按需求加载模块
    guyeu
        20
    guyeu  
       2020-04-23 18:57:18 +08:00
    我们也有这个需求,实现方式是一个 maven 模块,按包划分子模块,每个子模块有单独的 SpringBootApplication 主类,单独启可以单独启子模块的 SpringBootApplication 主类,合并启的话 springboot 原生支持的,SpringApplication.run 有一个重载可以传入多个主类。
    guyeu
        21
    guyeu  
       2020-04-23 18:57:43 +08:00
    当然同样的原理,分成 maven 子模块也可以。
    wangxiaoaer
        22
    wangxiaoaer  
       2020-04-23 19:16:06 +08:00
    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
       2020-04-23 19:24:42 +08:00
    @guyeu #20 怎么解决 web 的上下文问题?每个独立部署的时候 有自己的 context-path 合并之后 上下文怎么办?
    SaltedFish12138
        24
    SaltedFish12138  
       2020-04-23 20:10:12 +08:00
    我觉得,从大的方向上来说,你要在变化的客户需求之前,保证自己牢固的项目基础。如果可能,尽量以外部工具和设置满足客户差异化的部署需求。

    就楼主的实际情况来分析:
    1. 做成微服务,至于各模块要拆开为不同的项目,还是 subproject 或者 module 就随意了
    2. 用 docker 部署, 每个微服务不同的 dockerfile (实现多服务部署);再做一个 dockerfile,把所有微服务集成到一个 docker image 里(实现一个服务部署)(诚如楼主所言,不太符合 docker 设计原则,但客户需求千奇百怪,咱也得灵活运用工具不是)
    3. 多服务部署时,使用 docker compose 维护依赖和各容器间环境变量的关系。单服务的环境变量和上下文就很随意了,用 docker 设置还是 Spring 配置文件就看自己需求了
    guyeu
        25
    guyeu  
       2020-04-23 20:41:39 +08:00
    @rizon #23 一个应用可以有多个上下文的。
    rizon
        26
    rizon  
    OP
       2020-04-27 10:34:49 +08:00
    @guyeu #25 额 Spring 配置文件里的 contextpath 不就只有一个吗?
    guyeu
        27
    guyeu  
       2020-04-27 10:42:19 +08:00
    @rizon #26 一份配置文件对应一个 FileSystemXmlApplicationContext 或 ClassPathXmlApplicationContext,然而是可以有多个的,以 ApplicationContext 作为关键词搜一下吧。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5912 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 02:37 · PVG 10:37 · LAX 19:37 · JFK 22:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.