3

对于粘性会话,我需要设置嵌入式 tomcat 的 jvmRoute。

其实只有一个

System.setProperty("jvmRoute", "node1");

是必需的,但我想通过 application.properties 设置可配置属性。我不知道如何以及何时使用 @Value 注释属性设置它。

使用这里描述的@PostConstruct ,它不起作用(至少在 spring boot 2.0.0.RELEASE 中不起作用)

到目前为止我发现的唯一方法是

    @Component
public class TomcatInitializer implements ApplicationListener<ServletWebServerInitializedEvent> {

    @Value("${tomcat.jvmroute}")
    private String jvmRoute;

    @Override
    public void onApplicationEvent(final ServletWebServerInitializedEvent event) {
        final WebServer ws = event.getApplicationContext().getWebServer();
        if (ws instanceof TomcatWebServer) {
            final TomcatWebServer tws = (TomcatWebServer) ws;
            final Context context = (Context) tws.getTomcat().getHost().findChildren()[0];
            context.getManager().getSessionIdGenerator().setJvmRoute(jvmRoute);
        }
    }
}

它有效,但看起来并不优雅......

任何建议都非常感谢。

4

2 回答 2

2

Context您可以使用上下文定制器更优雅地定制 Tomcat 。它是一个函数式接口,因此您可以使用 lambda:

@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
    return (tomcat) -> tomcat.addContextCustomizers((context) -> {
        Manager manager = context.getManager();
        if (manager == null) {
            manager = new StandardManager();
            context.setManager(manager);
        }
        manager.getSessionIdGenerator().setJvmRoute(jvmRoute);
    });
}
于 2018-04-03T07:53:58.677 回答
0

我正在使用 Spring Boot 2.0.4。上面的答案一直对我不起作用。我不得不以这种方式更新它:

@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainer() {
    return (tomcat) -> {

        tomcat.addContextCustomizers((context) -> {
            Manager manager = context.getManager();
            if (manager == null) {
                manager = new StandardManager();
                context.setManager(manager);
            }

            ((ManagerBase) context.getManager()).getEngine().setJvmRoute("tomcatJvmRoute");

        });
    };
}
于 2018-08-03T08:32:31.840 回答