Implementing dynamic registration and discovery of microservices with Nest.js and Nacos.

Why is dynamic registration and discovery of microservices needed?

When the backend architecture becomes complex, a good solution is to use microservices for decoupling. Each service only develops the corresponding business functionality. If the service has a large traffic, it is also possible to deploy multiple servers.

After having many services, it involves questions like what services are there? Which instance under the service is good? And so on.

Dynamic registration is relatively easy to understand. When a service comes up, it automatically sends a notification to the service center: An instance of XX service is online!

Why is dynamic discovery necessary? I understand it from two perspectives:
  1. When a service has new nodes coming online or old nodes crashing, it is necessary to reroute the traffic to the operational nodes based on their status.
  2. If you need to develop corresponding routing rules every time a new service is added, wouldn’t that mean developing twice?

No matter what features are added, you can set a prefix, and I’ll just send it to you directly. How convenient is that!

What exactly is Nacos?

Nacos signifies a platform designed to streamline the creation of cloud-native applications. It offers features such as dynamic service discovery, configuration management, and service management, solidifying its spot in a developer’s toolbox. Originally developed by Alibaba, Nacos has gained immense popularity among Java-based microservices in China, largely due to the provision of a Java SDK by the official team. Microservice architectures across multiple languages, such as Go, Node.js, and Python can conveniently utilize Nacos. An API’s capabilities at the end of the day means it can seamlessly adapt to serve even non-microservices architectures. It can be utilized for various tasks such as interfacing with the configuration center or crafting a service state monitoring page, among others.

How does one facilitate dynamic registration and discovery in microservices?

In order to distinguish between services, we can do the following:

Nacos

Port: 8848

It offers functionality for both the configuration center and service center.

Gateway

Port: 3000

The Nest gateway service provides HTTP interfaces for access and forwards them to the respective microservices.

ms_aaa

Port: 4000

This is a Nest microservice. We’ve decided to forward traffic with paths beginning with ‘/aaa’ to this service.

ms_bbb

Port: 5000

Similarly, this is another Nest microservice. Traffic paths starting with ‘/bbb’ will be directed to this service.

Installation of Nacos

The Nacos software offers different means of installation; binary, Docker, and Kubernetes. The choice of mode is subjective to preference as installation, overall, is quite straightforward. Possessing a NAS allows me to initiate the Docker image directly in the Container Manager. For local testing, the environmental variable MODE should be set to ‘standalone,’ indicative of a single-node operation. The default, ‘cluster,’ implies a clustered set-up and demands the configuration of additional variables. It is suitable for formal environments with multi-container deployments. Database environments need not be populated for local testing courtesy of the built-in Derby sufficient for our testing use. Post successful installation, visit ‘http://ip:8848/nacos/ where you should observe the following:

Implementing dynamic registration and discovery of microservices with Nest.js and Nacos.

Establishing Nest.js Projects

Three projects will be created through commands. The project codes can be observed in the ‘example_nest_nacos’ repository.


nest new gateway

nest new ms_aaa

nest new ms_bbb

Microservice Renovation

The following operations are to be executed in both the ‘ms_aaa’ and ‘ms_bbb’ microservices.

1.Installing Dependent Packages

pnpm install @nestjs/microservices nacos-config nacos-naming

2.Adding the file ‘src/nacos.ts’ with the following code:

import { NacosConfigClient } from 'nacos-config';
import { NacosNamingClient } from 'nacos-naming';

const serverAddr = '192.168.28.28:8848';

export const startNacos = async (props) => {
 
  const {
    group = 'DEFAULT_GROUP',
    namespace = 'public',
    ip,
    port,
    serverName,
  } = props;

  const naming = new NacosNamingClient({
    logger: console,
    namespace,
    serverList: serverAddr,
  });

  await naming.ready();

  await naming.registerInstance(
    serverName,
    {
      enabled: true,
      healthy: true,
      instanceId: `${ip}:${port}`,
      ip, 
      port,
    },
    group,
  );

  naming.subscribe(serverName, (value) => {
    console.log('naming subscribe :>> ', value);
  });

  const config = new NacosConfigClient({
    namespace,
    serverAddr,
  });

  config.subscribe(
    {
      dataId: serverName,
      group,
    },
    (value) => {
      console.log('config subscribe :>> ', value);
    },
  );
};

3.Modifying the ‘src/main.ts’ file to reflect the following code:

import { NestFactory } from '@nestjs/core';
import { Transport } from '@nestjs/microservices';
import { AppModule } from './app.module';
import { startNacos } from './nacos';

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.TCP,
    options: {
      port: 4000, 
    },
  });

  startNacos({
    ip: 'localhost',
    port: 4000,
    serverName: 'ms_aaa',
  });

  await app.listen();
}
bootstrap();

4.Augmenting methods in ‘src/app.controller.ts’ for testing purposes

import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class AppController {
  // ...

  @MessagePattern('hello')
  hello(): string {
    return 'hello from ms_aaa';
  }
}

After executing the ‘pnpm run start:dev’ command, one should be able to observe the two services in Nacos.

Implementing dynamic registration and discovery of microservices with Nest.js and Nacos.

END
 0
Comment(No Comments)