簡體   English   中英

如何讓 PCF 應用程序管理器顯示有關我檢測為 Spring 引導應用程序的信息?

[英]How can I get PCF App Manager to display information about my detected as Spring Boot Application?

我有一個正在部署到 Pivotal Cloud Foundry (PCF) 的 Spring 引導應用程序。 PCF 將應用程序識別為 Spring 引導應用程序。 但是,沒有任何信息顯示。

應用程序正在使用上下文路徑運行。 已添加配置以重新映射:

  • /cloudfoundry應用程序
  • /執行器/普羅米修斯
  • /健康

從外部到上下文路徑。 我可以在瀏覽器中打開/actuator/prometheus/health
/cloudfoundryapplication返回HTTP 401錯誤頁面。

我已經添加

management:
  cloudfoundry:
    enabled: true
    skip-ssl-validation: true

application.yml
Spring 安全正在運行,但配置為忽略以下所有 URL。

@Override
public void configure(WebSecurity web) throws Exception
{
   web.ignoring()
      .antMatchers("/health",
                   "/actuator/health",
                   "/actuator/prometheus",
                   "/cloudfoundryapplication",
                   "/actuator/cloudfoundryapplication",
                   "/cloudfoundryapplication/**",
                   //"/report/daily",
                   "/index.html",
                   "/index.html**",
                   "/favicon.ico");
}

那么我怎樣才能讓 PCF 真正顯示我的應用程序的運行狀況,並將其視為 Spring 啟動應用程序呢?


更新:該應用程序已經在其上下文路徑之外提供 URL。 我已經列出了它所服務的 URL。 這是執行此操作的 class。 PCF 將應用識別為 Spring Boot,但沒有顯示 forms 或信息。

@Configuration
public class CloudMetricsConfig
{
   @Bean
   public TomcatServletWebServerFactory servletWebServerFactory()
   {
      return new TomcatServletWebServerFactory()
      {
         @Override
         protected void prepareContext(Host host, ServletContextInitializer[] initializers)
         {
            super.prepareContext(host, initializers);

            addContext(host, "/cloudfoundryapplication", getContextPath(),
                       "cloudfoundry");
            addContext(host, "/actuator/prometheus", getContextPath(),
                       "prometheus");
            addContext(host, "/health", getContextPath(),
                       "health");
         }
      };
   }

   private void addContext(Host host, String path, String contextPath,
                           String servletName)
   {
      StandardContext child = new StandardContext();
      child.addLifecycleListener(new Tomcat.FixContextListener());
      child.setPath(path);
      ServletContainerInitializer initializer =
             getServletContextInitializer(contextPath, servletName, path);
      child.addServletContainerInitializer(initializer, Collections.emptySet());
      child.setCrossContext(true);
      host.addChild(child);
   }

   private ServletContainerInitializer getServletContextInitializer(String contextPath,
                                                                    String servletName,
                                                                    String path)
   {
      return (c, context) ->
      {
         Servlet servlet = new GenericServlet()
         {
            @Override
            public void service(ServletRequest req, ServletResponse res)
                   throws ServletException, IOException
            {
               ServletContext context = req.getServletContext().getContext(contextPath);
               context.getRequestDispatcher(path).forward(req, res);
            }
         };
         context.addServlet(servletName, servlet).addMapping("/*");
      };
   }
}

上面重新映射的三個 URL 被 Spring-Security 設置為忽略。

在 PCF 應用程序管理器中,我可以看到為我的應用程序定義的以下路由

注意:只有第二條路由將上下文路徑定義為它的一部分。


進一步更新:

App Manager 正在向第一個列出的路由發送請求。 它似乎根本沒有得到回應。

日志看起來應該會響應:

2021-01-22T17:03:19.928-05:00 [RTR/9] [OUT] service-dev.apps.nonprod-mpn.ro11.company.com - [2021-01-22T22:03:19.918937681Z]”選項 /exe/v2/cloudfoundryapplication/health HTTP/1.1" 200 0 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/605.1. 15“” 10.204.253.14:53711“” 10.195.121.117:61118“ x_forwarded_for:” 10.90.161.66,10.204.253.14“ x_forwarded_proto:” 0.003056 app_id:"ea6df148-1809-4f02-87ac-39b4ea0ebeac" app_index:"0" x_cf_routererror:"-" x_b3_traceid:"9afab521ad427253" x_b3_spanid:"9afab521ad427253" x_b3_parentspanid:"-" b3:"9afab521ad427253-9afab521ad427253"

