Spring Boot - 如何在微服务之间进行通信?

时间:2018-05-24 09:45:18

标签: spring-boot microservices

我目前正在开发一个Spring Boot微服务项目。我创建了服务,每个服务都是单独运行的。有了这个,我需要一些服务来与其他服务进行通信。我怎样才能做到这一点?

我看到一些关于此的博客,使用Netflix,Eureka云服务器来实现这一目标。有没有办法在不使用云服务器的情况下在我的本地环境中实现这一目标?

7 个答案:

答案 0 :(得分:4)

当然可以。 微服务只是REST服务。 您需要了解REST服务的工作原理。 之后用Spring-boot编写2个微服务(2个Rest-Services:生产者服务和消费者服务),让它们在不同的服务器端口下运行,从另一个服务器端口调用消费者服务,就是这样:你有你的微服务。 现在这是编写微服务的原始方法。

为了让它们发展,你需要添加一些“魔法”(没有火箭科学),例如使用Ribbon在你的“生产者服务”的两个实例之间分配负载。

你可以使用一个发现服务,它只是一个带有注释@EnableEurekaServer的spring-boot应用程序(你需要在你的pom中添加适当的依赖项) 现在将第一个(原始)微服务添加到主类的注释@EnableDiscoveryClient,并在两者的application.properties(或application.yml)中指向您的eureka服务的defaultZone,启动您的eureka服务(发现服务)和2个微服务:那些将在发现服务上注册。当然,现在您不需要在消费者服务中对生产者服务的http地址进行硬编码 看一下这个tutorial

于2018年11月21日格林尼治标准时间12:41编辑

假设您的第一个(普通的)微服务(纯粹的休息服务)在您的PC上在端口8091下运行。

在你的第二个(普通)微服务的控制器中,你使用RestTemplate.getForEntity(url,responseType,uriVariables)调用你的第一个服务,就像链接教程中的例子一样:

ResponseEntity<CurrencyConversionBean> responseEntity = 
   new RestTemplate().getForEntity(
        "http://localhost:8091/currency-exchange/from/{from}/to/{to}", CurrencyConversionBean.class,  uriVariables);

其中 url:您的第一个(微)(休息)服务的网址。 responseType:等待作为响应的对象的类/类型。 uriVariables:是一个包含URI模板变量的映射。

答案 1 :(得分:1)

正如@ g00glen00b在评论中所提到的,Eureka不用于微服务之间的通信。它用于服务发现。 我知道有两种方法可以与其他微服务进行通信:

  1. RestTemplate
  2. Feign Client
  3. RestTemplate使用起来非常简单。它不需要配置。

    e.g。

       ResponseType obj=  new RestTemplate().getForObject(URL, ResponseType.class, params);
    

    url - 网址

    responseType - 返回值的类型

    params-扩展模板的变量

    Spring Doc link供您参考

答案 2 :(得分:1)

这取决于您的选择、您希望服务之间的同步通信或异步通信的天气。 对于同步服务,您可以使用以下任一第三方工具:

  1. Hashcorp 领事
  2. Netflix Eureka [您可以使用 Netflix RIBBON 进行客户端负载平衡]
  3. NATS 等

对于异步,您可以使用消息传递解决方案,例如:

  1. Redis [使用列表/流]
  2. ActiveMQ
  3. RabitMQ
  4. 卡夫卡
  5. NATS 等

答案 3 :(得分:0)

微服务之间有不同的通信方式。但是要使用哪一个:取决于用例。

  1. Api call:使用RestTemplateFeignClient等向其他服务进行实际的REST API调用。
ResponseType obj=  new RestTemplate().getForObject(URL, ResponseType.class, params);
  1. 但是如果用例不同,比如您有客户微服务和订单微服务都使用单独的数据库。您还拥有customer name数据库中的orders和其他详细信息。客户更新其姓名后,您还必须更新“订单”数据库中的详细信息。如何做到这一点。通过API call吗?如果帐户微服务也需要此更新怎么办。因此,Rest api将是开销。在这种情况下,我们可以像MessageQueues一样使用RabbitMQ。客户微服务将创建一个客户更新事件,任何对此感兴趣的微服务都可以订阅。
  

通过消息队列(如RabbitMQ)进行通信

Spring.io rabbit mq guide

答案 4 :(得分:0)

尽管REST很熟悉,因此很容易实现,但是如果您需要更灵活和类似于Java的通信,那么Spring的HTTP Invoker是一个不错的选择。

如果需要基于HTTP的远程处理,Spring的HTTP调用程序是一个不错的选择 而且还依赖Java序列化。它共享基本 具有RMI调用程序的基础架构,仅使用HTTP作为传输。注意 HTTP调用程序不仅限于Java到Java远程处理,而且 也要在客户端和服务器端都使用Spring。 (后者也 适用于非RMI接口的Spring RMI调用程序。)

答案 5 :(得分:0)

该帖子看起来很旧,但我会尝试与为同一问题搜索解决方案的新开发人员分享我的经验。

您将需要这些库: 祖尔网关, 尤里卡发现服务器, 尤里卡发现客户端, Rest 模板(如果您开发 REST API)。

Gateway 可以管理 Spring Boot 微服务应用的所有路由。仅使用注释和 application.properties 就可以设置整个服务器。您不需要编写一行 Java 代码。

发现服务器在新微服务启动或停止时侦听事件。它注册了所有使用@EnableEurekaClient 注解的微服务。

Rest Template 是一个成熟的 rest 客户端库,它在自定义 http 请求和 http 响应配置方面非常灵活。例如,您可以使用客户端 http 拦截器配置来拦截 http 请求和响应以添加更多数据,或记录信息等。

我的 GitHub 页面上有开源微服务应用程序。免费分发、分叉、克隆、商业化.. 没有欲望:-)

一切顺利..

答案 6 :(得分:-1)

@Autowired
    private RestTemplate restTemplate;

@Autowired
    private EurekaClient eurekaClient;


@RequestMapping("/dashboard/{myself}")
    public EmployeeInfo findme(@PathVariable Long myself) {
        Application application = eurekaClient.getApplication(employeeSearchServiceId);
        InstanceInfo instanceInfo = application.getInstances().get(0);
        String url = "http://" + instanceInfo.getIPAddr() + ":" + instanceInfo.getPort() + "/" + "employee/find/" + myself;
        System.out.println("URL" + url);
        EmployeeInfo emp = restTemplate.getForObject(url, EmployeeInfo.class);
        System.out.println("RESPONSE " + emp);
        return emp;
    }

来源: https://dzone.com/articles/microservices-communication-service-to-service