Date post: | 19-Jan-2017 |
Category: |
Technology |
Upload: | designveloper |
View: | 326 times |
Download: | 3 times |
9/30/16 1
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: Internal
MICROSERVICES WITH SENECAJSTrung Dang Session 2
9/30/16 2
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
Agenda – Session 2▪Docker▪AMQP / RabbitMQ: What is it?▪SenecaJS transportation with AMQP▪Multiple service instances: PM2 or Docker?▪Consul - Service health checker & Configuration▪JWT for Auth▪Introducing servicebase package▪Q/A
9/30/16 3
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
Sample source code is available at https://github.com/immanuel192/seneca-with-rabbitmq-seminar
9/30/16 4
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: Internal
Review Session 1
9/30/16 5
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
Monolithic Application Model
1. How to scale this application to serve more customer requests?
2. The Payments Module is taking very long time to process the requests. Is there any solution with cheap cost?
9/30/16 6
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
9/30/16 7
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
Microservices with Seneca, RabbitMQ, Consul, and FeathersJS
servicebase
Database Models
Service Logic
Service B
NGI
NX
– Lo
ad B
alan
cer
Gate
way
API
1Ga
tew
ay A
PI 2
Rabb
itMQ
Configuration Storage & Health Checker
Docker
servicebase
Database Models
Service Logic
Service A
Redis
9/30/16 8
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
Docker - https://www.docker.com/
9/30/16 9
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
AMQP & RabbitMQ. What is it?
• RabbitMQ is a messaging broker - an intermediary for messaging.
9/30/16 10
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
Service 1
RabbitMQ - How it works
Service 2
Queue
Queue
Exchange
client
Service 1
9/30/16 11
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
docker run -d \
--hostname rabbitmq-server \
-p 5672:5672 -p 15672:15672 \
--name rabbitmq-server \
-e RABBITMQ_DEFAULT_USER=username -e
RABBITMQ_DEFAULT_PASS=password \
rabbitmq:management
Docker – Start RabbitMQ
9/30/16 12
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
SenecaJS Philosophy
• Pattern Matching: instead of fragile service discovery, you just let the world know what sort of messages you are about.
• Transport Independence: you can send messages between services in many ways, all hidden from your business logic.
9/30/16 13
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
SenecaJS – Your first microservicelet seneca = require('seneca')()
seneca.add('service:math,cmd:sum', (msg, reply) => { reply(null, { answer: (msg.left + msg.right) }) })
seneca.act({ service: 'math', cmd: 'sum', left: 1, right: 2 }, (err, result) => {
if (err) return console.error(err) console.log(result) })
9/30/16 14
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
SenecaJS – Pattern Matchingseneca.add('service:math,cmd:sum', (msg, reply) => { reply(null, { answer: (msg.left + msg.right) }) })
Can this service return the result as an integer only whenever I need?
9/30/16 15
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
SenecaJS – Pattern Matching - 2
seneca.add(‘service:math,cmd:sum’, function (msg, reply) { if (msg.integer === true){ reply(null, { answer: (parseInt(msg.left) + parseInt(msg.right)) }) } else{ reply(null, { answer: (msg.left + msg.right) }) }})
9/30/16 16
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
SenecaJS – Pattern Matching - 3seneca.add('service:math,cmd:sum', (msg, reply) => { reply(null, { answer: (msg.left + msg.right) }) })
seneca.add('service:math,cmd:sum,integer:true', (msg, reply) => { reply(null, {
answer: ( parseInt(msg.left) + parseInt(msg.right)
) })
})
9/30/16 17
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
SenecaJS – Pattern Matching - Recap• Matches against top level properties of JSON message• Patterns are unique• Specialised patterns win over generic patterns• Competing patterns win based on value
9/30/16 18
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
SenecaJS – Transport
• Seneca can work with multiple transports
• Available transports: RabbitMQ, Kafka, Redis, BeansTalk, mqp, Mesh, SQS, NSQ, ZeroMQ, NATS, Azure Service Bus, NServiceBus, Aliyun-MNS, Google Cloud PubSub
• HTTP/TCP is supported by default
9/30/16 19
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
SenecaJS with AMQP Transport
• seneca-amqp-transporthttps://github.com/seneca-contrib/seneca-amqp-transport• It is a plugin to allow seneca listeners and clients to communicate
over AMQP• Currently support AMQP 0.9.1• For AMQP 1.0, please use seneca-servicebus-transport
9/30/16 20
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
SenecaJS with AMQP Transport – Serverlet seneca = require('seneca')() .use('seneca-amqp-transport') .add('service:myService,cmd:create', function (args, done) { console.log(`From client ${args.clientId}: ${args.i}`); done(null, { i: args.i }) }) .listen({ type: 'amqp', pin: 'service:myService', url: 'amqp://username:password@rabbitmq-server:5672' })
9/30/16 21
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
SenecaJS with AMQP Transport – Clientlet clientId = 1let args = process.argv.slice(2)if (args.length > 0) {
clientId = args[0]}
let client = require('seneca')().use('seneca-amqp-transport').client({type: 'amqp',pin: 'service:myService',url: 'amqp://username:password@rabbitmq-server:5672'
})let i = 0setInterval(function() {
client.act(`service:myService,cmd:create,clientId:${clientId},i:${i}`,function(err, ret) {
console.log('Client: received i = ' + ret.i);});
i++;}, 100)
9/30/16 22
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
SenecaJS with AMQP Transport – How it works Consumer Queue
Queue
myServiceclient
Requestreply_to = my_client_id
correlation_id = abc
Reply
correlation_id = abcQueue
Client Queue
Routingpin = service:myService
Routingpin = my_client_id
9/30/16 23
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: Internal
DEMO
9/30/16 24
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: Internal
TEA-BREAK
9/30/16 25
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
PM2
• Advanced process manager for production Node.js applications. Load balancer, logs facility, startup script, micro service management, at a glance.
• We can use pm2 to start our services with scalepm2 start config-file.jsonpm2 start your-app.jspm2 scale app-name instance-number
9/30/16 26
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
PM2 - Sample JSON configuration
File start-service.json{
apps: [{
name: "myService",script: "index.js",watch: false,env: {
"NODE_ENV": "development"},instances: 1
}]
}
9/30/16 27
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
Docker – Run your service in multiple containerexport pwd=`pwd`docker run -d --link=rabbitmq-server -v "$pwd":/app \ mhart/alpine-node:latest node /app/server.js
docker run -d --link=rabbitmq-server -v "$pwd":/app \ mhart/alpine-node:latest node /app/client.js 1
docker run -d --link=rabbitmq-server -v "$pwd":/app \ mhart/alpine-node:latest node /app/client.js 2
9/30/16 28
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
Configuring your service
• How can we protect our configuration for production ENV?• How can we monitor our services’s heath?
References:• Health - Consul
https://www.consul.io/docs/agent/http/health.html
• Key / Value store - Consulhttps://www.consul.io/docs/agent/http/kv.html
9/30/16 29
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
JWT for Authentication
• JWT stands for Json Web Token• No more cookies.• JWT has 3 parts: header.body.signature
Example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzY290Y2guaW8iLCJleHAiOjEzMDA4MTkzODAsIm5hbWUiOiJDaHJpcyBTZXZpbGxlamEiLCJhZG1pbiI6dHJ1ZX0.03f329983b86f7d9a9f5fef85305880101d5e302afafa20154d094b229f75
• JWT helps to verify the sender, authorize the request, prevent man in middle and good with CORS.
9/30/16 30
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
Introducing servicebase package
https://www.npmjs.com/package/servicebase
Features :• Listener / Client mode, with AMQP Transport or HTTP Transport• Promisify all functions• Use Consul as Configuration Storage & Service Health Checker• Support multiple database adapters. Postgresql & Sqlite are build-in supported adapters• Use Loggly as logs monitoring service• Support Authorization when consuming the service’s action• Error handler: no more terminating your service because of TIMEOUT or fatal$ error• Including test helper• Including typed-definitions file
9/30/16 31
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: Internal
DEMO
9/30/16 32
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
Testing your services
• Use sqlite in-memory for integration test• For unit-test: test your logic-class instead of test the function you
registered with seneca• For integration-test with other services: use pm2 & rabbitmq
9/30/16 33
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
Microservices are the kind of SOA. Microservices must be independently deployable, whereas SOA services are often implemented in deployment monoliths. Classic SOA is more platform driven, so microservices offer more choices in all dimensions.
Torsten Winterberg (Oracle ACE Director)
Microservices vs SOA
9/30/16 34
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: Internal
Q&AThank you very much
9/30/16 35
CLICK TO EDIT MASTER TITLE STYLE
Security Classification: InternalSecurity Classification: Internal
Stateful / Stateless & Authorization
• Stateful means that there is memory of the past. Previous transactions are remembered and may affect the current transaction.
• Stateless means there is no memory of the past. Every transaction is performed as if it were being done for the very first time.
• In Stateless service, we use JWT (Json Web Token) for Authentication. No more Cookies.
• Authorization will be done by each service regarding to the authenticated user.