Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 开发者环境-如何调用/使用其他微服务_Java_Rest_Playframework_Docker - Fatal编程技术网

Java 开发者环境-如何调用/使用其他微服务

Java 开发者环境-如何调用/使用其他微服务,java,rest,playframework,docker,Java,Rest,Playframework,Docker,背景 我的环境-Java、Play2、MySql 我已经在Play2->/S1、/S2、/S3上编写了3个无状态Restful微服务 S1使用S2和S3的数据。所以,当用户点击/S1时,该服务异步调用/S2、/S3,合并数据并返回最终的json输出。旁注-服务最终将以docker图像的形式发布 为了在开发人员环境中进行测试,我分别在端口9000、9001和9002上运行/s1、/s2和/s3。我从配置文件中获取端口号等。我点击服务,一切正常。但是有更好的方法在我的开发者盒上设置测试环境,对吗?示

背景

我的环境-Java、Play2、MySql

我已经在Play2->/S1、/S2、/S3上编写了3个无状态Restful微服务

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容器(每个容器运行一个服务)完成同样的事情

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

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

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

这是一个悬而未决的问题,下面是一些关于这个主题的问题。SkyDNS为您提供了服务发现的大部分方式,并使您能够轻松使用远程docker容器之间的网络。我还没有看到更好的端到端解决方案,尽管可能有一些解决方案。

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

在一堆不同的容器中设置大型微服务的最简单方法可能是使用Docker即将发布的。由于我们没有关于即将发生什么的所有细节,我将使用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
文件将在应用程序和所有服务之间建立链接,以便在代码中,您可以通过主机名
service1
service2
等来引用它们

出于开发目的,这里还需要做更多的工作:对于每个服务,您可能希望挂载一个目录,在其中编辑代码,您可能希望公开一些端口,以便可以直接测试服务,等等。但在其核心,开发环境与生产环境相同


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

您将该链接称为主机名。可以安全地假设,在生产过程中,这将由DNS解决,但在开发过程中,这将通过链接解决吗?不,在开发和生产过程中,这将通过链接解决。链接Docker容器时,Docker在
/etc/hosts
中创建一个条目,为链接的容器分配一个名称,以便您可以直接引用它。我假设在开发过程中,这些容器将在同一台机器上运行,但在生产过程中,它们将在单独的机器上运行,并可能作为集群运行。这很有意义-我假设它们将是在开发和生产中的同一主机上运行。恐怕我没有太多在多台机器上部署应用程序的经验,尽管设置容器以便它们在生产中使用DNS进行名称解析应该不会太困难。是的。。诀窍是使用链接中使用的相同名称。我假设您可以在链接的名称中使用点,即service.domain如果您有一个应用程序容器、服务容器,并希望从应用程序容器中动态调用,该怎么办?限制:正如您所建议的,我的代码中没有硬编码的IP或端口。我可以从/etc/hosts获取IP,但不能从服务的端口获取。您的服务应该侦听众所周知的端口,因为每个容器都有自己的IP(至少在桥接网络中是这样),因此没有端口冲突。如果你需要可变端口,那么你需要一个更重的服务发现解决方案,比如zookeeper。好的,我已经硬编码了服务端口,但是ENV只显示Docker Swarm上的内部IP。我的PHP容器前端页面上的javascript无法使用该内部IP,因此concur、Etcd似乎没用。我可以传递公共IP吗?对于公共端口,您几乎必须使用反向代理或自行管理随机端口分配。Rancher.io通过其负载平衡器提供反向代理。还有其他可能的反向代理解决方案。啊,糟糕透了。Rackspace不支持Rancher,因为AppArmor不允许使用
--privileged
标志。