gpt4 book ai didi

spring-boot - 如何设置 Spring Cloud Gateway 应用程序以便它可以使用 Spring Cloud Kubernetes 的服务发现?

转载 作者:行者123 更新时间:2023-12-03 19:29:11 25 4
gpt4 key购买 nike

我创建了两个 Spring Boot 应用程序,它们都将部署在 Kubernetes 集群中。其中一个应用程序将充当网关,因此使用 Spring Cloud Gateway 作为依赖项。另外我想将服务发现与 Spring Cloud Kubernetes 集成,网关使用服务发现来自动生成相应的路由。但是,当我公开在本地 Minikube 集群中运行的网关应用程序并调用第二个应用程序/服务时,我收到 503 错误并显示以下消息:Unable to find instance for ...-service
目前我已经安装了以下内容:

  • Minikube
  • VirtualBox
  • Docker 工具箱

  • 我创建了一个包含两个子项目(网关和另一个服务)的 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 集群中部署这两个服务的步骤。还显示了所有可用的端点。但有趣的部分是 application.yaml 和网关的应用程序类。

    应用程序.yaml:
    spring:
    application:
    name: gateway-service
    cloud:
    gateway:
    discovery:
    locator:
    enabled: true
    lower-case-service-id: true
    management:
    endpoints:
    web:
    exposure:
    include: '*'

    网关应用程序

    @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 响应和基于应用程序其余 Controller 的正确答案。

    最佳答案

    我刚刚使用 Spring Cloud Gateway 和 Kubernetes 实现了一个示例应用程序,它在 Docker Desktop 中的作用就像一个魅力。不需要额外或有趣的配置。
    如果它可以帮助这是我的 build.gradle :

    plugins {
    id 'org.springframework.boot' version '2.4.2'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
    }

    group = 'com.example'
    version = '0.1.0-SNAPSHOT'

    repositories {
    mavenCentral()
    maven { url 'https://repo.spring.io/milestone' }
    }

    ext {
    set('springCloudVersion', "2020.0.0")
    set('springCloudKubernetesVersion', '1.1.7.RELEASE')
    set('springCloudVersion', '2020.0.0')
    }

    dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
    implementation 'org.springframework.cloud:spring-cloud-starter-sleuth'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    implementation "org.springframework.cloud:spring-cloud-starter-kubernetes:$springCloudKubernetesVersion"
    implementation "org.springframework.cloud:spring-cloud-starter-kubernetes-config:$springCloudKubernetesVersion"
    implementation "org.springframework.cloud:spring-cloud-starter-kubernetes-ribbon:$springCloudKubernetesVersion"
    implementation "org.springframework.cloud:spring-cloud-starter-kubernetes-loadbalancer:$springCloudKubernetesVersion"
    }

    dependencyManagement {
    imports {
    mavenBom "org.springframework.cloud:spring-cloud-dependencies:$springCloudVersion"
    }
    }

    test {
    useJUnitPlatform()
    }
    这是来自 application.yaml 的配置:
    spring:
    cloud:
    gateway:
    discovery:
    locator:
    enabled: true
    最后, DiscoveryClient在应用程序中启用:
    @SpringBootApplication
    @EnableDiscoveryClient // So services can be discovered
    public class GatewayApplication {

    public static void main(String[] args) {
    SpringApplication.run(GatewayApplication.class, args);
    }

    }
    请注意,正如 Jakub Kubrynski 所说,您必须包含 Ribbon 依赖项。
    还要注意路由仅在网关部署到 K8s 集群时才有效。在它之外,它可以看到 K8s 服务,但无法路由到它们,因为它们使用的是 K8s 网络中的 IP 地址。

    关于spring-boot - 如何设置 Spring Cloud Gateway 应用程序以便它可以使用 Spring Cloud Kubernetes 的服务发现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56170511/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com