Microservices avec @SenecaJS chez @Clever_Cloud - PART I
Les origines de cet articles
Pour cette annĂ©e 2017, jâai dĂ©cidĂ© de me remettre Ă lâIOT et en cherchant les plateformes opensource(s?) de gestion dâobjets connectĂ©s, provisionning, ⊠(en gros, un application web qui vous affiche la liste de vos objets connectĂ©s, les donnĂ©es associĂ©es, des graphiques temps rĂ©els, qui vous permet dâajouter des objets, dans dĂ©couvrir, âŠ) je nâai rien trouvĂ© qui me corresponde rĂ©ellement, qui soit facile Ă utiliser, Ă âcoderâ et Ă hĂ©berger. Mon modĂšle câest thingworx ⊠Mais ce nâest pas opensource. Donc finalement, pourquoi ne pas faire ma propre plateforme? Ok, câest ambitieux, mais câest bien dâavoir un âside projectâ avec un âvrai sujetâ et câest formateur. En effet, au cours de ma quĂȘte et de mes rĂ©flexions jâai notamment dĂ©cidĂ© dâutiliser le concept de microservices qui me semble bien se prĂȘter Ă mes besoins de construction dâune plateforme modulaire, Ă©volutive, âŠ
đ Vous pouvez lire la partie II ici: http://k33g.github.io/2017/01/15/MICROSERVICES-ON-CC2.html
Micro services?
Alors, cet article nâest pas un dossier sur les microservices, mais plutĂŽt le journal de mes expĂ©rimentations avec les microservices.
Pour une prĂ©sentation sympa je vous engage Ă lire lâarticle paru dans Programmez paru en DĂ©cembre 2015, Ă©crit par 2 consultants de chez Xebia: Les nouvelles architectures logicielles.
Pour moi, rapidement, un microservice, câest une fonction ou un ensemble de fonctions que jâappelle de mon programme principal, mais qui ne sont pas localisĂ©es au mĂȘme endroit que mon programme principal (eg: les microservices que jâutilise peuvent ĂȘtre hĂ©bergĂ©s sur diffĂ©rents serveurs et je vais les utiliser dans mon code comme si jâen disposais en local sans me prĂ©occuper de savoir oĂč ils sont). Un microservice est indĂ©pendant, ça a lâavantage de simplifier le travail en Ă©quipe sur un projet dâenvergure, de faciliter le partage de fonctionnalitĂ©s avec dâautres projets ⊠Sans parler des notions de haute dispo, scalabilitĂ©, âŠ
Mais lisez donc lâarticle dont je vous parlais plus haut.
Mes 1ers microservices avec SenecaJS
Jâai une appĂ©tence pour le JavaScript, ce qui a donc influĂ© tout naturellement mes recherches et mon choix sâest portĂ© sur le projet SenectaJS. Cette vidĂ©o et une bonne introduction Ă lâutilisation de SenecaJS: Michele Capra - Microservices in practice with Seneca.js.
Préparation du 1er microservice
Le mieux est de directement crĂ©er un projet sur GitHub car je mâen sers pour dĂ©ployer mes services. Donc une fois votre projet crĂ©Ă© et clonĂ© sur votre poste, dans votre projet crĂ©ez un fichier package.json
:
# on imagine que votre projet GitHub s'appelle ping-service đ
cd ping-service
npm init -y
npm install seneca --save
Votre fichier package.json
devrait ressembler Ă minima Ă ceci:
{
"name": "ping-service",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"seneca": "^3.2.2"
}
}
Ensuite (dans le répertoire /ping-service
), créez un fichier index.js
const seneca = require('seneca')()
const os = require('os')
const port = process.env.PORT || 8082
function pingpong(options) {
this.add({role: "sport", cmd: "ping"}, (message, reply) => {
reply(null, {answer: "pong"})
})
}
seneca
.use(pingpong)
.listen({
host: '0.0.0.0',
port: port
})
console.info(`đ service is listening on ${port}`)
Vous pouvez dĂšs maintenant lancer votre formidable service:
node index.js # ou npm start
Et le tester dans votre navigateur en appelant http://localhost:8082/act?role=sport&cmd=ping
et vous obtiendrez en réponse:
{"answer":"pong"}
Ce qui vaut bien une petite đș de victoire.
Préparation du 2Úme microservice
LĂ , vous ĂȘtes chaud comme la braise, on ne sâarrĂȘte pas, vous mâen faites un deuxiĂšme. LĂ aussi, il faudra crĂ©er un projet sur GitHub, et avec beaucoup dâimagination, appelons le pong-service
:
const seneca = require('seneca')()
const os = require('os')
const port = process.env.PORT || 8081
function pingpong(options) {
this.add({role: "sport", cmd: "pong"}, (message, reply) => {
reply(null, {answer: "ping"})
})
}
seneca
.use(pingpong)
.listen({
host: '0.0.0.0',
port: port
})
console.info(`đ service is listening on ${port}`)
Si vous prenez le temps de le tester, vous obtiendrez:
{"answer":"ping"}
On héberge les 2 services chez @Clever_Cloud
PlutĂŽt que de tout faire en local, nous allons hĂ©berger nos services Ă lâextĂ©rieur. Jâai choisi de faire ça chez @Clever_Cloud pour plusieurs raisons:
- la simplicitĂ© dâutilisation pour le dĂ©ploiement et la maintenance (je suis un dev, je nâai pas envie de perdre mon temps avec des solutions compliquĂ©es pour hĂ©berger mes applis)
- la possibilitĂ© dâajouter une base de donnĂ©es facilement
- la gestion automatique des updates, des fixes des failles de sécurité
- lâautoscalabilitĂ© (je vous rappelle que je veux faire de lâIOT ⊠et que je suis un dev)
- âNo-downtime deploymentâ, ce qui est plutĂŽt rare ou alors faut te le gĂ©rer toi-mĂȘme
- le support utilisateurs fait par la core team (et en dans mon cas, mĂȘme si mon job actuel mâoblige Ă pratiquer lâanglais presque tous les jours, câest quand mĂȘme super agrĂ©able et reposant de pouvoir utiliser sa langue natale)
- âŠ
Câest parti
- Alors, nos deux microservices sont sur GitHub
- Pour les grosses faignasses vous pouvez les cloner par ici:
- https://github.com/wey-yu/ping-service
- https://github.com/wey-yu/pong-service
- il vous faudra vous enregistrer chez @Clever_Cloud (il y a une offre découverte gratuite)
Et maintenant on dit que vous avez un compte et que vous voulez déployer:
1- Créer une application:
- clicker sur
+ Add an application
- dans la liste
Select your GitHub repository
, sélectionner votre projet sur GitHub
2- Choisissez le type de lâapplication:
- dans notre cas, ce sera NodeJS
3- Editez le type dâinstance
- Clicker sur
EDIT
- Choisir une instance de taille pico
- Clicker sur
NEXT
4- Donnez un nom Ă votre service et crĂ©ez lâapplication
5- Ne pas ajouter dâAdd-On
- Pour cette partie nous nâavons pas besoin dâadd-on
6- Les variables dâenvironnement
- Par défaut il y a toujours une variable
PORT
Ă©gale Ă8080
- une application sur Clever doit toujours âĂ©couterâ sur le port http
8080
- le port http
8080
est mappé sur le port80
- donc pour accĂ©der Ă vos webapps de lâextĂ©rieur, vous utiliserez le port
80
- donc ne changez rien
- une application sur Clever doit toujours âĂ©couterâ sur le port http
- Clicker sur
NEXT
7- La crĂ©ation de lâapplication commence
-
Une application Node chez Clever doit posséder un fichier
package.json
indiquant comment démarrer"scripts": { "start": "node index.js" }
-
Remarque:
"main": "index.js"
peut suffire - maintenant patientez un peuâŠ
- Vous pouvez ensuite suivre le déploiement de votre microservice:
8- Donnez une url humainement lisible Ă votre microservice
9- Testez votre microservice
10- Exercice
Vous avez vu, câest ultra facile, faites donc la mĂȘme chose pour le 2Ăšme microservice (pong)
Nous avons donc maintenant 2 microservices hebergés
- đ ping: http://mypingservice.cleverapps.io/act?role=sport&cmd=ping
- đ et pong: http://mypongservice.cleverapps.io/act?role=sport&cmd=pong
Nous allons maintenant voir comment créer un client pour les utiliser.
Utilisons nos microservices
Sur votre poste en local (vous pourrez lâhĂ©berger plus tard si vous le souhaitez), crĂ©ez un nouveau projet Node, avec du Express:
npm init -y
npm install express --save
npm install body-parser --save
npm install seneca --save
Ensuite créez un fichier index.js
:
const express = require("express");
const bodyParser = require("body-parser");
const seneca = require('seneca')
const port = process.env.PORT || 8080;
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
let clientPong = seneca().client({host:'mypongservice.cleverapps.io', port:80})
let clientPing = seneca().client({host:'mypingservice.cleverapps.io', port:80})
app.get('/service/ping', (req, res) => {
clientPing.act({role: "sport", cmd: "ping"}, (err, item) => {
res.send(item)
})
});
app.get('/service/pong', (req, res) => {
clientPong.act({role: "sport", cmd: "pong"}, (err, item) => {
res.send(item)
})
});
app.listen(port);
console.log(`đ Web Server is started - listening on ${port}`);
â ïž Remarque: il existe une intĂ©gration Express-Seneca, mais lĂ jâai fait au plus simple.
- Lancez
node index.js
- ouvrez votre navigateur
- essayez http://localhost:8080/service/ping
- essayez http://localhost:8080/service/pong
đ gĂ©nial, on a bien nos services distants utilisables (une petite đș).
Maintenant ce qui serait bien, cs serait dâavoir un systĂšme de âservice discoveryâ pour Ă©viter dâavoir Ă renseigner les urls des microservices.
Mais ce sera pour un prochain article (jâai encore quelques coup de tournevis Ă donner đ)
Tweet