SlideShare una empresa de Scribd logo
1 de 54
Descargar para leer sin conexión
Node.js Enterprise Middleware
Behrad Zari
behradz@gmail.com
June 2014
Tehran/Iran Chapter
http://www.acm.org.ir
=Server-Side Javascript
Context
 Soft Real-Time Push-Based Applications
 twitter, chat, sport bets, mobile, …
 SPA
 many req/sec with low response times, sharing
things like validation code between the client
and server, FAT client
 Cloud
 SaaS, PaaS, DBaaS
Context (cont.)
 Queued Inputs
 High concurrency, DB bottleneck, Brokers (MOM)
 JSON-based REST-full Interfaces
 Service mediation & federation (SOA)
 Polyglot-Database Applications
 NoSQL + Relational + Distributed Caches
in a rapid agile development fashion
Motivation: grow
Cloud
Enterprise Service Farms
IoT
Mobile
Rapid Change
Data Volume
Integration
Performance + Scalability
Concurrency
CGI (1993)
a process/request
PHP (1994)
a thread/request
No Pooling
Java Servlet (1995)
a thread/request
with pooling in container = pre-allocation
Problem 1?
 Context switching is not free
 Execution stacks take up memory
A quick calculation: assuming that each thread potentially
has an accompanying 2 MB of memory with it, running on a
system with 8 GB of RAM puts us at a theoretical maximum of
4000 concurrent connections, plus the cost of context-
switching between threads.
For massive concurrency,
cannot use an OS thread for each
connection
Problem 2?
We always do I/O
result = db.query("select somthing from T");
// use result
which is blocking
I/O latency
L1: 3 cycles
L2: 14 cycles
RAM: 250 cycles
DISK: 41,000,000 cycles
NETWORK: 240,000,000 cycles
Non-Blocking IO
Non-Blocking IO
Callbacks + Polling
Epoll, POSIX AIO, …
Event-Driven
While there are events to process
e = get the next event
perform the action requested by e in a thread
if e’s thread is complete and e has an associated callback
call the callback
Event Loop
Now…
var result = null;
db.query("select..", function (passedResult) {
// use passed result…
result = passedResult;
});
console.log( result ); // what’s result now?
Concurrency Models
Thread-based
 Locks and Shared State
VS
Event-driven Concurrency
 I/O parallelism without requiring CPU parallelism
 no synchronization is required
 maximize resource efficiency
Where were you!?
Why everyone isn’t using event loops,
callbacks, non-blocking IO?
 Cultural
 Infrastructural
