ingredient-service
服务,并收到六个服务实例,那该如何选择正确的服务实例呢?getForObject()
的 URL 是硬编码到特定的主机和端口的。虽然您可以将 URL 提取到一个配置属性中,但如果请求是对 Ingredient 服务的多个实例之一,您配置的任何 URL 都将只针对特定实例,而不能在多个实例中进行负载均衡。@Bean
和 @LoadBalanced
注解:@LoadBalanced
注解有两个目的:首先也是最重要的,它告诉 Spring Cloud,这个 RestTemplate 应该能够通过 Ribbon 查找服务。另外,它可以作为一个注入限定符。因为,如果您有两个或两个以上的 RestTemplate,这指定了要使用带有负载均衡的 RestTemplate。getIngredientById()
方法来获取 Ingredient,以便它使用服务的注册名称,而不是显式的指定主机和端口:getForObject()
指定的 URL,没有使用任何特定的主机名或端口。使用服务名称 ingredient-service
来代替主机名和端口。内部 RestTemplate 要求 Ribbon 查找服务并选择一个实例。Ribbon 很高兴提供帮助,重写 URL 以包含所选服务实例的主机和端口,然后让 RestTemplate 照常进行后续工作。@LoadBalanced
注解到 WebClient.Builder
方法上:WebClient.Builder
bean,现在就可以注入到任何需要使用它的地方了。例如,您可以将其注入到 IngredientServiceClient 的构造函数中:WebClient.Builder
以构建一个 WebClient,然后使用各服务在Eureka 中注册的服务名称发出实际请求:Feign
这个词的意思是“假装”,您很快就会看到,使用这个词,对于假装的 REST 的客户端确实是非常合适。<dependency>
做到了这一点:Feign
复选框,自动添加相同的启动依赖项。不幸的是,基于这个依赖的自动配置无法自动启用 Feign。因此,需要将 @EnableFeignClient
注解添加到其中一个配置类:ingredient-service
服务,并进而获取 Ingredient。您应该像下面这样使用:@FeignClient
注解,指明了在此接口中声明的任何方法,将对名称为 ingredient-service
的服务发出请求。在内部,将通过 Ribbon 查找,就像使用 RestTemplate 时那样。getIngredient()
方法,您一定认出了来自于 Spring MVC 的 @GetMapping
注解。事实上,确实是同样的注解!只是这次是用在客户端上,而不是在 Controller 上。也就是说,任何对 getIngredient()
的调用,都将导致 Ribbon 选择相应主机和端口,并把 GET 请求转到 /ingredients/{id}
上。@PathVariable
注解同样来自 Spring MVC,会将参数映射到给定路径中的占位符中。@RequestLine
和 @Param
大致类似于 Spring MVC 的 @RequestMapping
和 @PathVariable
,只是使用方式有点差异。不过,能够在客户端上使用已经熟悉的 Spring MVC 注解,这一点是相当好的。