微服务如何与 JHipster 中的其他微服务通信

Posted

技术标签:

【中文标题】微服务如何与 JHipster 中的其他微服务通信【英文标题】:How can microservice can talk to other microservice in JHipster 【发布时间】:2017-12-31 20:21:51 【问题描述】:

我计划创建一个微服务应用程序,其中包含用于处理数据的专用服务(主要是基于 Mongodb 的服务)。我想知道是否有一种方法可以让我的其他微服务能够与该服务通信以使用共享数据。 JHipster API Gateway 可以吗? 如果不是我怎么能做到这一点。我不想在每个微服务中保留相同数据的多个副本。

【问题讨论】:

应该尽可能避免微服务之间的依赖,它只会让你的整体解决方案变得更慢更弱,这可能表明你的域边界是错误的(参见 DDD)。您的问题缺少详细信息,但网关将 JWT 令牌传递给可以将其转发给另一个服务的服务 不要进行专门的数据存储。每个 MS 都应该有自己的持久性。 @GaëlMarziou,如果请求是通过批处理调用或直接从服务本身而不是从网关发起的呢? 我看不出有什么不同。也许你应该用更多细节打开你自己的问题。 【参考方案1】:

您还可以将 Feign 客户端与 JHipster 一起使用。

@EnableFeignClients注释你的SpringBootApplication

...
import org.springframework.cloud.openfeign.EnableFeignClients;
...
@SpringBootApplication
@EnableConfigurationProperties(LiquibaseProperties.class, ApplicationProperties.class)
@EnableDiscoveryClient
@EnableFeignClients
public class MyApp 
    ...

在你的微服务中创建一个 Feign 客户端

...
import org.springframework.cloud.openfeign.FeignClient;
...
@FeignClient("another-service")
public interface AnotherClient 

    @RequestMapping(method = RequestMethod.GET, value = "/api/another")
    List<AnotherDTO> getAll();

使用@Autowired 注入Feign 客户端并调用它。它应该可以使用了。

@RestController
@RequestMapping("/api")
public class MyResource 
    ...
    @Autowired
    private AnotherClient anotherClient;
    ...
    @GetMapping("/another")
    @Timed
    public List<AnotherDTO> getAll() 
        log.debug("REST request to get all");
        return anotherClient.getAll();
    

对我们来说,它在没有实现 ClientHttpRequestInterceptor 和设置 JWT 令牌的情况下工作。

【讨论】:

【参考方案2】:

您可以将您的微服务注册到同一个注册中心,然后它们就可以相互调用。

更新:这是我的工作方式。 在使用数据的微服务一中,在 API 调用的 Authorization-header 中将 RestTemplate 与当前用户的 jwt-token 一起使用:

@Component
public class AuthenticateClientHttpRequestInterceptor implements ClientHttpRequestInterceptor 

    @Override
    public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException 
        String token = SecurityUtils.getCurrentUserJWT();
        httpRequest.getHeaders().add("Authorization","Bearer "+token);
        return clientHttpRequestExecution.execute( httpRequest, bytes );
    

我的自定义 restTemplate 使用 ClientHttpRequestInterceptor 在标头中添加令牌。

@Configuration
public class CustomBean 
    @Autowired
    AuthenticateClientHttpRequestInterceptor interceptor;
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() 
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setInterceptors(Collections.singletonList(interceptor));
        return restTemplate;
    

在您调用数据的资源控制器中:

@RestController
@RequestMapping("/api")
public class DataResource     
    @Autowired
    RestTemplate restTemplate;

            @PostMapping("/hello")
            @Timed
            public ResponseEntity<Hello> createHello(@RequestBody Hello Hello) throws URISyntaxException 
                
    //The name your data micro service registrated in the Jhipster Registry
                String dataServiceName = "data_micro_service";
            
                URI uri = UriComponentsBuilder.fromUriString("//" + dataServiceName + "/api/datas")
                    .build()
                    .toUri();
            
                //call the data microservice apis
                List<Data> result = restTemplate.getForObject(uri, Data[].class);
            
            
            return ResponseEntity.created(new URI("/api/hellos/" + result.getId()))
                    .headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString()))
                    .body(result);
        
        


【讨论】:

救命稻草!几个星期以来,我一直在努力解决这个问题......【参考方案3】:

通常,微服务会相互通信。这就是重点。有了 Eureka 发现,您只需按名称调用微服务,而不是我们通常在没有微服务的情况下使用的 FQDN。

例如你的book-service 会像这样调用author-service http://author-service/authors

这里有完整的例子https://spring.io/blog/2015/01/20/microservice-registration-and-discovery-with-spring-cloud-and-netflix-s-eureka

请不要忘记 JHipster 是一个基于 Spring Cloud 的固执己见的框架,因此您可以通过搜索 Spring 文档找到其中的大部分内容。

【讨论】:

【参考方案4】:

您可以使用以下解决方案: 微服务 A(即 UAA-SERVICE)和微服务 B 微服务 B 想连接微服务 A 并通过 Feign 客户端调用服务。

1)微服务 B 的代码 客户端代理:- @AuthorizedFeignClient(name = "UAA-SERVICE")

@AuthorizedFeignClient(name = "UAA-SERVICE")

公共接口 UaaServiceClient

@RequestMapping(method = RequestMethod.GET, path = "api/users")
public List<UserDTO> getUserList();

@RequestMapping(method = RequestMethod.PUT, path = "api/user-info")
public String updateUserInfo(@RequestBody UserDTO userDTO);

UAA-SERVICE : 通过注册表运行应用程序实例找到此名称。

2) 在微服务 B (application.yml)中 增加feign客户端连接超时: 假装: 客户: 配置: 默认值: 连接超时:10000 读取超时:50000

增加 hystrix 线程超时时间:-

hystrix: 命令: 默认: 执行: 隔离: 线: 超时毫秒:60000 shareSecurityContext: 真

3) 在@SpringBootApplication 主类中添加@EnableFeignClients。 这个解决方案对我来说很好。

【讨论】:

以上是关于微服务如何与 JHipster 中的其他微服务通信的主要内容,如果未能解决你的问题,请参考以下文章

JHipster - 如何在 Eclipse 中仅调试微服务架构中的一个网关(或微服务)?

JHipster - 网关如何在微服务中进行身份验证?

两个微服务之间的通信

微服务中的用户语言环境 - JHipster

JHipster创建微服务及相关微服务架构组件介绍

JHipster生成微服务架构的应用 - 准备工作