Search code examples
microservicesnetflix-eurekaspring-cloud-gatewayeureka-js-client

Can't reach NodeJS microservice through Spring Cloud Gateway + Eureka


I use a microservices architecture in the backend where I have services created using TypeScript and others using Java. Also I have a Spring Gateway and an Eureka server (both using Spring).

Then, Gateway works fine, Eureka works fine and also others microservices written in Java work fine too. The problem is when I try to reach the TypeScript microservice accross the Gateway.

I have a simple Eureka Server using the annotation @EnableEurekaServer in Spring.

Also a Gateway connected to Eureka as client where the yaml has this part:

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lowerCaseServiceId: true
      routes:
        - id: ms1
          uri: lb://ms1
          predicates:
            - Path=/ms1/**
        - id: ms2
          uri: lb://ms2
          predicates:
            - Path=/ms2/**

With this Gateway I want to have two routes /ms1 and /ms2 to access the microservice1 (written in TS) or microservice2 (written in Java).

When I run all services, Eureka is shown like this: enter image description here

You can see the gateway, ms1 and ms2. But, why Java services has 192.168.8.121 and TS service not?

By the way, the links work ok, every service is routed to the port where exists, Gateway and Java microservice are routed to <gateway_url>:<service_port>/actuator/info and TypeScript microservice is routed to localhost:<service_port>.

Microservice2 is so simple:

@RestController
public class Controller {
    @GetMapping("/hello-world")
    public ResponseEntity<String> getHi() {
        return ResponseEntity.ok("hi");
    }
}

And also into application.yml:

spring:
  application:
    name: ms2

But TS microservice uses eureka-js-client with this configuration:

this._client = new Eureka({
                instance: {
                    app: 'ms1',
                    instanceId: 'ms1',
                    hostName: 'localhost',
                    ipAddr: '127.0.0.1',
                    statusPageUrl: `http://localhost:8081`,
                    healthCheckUrl: `http://localhost:8081/health`,
                    port: {
                        '$': 8081,
                        '@enabled': true,
                    },
                    vipAddress: 'myvip',
                    dataCenterInfo: {
                        '@class': 'com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo',
                        name: 'MyOwn',
                    },
                },
                eureka: {
                    host: 'localhost',
                    port: 8761,
                    servicePath: '/eureka/apps/'
                },
            })

So, my idea is:

  • When I hit <gateway_url>:<gateway_port>/ms1/hello-world it appears the data from TypeScript microservice.
  • When I hit <gateway_url>:<gateway_port>/ms2/hello-world it appears the data from Java microservice.

The second one works fine, but the route http://192.168.8.121:8762/ms1/hello-world returns a 503 error:

Whitelabel Error Page

This application has no configured error view, so you are seeing this as a fallback.
Mon May 16 19:02:56 CEST 2022
[fa1d8857-5] There was an unexpected error (type=Service Unavailable, status=503).

And console says No servers available for service: ms1.

So I don't know if I'm misunderstanding something, the name from eureka-js-client is ms1. The LB is to that service... but it not works.

As I've said, with a Java service works fine, so maybe the problem is the way the service connect to Eureka, the name who uses or something like that? But in the dashboard it appears as MS1 and MS2 so I'm confused...

Thanks in advance


Solution

  • Solved my issue, it was a weird thing.

    My vipAddress was not correct. It seems Spring Cloud Gateway checks for the instance.vipAddress instead of instance.app.

    So replacing myvip with ms1 it works perfectly.