Facebook EmaiInACirclel
Software Development

How to Combat Node.js Microservices ‘Shell Hell’ with Fuge.io

PentaGuy
PentaGuy
Blogger

When developing microservices in Node.js or any other language, you need to spinoff multiple processes and this usually signifies multiple console terminals. A useful tool that helps solve these issues is fuge.

In this tutorial, we will investigate a simple microservice system and then display the powerful features of fuge.io service.

Node.js Microservices

Fuge provides an execution environment for developing microservice systems, eliminating shell hell and significantly reducing developer friction.

Summary

Fuge – is a very handy microservice oriented development tool whose main objective is to solve the problems of maintaining big numbers of shell terminals, otherwise known as “shell hell”. 

Vivacious Ants

The system we are going to build is called Vivacious-Ants, – it’s based on a very cool problem that I enjoyed solving called Dead Ants.

The idea behind the problem is that we are given a string in the form of:

..ant..ant.ant...ant.ant..ant.ant....ant..ant.ant.ant...ant..// the answer to this one is zero dead ants
ant ant .... a nt// 1 dead ant

And, we are given the task to count how many ants have died.

Our microservice system will have the following structure:

vivacious-ants/  antscounter/  analytics/  app/  fuge.yml

We have 2 microservices and an express application generated with express-generator as frontend.

(The full code for the solution can be found on github as in this post I’ll focus more on fuge.io configuration and features.) 

Fuge Configuration

Let’s analyze the file fuge.yml from vivacious-ants directory:

# fuge.ymlfuge_global:  tail: true  run_containers: false  monitor: true  monitor_excludes:    - '**/node_modules/**'    - '**/.git/**'    - '**/*.log/'antscounter:  type: node  path: ./antscounter  run: 'node index.js'  ports:    - main=8080analytics:  type: node  path: ./analytics  run: 'node index.js'  ports:    - main=8081webbapp:  type: node  path: ./webapp  run: 'node ./bin/www'  ports:    - main=3000mongo:  image: mongo  type: container  ports:    - main=27017:27017

Fuge is configured by providing a config.yml file, the configuration seems very intuitive and I was pleasantly surprised by the simplicity and robustness of the system.

The fuge configuration starts with fuge_global:

  • tail: true will join all the logs from microservices into your main terminal. This is very handy when you are connecting different microservices and need to debug them.
  • monitor: true – will restart the microservices every time you make a change in the code. Fuge is using (chokidar), a super fast alternative to fs.watch Node.js module with a lot more features.
  • run_containers: false – this will allow the Docker containers like mongodb, or mysql, to be managed by the user.  This will be useful when you reuse the Docker services across different projects.

Then, we define all our microservices by providing a name like antscounter, analytics. The name of the microservice is very important because fuge will generate some environment variables for us in the following form:

antscounter:  type: node  path: ./antscounter  run: 'node index.js'  ports:    - main=8080

This will generate 2 environment variables: 

 const {   ANTSCOUNTER_SERVICE_HOST, // 127.0.0.1   ANTSCOUNTER_SERVICE_PORT, // 8080 } = process.env;

You can check the envars created by running this command: 

fuge> info webapp full

And, the output will be: 

ANTSCOUNTER_SERVICE_HOST=127.0.0.1  ANTSCOUNTER_SERVICE_PORT=8080  ANTSCOUNTER_PORT=tcp://127.0.0.1:8080  ANTSCOUNTER_PORT_8080_TCP=tcp://127.0.0.1:8080  ANTSCOUNTER_PORT_8080_TCP_PROTO=tcp  ANTSCOUNTER_PORT_8080_TCP_PORT=8080  ANTSCOUNTER_PORT_8080_TCP_ADDR=127.0.0.1  ANALYTICS_SERVICE_HOST=127.0.0.1  ANALYTICS_SERVICE_PORT=8081  ANALYTICS_PORT=tcp://127.0.0.1:8081  ANALYTICS_PORT_8081_TCP=tcp://127.0.0.1:8081  ANALYTICS_PORT_8081_TCP_PROTO=tcp  ANALYTICS_PORT_8081_TCP_PORT=8081  ANALYTICS_PORT_8081_TCP_ADDR=127.0.0.1  WEBBAPP_SERVICE_HOST=127.0.0.1  WEBBAPP_SERVICE_PORT=3000  WEBBAPP_PORT=tcp://127.0.0.1:3000  WEBBAPP_PORT_3000_TCP=tcp://127.0.0.1:3000  WEBBAPP_PORT_3000_TCP_PROTO=tcp  WEBBAPP_PORT_3000_TCP_PORT=3000  WEBBAPP_PORT_3000_TCP_ADDR=127.0.0.1  MONGO_SERVICE_HOST=127.0.0.1  MONGO_SERVICE_PORT=27017  MONGO_PORT=tcp://127.0.0.1:27017  MONGO_PORT_27017_TCP=tcp://127.0.0.1:27017  MONGO_PORT_27017_TCP_PROTO=tcp  MONGO_PORT_27017_TCP_PORT=27017  MONGO_PORT_27017_TCP_ADDR=127.0.0.1  SERVICE_HOST=127.0.0.1  SERVICE_PORT=8080

The structure {MICROSERVICENAME}_SERVICE_HOST, {MICROSERVICENAME}_SERVICE_PORT is used also by kubernetes and docker-swarm. So, the interface will be practically the same when deploying our microservices.

System Init

  • git clone vivacious-ants
  • Go to vivacious-ants directory and start the fuge shell.
bash> fuge shell fuge.yml # will start the shell for all the microservicesfuge> apply npm install # will run npm install for every microservicefuge> start all
  • After running:
 fuge> ps

You should get something like:

name                          type           status         watch          tailantscounter                   node           running        yes            yesanalytics                     node           running        yes            yeswebapp                        node           running        yes            yesmongo                         container      not managed

Usage

  • Ants home page http://localhost:3000/
  • Ants analytics http://localhost:3000/analytics

Conclusions

We learned about the main features of fuge.io, which helps a lot during the development process of microservices in node.js.

Advice! Do not use the fuge in production. It is not meant for that and is purely a dev tool.

When you learn how to use it your life as a Node.js developer will become much easier.

Learn more about Node.js and learn to write your own microservices with Node.js from Pentalog & SkillValue’s dedicated events in Romania and Moldova! Sign up here

Test your technical knowledge by taking this NodeJS quiz.


Leave a Reply

Your email address will not be published. Required fields are marked *