【发布时间】:2017-07-14 15:50:37
【问题描述】:
我已经开始使用 Spring Cloud 和 Netflix 的项目了解更多有关此架构的旅程。
从一般的角度来看,我确实了解架构,但现在我实际上正在编写一个应用程序,对于一些可能对该架构的大方法产生重大影响的最小内容出现了怀疑。
首先,我的应用基于本教程,我认为它是有效的,因为它来自 Spring 本身:https://spring.io/blog/2015/07/14/microservices-with-spring
现在,问题是:(所有这些都使用 EUREKA)假设我有一个微服务“帐户”,它仅包含在 Spring Data REST 中用于持久性/HATEOAS,最重要的是我有一个客户端服务,它使用那些使用 RestTemplate 的端点(因为我使用的是 Ribbon 的负载均衡器)。在我看来,它是这样工作的:用户 -> 前端 -> 客户端服务 -> Spring Data REST 端点(微服务) -> 数据库。
这很好,但当我获得端点响应(来自 RestTemplate)时,它包含直接进入微服务的超媒体,并且就其本身而言,您现在可以在忽略负载均衡器的情况下自行通过微服务,这,对我来说,扼杀了它的目的。如果我喜欢 5 个微服务相互扩展,这意味着用户现在只关注应该由负载均衡器管理的 5 个微服务的广泛方式之一。
第一季度: 用户了解 API 是否可以(然后有点杀死结构的一部分)?
即使我将链接添加到 Eureka 检测到的服务并删除该微服务的当前端点,这些链接也不起作用,这意味着我正在切断超媒体链接。
第二季度: 还有另一种方法吗?通过某种代理、外部负载均衡器、dns 或类似的东西?
P.D:我不知道我说得够不够清楚。如果有什么模糊不清的地方请告诉我。
P.D.2:总结性问题:如何处理这些媒体链接?让他们成为或使用其他东西(请告诉)真正让他们“正确”?
编辑:根据以下建议,我添加了 Zuul,这似乎可以解决我的问题。现在,关于 Zuul,我应该在哪里过滤?
我的应用程序现在是这样的:account-microservice (Spring Data REST) 和 account-web-service(带有 RestTemplate 负载均衡器的客户端)。这些是 Eureka 注册的名称。
@EnabledZuulProxy 必须去哪里?在微服务内部还是在客户端内部?
我当前的配置是这个(目前,@EnabledZuulProxy 在客户端):
我的微服务:
@SpringBootApplication
@EnableEurekaClient
public class AccountServer {
public static void main(String[] args) {
System.setProperty("spring.config.name", "AccountServerClient");
SpringApplication.run(AccountServer.class, args);
}
}
//Config:
spring.application.name=account-microservice
spring.application.freemarker.enabled=false
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
eureka.client.instance.leaseRenewalIntervalInSeconds=5
我的客户:
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
@EnableCircuitBreaker
public class AccountMicroService {
public static void main(String[] args) {
// Tell server to look for registration.properties or registration.yml
System.setProperty("spring.config.name", "AccountMicroServiceClient");
SpringApplication.run(AccountMicroService.class, args);
}
}
//Config
# Spring properties
spring.application.name=account-web-service
spring.freemarker.enabled=false
eureka.instance.leaseRenewalIntervalInSeconds: 5
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
zuul.routes.account-web-service.path=/accounts/**
zuul.routes.account-web-service.serviceId=account-web-service
zuul.routes.account-web-service.stripPrefix=false
使用 SDR 的客户端代码:
//@HystrixCommand(fallbackMethod="test")
public ResponseEntity<PagedResources<AccountResource>> findAll(Pageable pageable) throws RestClientException, URISyntaxException {
return restTemplate.exchange(serviceUrl + "/accounts" + "?page={page}&size={size}&sort={sort}", HttpMethod.GET,
null, new ParameterizedTypeReference<PagedResources<AccountResource>>() {
}, pageable.getPageNumber(), pageable.getPageSize(), pageable.getSort());
}
像这样,它根本不起作用。也没有过滤。如果我更改它并在微服务中使用它,那么它会不断将指向微服务的所有内容发送到客户端,甚至是来自客户端的请求,最终会出现一个循环,然后是一个错误(超时、负载均衡器已满、电路损坏) ...) 这通常是这样的:com.netflix.zuul.exception.ZuulException: Forwarding error.
编辑 2: 我终于让 Zuul 工作并了解它的作用。现在,当我访问我的新网关应用程序时,它会将请求转发到我的微服务,生成的超媒体现在指向该网关,这正是我想要的。
这个问题最初是架构问题,然后变成了编码问题,但现在我认为这些技术已经很清楚了。
这杯茶是了解 Zuul 做什么、何时以及如何做的。 @Ryan Baxter 指南和这两篇文章:https://dzone.com/articles/microservice-architecture-with-spring-cloud-and-do 和 https://spring.io/guides/gs/routing-and-filtering/ 完成这项工作的基础。我会用我所做的和我理解的来编辑这个答案。
【问题讨论】:
标签: spring-cloud spring-data-rest microservices spring-cloud-netflix