astricon 2016 - scaling ari and production
TRANSCRIPT
ARI Scaling & Production
Dan Jenkins
@dan_jenkins
Dan Jenkins
@dan_jenkins
5th Astricon!
Author of node-asterisk-ami package on github/npm
Lego
Google Developer Expert
Web Technologies GDE
@dan_jenkins
Real Time Communications Consultancy
@nimbleapeltd
I've become fairly well known to use lego images
in my slide decks...
@dan_jenkins
They're interesting
@dan_jenkins
And I ♥ Lego.
@dan_jenkins
So its Lego time!
@dan_jenkins
A tale of two parts
Scaling ARI
@dan_jenkins
Scaling is how we handle traffic to and from Asterisk via the ARI interface in a way
that we can support load
@dan_jenkins
Production
@dan_jenkins
How to architect your ARI app for running in
production, failing over, monitoring and reporting
@dan_jenkins
Who knows of the ARI?
@dan_jenkins
Who's built something with the ARI?
@dan_jenkins
Who's deployed an ARI app to production?
@dan_jenkins
Lets deconstruct how things work with the other Asterisk interfaces...
@dan_jenkins
Built in Dialplan Applications
app_queue app_dial
app_*
@dan_jenkins
Built in, no thought needed. Contributors have sorted
everything...right?
@dan_jenkins
AMIAsterisk Manager Interface
@dan_jenkins
TCP connection to Asterisk
@dan_jenkins
Build something to scale AMI yourself
@dan_jenkins
Asterisk
@dan_jenkins
Asterisk
@dan_jenkins
AMI Proxy
https://github.com/davetroy/astmanproxy
@dan_jenkins
AstMan Proxy
Asterisk Asterisk Asterisk
@dan_jenkins
(Fast)AGI
Asterisk Gateway Interface
@dan_jenkins
AGI adds processes to our Asterisk
instance
Making our Asterisk instance busier
@dan_jenkins
Asterisk Asterisk Asterisk
@dan_jenkins
FastAGI allowed a TCP call out to something,
somewhere else
@dan_jenkins
You can load balance these calls out using a
TCP Proxy
@dan_jenkins
TCP Load Balancer
Asterisk Asterisk Asterisk
@dan_jenkins
But there are reasons I love the ARI compared to AMI and AGI
@dan_jenkins
It does greatthings with minimal
fuss and issue@dan_jenkins
It does things "the Web" way
@dan_jenkins
Thank you Asterisk Team!
@dan_jenkins
Before we look at how to scale the ARI, we need to understand
what it is
@dan_jenkins
What makes up the ARI?
@dan_jenkins
Dialplan
Its beautiful isn't it? 4 lines. That's it!
(It would be better without the Dialplan)
[Astricon] exten = 100,1,Verbose(1, "Astricon call, woot") same = n,Stasis(dangerous-demos) same = n,Hangup()
@dan_jenkins
HTTP Interface and a Websocket for Events
@dan_jenkins
HTTP
curl -v -u asterisk:asterisk -X POST "http://localhost:8088/ari/channels/1400609726.3/
play?media=sound:hello-world"
@dan_jenkins
Websocket{ "application":"hello-world", "type":"StasisStart", "timestamp":"2014-05-20T13:15:27.131-0500", "args":[], "channel":{ "id":"1400609726.3", "state":"Up", "name":"PJSIP/1000-00000001", "caller":{ "name":"", "number":""}, "connected":{ "name":"", "number":""}, "accountcode":"", "dialplan":{ "context":"default", "exten":"1000", "priority":3}, "creationtime":"2014-05-20T13:15:26.628-0500"} }
@dan_jenkins
Call sessions from Asterisk are tied to a Websocket session
@dan_jenkins
Writing your ARI app for Production
@dan_jenkins
With Dialplan Applications we don't
need to care about latency or load
@dan_jenkins
If Asterisk couldn't cope, then you've got bigger
issues.
@dan_jenkins
In attempt to fix that, you'd put Asterisk on a bigger
box
@dan_jenkins
Or spin up another and put it behind a SIP proxy or
something
@dan_jenkins
Its kinda an already solved problem
@dan_jenkins
But writing external applications to Asterisk is
a different ball game.
@dan_jenkins
More moving parts.
@dan_jenkins
More connected services.
@dan_jenkins
More to monitor.
@dan_jenkins
VoIP infrastructure grows into a Service Oriented
Architecture
@dan_jenkins
Where Asterisk is just a small part of it.
@dan_jenkins
So what do we need to care about when building
& deploying your ARI app?
@dan_jenkins
Latency
@dan_jenkins
Don't put your ARI app too far away
@dan_jenkins
Its not like a normal API being consumed.
@dan_jenkins
Making decisions and informing Asterisk of them shouldn't be hundreds of
milliseconds away
@dan_jenkins
Make your app do your thing
@dan_jenkins
Conference engine with your feature set
@dan_jenkins
Outbound Dialer via your Customer API/
CRM
@dan_jenkins
Your specific idea.
@dan_jenkins
Your specific issue.
@dan_jenkins
Don't aim to replace app_dial / app_queue /
app_voicemail / *
@dan_jenkins
Do your thang!
@dan_jenkins
Logging
@dan_jenkins
Log out data that is useful.
@dan_jenkins
Pipe that data to a centralised place
The ELK Stack for example
(Elasticserch | Logstash | Kibana)
@dan_jenkins
Think of future you reading the logs.
Are they useful?
@dan_jenkins
Metrics
@dan_jenkins
Send stats out of your application
StatsD - data points specific to your application
@dan_jenkins
And then graph and utilise them
(Telegraf | InfluxDB | Grafana)
@dan_jenkins
Inter process communication
@dan_jenkins
Does your app need to talk to other apps serving the
same ARI app name?
@dan_jenkins
Got a call on another Asterisk/ARI app and need
to terminate it?
@dan_jenkins
How do you tell that other App to terminate the call?
@dan_jenkins
Scaling
@dan_jenkins
Lets take a step away from Asterisk
@dan_jenkins
Deploying and scaling a HTTP Service in
Production
@dan_jenkins
HTTP Proxy/Load Balancer
HTTP Service
HTTP Service
HTTP Service
@dan_jenkins
Deploying a service that communicates
with an API
@dan_jenkins
Consuming HTTP Based API
@dan_jenkins
HTTP Proxy/Load Balancer
External API
External API
External API
@dan_jenkins
Consuming Websocket Event API
@dan_jenkins
HTTP/TCP Proxy/Load Balancer
External API
External API
External API
@dan_jenkins
They all have a load balancer
@dan_jenkins
If there is state involved then the application deals
with that
@dan_jenkins
Back to Asterisk
@dan_jenkins
The ARI Websocket is tied to one or many
Stasis/ARI Apps
@dan_jenkins
You can't have multiple Websockets tied to one Asterisk using the same
App name
@dan_jenkins
Asterisk
Stasis App Name "hello-world"
@dan_jenkins
Asterisk
Stasis App Name "hello-world"
@dan_jenkins
Each Asterisk can only handle 1
Websocket per App Name
@dan_jenkins
You can have one web socket handle
multiple app names
@dan_jenkins
For example, a conferencing ARI App
@dan_jenkins
Simple 1 Asterisk and 1 ARI App
@dan_jenkins
Asterisk
Stasis App Name "conferencing"
@dan_jenkins
Pros and Cons
Pros Cons
• Simple • Doesn't scale• You lose all your calls when
your app fails
@dan_jenkins
Not so simple 2 Asterisk and 1 ARI App
@dan_jenkins
AsteriskAsterisk
Stasis App Name "conferencing"
@dan_jenkins
Pros and Cons
Pros Cons
• Can potentially handle more calls than a single Asterisk
• Doesn't scale• You lose all your calls when
your app fails• There will eventually be a
bottleneck in your application
@dan_jenkins
ComplexMultiple Asterisk &
Multiple Process (1:1)
@dan_jenkins
AsteriskAsteriskAsteriskAsterisk
Stasis App Name "conferencing"
@dan_jenkins
Pros and Cons
Pros Cons
• Fairly simple • You lose all calls on that Asterisk when your app fails
• Nightmare configuring it• Not flexible
@dan_jenkins
Really Complex1 Asterisk & Multiple Processes(through some dial plan magic)
@dan_jenkins
Asterisk
Stasis App Names
"conferencingA" "conferencingB" "conferencingC" "conferencingD"
@dan_jenkins
Pros and Cons
Pros Cons
• There are none • Complicated to maintain in your Dialpan
• If Asterisk dies, you lose all your calls
@dan_jenkins
Add in Automated infrastructure and you've got a mess
@dan_jenkins
AsteriskAsteriskAsteriskAsterisk
Stasis App Names
"conferencingA" ...
"conferencingZ"
Asterisk
@dan_jenkins
AsteriskAsteriskAsteriskAsterisk
Stasis App Names
"conferencingA" ...
"conferencingZ"
Asterisk
@dan_jenkins
Pros and Cons
Pros Cons
• There are none • Complicated to maintain in your Dialpan
• If Asterisk dies, you lose all your calls
• A huge mess
@dan_jenkins
So how do we scale?
@dan_jenkins
So how do we scale easily?
@dan_jenkins
Quite simply, today, there is only one way.
@dan_jenkins
ARI Proxy & Message Bus
@dan_jenkins
2 ARI Proxies Available
Both support the same Message Bus Message format (https://github.com/nvisibleinc/go-ari-library/wiki/Message-Format)
@dan_jenkins
Message Bus
RabbitMQ
NATS (Go Proxy only)
@dan_jenkins
AsteriskAsteriskAsteriskAsterisk
Stasis App Name "conferencing"Message Bus
Proxy Proxy Proxy Proxy
*n
*n
@dan_jenkins
Libraries that support it
Go
.Net
Soon Node.js
@dan_jenkins
Libraries that support itGo
.Net
Soon Node.js
What library do you use? PHPARI? ari4java?
@dan_jenkins
We need better library support
@dan_jenkins
None of this is perfect
@dan_jenkins
I wish Asterisk gave us a way of easily scaling with ARI
@dan_jenkins
We talked about it at AstriDevCon this year
@dan_jenkins
Should Asterisk do this or should an external
Proxy do it?
@dan_jenkins
I'm not sure.
(And I was the one who brought it up)
@dan_jenkins
Building with ARI is more complicated
than "Using Asterisk"@dan_jenkins
But that's no different to learning how to ride your bikewithout stabilisers
@dan_jenkins
And you don't ride your bike with stabilisers any more do you?
@dan_jenkins
Its time to get on the bike and start peddling
@dan_jenkins
And hope you don't fall off
@dan_jenkins
But if you do, just get back up and try again
@dan_jenkins
Come see Dangerous Demos Later!
https://upload.wikimedia.org/wikipedia/commons/2/21/250_365_-_Bricks_(4247555680).jpg
https://www.flickr.com/photos/clement127/ (Huge thank you to clement127 for all their pictures over the years)
https://en.wikipedia.org/wiki/Lego#/media/File:LEGO_Building_At_KSC.jpg
https://www.flickr.com/photos/kalexanderson/8145886918
https://c2.staticflickr.com/8/7482/15936739285_460b008ec5_b.jpg
https://www.flickr.com/photos/arul72/23816127556
https://www.flickr.com/photos/kalexanderson/6101914287