I'm working on a microservices architecture just on spring and kubernetes. Right now I'm working on the gateway microservice. During the startup of the microservice I have the following error at runtime:
Blockquote
2020-01-15 11:00:57.312 ERROR 1 --- [ elastic-4] reactor.core.scheduler.Schedulers : Scheduler worker in group main failed with an uncaught exception
reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IllegalStateException
Caused by: java.lang.IllegalStateException: null
at java.util.Optional.orElseThrow(Optional.java:290) ~[na:1.8.0_212]
at org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClient.findEndpointPort(KubernetesDiscoveryClient.java:218) ~[spring-cloud-kubernetes-discovery-1.1.1.RELEASE.jar!/:1.1.1.RELEASE]
at org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClient.getNamespaceServiceInstances(KubernetesDiscoveryClient.java:161) ~[spring-cloud-kubernetes-discovery-1.1.1.RELEASE.jar!/:1.1.1.RELEASE]
at org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClient.getInstances(KubernetesDiscoveryClient.java:118) ~[spring-cloud-kubernetes-discovery-1.1.1.RELEASE.jar!/:1.1.1.RELEASE]
at org.springframework.cloud.kubernetes.discovery.reactive.KubernetesReactiveDiscoveryClient.lambda$getInstances$0(KubernetesReactiveDiscoveryClient.java:58) ~[spring-cloud-kubernetes-discovery-1.1.1.RELEASE.jar!/:1.1.1.RELEASE]
at reactor.core.publisher.FluxDefer.subscribe(FluxDefer.java:46) ~[reactor-core-3.3.2.RELEASE.jar!/:3.3.2.RELEASE]
at reactor.core.publisher.FluxSubscribeOn$SubscribeOnSubscriber.run(FluxSubscribeOn.java:194) ~[reactor-core-3.3.2.RELEASE.jar!/:3.3.2.RELEASE]
at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84) ~[reactor-core-3.3.2.RELEASE.jar!/:3.3.2.RELEASE]
at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37) ~[reactor-core-3.3.2.RELEASE.jar!/:3.3.2.RELEASE]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_212]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_212]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[na:1.8.0_212]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_212]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_212]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_212]
2020-01-15 11:00:57.481 INFO 1 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port(s): 9080
2020-01-15 11:00:57.485 INFO 1 --- [ main] i.m.gateway.GatewayApplication : Started GatewayApplication in 7.941 seconds (JVM running for 8.67)
Blockquote
The problem appeared with the move to kubernetes service discovery by adding the spring-cloud-starter-kubernetes dependency. By using another service discovery such as eureka or consul the gateway works correctly. Below is the pom:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>
<groupId>it.milionaires</groupId>
<artifactId>gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway</name>
<description>Gateway service</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!--Dipendenza per gateway spring-->
<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-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>3.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</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>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.13</version>
<executions>
<execution>
<id>tag-latest</id>
<goals>
<goal>build</goal>
<goal>tag</goal>
<goal>push</goal>
</goals>
<configuration>
<repository>gateway</repository>
<tag>latest</tag>
</configuration>
</execution>
<execution>
<id>tag-version</id>
<goals>
<goal>build</goal>
<goal>tag</goal>
<goal>push</goal>
</goals>
<configuration>
<repository>gateway</repository>
<tag>${project.version}</tag>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Has anyone encountered this problem or know how to fix it? Thanks in advance This is my deployment.yml :
apiVersion: apps/v1
kind: Deployment
metadata:
name: gateway-deployment
labels:
app: gateway
spec:
replicas: 1
selector:
matchLabels:
app: gateway
template:
metadata:
labels:
app: gateway
spec:
containers:
- name: gateway
image: liviucornel/gateway
ports:
- containerPort: 9080
---
apiVersion: v1
kind: Service
metadata:
name: gateway
spec:
selector:
app: gateway
ports:
- port: 9080
targetPort: 9080
# nodePort: 30010
type: ClusterIP
This is the property file :
server:
port: 9080
spring:
application:
name: gateway
profiles:
active: zone2
cloud:
loadbalancer:
ribbon:
enabled: false
config:
uri: http://configuration-server
failFast: false
discovery:
service-id: configuration-server
enabled: true
retry:
maxAttempts: 20
enabled: true
request-connect-timeout: 500
request-read-timeout: 500
kubernetes:
discovery:
service-name: gateway
primary-port-name: 9080
enabled: true
all-namespaces: true
gateway:
routes:
- id : servizio1
uri : lb://servizio1
predicates :
- Path=/servizio1/**
filters :
- RewritePath=/servizio1/servizio1/(?<path>.*), /$\{path}
# - name : ServiceGatewayPreFilter
# - name : ServiceGatewayPostFilter
- id: servizio2
uri: lb://servizio2
predicates:
- Path=/servizio2/**
filters:
- RewritePath=/servizio2/servizio2/(?<path>.*), /$\{path}
default-filters:
- name : ServiceGatewayGlobalFilter
discovery:
locator:
enabled: true
This is the docker file :
FROM openjdk:8-jdk-alpine
MAINTAINER Liviu <liviucornelciobanu91@gmail.com>
# Add a volume pointing to /tmp
VOLUME /tmp
# Make port 9080 available to the world outside this container
EXPOSE 9080
# The application's jar file
ARG JAR_FILE=target/gateway-0.0.1-SNAPSHOT.jar
# Add the application's jar to the container
ADD ${JAR_FILE} gateway.jar
# Run the jar file
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/gateway.jar"]
I have found the solution for my problem. The problem was with the DiscoveryClient Route Definition Locator on spring-cloud-gateway. I saw in the documentation that:
"The Gateway can be configured to create routes based on services registered with a DiscoveryClient compatible service registry. To enable this, set spring.cloud.gateway.discovery.locator.enabled=true and make sure a DiscoveryClient implementation is on the classpath and enabled (such as Netflix Eureka, Consul or Zookeeper)."
This properties doesn't work with Kubernate configuration Service Discovery. I have changed it to False and it worked!! Greetings