但在 Safari 中它說:

回復
沒有響應頭

這是專門針對/cloudfoundryapplication/health端點的。
/cloudfoundryapplication成功返回響應。

應用程序正在使用上下文路徑運行。

這需要特殊處理才能使其工作。 通過使用上下文路徑, /cloudfoundryapplication端點不再可用。 它是/your-context-path/cloudfoundryapplication 這意味着應用程序管理器將找不到它。

看...

  1. 如果已配置自定義 servlet 上下文路徑,則 Spring 引導執行器端點將不再位於/cloudfoundryapplication路徑。

這篇知識庫文章中

有一種解決方法, 在此處記錄(當我寫這篇文章時,KB 中的鏈接是錯誤的,但我會修復它)。

報價:

配置因使用的 web 服務器而異。 對於Tomcat,可以添加如下配置:

@Bean
public TomcatServletWebServerFactory servletWebServerFactory() {
    return new TomcatServletWebServerFactory() {

        @Override
        protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
            super.prepareContext(host, initializers);
            StandardContext child = new StandardContext();
            child.addLifecycleListener(new Tomcat.FixContextListener());
            child.setPath("/cloudfoundryapplication");
            ServletContainerInitializer initializer = getServletContextInitializer(getContextPath());
            child.addServletContainerInitializer(initializer, Collections.emptySet());
            child.setCrossContext(true);
            host.addChild(child);
        }

    };
}

private ServletContainerInitializer getServletContextInitializer(String contextPath) {
    return (c, context) -> {
        Servlet servlet = new GenericServlet() {

            @Override
            public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
                ServletContext context = req.getServletContext().getContext(contextPath);
                context.getRequestDispatcher("/cloudfoundryapplication").forward(req, res);
            }

        };
        context.addServlet("cloudfoundry", servlet).addMapping("/*");
    };
}

這樣做是在您的嵌入式 Tomcat 中設置第二個上下文,它將查找/cloudfoundryapplication (從根目錄)並將這些請求轉發到您的實際應用程序上下文下的/cloudfoundryapplication (它使用跨上下文支持來執行此操作)。

因此,當應用程序管理器將請求發送到您的https://<host>.apps.example.com/cloudfoundryapplication時,它會轉發到https://<host>.apps.example.com/<context-path>/cloudfoundryapplication ,它到達了它需要的地方。

但這只是成功的一半。

重要的是要了解,要使其正常工作,您仍然需要在 Cloud Foundry 中為該流量映射一個路由。 否則,來自應用程序管理器的流量將不會進入您的應用程序。 如果您使用--path映射路由,那將是不夠的,因為這只會將該路徑的流量發送到您的應用程序,並且/cloudfoundryapplication請求(這是一條不同的路徑)永遠不會在您的應用程序中結束使用上面的解決方法。

例如,如果您已映射路線https://<host>.apps.example.com/<context-path> ,則平台只會將針對該確切主機和路徑的流量發送到您的應用程序。 由於https://<host>.apps.example.com/cloudfoundryapplication不在該路徑下,因此到它的流量將永遠不會到達您的應用程序(它可能是 go 到其他一些應用程序,所以您必須小心)。

要使用此解決方法 function,您需要有一條沒有路徑的路由或兩條路由,一條帶有您的上下文路徑,一條帶有/cloudfoundryapplication

例如:

a.) https://<host>.apps.example.com

b.) https://<host>.apps.example.com/<context-path> + https://<host>.apps.example.com/cloudfoundryapplication

這實質上意味着您只能對每個主機名使用一個 Spring 引導應用程序使用此解決方法,因為所有 Spring 引導應用程序都需要在相同的/cloudfoundryapplication路徑上接收請求,並且只有一個應用程序可以映射到該路由(從技術上講,您可以 Z1D78AE5DC8ED51244E到多個應用程序的路由,但這會導致流量在所有應用程序之間循環分配,這不是您想要的)。

最后一點,你提到...

已添加配置以重新映射:

我在您發布的信息中沒有看到這一點。 您有一些 Spring 安全代碼,但這只會禁用這些 URL 的 Spring 安全性,而不是重新映射/重定向 URL。 如果您在其他地方重新映射 URL,請忽略此注釋。 只是想指出這一點。 如果您期望它重新映射/重定向它們,它不會。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM