Using Sidecar to introduce Node.js into Spring Cloud

theory

brief introduction

Spring Cloud is a popular micro service solution at present. It combines the convenient development of Spring Boot with the rich solution of Netflix OSS. As we all know, Spring Cloud is different from Dubbo and uses Rest services based on HTTP (s) to build the whole service system.

Is it possible to develop some Rest services using some non JVM languages, such as Node.js, which we are familiar with? Yes, of course. However, if only Rest services are available, it is not possible to access the Spring Cloud system. We also want to use the Eureka provided by Spring Cloud for service discovery, use Config Server to do configuration management, and use Ribbon to do client load balancing. At this point, Spring sidecar will be able to show its talents.

Sidecar originated from Netflix Prana. He provides a HTTP API that allows access to all instances of established services, such as host, ports, etc. You can also use an embedded Zuul proxy service to get the relevant routing nodes from Eureka. Spring Cloud Config Server can be accessed directly through the host or through proxy Zuul.

Netflix Prana

What you need to be aware of is the Node.js application you have developed, and you have to implement a health check interface to allow Sidecar to report the health of this service instance to Eureka.

In order to use Sidecar, you can create a Spring Boot program with @EnableSidecar annotation. Let’s look at what this annotation has done.

@EnableSidecar

@EnableCircuitBreaker

Look, hystrix fuse, Eureka service discovery, zuul agent, all of these components have been opened.

Health examination

Next, we need to add the configuration of sidecar.port and sidecar.health-uri in application.yml. The sidecar.port attribute represents the port of the Node.js application listener. This is to enable sidecar to register in Eureka services. sidecar.health-uri is a URI that simulates the interface of Spring Boot application health indicators. It must return the following form of JSON document: health-uri-document

Sidecar.port

Sidecar.health-uri

Sidecar.port

Sidecar.health-uri

Health-uri-document

{

The application.yml of the entire Sidecar application is as follows: application.yml

Application.yml

Application.yml

Server:

Service access

After building this application, you can use the /hosts/{serviceId} API to get the result of DiscoveryClient.getInstances () . Here is an example of returning two instances of information from different /hosts/customers from host. If sidebar runs on the 5678 port, then the Node.js application can access the API via the http://localhost:5678/hosts/{serviceId}.

/hosts/{serviceId}

DiscoveryClient.getInstances ()

/hosts/customers

Http://localhost:5678/hosts/{serviceId}

/hosts/customers

[

Zuul proxy can automatically be registered to the Eureka association to /< serviceId> services add routing, so the customer service can be accessed via the /customers URI. It is also assumed that sidecar is listening on the 5678 port, so our Node.js application can access the customer service by http://localhost:5678/customers.

/< serviceId>

/customers

Http://localhost:5678/customers

Config Server

If we use the Config Server service and register it to Eureka, Node.js application can access it through Zull Proxy. If ConfigServer’s serviceId is configserver and Sidecar listens on the 5678 port, then it can be accessed through the

So the whole architecture of Node.js application accessing to Spring Cloud micro service cluster through Sidecar is roughly shown as follows:

Demo practice

Let’s suppose that there is such a very simple data. It is called User:

Class User {

It looks very classic, Kazakhstan!

Another data structure is used to represent books, Book:

Class Book {

The authorId in Book corresponds to the ID of User. Now we need to develop Rest services for these two data.

First, User, we use spring to develop, first in the controller construction method, mock some false data users, and then a very simple Get interface based on the ID user.

@GetMapping (“/{id}”)

After starting, we curl visited:

Curl localhost:8720/12

Next, we use Node.js to develop Book related interfaces.

Because the Node.js community is very active, the optional Rest service framework is very large. The mainstream is express, koa, hapi, and so on, very light and easy to extend like connect. Here I consider the mass base and document richness, and choose to use to develop such a Rest service that can access Spring Cloud.

Express

KOA

Hapi

Connect

Express

Const express = require (‘express’)

It is also first to use faker to the mock100 bar data, and then write a simple get route.

Now that we have two micro services, next we launch a Sidecar instance to connect Node.js to Spring Cloud.

@SpringBootApplication

Very simple, it needs to be noted that before this, you need a eureka-server to test the ability of the sidecar agent to access Spring Config, and I also use config-server, believing that students who are familiar with spring cloud should know.

In the configuration of sidecar, bootstrap.yaml simply specifies the address of the service port and the config-server, and the node-sidecar.yaml configuration is as follows:

Node-sidecar.yaml

Eureka:

The address of the node.js service directed by sidecar is specified here, and hystrix.command.default.execution.timeout.enabled: false is mainly because sidecar uses hystrix’s default timeout fuse for a second, and the speed of domestic access to GitHub, as you know, I often visit config-server when I test the test, so I often go out of time, so I dropped it with disable, and you could choose to extend the overtime time.

Hystrix.command.default.execution.timeout.enabled: false

When eureka-server, config-server, user-service, node-sidecar, node-book-service are all started, we open the main page of Eureka

You can see the information in the return information such as the URI of the Node.js application, so is it possible that we can first access the sidecar’s interface, and then get the real URI, and then call book-service’s /books? Uid=< uid> the interface? Of course, in fact, there’s already a tool for spring cloud to do this for us, that is, Feign, new BookFeighClient.java:

/books? Uid=< uid>

Feign

BookFeighClient.java

@FeignClient (name = “node-sidecar”)

FeignClient can automatically find the corresponding service address on the serviceId to Eureka. If there are more than one instance of the service, the client load balance will be used by Ribbon, and a number of RequestMapping – like annotations can be used to keep the client in line with the server controller. By defining this findByUid method, we can easily call the /books? Uid=&lt, uid> interface defined in the above Node.js. This is also consistent with the sidecar schema we painted above.

FeignClient

RequestMapping

FindByUid

/books? Uid=< uid>

Now, we define a new type of Author in user-service, which inherits from User and adds a books field:

Class Author extends User {

Add an interface to get Author:

@GetMapping (“/author/{id}”)

Logic is also very simple, get the corresponding user, get books from bookFeignClient from uid, and then build author to return.

Well, so far, we have completed the JAVA and Node.js two languages with the help of sidecar and general HTTP protocol to complete the process of calling each other. For more similar configuration information from config-server, access to application information from Eureka and other operations, you can download the source code of my experiment to understand.

I put the whole DEMO in my GitHub, you can directly clone down.

Git clone https://github.com/marshalYuan/spring-cloud-example.git

The whole project is roughly the same:

eureka-server / / corresponds to the Eureka Server

above.

Eureka-server / / / / Eureka Server for the above figure

Config-server / / / / Config Server for the above figure

SearchPath of config-repo //config-server warehouse address

The services developed by user-service //java are both service providers (Provider) and consumers (Coustomer).

In this order, these five applications are started, because demo is used for testing, so I have no bug.

Write at the end

As the opening point says, thanks to the general Http protocol and the Netflix rich suite, we can connect many non JVM languages such as Node.js, PHP, and Python to the very mature micro service framework of Spring Cloud to quickly build our micro service business system. You might say why not all use Java? Indeed, the cost of developing and maintaining a single language in a single system is much lower, but there are other situations worth our choosing the sidecar solution.

For example, the burden of history is too heavy to be cut to the Java platform, but it does not want to rewrite the services of the past, so that it can be integrated at the cost of a unified protocol, from Java to other platforms.

There is also a saying called “hugging the language dividend”. Choosing a development language means choosing a tool and library corresponding to the programming language. For example, it is now popular to use Python to do data analysis, then the service of this part of the micro service system can be developed with Python; the asynchronous event driver mechanism of Node.js is excellent, and can it be used to develop some services that need to deal with a large number of asynchronous requests; and so on. This is not really triggering the “best language Jihad”. It is thought that the comparison between the advantages and disadvantages of language from the use of scenarios and ecology is to play gangsters. Take all as an example, and I don’t think there is any language that can be understood as simple as the code of Haskell.

Pythagorean triple

[(x, y, z) x < – [1..100], y < – [x..100], Z < – Z, + + = = =]

Besides, our title is Node.js, and the best language is PHP. Escape ~ ~ ~