Cultural
This is How we’re taught I/O:
puts("Enter your name: "
var name = gets();
puts("Name: " + name);
Cultural (2)
Rejected as too complicated
puts("Enter your name: ");
gets(function (name) {
puts("Name: " + name);
});
Missing Infrastructure
Single threaded event loops require I/O to be
non-blocking
Most libraries are not.
Too Much Infrastructure
EventMachine, Twisted, AnyEvent, Apache
Mina, Java nio, …
users are confused how to
combine with other available
libraries
Why Javascript?
Javascript designed specifically to be used with
an event loop purely:
 Anonymous functions, closures
 Only one callback at a time
 I/O through DOM event callbacks
 culture of Javascript is already geared towards
evented programming
What is Node.js?
Node.js emerged from a project at cloud service provider
Joyent in 2009
Node.js Project on www.ohloh.net
Node.js Architecture
Cross-platform asychronous I/O
Open source JavaScript engine,
Optimizer, JIT, inline caching, GC
Node.js Server (2009)
Node.js Ecosystem
Modules (CommonJS Securable Module)
 Think Modular, not Monolithic
 Fine grained pieces of logic
innovation through modularity
npm
module (package) manager, taking care of
recursive dependencies and resolving
collisions, …
Publishing a node module fulfills satisfaction
for developers much greater than contributing
to a larger code base
Module’s package.json
Dependencies are your friends
Do not force everyone to agree on the same version of a
module
lets you avoid
dependency hell by
modifying the
require.paths at runtime
Node.js Ecosystem
Node.js Ecosystem
event loop and event handlers yields
an IoC:
why we needed IoC?
how is real world?
Node.js TCP Server Socket
RPC (RMI) in node.js
Dnode Server Dnode Client
How to scale our single-threaded high performance
node.js service?
with node.js built-in Cluster module
Cluster Module
Node.js
achieves
scalability
levels of over
1Million
concurrent
connections
N-Copy,
Shared Socket,
Round-Robin
Node.js Scalability Model
independently scale the subsystems
a JavaEE 3-tier app is actually not written with
Horizontal clustering in mind
Horizontal, share-nothing
Microservice Architecture
http://martinfowler.com/articles/microservices.html
Decentralized Responsibility & Data
Polyglot
Persistence
continuousdeployment
Independently deployable services
http://martinfowler.com/articles/microservices.html
gracefully fail
SPoF
Easy monitoring
Node.js Enterprise Middleware
Node.js Middleware Benefits
 Performance & Scalability
 single threaded event loop + async IO (built-in)
 easy high performance middleware stack (as a primary goal)
 hard to write slow programs
 Agile and lightweight development
 Javascript
 modularity
 TDD, BDD, automated tests(mocha,…)
 avoid build step (live coding)
 Auto Restart and Continuous Deployment
 process monitoring (forever, pm2,…)
 fail fast:  just fail & let some other process do error recovery
Node.js Business Benefits
 Motivation
 high risk
 fast prototyping
 continuous delivery
 Productivity
 an enterprise scale web server in 5 lines
 >80K modules on npm (growing ecosystem)
 Comet, Pervasive Computing, REST, MOM, Integration?
 Developer Joy
 more happy, works better, more developers join
 Cost Savings
 fewer developers
 smaller iterations + more velocity => half-time
 Less hardware
Market Share
whalepath.com report
Success Stories
Name Usage
Paypal $3.5 billion IN 2011, In Java Spring: unfriendly environment for front-
end engineers
With Java, when deployed to a staging server was a few thousandths
of a second wait in Node.js, Bill Scott , 33-50% fewer lines of code to get a job done
PayPal has redone 22 of its customer applications:
PayPal Funding Source, PayPal Account Details, PayPal LogOn, and Wallet
eBay released ql.io, an event-driven aggregation tool for API consumption
LinkedIn massive performance gains with Node
Yahoo! Mojito, 200 developers, 500 private, 800 extra modules, 2,000,000 req/min
Walmart mobile development, no server down time!
Oracle Nashorn: a JVM-based JavaScript engine
Repository Module Count
www.modulecounts.com
Monthly Contributors
Node.js Project on Ohloh (2014)
8000 lines of C/C++, 2000 lines of Javascript, 14 contributors @ 2009
.end()
References
• It was a huge list, please surf the web as me, or contact
me :)
Let me know if you have…
 High Throughput & Scalable backend
 NoSQL, Data Engineering, BI
 Enterprise Integration
problems.
Supplementary Content...
– Js anti-pattern 1: Callback hell
JS Callback hell
Solution 1: async module
Solution 2: promises
Solution 3: generators

Más contenido relacionado

La actualidad más candente

Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1
Mohammad Qureshi
 
Node.js, toy or power tool?
Node.js, toy or power tool?Node.js, toy or power tool?
Node.js, toy or power tool?
Ovidiu Dimulescu
 

La actualidad más candente (20)

Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js + Expres...
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js +  Expres...Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js +  Expres...
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js + Expres...
 
Introduction to node.js
Introduction to node.jsIntroduction to node.js
Introduction to node.js
 
Node.js: A Guided Tour
Node.js: A Guided TourNode.js: A Guided Tour
Node.js: A Guided Tour
 
Searching for the framework of my dreams in node.js ecosystem by Mykyta Semen...
Searching for the framework of my dreams in node.js ecosystem by Mykyta Semen...Searching for the framework of my dreams in node.js ecosystem by Mykyta Semen...
Searching for the framework of my dreams in node.js ecosystem by Mykyta Semen...
 
Introduction to node.js
Introduction to node.jsIntroduction to node.js
Introduction to node.js
 
Introduction to NodeJS
Introduction to NodeJSIntroduction to NodeJS
Introduction to NodeJS
 
[212] large scale backend service develpment
[212] large scale backend service develpment[212] large scale backend service develpment
[212] large scale backend service develpment
 
Building a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless frameworkBuilding a serverless company on AWS lambda and Serverless framework
Building a serverless company on AWS lambda and Serverless framework
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1
 
React Development with the MERN Stack
React Development with the MERN StackReact Development with the MERN Stack
React Development with the MERN Stack
 
Node.js, toy or power tool?
Node.js, toy or power tool?Node.js, toy or power tool?
Node.js, toy or power tool?
 
Philly Tech Week Introduction to NodeJS
Philly Tech Week Introduction to NodeJSPhilly Tech Week Introduction to NodeJS
Philly Tech Week Introduction to NodeJS
 
