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

Olle E. Johansson oej at edvina.net
Mon Feb 23 14:07:41 CST 2015

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.

Forking doesn't cost much, really. Using SIP makes life simple. The network flow is already established.

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.

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.

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.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-dev/attachments/20150223/6a7458d2/attachment.html>

More information about the asterisk-dev mailing list