skip to Main Content

I’m getting a NotFoundException: 503 SERVICE_UNAVAILABLE exception in the gateway-server logs. I’m running microservices in docker containers. I have an auth-service microservice which handles authentication and Jwt. I can connect directly to the auth-service using Postman and register, validate and receive tokens via the auth-service’s AuthController. However, using the gateway causes the 503 error. Since the problem is with the gateway, I will highlight pertinent gateway code:

SecurityConfig


package com.microservices.gatewayserver.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
//Configures security settings for the gateway server. Authentication uses JWT tokens
//    for the pathMatchers and disables CSRF protection.
    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http.authorizeExchange(exchanges -> exchanges
                        .pathMatchers("/login-service/**").authenticated()
                        .pathMatchers("/employee-service/**").authenticated()
                        .pathMatchers("/registration-service/**").authenticated()
                        .pathMatchers("/auth-service/**").permitAll())
                        //.pathMatchers("/actuator/**").permitAll())
                .oauth2ResourceServer()
                .jwt();
        http.csrf().disable();
        return http.build();
    }

}

GatewayServerApplication

package com.microservices.gatewayserver;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
@EnableDiscoveryClient
@LoadBalancerClient(name= "auth-service")
public class GatewayServerApplication {

   public static final Logger LOGGER = LoggerFactory
           .getLogger(GatewayServerApplication.class);

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

application.yml

server:
  port: 8097

spring:
  application:
    name: gateway-service
  output:
    ansi:
      enabled: always
  cloud:
    config:
      enabled: false
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: auth-service
          uri: lb://auth-service
          predicates:
            - Path=/auth-service/**
          filters:
            - RewritePath=/auth-service/(?<path>.*), /${path}

        - id: employee-service
          uri: lb://employee-service
          predicates:
            - Path=/employee/**
          filters:
            - RewritePath=/employee/(?<path>.*), /${path}

        - id: login-service
          uri: lb://login-service
          predicates:
            - Path=/login/**
          filters:
            - RewritePath=/login/(?<path>.*), /${path}

        - id: registration-service
          uri: lb://registration-service
          predicates:
            - Path=/registration/**
          filters:
            - RewritePath=/registration/(?<path>.*), /${path}

        - id: openapi
          uri: http://localhost:${server.port}
          predicates:
            - Path=/v3/api-docs/**
          filters:
            - RewritePath=/v3/api-docs/(?<path>.*), /${path}/v3/api-docs

  main:
    web-application-type: reactive

  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: http://localhost:7080/realms/master/protocol/openid-connect/certs
eureka:
  client:
    serviceUrl:
      defaultZone: http://discovery-service-container:8761/eureka/

springdoc:
  swagger-ui:
    urls:
      - name: auth
        url: /v3/api-docs/auth
      - name: employee
        url: /v3/api-docs/employee
      - name: login
        url: /v3/api-docs/login
      - name: registration
        url: /v3/api-docs/registration

logging:
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%X{traceId:-},%X{spanId:-}] ${LOG_LEVEL_PATTERN:-%5p} %m%n"
  level:
    springframework:
      boot:
        autoconfigure: DEBUG
    web: DEBUG
    root: DEBUG



POM

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <artifactId>gateway-server</artifactId>
    <version>3.0.6-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>17</java.version>
        <spring-cloud.version>2022.0.2</spring-cloud.version>
        <sonar.moduleKey>${project.artifactId}</sonar.moduleKey>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-tracing-bridge-otel</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-exporter-zipkin</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
            <version>2.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-resource-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-jose</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>io.micrometer</groupId>
                <artifactId>micrometer-tracing-bom</artifactId>
                <version>${micrometer-tracing.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>


</project>

Stacktrace

2023-05-25 05:45:20 [,] -DEBUG Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/auth-service/**', method=null}
2023-05-25T05:45:20.457679873Z 2023-05-25 05:45:20 [,] -DEBUG Checking match of request : '/auth-service/register'; against '/auth-service/**'
2023-05-25T05:45:20.457699175Z 2023-05-25 05:45:20 [,] -DEBUG matched
2023-05-25T05:45:20.457742344Z 2023-05-25 05:45:20 [,] -DEBUG Checking authorization on '/auth-service/register' using org.springframework.security.config.web.server.ServerHttpSecurity$AuthorizeExchangeSpec$Access$$Lambda$648/0x00000008010ce248@1b9bc02
2023-05-25T05:45:20.458327743Z 2023-05-25 05:45:20 [,] -DEBUG Authorization successful
2023-05-25T05:45:20.459204178Z 2023-05-25 05:45:20 [,] -DEBUG Route matched: auth-service
2023-05-25T05:45:20.459229258Z 2023-05-25 05:45:20 [,] -DEBUG Mapping [Exchange: POST http://localhost:8097/auth-service/register] to Route{id='auth-service', uri=lb://auth-service, order=0, predicate=Paths: [/auth-service/**], match trailing slash: true, gatewayFilters=[[[RewritePath /auth-service/(?<path>.*) = '/${path}'], order = 1]], metadata={}}
2023-05-25T05:45:20.459233539Z 2023-05-25 05:45:20 [,] -DEBUG [afe63e91-2] Mapped to org.springframework.cloud.gateway.handler.FilteringWebHandler@363dab18
2023-05-25T05:45:20.459345964Z 2023-05-25 05:45:20 [,] -DEBUG Sorted gatewayFilterFactories: [[GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.RemoveCachedBodyFilter@6a74d228}, order = -2147483648], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@720653c2}, order = -2147482648], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@36bc415e}, order = -1], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.ForwardPathFilter@3e134896}, order = 0], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.GatewayMetricsFilter@2e3a5237}, order = 0], [[RewritePath /auth-service/(?<path>.*) = '/${path}'], order = 1], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@349d0836}, order = 10000], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@301d8120}, order = 10150], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.LoadBalancerServiceInstanceCookieFilter@6d367020}, order = 10151], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@72ba28ee}, order = 2147483646], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyRoutingFilter@72458efc}, order = 2147483647], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.ForwardRoutingFilter@6a714237}, order = 2147483647]]
2023-05-25T05:45:20.460796164Z 2023-05-25 05:45:20 [,] - WARN No servers available for service: auth-service
2023-05-25T05:45:20.461939954Z 2023-05-25 05:45:20 [,] -DEBUG [afe63e91-2] Resolved [NotFoundException: 503 SERVICE_UNAVAILABLE "Unable to find instance for auth-service"] for HTTP POST /auth-service/register
2023-05-25T05:45:20.462477063Z 2023-05-25 05:45:20 [,] -DEBUG [afe63e91-2] Encoding [{timestamp=Thu May 25 05:45:20 GMT 2023, path=/auth-service/register, status=503, error=Service Unav (truncated)...]
2023-05-25T05:45:20.467139970Z 2023-05-25 05:45:20 [,] -DEBUG [afe63e91-2, L:/172.27.0.9:8097 - R:/172.27.0.1:58344] Decreasing pending responses, now 0
2023-05-25T05:45:20.468226365Z 2023-05-25 05:45:20 [,] -DEBUG [afe63e91-2] Completed 503 SERVICE_UNAVAILABLE
2023-05-25T05:45:20.468294940Z 2023-05-25 05:45:20 [,] -DEBUG [afe63e91-2, L:/172.27.0.9:8097 - R:/172.27.0.1:58344] Last HTTP response frame

2

Answers


  1. you need to use a service discovery like netflix eureka to register your applications like auth service in this service and gateway can find auth service by name ->

    routes:
    – id: auth-service
    uri: lb://auth-service
    predicates:
    – Path=/auth-service/**
    filters:
    – RewritePath=/auth-service/(?.*), /${path}

    I think maybe somehow if you define DNS in your docker and setting the auth service name to the auth service ip and port no need to using discovery service

    Login or Signup to reply.
  2. The log traces you’ve shared suggest that your application is attempting to connect to a service labeled ‘auth-service’, but it can’t find any instances of that service. This scenario is typically seen in microservices architectures, where services discover each other using tools like Netflix’s Eureka or Kubernetes service discovery.

    Looking at the message "No servers available for service: auth-service", it seems that the service discovery component (likely Eureka, based on your POM file) isn’t able to locate any registered ‘auth-service’ instances.

    Here’s a list of potential issues that you might want to investigate:

    1. Confirm whether the ‘auth-service’ is currently operational. If it’s not, you’ll need to get it running.

    2. If the ‘auth-service’ is indeed running, ensure that it’s properly registered with the service discovery component (possibly Eureka). To verify this, you can check the Eureka dashboard or inspect the logs from ‘auth-service’.

    3. Make sure that ‘auth-service’ and the gateway are on the same network. If they aren’t, network issues might prevent service discovery from functioning correctly.

    4. Review the ‘auth-service’ configuration. It should be set up with the correct Eureka server address, and its instance name should be ‘auth-service’.

    5. Sometimes, the issue can be a matter of timing. One service might start and try to discover other services before they’ve had a chance to register with the service discovery tool. In such a case, implementing a retry mechanism or ensuring services start in the right order might help.

    If you’re still experiencing issues after checking these potential problems, please share more information or context about your setup so that I can provide more targeted assistance.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search