【问题标题】:Debugging GAE microservices locally but without using localhost在本地调试 GAE 微服务,但不使用 localhost
【发布时间】:2018-07-19 23:05:12
【问题描述】:

我想在本地调试我的 Google App Engine (GAE) 应用程序,但不使用 localhost。由于我的应用程序是由微服务组成的,因此生产环境中的 url 大致如下:

https://my-service.myapp.appspot.com/

但是一个服务中的代码可以调用另一个服务,这意味着网址是硬编码的。我当然可以在代码中使用一种机制来确定应用程序是在本地运行还是在 GAE 上运行,并使用不同的 url,尽管我看不到本地 url 将如何处理,因为在本地运行应用程序的唯一方法是使用本地主机。因此:

http://localhost:8080/some-service

请注意,“some-service”映射到 servlet,而“my-service”是在上传应用程序时分配给服务的名称。这实际上是两种不同的东西。

我能找到的唯一可能的解决方案是使用反向代理,它将一个 URL 映射到另一个 URL。不过,目前尚不清楚 GAE 开发 SDK 是否支持这一点。

【问题讨论】:

  • 标准环境还是灵活?
  • 标准环境。

标签: google-app-engine


【解决方案1】:

我个人选择检测本地开发与 GAE 环境并相应地构建我的跨服务 URL。我觉得这是一项非常值得的努力,我已经(重新)使用了很多次。不需要反向代理或任何其他额外的操作,它就可以工作。

当然,我使用的是 Python,所以我不能 100% 确定是否存在完整的类似 Java 解决方案。但也许它可以为您指明正确的方向。

为了构建每个服务的 URL,我使用了 modules.get_hostname()(实现在 Resolve Discovery path on App Engine Module 中介绍)。我相信 Java 等价物将是来自 com.google.appengine.api.modulesgetInstanceHostname()。 此方法在本地服务器上执行时,会自动提供服务器为每个服务侦听的特定端口。

顺便说一句,我为应用程序提供的所有服务都由单个开发服务器进程执行,该进程侦听多个端口(我猜这是它如何提供modules.get_hostname() 信息)。见Running multiple services using dev_appserver.py on different ports。这是我不确定的部分:java本地开发服务器是否/如何同时运行多个服务。显然,这曾经是前一段时间支持的(当时services 仍被称为modules):

【讨论】:

    【解决方案2】:

    这可以通过以下步骤来完成:

    1. 在 hosts 文件中创建一个条目
    2. 使用某些选项从终端运行 App Engine 开发服务器
    3. 使用带有远程调试功能的 IntelliJ 来附加 App Engine 开发服务器。

      1. 要在 Mac 上编辑 hosts 文件,请编辑文件 /etc/hosts 并提供与您的服务对应的域:。示例:

    127.0.0.1 my-service.myapp.com

    保存后,您需要重新启动计算机以使更改生效。

    1. 手动运行 App Engine 开发服务器:

    dev_appserver.sh --address=0.0.0.0 --jvm_flag=-Xdebug --jvm_flag=-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 [path_to_exploded_war_directory]

    1. 在 IntelliJ 中,创建调试配置。使用远程模板创建此配置。将主机设置为您在hosts文件中设置的url,并将端口设置为8000。

    您可以设置断点并在 IntelliJ 中运行应用程序。 IntelliJ 将附加到正在运行的 App Engine 开发服务器实例。

    由于您在调试期间使用端口,而在生产期间将应用上传到 GAE 时并未实际使用任何端口,因此您需要添加代码来识别应用何时在本地运行以及何时在 GAE 上运行。这可以按如下方式完成:

    private String mServiceUrl = "my-service.my-app.appspot.com";
    ...
    if (SystemProperty.environment.value() != SystemProperty.Environment.Value.Production) {
               mServiceUrl += ":8000";
    }
    

    https://cloud.google.com/appengine/docs/standard/java/tools/using-local-server

    一种改进的解决方案是避免完全包含端口,而不必使用代码来确定您的应用是在本地运行还是在生产服务器上运行。一种方法是使用 Charles(一个用于监视和与请求交互的应用程序)并使用称为远程映射的功能,它允许您将一个 url 映射到另一个。启用后,您可以映射如下内容:

    https://my-service.my-app.appspot.com/

    https://localhost:8080

    然后,您将启用包含原始主机的选项,以便将其传送到本地开发服务器。就您的代码而言,它只看到:

    https://my-service.my-app.appspot.com/

    虽然启用远程映射时 IP 地址将为 127.0.0.1:8080。但是,要在本地主机上使用 https 确实需要您为 Charles 启用 ssl 证书。

    有关如何在 IntelliJ 中为 GAE Java 应用程序设置和调试微服务的完整概述,请参阅:

    https://github.com/JohannBlake/gae-microservices

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-20
      • 1970-01-01
      • 2015-04-21
      • 1970-01-01
      • 1970-01-01
      • 2011-06-15
      • 2018-06-09
      • 1970-01-01
      相关资源
      最近更新 更多