Discussion:
Asterisk send calls to SIP Trunks with Round Robin Call Distribution
(too old to reply)
JR Richardson
2010-04-02 13:02:22 UTC
Permalink
Hi All,



I know I can do this pretty easily with one of the SIP Proxy/Routers, I
already do this using OpenSER as a load balancer.



I have a special requirement that insist an Asterisk server, 1.6.1.x, is
used. I will have 2 SIP trunks coming into the server and I will have to
send calls to these SIP trunks with a round robin distribution pattern. I
was thinking of using a group count function, if call count is even send
call to SIP Trunk 1, if call count is odd, send call to SIP Trunk 2.



Is there another mechanism I could use to accomplish such a need?



I appreciate any ideas or guidance.



Thanks.



JR
Steve Edwards
2010-04-02 13:45:19 UTC
Permalink
Post by JR Richardson
I have a special requirement that insist an Asterisk server, 1.6.1.x, is
used.  I will have 2 SIP trunks coming into the server and I will have
to send calls to these SIP trunks with a round robin distribution
pattern.  I was thinking of using a group count function, if call count
is even send call to SIP Trunk 1, if call count is odd, send call to SIP
Trunk 2.
The "decimal" portion of ${UNIQUEID} is incremented every time Asterisk
creates a channel. Applying your even/odd logic to this should work fine.
--
Thanks in advance,
-------------------------------------------------------------------------
Steve Edwards ***@sedwards.com Voice: +1-760-468-3867 PST
Newline Fax: +1-760-731-3000
JR Richardson
2010-04-05 19:18:31 UTC
Permalink
Post by Steve Edwards
Post by JR Richardson
I have a special requirement that insist an Asterisk server, 1.6.1.x, is
used.? I will have 2 SIP trunks coming into the server and I will have
to send calls to these SIP trunks with a round robin distribution
pattern.? I was thinking of using a group count function, if call count
is even send call to SIP Trunk 1, if call count is odd, send call to SIP
Trunk 2.
The "decimal" portion of ${UNIQUEID} is incremented every time Asterisk
creates a channel. Applying your even/odd logic to this should work fine.
Thanks Steve, works great:

exten => _X.,1,Set(uniqueidcut=${CUT(CDR(uniqueid),.,2)})
exten => _X.,n,Set(result=${MATH(${uniqueidcut}%2)})
exten => _X.,n,GotoIf($[${result} > 0 ]?siptrunk1,1:siptrunk2,1)

Thanks.

JR
--
JR Richardson
Engineering for the Masses
Steve Edwards
2010-04-05 21:26:07 UTC
Permalink
Post by JR Richardson
Post by Steve Edwards
Post by JR Richardson
I have a special requirement that insist an Asterisk server, 1.6.1.x,
is used.? I will have 2 SIP trunks coming into the server and I will
have to send calls to these SIP trunks with a round robin distribution
pattern.? I was thinking of using a group count function, if call
count is even send call to SIP Trunk 1, if call count is odd, send
call to SIP Trunk 2.
The "decimal" portion of ${UNIQUEID} is incremented every time Asterisk
creates a channel. Applying your even/odd logic to this should work fine.
exten => _X.,1,Set(uniqueidcut=${CUT(CDR(uniqueid),.,2)})
exten => _X.,n,Set(result=${MATH(${uniqueidcut}%2)})
exten => _X.,n,GotoIf($[${result} > 0 ]?siptrunk1,1:siptrunk2,1)
I don't have any empirical evidence, but I would suspect a variable
reference ("${UNIQUEID}") would be insignificantly faster than invoking a
function that references a variable ("CDR(uniqueid)").

Also, for the forseeable future, the Unix epoch will be 10 digits, so I
suspect specifying the character offset in the variable reference (":11"*)
will be insignificantly faster than invoking a function ("${CUT()}").

And, unless you have a specific need for the "decimal" portion of the
UNIQUEID, you could roll it all into a single conditional like:

gotoif($[${MATH(${UNIQUEID:11} % 2,int)} > 0]?siptrunk1,1:siptrunk2,1)

*) Assuming you're not using the "systemname" prefix.
--
Thanks in advance,
-------------------------------------------------------------------------
Steve Edwards ***@sedwards.com Voice: +1-760-468-3867 PST
Newline Fax: +1-760-731-3000
JR Richardson
2010-04-06 14:49:01 UTC
Permalink
Post by Steve Edwards
Post by JR Richardson
Post by Steve Edwards
Post by JR Richardson
I have a special requirement that insist an Asterisk server, 1.6.1.x,
is used.? I will have 2 SIP trunks coming into the server and I will
have to send calls to these SIP trunks with a round robin distribution
pattern.? I was thinking of using a group count function, if call
count is even send call to SIP Trunk 1, if call count is odd, send
call to SIP Trunk 2.
The "decimal" portion of ${UNIQUEID} is incremented every time Asterisk
creates a channel. Applying your even/odd logic to this should work
fine.
exten => _X.,1,Set(uniqueidcut=${CUT(CDR(uniqueid),.,2)})
exten => _X.,n,Set(result=${MATH(${uniqueidcut}%2)})
exten => _X.,n,GotoIf($[${result} > 0 ]?siptrunk1,1:siptrunk2,1)
I don't have any empirical evidence, but I would suspect a variable
reference ("${UNIQUEID}") would be insignificantly faster than invoking a
function that references a variable ("CDR(uniqueid)").
Also, for the forseeable future, the Unix epoch will be 10 digits, so I
suspect specifying the character offset in the variable reference (":11"*)
will be insignificantly faster than invoking a function ("${CUT()}").
And, unless you have a specific need for the "decimal" portion of the
gotoif($[${MATH(${UNIQUEID:11} % 2,int)} > 0]?siptrunk1,1:siptrunk2,1)
*) Assuming you're not using the "systemname" prefix.
I believe you are correct, that would be more efficient.

After mocking this up, the results were not as expected. The even/odd
modulus worked fine using the ${UNIQUEID}, it actually worked too
well. The issue I ran into was each inbound call was consistently
even or odd so all calls went to the same outbound trunk. Each call
would initiate another SIP call out, so the counter would do exactly
what it is supposed to do and increment on each SIP channel. It seems
pretty obvious now that I think about it. So the call distribution to
the outbound trunks will not work based on the incrementing counter of
the ${UNIQUEID}.

After some thought, I decided to send all outbound calls through a
GROUP_COUNT function and distribute calls to the trunks based on >
grater-than GottoIf statement like this:

[inbound]
exten => _X.,1,GotoIf($[${GROUP_COUNT(siptrunk1calls)} >
${GROUP_COUNT(siptrunk2calls)}
]?siptrunk2,${EXTEN},1:siptrunk1,${EXTEN},1)

[siptrunk1]
exten => _X,1,Set(GROUP()=siptrunk1calls)
exten => _X,n,Dial(SIP/${EXTEN}@siptrunk1,60,)

[siptrunk2]
exten => _X,1,Set(GROUP()=siptrunk2calls)
exten => _X,n,Dial(SIP/${EXTEN}@siptrunk2,60,)

This worked as expected and is evenly distributing inbound calls to
both SIP trunks based on channel usage, with is ultimately desired.
Of course this is not exactly a round robin distribution but works for
what I need.

Thanks.

JR
--
JR Richardson
Engineering for the Masses
Continue reading on narkive:
Loading...