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

Olle E. Johansson oej at edvina.net
Mon Feb 23 09:26:21 CST 2015


On 23 Feb 2015, at 16:19, Matthew Jordan <mjordan at digium.com> wrote:

> 
> 
> On Wed, Feb 11, 2015 at 11:12 AM, Olle E. Johansson <oej at edvina.net> wrote:
> 
> On 11 Feb 2015, at 17:50, Matthew Jordan <mjordan at digium.com> wrote:
> 
>> 
>> 
>> On Tue, Feb 3, 2015 at 6:11 AM, Daniel-Constantin Mierla <miconda at gmail.com> wrote:
>> 
>> 
>> I was thinking some more about this, and I realized that I'm not really sure how I would pick a specific Asterisk server in a pool of servers.
>> 
>> This is probably going to demonstrate some of my ignorance when it comes to Kamailio, but I'm going to go ahead anyway :-)
>> 
>> Say, for example, we have n Asterisk servers, all of which can serve any need that an inbound SIP request requires. They are generic media application servers, and Kamailio just needs to pick one and send the request to it, most likely indicating the purpose in a SIP header. Then, we may receive a request from Alice to go into a conference room:
>> 
>> INVITE sip:conference at my-service-provider.com SIP/2.0
>> From: Alice <alice at super-awesome-company.com>
>> ...
>> 
>> And we want to proxy that request to one of our media application servers, turning it into something like this:
>> 
>> INVITE sip:conference at asterisk-node-five.mydomain.com SIP/2.0
>> From: Alice <alice at super-awesome-company.com>
>> To: ...
>> X-Exec-App: Conference
>> X-Exec-App-Data: 1000
> No need to retarget unless your asterisk is really requiring that domain.
> 
> True. The same questions exist even if we are sending the INVITE request to sip:conference at asterisk-node-five.myservice-provider.com however.
>  
> 
>> 
>> Any Asterisk server can then receive the request, extract the application to execute, and start the correct application, letting an ARI application do the heavy lifting of actually implementing the requested application.
>> 
>> exten => s,1,NoOp()
>>  same => n,Set(app=${PJSIP_HEADER(read,X-Exec-App)})
>>  same => n,Set(args=${PJSIP_HEADER(read,X-Exec-App-Data)})
>>  same => n,Stasis(${app}, ${args})
>>  same => n,Hangup()
>> 
>> All of that is fine and good - but how did Kamailio choose "asterisk-node-five" as the Asterisk server to send the request to?
> There are many ways, our dispatcher module has as many ways to dispatch traffic as Asterisk has
> queue algorithms.
> 
> 
> I think that's a very apt comparison :-)
> 
> The Queue application's ring strategies can be problematic. In relatively simple scenarios they apply fairly well; with sufficient complexity, you either have to use other mechanics to achieve the functionality you want (say, for example, Local channel members) or you find that your ring strategy simply isn't achievable. Sometimes, Asterisk _can_ provide you the levers to toggle the behaviour you want; however, in many complex scenarios, it can't give you all the functionality you desire. Ideally, you want the developer building a system on top of Asterisk to control the business application logic - hence, the advent of ARI. In fact, the Queue application's ring strategy limitations were a major contributing factor in the development of ARI.
> 
> The same could be said here. Sure, I can use one of the many levers that exist in the dispatcher module, and there's a reasonable chance that it will accommodate the complexity of a particular scenario. Playing around with it over the past few days, ds_select_dst is clearly very powerful. On the other hand, I'm still limited to the algorithms implemented in Kamailio. While I could write my own algorithm in C and contribute it upstream, not everyone is a C programmer!
> 
Which is why we have python, lua, java, perl support...

> It may be given the tight timing constraints that Kamailio exists under (which is somewhat tighter than Asterisk determining who to ring in a Call Queue) that hardcoding the algorithms in Kamailio is the best way to do it - but I'm curious if there are ways outside of that.
Of course there are.

>  
>> What's more, if those servers are truly dynamic, where we are using something like OpenStack to spin up and spin down Asterisk servers on an as-needed basis, than the mere act of knowing the pool of available Asterisk server is going to be tricky. Granted, the Asterisk servers could register themselves to Kamailio, so it will know at any one time who all is available for a resource, but it feels like the Kamailio routing could get tricky, with a lot of business logic sprinkled into it.
> We could add the new DMQ message buss to Asterisk which would make Kamailio aware of it.
> There are many ways. Kamailio monitors the cluster with OPTIONs so if you spin up one that was 
> down, it won't take long before we send traffic.
> 
> 
> Or we could have Kamailio integrate with Asterisk using Corosync :-)
> 
> The DMQ message bus module looks to be rather generic. Is there any documentation on the actual messages published over the message bus?
DMQ sip messages :-)