Play Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and ScalaPlay Framework: async I/O with Java and Scala
Play Framework: async I/O with Java and Scala
 
DjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling DisqusDjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling Disqus
 
Introduction to Node js
Introduction to Node jsIntroduction to Node js
Introduction to Node js
 
Building Applications With the MEAN Stack
Building Applications With the MEAN StackBuilding Applications With the MEAN Stack
Building Applications With the MEAN Stack
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
 
Node.js code tracing
Node.js code tracingNode.js code tracing
Node.js code tracing
 
Cracking JWT tokens: a tale of magic, Node.js and parallel computing - Code E...
Cracking JWT tokens: a tale of magic, Node.js and parallel computing - Code E...Cracking JWT tokens: a tale of magic, Node.js and parallel computing - Code E...
Cracking JWT tokens: a tale of magic, Node.js and parallel computing - Code E...
 
Introduction to Node.js Platform
Introduction to Node.js PlatformIntroduction to Node.js Platform
Introduction to Node.js Platform
 

Destacado

Node Security: The Good, Bad & Ugly
Node Security: The Good, Bad & UglyNode Security: The Good, Bad & Ugly
Node Security: The Good, Bad & Ugly
Bishan Singh
 
Node js presentation
Node js presentationNode js presentation
Node js presentation
martincabrera
 
Cross Platform Mobile Application Architecture
Cross Platform Mobile Application ArchitectureCross Platform Mobile Application Architecture
Cross Platform Mobile Application Architecture
Derrick Bowen
 
Enterprise Architectures with Ruby (and Rails)
Enterprise Architectures with Ruby (and Rails)Enterprise Architectures with Ruby (and Rails)
Enterprise Architectures with Ruby (and Rails)
Konstantin Gredeskoul
 

Destacado (20)

NodeJS for Beginner
NodeJS for BeginnerNodeJS for Beginner
NodeJS for Beginner
 
Anatomy of a Modern Node.js Application Architecture
Anatomy of a Modern Node.js Application Architecture Anatomy of a Modern Node.js Application Architecture
Anatomy of a Modern Node.js Application Architecture
 
The Enterprise Case for Node.js
The Enterprise Case for Node.jsThe Enterprise Case for Node.js
The Enterprise Case for Node.js
 
Node.js In The Enterprise - A Primer
Node.js In The Enterprise - A PrimerNode.js In The Enterprise - A Primer
Node.js In The Enterprise - A Primer
 
Node Security: The Good, Bad & Ugly
Node Security: The Good, Bad & UglyNode Security: The Good, Bad & Ugly
Node Security: The Good, Bad & Ugly
 
Node Architecture and Getting Started with Express
Node Architecture and Getting Started with ExpressNode Architecture and Getting Started with Express
Node Architecture and Getting Started with Express
 
node.js: Javascript's in your backend
node.js: Javascript's in your backendnode.js: Javascript's in your backend
node.js: Javascript's in your backend
 
Bdd with Cucumber and Mocha
Bdd with Cucumber and MochaBdd with Cucumber and Mocha
Bdd with Cucumber and Mocha
 
NodeJS ecosystem
NodeJS ecosystemNodeJS ecosystem
NodeJS ecosystem
 
Node.js architecture (EN)
Node.js architecture (EN)Node.js architecture (EN)
Node.js architecture (EN)
 
NodeJS - Server Side JS
NodeJS - Server Side JS NodeJS - Server Side JS
NodeJS - Server Side JS
 
Apache spark linkedin
Apache spark linkedinApache spark linkedin
Apache spark linkedin
 
Node js presentation
Node js presentationNode js presentation
Node js presentation
 
Chuong 2 tổ chức dữ liệu trong HTTT kế toán
Chuong 2 tổ chức dữ liệu trong HTTT kế toánChuong 2 tổ chức dữ liệu trong HTTT kế toán
Chuong 2 tổ chức dữ liệu trong HTTT kế toán
 
Cross Platform Mobile Application Architecture
Cross Platform Mobile Application ArchitectureCross Platform Mobile Application Architecture
Cross Platform Mobile Application Architecture
 
Architecting large Node.js applications
Architecting large Node.js applicationsArchitecting large Node.js applications
Architecting large Node.js applications
 
Nodejs intro
Nodejs introNodejs intro
Nodejs intro
 
Are ESBs Relevant in the Age of Microservices?
Are ESBs Relevant in the Age of Microservices?Are ESBs Relevant in the Age of Microservices?
Are ESBs Relevant in the Age of Microservices?
 
