【问题标题】:Developer environment - how to call/consume other micro services开发者环境——如何调用/使用其他微服务
【发布时间】:2014-12-10 18:43:32
【问题描述】:

背景

我的环境 - Java、Play2、MySql

我在 Play2 上写了 3 个无状态的 Restful 微服务 -> /S1,/S2,/S3

S1 使用来自 S2 和 S3 的数据。因此,当用户点击 /S1 时,该服务会异步调用 /S2、/S3,合并数据并返回最终的 json 输出。旁注 - 服务最终将作为 docker 镜像提供。

为了在开发人员环境中进行测试,我分别在端口 9000、9001 和 9002 上运行 /s1、/s2、/s3。我从配置文件等中获取端口号。我点击了服务,一切正常。但是有更好的方法来在我的开发人员盒子上设置测试环境吗?示例 - 如果我想运行 20 个服务等怎么办?

话虽如此,在生产环境中,它们将被称为 mydomain.com/s1、mydomain.com/s2、mydomain.com/s3 等。我想在我的开发环境框中完成此操作....我猜想我会想到一些反向代理。

问题

所以问题是,我如何在 S1 中调用 /S2 和 /S3 而无需在开发人员环境中指定或使用端口号。人们如何在本地机器上测试微服务?

额外奖励

知道我将把我的服务作为 docker 镜像发送,我如何使用 docker 容器(每个容器运行一个服务)来完成同样的事情

【问题讨论】:

    标签: java rest playframework docker


    【解决方案1】:

    最简单的方法 (IMO) 是设置您的开发环境以尽可能接近您的生产环境。如果您希望您的生产应用程序与 20 个微服务一起工作,每个微服务都在一个单独的容器中运行,那么请使用您的开发机器来实现。这样,当您部署到生产环境时,您不必从使用端口更改为使用主机名。

    在一堆不同的容器中设置大量微服务的最简单方法可能是使用 Fig 或 Docker 即将推出的 integrated orchestration tools。由于我们没有关于即将发生的事情的所有详细信息,我将使用 Fig. 这是用于生产服务器的 fig.yml 文件:

    application:
      image: application-image
      links:
        - service1:service1
        - service2:service2
        - service3:service3
        ...
    
    service1:
      image: service1-image
      ...
    
    service2:
      image: service2-image
      ...
    
    service3:
      image: service3-image
      ...
    

    这个缩写的fig.yml 文件将在应用程序和所有服务之间建立链接,以便在您的代码中,您可以通过主机名service1service2 等来引用它们。

    出于开发目的,这里需要做的还有很多:对于每个服务,您可能需要挂载一个目录来编辑代码,您可能需要公开一些端口以便测试服务直接等。但本质上,开发环境和生产环境是一样的。

    听起来确实很多,但是像 Fig 这样的工具让配置和运行应用程序变得非常容易。如果你不想使用 Fig,那么你可以用 Docker 命令来做同样的事情——关键是容器之间的链接。我可能会创建一个脚本来为生产和开发环境进行设置。

    【讨论】:

    • 您将链接称为主机名。假设在生产中这将由 DNS 解决,但在开发中通过链接解决,是否安全?
    • 不,在开发和生产中,它们将通过链接解决。当您链接 Docker 容器时,Docker 在 /etc/hosts 中创建一个条目,为该链接容器分配一个名称,以便您可以直接引用它。
    • 我假设在开发中这些容器将在同一台机器上运行,但在生产中它们将在不同的机器上并可能作为集群运行。
    • 这是有道理的——我假设它们将在开发和生产中运行在同一台主机上。恐怕我没有太多在多台机器上部署应用程序的经验,尽管设置容器以便它们在生产中使用 DNS 进行名称解析应该不会困难。
    • 是的.. 诀窍是使用链接中使用的相同名称。我假设您可以在链接名称中使用点,即 service.domain
    【解决方案2】:

    示例 - 如果我想运行 20 个服务等怎么办

    docker 将使用它们的别名在每个链接的容器的 etc hosts 文件中创建条目。因此,如果您链​​接很多容器,您可以使用它们的别名来寻址它们。不要使用 -p 9000:9000 将端口映射到公共端口。这样你的所有服务都可以在他们自己的 docker 主机上的 9000 端口上,可以从 /etc/hosts 中查找

    “我如何完成同样的事情......”

    这是一个悬而未决的问题,这里有一些关于该主题的good readingSkyDock 和 SkyDNS 为您提供服务发现的大部分方式,weave 让您在远程 docker 容器之间轻松使用网络。我还没有看到更好的端到端解决方案,虽然可能有一些。

    【讨论】:

    • 如果你有一个应用容器,服务容器,想从应用容器中动态调用service:port/api/call.json怎么办?限制:正如您所建议的,我的代码中没有硬编码的 IP 或端口。我可以从 /etc/hosts 获取 IP,但不能获取服务的 PORT。
    • 您的服务应该监听众所周知的端口,因为每个容器都有自己的 IP(至少在桥接网络中)没有端口冲突。如果您需要可变端口,那么您需要更重量级的服务发现解决方案,例如 zookeeper。
    • 好的,我已经硬编码了服务端口,但是 ENV 只显示了 Docker Swarm 上的内部 IP。我在 PHP 容器前端页面上的 javascript 无法使用该内部 IP,因此 Consul、Etcd 似乎没用。可以通过公网IP吗?
    • 对于公共端口,您几乎必须使用反向代理或以某种方式自行管理随机端口分配。 Rancher.io 通过其负载均衡器提供反向代理。还有其他潜在的反向代理解决方案。
    • 啊,真可惜。由于 AppArmor 不允许 --privileged 标志,Rackspace 不支持 Rancher。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-05
    • 2015-03-09
    • 2017-05-28
    • 2017-02-14
    • 2012-12-22
    • 2014-11-15
    • 1970-01-01
    相关资源
    最近更新 更多