【问题标题】:How to make Javamelody use different port (Spring Boot+two HTTP ports exposed)如何让Javamelody使用不同的端口(Spring Boot+暴露的两个HTTP端口)
【发布时间】:2017-04-29 23:06:12
【问题描述】:

我有 Spring Boot Web 应用程序。它在端口 8080 上公开 REST API。它还使用 Spring Boot 管理端点 (http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-monitoring.html) 公开管理端口 8081。 我没有任何自定义 Tomcat 配置来实现这一点。我的application.properties 文件中只有属性management.port=8081

我已按照中所述配置了 JavaMelody https://github.com/javamelody/javamelody/wiki/UserGuideAdvanced#spring-boot-app (我有我的自定义JavaMelodyConfiguration 类,其中org.springframework.boot.web.servlet.FilterRegistrationBean 注册net.bull.javamelody.MonitoringFilter)。

@Bean
    public FilterRegistrationBean javaMelody() {
        final FilterRegistrationBean javaMelody = new FilterRegistrationBean();
        javaMelody.setFilter(new MonitoringFilter());
        javaMelody.setAsyncSupported(true);
        javaMelody.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC);
        javaMelody.addUrlPatterns("/*");
        return javaMelody;
    }

通过这种配置,Javamelody 暴露在 8080 端口(业务端口)上。我想把它移到 8081(管理端口)。怎么改?

我使用 Spring Boot 1.4.2.RELEASE,javamelody 1.62.0

【问题讨论】:

  • 在你的项目中搜索 8080,看看你是否找到将其更改为 8081 的地方。
  • 这不会解决我的问题。我仍然希望我的应用在 8080 端口上公开业务 REST api,在 8081 上公开管理 API,在 8081 上公开 javamelody。

标签: java spring-mvc spring-boot servlet-filters java-melody


【解决方案1】:

编辑:此答案仍然正确,但请参阅已接受的答案以获得更简单的解决方案。

EmbeddedTomcatConfiguration.java

package ...

import java.util.ArrayList;
import java.util.List;

import org.apache.catalina.connector.Connector;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class EmbeddedTomcatConfiguration {

    @Value("${server.additionalPorts}")
    private String additionalPorts;

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
        Connector[] additionalConnectors = this.additionalConnector();
        if (additionalConnectors != null && additionalConnectors.length > 0) {
            tomcat.addAdditionalTomcatConnectors(additionalConnectors);
        }
        return tomcat;
    }

    private Connector[] additionalConnector() {
        if (StringUtils.isBlank(this.additionalPorts)) {
            return null;
        }
        String[] ports = this.additionalPorts.split(",");
        List<Connector> result = new ArrayList<>();
        for (String port : ports) {
            Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
            connector.setScheme("http");
            connector.setPort(Integer.valueOf(port));
            result.add(connector);
        }
        return result.toArray(new Connector[] {});
    }
}

application.yml

server:
  port: ${appPort:8800}
  additionalPorts: 8880,8881

Application.java

@SpringBootApplication
@ComponentScan(...)
@Import(EmbeddedTomcatConfiguration.class)
public Application {

    public static void main(String[] args) {
        SpringApplication.run(Application .class, args);
    }
}

我对限制从特定端口访问 javamelody 的建议是扩展 javamelody 过滤器,如果请求来自特定端口,则只链接请求,否则返回 404。

来自日志:

INFO  TomcatEmbeddedServletContainer:185 - Tomcat started on port(s): 8800 (http) 8880 (http) 8881 (http)

顺便说一句,这种方法会在这些端口上公开其他端点。 为了解决这个问题并将 javamelody 过滤器(/monitoring)限制到特定端口,您需要编写一个过滤器来验证从允许端口请求的路径(servlet 和过滤器路径),记住这些过滤器的顺序很重要。

基于这个答案和我在回答这个问题时已经获得的部分源代码,我在http://tech.asimio.net/2016/12/15/Configuring-Tomcat-to-Listen-on-Multiple-ports-using-Spring-Boot.html发布了一篇关于这个主题的博客文章

【讨论】:

  • 谢谢!使用这样的配置,当我按照描述注册 javamelody 时(我已经编辑了我的问题以包含它),net.bull.javamelody.MonitoringFilter 是否会注册到两个端口?
  • Yw,假设您想使用管理端口和管理上下文路径访问 Javamelody UI,我会尝试将 Javamelody 过滤器映射到 /admin/monitoring
  • 我的意思是 server.servlet-path 设置为 /,management.context-path 设置为 /admin
【解决方案2】:

如果目标是从 java melody 版本 1.76 开始公开对管理端口的监控现在要简单得多。

您需要 Spring Boot 2.x、执行器以及 yml 或属性文件:

  • management.server.port:{您的自定义端口}
  • management.endpoints.web.exposure.include:{你通常想要什么},监控
  • javamelody.management-endpoint-monitoring-enabled: true

在此处查看更多详细信息: https://github.com/javamelody/javamelody/wiki/SpringBootStarter#configuration-in-case-of-management-port

【讨论】:

    【解决方案3】:

    您可以通过 MvcEndpoint 使用 ReportServlet。像这样的:

        import net.bull.javamelody.MonitoringFilter;
        import net.bull.javamelody.ReportServlet;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.boot.actuate.endpoint.Endpoint;
        import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
        import org.springframework.boot.web.servlet.FilterRegistrationBean;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.web.bind.annotation.GetMapping;
    
        import javax.servlet.ServletConfig;
        import javax.servlet.ServletException;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import java.io.IOException;
    
        /**
         * We configure the Java Melody {@link MonitoringFilter} normally, but disables all access to the UI. Instead,
         * we create a {@link ReportServlet}, and expose it through a {@link MvcEndpoint} in {@link #javaMelodyReportEndpoint()}.
         */
        @Configuration
        public class JavaMelodyConfiguration {
    
            private final ServletConfig servletConfig;
    
            @Autowired
            public JavaMelodyConfiguration(ServletConfig servletConfig) {
                this.servletConfig = servletConfig;
            }
    
            @Bean
            MvcEndpoint javaMelodyReportEndpoint() {
                ReportServlet reportServlet = new ReportServlet();
                // We initialize the servlet with the servlet configuration from the server that runs on server.port, as
                // it currently only uses it to access the Collector instance, and some system information.
                reportServlet.init(servletConfig);
    
                return new MvcEndpoint() {
                    @Override
                    public String getPath() {
                        return "/monitoring";
                    }
    
                    @Override
                    public boolean isSensitive() {
                        return false;
                    }
    
                    @Override
                    public Class<? extends Endpoint> getEndpointType() {
                        return null;
                    }
    
                    @GetMapping
                    public void report(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws ServletException, IOException {
                        reportServlet.service(httpRequest, httpResponse);
                    }
                };
            }
    
            @Bean
            FilterRegistrationBean javaMelodyFilterRegistration() {
                FilterRegistrationBean javaMelody = new FilterRegistrationBean();
                javaMelody.setFilter(monitoringFilter());
                javaMelody.setName("javamelody");
                return javaMelody;
            }
    
            @Bean
            MonitoringFilter monitoringFilter() {
                return new MonitoringFilter() {
                    @Override
                    protected boolean isAllowed(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException {
                        // We allow no access to the report (/monitoring) from this filter, access is done through the
                        // MvcEndpoint above, using the management port.
                        return false;
                    }
                };
            }
        }
    

    (我也在这里发布了这个:https://github.com/javamelody/javamelody/issues/601

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 2018-07-10
      • 2019-10-24
      • 2019-06-22
      • 1970-01-01
      相关资源
      最近更新 更多