What's Better than Microservices? Serverless Microservices.
What's Better than Microservices? Serverless Microservices.What's Better than Microservices? Serverless Microservices.
What's Better than Microservices? Serverless Microservices.
 
Enterprise Architectures with Ruby (and Rails)
Enterprise Architectures with Ruby (and Rails)Enterprise Architectures with Ruby (and Rails)
Enterprise Architectures with Ruby (and Rails)
 

Similar a Node.js Enterprise Middleware

No More Hops Towards A Linearly Scalable Application Infrastructure
No More Hops Towards A Linearly Scalable Application InfrastructureNo More Hops Towards A Linearly Scalable Application Infrastructure
No More Hops Towards A Linearly Scalable Application Infrastructure
ConSanFrancisco123
 
Class 7: Introduction to web technology entrepreneurship
Class 7: Introduction to web technology entrepreneurshipClass 7: Introduction to web technology entrepreneurship
Class 7: Introduction to web technology entrepreneurship
allanchao
 
Web Development Environments: Choose the best or go with the rest
Web Development Environments:  Choose the best or go with the restWeb Development Environments:  Choose the best or go with the rest
Web Development Environments: Choose the best or go with the rest
george.james
 

Similar a Node.js Enterprise Middleware (20)

Node js
Node jsNode js
Node js
 
StrongLoop Overview
StrongLoop OverviewStrongLoop Overview
StrongLoop Overview
 
Beginners Node.js
Beginners Node.jsBeginners Node.js
Beginners Node.js
 
Reactive Microservices with Spring 5: WebFlux
Reactive Microservices with Spring 5: WebFlux Reactive Microservices with Spring 5: WebFlux
Reactive Microservices with Spring 5: WebFlux
 
Proposal
ProposalProposal
Proposal
 
18_Node.js.ppt
18_Node.js.ppt18_Node.js.ppt
18_Node.js.ppt
 
18_Node.js.ppt
18_Node.js.ppt18_Node.js.ppt
18_Node.js.ppt
 
Comet with node.js and V8
Comet with node.js and V8Comet with node.js and V8
Comet with node.js and V8
 
Why Reactive Architecture Will Take Over The World (and why we should be wary...
Why Reactive Architecture Will Take Over The World (and why we should be wary...Why Reactive Architecture Will Take Over The World (and why we should be wary...
Why Reactive Architecture Will Take Over The World (and why we should be wary...
 
Functional Programming in Serverless World (Serveless UG Poland)
Functional Programming in Serverless World (Serveless UG Poland)Functional Programming in Serverless World (Serveless UG Poland)
Functional Programming in Serverless World (Serveless UG Poland)
 
RavenDB overview
RavenDB overviewRavenDB overview
RavenDB overview
 
No More Hops Towards A Linearly Scalable Application Infrastructure
No More Hops Towards A Linearly Scalable Application InfrastructureNo More Hops Towards A Linearly Scalable Application Infrastructure
No More Hops Towards A Linearly Scalable Application Infrastructure
 
Voldemort & Hadoop @ Linkedin, Hadoop User Group Jan 2010
Voldemort & Hadoop @ Linkedin, Hadoop User Group Jan 2010Voldemort & Hadoop @ Linkedin, Hadoop User Group Jan 2010
Voldemort & Hadoop @ Linkedin, Hadoop User Group Jan 2010
 
Hadoop and Voldemort @ LinkedIn
Hadoop and Voldemort @ LinkedInHadoop and Voldemort @ LinkedIn
Hadoop and Voldemort @ LinkedIn
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
 
Resume
ResumeResume
Resume
 
Class 7: Introduction to web technology entrepreneurship
Class 7: Introduction to web technology entrepreneurshipClass 7: Introduction to web technology entrepreneurship
Class 7: Introduction to web technology entrepreneurship
 
Introduction to Node.JS
Introduction to Node.JSIntroduction to Node.JS
Introduction to Node.JS
 
Web Development Environments: Choose the best or go with the rest
Web Development Environments:  Choose the best or go with the restWeb Development Environments:  Choose the best or go with the rest
Web Development Environments: Choose the best or go with the rest
 
World of Node.JS
World of Node.JSWorld of Node.JS
World of Node.JS
 

Último

%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
chiefasafspells
 

Último (20)

WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
WSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AI
 
WSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - KanchanaWSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - Kanchana
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 

Node.js Enterprise Middleware