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

怎么在一个 JVM 里启动多个 Spring Boot Application?

  •  
  •   siteshen · 2019-07-22 16:22:29 +08:00 · 5605 次点击
    这是一个创建于 1980 天前的主题,其中的信息可能已经有所发展或是发生改变。

    公司项目使用了微服务架构,会启动十多个的 Spring Boot Application,8G 内存的 MacBook Pro 内存有些紧张。当然有一些的办法,比如连接到开发服务器,设置启动参数降低内存,增加电脑内存等,但此处暂不考虑这些方案

    想到的一个办法是只启动一个 JVM (比如总共分配 4G 内存),同时启动多个 App。一番研究之后,看到这个东西:

    org.springframework.boot.SpringApplication(ResourceLoader, Class<T>).run(args)

    但默认应该会去读取 all_in_one/src/resources/application.properties 的内容,只有一个 App 时当然没问题,但希望能启动多个 App。复制配置太麻烦,而每个 App 配置文件都是相同的文件名(如下),没办法通过 classpath 区分。

    app1/src/resources/application.properties app2/src/resources/application.properties

    尝试过自己实现 ResourceLoader,但不知道怎么得到另外一个 jar 包里的 resources 目录。

    package all_in_one;
    
    import app1.ServiceAccountApplication;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.core.io.DefaultResourceLoader;
    import org.springframework.core.io.Resource;
    
    class AccountResourceLoader extends DefaultResourceLoader {
        @Override
        public Resource getResource(String location) {
            // 怎么让这块代码应用“看起来”是在 app1.Application.main 里启动,而不是默认是的在 all_in_one.Application.main 一样启动?
            Resource resource = super.getResource(location);
    
            System.out.println("location = " + location + " | " + resource.isReadable());
            return resource;
        }
    }
    
    @SpringBootApplication
    // @ComponentScan(basePackages = "cn.com.actwill.oa.service.account.*")
    public class FullApplication {
    
        public static void main(String[] args) {
            System.out.println("hello, world");
            SpringApplication application = new SpringApplication(new AccountResourceLoader(), ServiceAccountApplication.class);
            application.run(args);
            System.out.println("bye, world");
        }
    }
    

    如果解决了使用自定义 ResourceLoader 读取文件的问题,应该就能用多个线程启动不同的 App 了(可能有 Bean 冲突,可能会试着用自定义 BeanFactory 增加 namespace 的方式解决)。

    5 条回复    2019-07-23 11:04:26 +08:00
    gfuzan
        2
    gfuzan  
       2019-07-22 18:00:28 +08:00   ❤️ 1
    用类加载器是可行的.启动多个 Application 就是启动多个线程,这里有一个我做个热启动的程序,他现在只能启动一个 App,可以修改一下.
    github.com/GFuZan/HotStart
    arrow8899
        3
    arrow8899  
       2019-07-23 09:51:16 +08:00
    所以服务都启在本地吗,那如果有 40 个 50 个服务呢,还是搭建一套测试环境吧
    siteshen
        4
    siteshen  
    OP
       2019-07-23 10:42:24 +08:00
    @arrow8899 是的,都在本地启动。如果解决了这个问题,同时还能应用到自动化测试上面,不需要各种 mock 微服务。
    arrow8899
        5
    arrow8899  
       2019-07-23 11:04:26 +08:00
    @siteshen 微服务本来就是拆分和解耦的,感觉你是用微服务在做 SOA。😂
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1665 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 16:26 · PVG 00:26 · LAX 08:26 · JFK 11:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.