我创建了两个 Spring Boot 应用程序,它们都将部署在 Kubernetes 集群中。其中一个应用程序将充当网关,因此使用 Spring Cloud Gateway 作为依赖项。另外我想将服务发现与 Spring Cloud Kubernetes 集成,网关使用服务发现自动生成相应的路由。但是,当我公开在本地 Minikube 集群中运行的网关应用程序并调用第二个应用程序/服务时,我收到 503 错误并显示以下消息:Unable to find instance for ...-service
目前我已经安装了以下内容:
- Minikube
- 虚拟盒子
- 码头工人工具箱
我创建了一个带有两个子项目(网关和另一个服务)的 Gradle 项目。所有项目都将在本地构建/部署。默认服务帐户有权读取 Kubernetes API。部署这些服务后,我将网关服务公开在外部。在网关服务中,我实现了一些端点,其中
- 通过 DiscoveryClient 提供集群中所有服务的列表。
- 在应用层根据 DiscoveryClient 提供的 URI 调用其他服务。
一切似乎都正常,但是当我调用其他服务时,URI/serviceId
我得到了 503 错误......
使用以下 Spring Cloud 版本: spring-cloud-starter-kubernetes 1.0.1.RELEASE spring-cloud-starter-gateway 2.1.1.RELEASE
我的演示应用程序可在https://github.com/nmaoez/spring-cloud-gateway-kubernetes获得,README.md 提供了将这两种服务部署在本地 Minikube 集群中的步骤。还显示了所有可用的端点。但有趣的部分是应用程序.yaml 和网关的应用程序类。
应用程序.yaml:
spring:
application:
name: gateway-service
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
management:
endpoints:
web:
exposure:
include: '*'
GatewayApplication.java
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class GatewayApplication {
@Autowired
RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/")
@ResponseBody
public String hello() {
return "GatewayApplication says hello!";
}
@GetMapping("/test")
@ResponseBody
public String invokeTestService() {
List<ServiceInstance> testServiceInstances = this.discoveryClient.getInstances("test-service");
return restTemplate.getForObject(testServiceInstances.get(0).getUri(), String.class);
}
@GetMapping("/services")
public List<String> services() {
return this.discoveryClient.getServices();
}
@GetMapping("/services/{serviceId}")
public List<ServiceInstance> servicesById(@PathVariable("serviceId") String serviceId) {
return this.discoveryClient.getInstances(serviceId);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
在将 gateway-service/application.yaml 中的 url-expression 字段覆盖为之后,我知道它是如何运行的
url-expression: "uri+'/'"
之后,我在调用后得到了正确的响应gateway-uri/another-service/
。但我的愿望是不明确替换lb://serviceid
. 我怎样才能做到这一点?
我希望如果我通过网关调用集群中的另一个服务,我会得到 200 响应和基于应用程序其余控制器的正确答案。