> 
>  
>> 
>> Expanding on the snippet above, if I send another request from Bob <bob at super-awesome-company.com>, and Bob is attempting to get into the same conference room by sending a request to conference at my-service-provider.com, I need to have the logic someplace that we would preferably send Bob to the same Asterisk server. Granted, two Asterisk servers can form a single conference room by connecting themselves together, but that's less efficient than having both SIP requests land on the same Asterisk server.
> That is one area that needs some logic. I have used a realtime database for this with kamailio asking
> for routing. Or in another setup I just fork to all asterisk servers and the one that has the conference
> answers. If no one answer, I retarget the request to another uri which means "OPEN the damn conference"
> and target that to one specific server.
> 
> 
> Ouch on the forking. That's a bit of extra traffic on the Asterisk servers!
Nothing compared with the RTP traffic. That's the hard part for ASterisk. 
> 
> I think this goes back to my previous point of having "business logic" be accessible from the routing logic in Kamailio, where that business logic is hopefully not hardcoded in a non-scalable way.
>  
>> 
>> There may be elegant ways to handle this in Kamailio already; I'm just not sure what they would be in this scenario.
>> 
>> One way of handling this using Asterisk would be to have another Asterisk instance (or predictable set of Asterisk instances) act as a Redirect server. All requests that require a media application server get sent to those limited number of Asterisk servers, and they use an ARI application to perform the business logic lookups of who to forward the request onto. That Asterisk server would always return a 302 Redirect. Whether or not that removes Kamailio from the entire path or not is probably up to Kamailio to decide. But that ends up adding more communication to the path, and I'm not sure that's the right way to handle this.
> Too complex.
>> 
>> At some point in time, there's going to be (a) logic that requires dynamic lookups to determine where to send a request, and (b) business logic that has to live somewhere to govern those routing rules. I do know that having all of that live or be replicated across Asterisk servers is not fantastic; my inclination right now is to pull that out of the Asterisk instances and have those kinds of lookups live outside of the communications engines. I'd be curious what other options are available in a larger system architecture.
> 
> Sorry, but you are discussing non-issues. At least for me.
> 
> An issue in my mind would be to feed the load of one asterisk into
> kamailio to help with load-balancing algorithms. We have the data in Asterisk, but it's
> not in Kamailio. DMQ could be one option here, or an AMI module for Kamailio.
> 
> 
> 
> I'm not sure it's completely a non-issue. The scenario where individual requests are logically grouped at a higher level than what a pure load-balancing algorithm can ascertain is certainly "an issue," even if you solved it in a particular manner. Going to a database to determine whether or not a request should go to a particular server is certainly one way of solving it. However, you may either have to hit that database for every request, or you have to know in your routing that some destinations will require that lookup - which again requires adding business related logic to the Kamailio routing. Maybe that result is a foregone conclusion, but I'm curious if there are other ways around it.
We have a lot of tables in RAM in kamailio using htable.
> 
> The internet is certainly not overflowing with information on this topic, at the very least :-)
> 
> I agree that having the load of Asterisk feed out would be interesting. We had some discussion about this at AstriDevCon; particularly, what data items would be needed. There was some contention around exactly what should be available from Asterisk. Things that were listed were:
> CPU usage
> Channel count
> Memory usage
> Call quality statistics (as a secondary indicator)
> Distribution of response times on requests/responses
> I believe Torey mentioned that they send an INVITE request every so often and just see what happens - which is probably similar to the OPTIONS request pinging, although you'll get a bit more useful data out of the INVITE request.
> 
> Can you think of anything else?
SUBSCRIBE/NOTIFY format for Asterisk status.

> 
> Are there other ways of distributing this information other than AMI/DMQ? Asterisk also supports other mechanisms, including more standardized ones such as Corosync, statsd, etc. Given how easy it is to build an interface on top of the internal message bus in Asterisk, we're pretty flexible there. If we did push more information about load out of Asterisk, it'd be nice if it was in a standard way of consuming, such that it benefited users outside of Kamailio as well.

Use SIP!

/O

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


More information about the asterisk-dev mailing list