[asterisk-dev] AstriDevCon Follow Up - Asterisk and Kamailio - smoother integration

Matthew Jordan mjordan at digium.com
Tue Feb 24 10:58:49 CST 2015

On Mon, Feb 23, 2015 at 2:07 PM, Olle E. Johansson <oej at edvina.net> wrote:

> On 23 Feb 2015, at 20:10, Matthew Jordan <mjordan at digium.com> wrote:
> On Mon, Feb 23, 2015 at 11:16 AM, James Cloos <cloos at jhcloos.com> wrote:
>> >>>>> "MJ" == Matthew Jordan <mjordan at digium.com> writes:
>> MJ> What I'm trying to reason out is: given a set of routing constraints -
>> MJ> which includes not only load balancing but also "application" level
>> routing
>> MJ> decisions - what's the appropriate place for that information to live?
>> MJ> Particularly when you want your entire system - not just Asterisk -
>> to be
>> MJ> scalable?
>> You need to use something to keep track of whether each box is reachable
>> and what each is doing.  There a lots of ways of doing that, including
>> custom network applications, shared networkable databases, shared nfs,
>> et alia.
>> Then each node needs a bit of logic to use that data to determine what
>> to do with any given event.
>> As one example, if a sip server gets an invite which directs on to an
>> existing conference, it needs to know which asterisk is handling that
>> conference, so that it can send the invite there.
>> A shared database is required, but whether it is a custom application, a
>> networkable db or a local db stored on a networked file systems is
>> something anyone writing the code needs to choose.
> Completely agree.
> What I'm driving towards - albeit in something of a roundabout fashion -
> are two notions:
> (1) Hard coding logic in application configuration does not lend itself
> well to scalability. Kamailio lessens the pain in certain ways - you're
> typically going to have fewer proxies than application servers (although, I
> suppose that depends on what you are doing). Also, as Olle pointed out, you
> can replicate information out using an htable. Or use a database. To some
> extent though, this is not much different than using func_odbc with
> Asterisk (a concept many people miss often.) At the same time, requiring
> direct access to a database from my routing engine/media application server
> does not lend itself well to expressive logic. While I've managed to push
> the data out of the application, I haven't necessarily done the same with
> the business rules.
> If you approach the problem purely from a "how horizontally scalable can I
> make this," then ideally most of your business logic would lie outside of
> the routing engine (Kamailio) or the media application server (Asterisk).
> That may mean a web microservice architecture that exposes REST APIs for
> the real-time component to consume. That may mean something else. As Daniel
> noted, the more REST APIs you hit using a cURL module (or what have you),
> the slower things get in Kamailio. The same is true for Asterisk. What I'm
> trying to fish for is where that dividing line should occur - that is, what
> properly belongs to Kamailio (routing decisions) and what properly belongs
> to something else.
> (2) Domain specific languages require domain specific knowledge. This is
> not necessarily a bad thing. At the same time, it's far easier to
> parallelize the problem of application development if you can split tasks
> into well defined domains that make use of tools that have a wider base of
> knowledge. If, for example, the logic of "who is in a conference on which
> server" can be answered by a REST API written in Python, or JavaScript, or
> something else - and does not even live on the Kamailio server - then not
> only does the job of the Kamailio integrator become easier, it is also
> becomes easier to find multiple people to help write the services that it
> integrates with.
> Kamailio really doesn't need to know as long as Asterisk knows... You are
> trying to solve something that is not really a problem, Matt. I have tried
> this path before with conferences and ended up with something too complex.
> Went back to
> forking, if a server responded with 200 OK I added a temporary state in an
> autoexpire hashtable so I remembered for next call which did not need to
> fork. Simple. Fast. No distributed states.
> The real key to scalability is keeping it simple and keeping states local.
> As soon as you start trying to synch or distribute states it gets very
> complex and you loose a lot of scalability. Asterisk is filled with all
> kinds of states, keep it there as much as possible and be smart with your
> signalling. You want to be able to restart Kamailio anytime without loosing
> states and without disrupting any single call. As soon as you start adding
> call states, server states and conference server states you loose a lot of
> that and end up with replication in databases and other complex schemes.
Really, distributing the state in Asterisk is not much of a problem in this
scenario. Sure, if the application in question is ConfBridge, or Queue, or
some other dialplan application, then the difficulty of sharing that state
across clustered Asterisk instances is non-trivial. However, in a system
where the application state lives off of the Asterisk boxes - that is,
where ARI is used to control the Asterisk instances and an external process
(or set of processes - everyone must scale!) manages the application state
- then the question of how the application state distributed is solved.

That is: I'm not really questioning where the application state lives. I'm
questioning how routing decisions - which may be impacted by that
application state - should be made. It sounds like the answer is "don't
worry, and just use Kamailio's built-in routing mechansims." Which is an
acceptable answer - there's ways to work with that answer in a clustered
Asterisk environment.

> Forking doesn't cost much, really. Using SIP makes life simple. The
> network flow is already established.
Forking to all Asterisk servers is certainly a solution. I could also 302
the INVITE request or send a REFER request to the initiator to move the
session to another Asterisk server if the one it lands on isn't the one
that is "correct" based on some application state. Handling that at the
application level is relatively straight forward; my line of questioning
was really to make sure that there isn't some mechanism in Kamailio that
would be more appropriate.

> If you are looking for restful interfaces, Kamailio has an embedded HTTP
> server you can use for quite a lot compared with the Asterisk one. The HTTP
> requests are as configurable and routable as the SIP requests... Quite cool.
You do know we built all of ARI on the internal Asterisk HTTP server,
right? :-)

Of course, the request callbacks aren't exposed to the dialplan - but then
again, that's not really a concept that the Asterisk dialplan syntax would
handle well.

> There are a few applications that require more states, like trying to
> build a PBX in Kamailio. - but why try that when Asterisk has all the
> functionality you need? :-)
> Keep the states where they belong.
> Now for load balancing, we could add a module to Asterisk that sends
> simple SIP messages with an attachment that describes current call load and
> maybe a few global variables that I configure. application/asteriskstate -
> simple json structure that we can parse in Kamailio and use for load
> balancing on call and cpu load. This could be a subscribe/notify event
> package that Kamailio feeds into the DMQ cluster.
Since this would be consumable in Kamailio, a spec on the event package
would be handy.

I noticed that there are some RFCs for this already. Most are
informational, although RFC 7200 looks to take things to quite a logical
extreme. Any thoughts on these?

* RFC 5390: Requirements for Management of Overload in the Session
Initiation Protocol - https://tools.ietf.org/html/rfc5390
* RFC 6357: Design Considerations for Session Initiation Protocol (SIP)
Overload Control - https://tools.ietf.org/html/rfc6357
* RFC 7200: A Session Initiation Protocol (SIP) Load-Control Event Package
- https://tools.ietf.org/html/rfc7200

> Another thing would be to have events triggered on startup of asterisk and
> shutdown - maybe something as simple as a REGISTER. These could be used to
> enable and disable one  Asterisk server in a dispatcher set.
I would imagine that in any clustered scenario, you would want Asterisk to
REGISTER to Kamailio to notify it of its existence. If a SUBSCRIBE/NOTIFY
scheme were used to inform Kamailio of the loaded status of the Asterisk
instances, Kamailio could then SUBSCRIBE to Asterisk and start receiving
subsequent NOTIFY requests.

Matthew Jordan
Digium, Inc. | Director of Technology
445 Jan Davis Drive NW - Huntsville, AL 35806 - USA
Check us out at: http://digium.com & http://asterisk.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-dev/attachments/20150224/55f049dd/attachment.html>

More information about the asterisk-dev mailing list