我正在使用Perl编写多个AGI,这些AGI将从Asterisk拨号方案中调用。我希望收到许多同声电话,所以我需要一种方法来加载它们。我被建议使用FastAGI而不是AGI。问题是我的AGI将分布在许多服务器而不仅仅是一个服务器上,我需要我的入口点Asterisk根据它们的可用性在这些服务器(agis所在的位置)之间调用这些调用。所以,我想为FastAGI应用程序提供多个IP地址而不是一个。有可能吗?
答案 0 :(得分:2)
任何TCP反向代理都可以解决问题。 HAProxy是一个nginx而TCP module是另一个。{/ p>
前段时间,我使用node.js(nodast)制作了自己的FastAGI代理,以解决这个非常具体的问题和更多问题,包括通过SSL运行FastAGI协议和基于路由请求的能力在AGI请求位置和参数(例如$ dnis,$ channel,$ language,...)
此外,由于代理配置基本上是javascript,你实际上可以用非常有趣的方式加载平衡。
示例配置如下所示:
var config = {
listen : 9090,
upstreams : {
test : 'localhost:4573',
foobar : 'foobar.com:4573'
},
routes : {
'agi://(.*):([0-9]*)/(.*)' : function() {
if (this.$callerid === 'unknown') {
return ('agi://foobar/script/' + this.$3);
} else {
return ('agi://foobar/script/' + this.$3 + '?callerid' + this.$callerid);
}
},
'.*' : function() {
return ('agi://test/');
},
'agi://192.168.129.170:9090/' : 'agi://test/'
}
};
exports.config = config;
答案 1 :(得分:1)
我有一个使用FastAGI的大型IVR实现(24个E1都在进行FastAGI调用,峰值大约为80%,所以近600个Asterisk频道调用FastAGI)。我没有找到一种简单的方法来进行负载平衡,但在我的情况下,有不同的FastAGI调用:一个在调用开始时验证数据库中的用户,然后另一个调查用户的余额或最多最近的交易,另一个交易。
所以我所做的是将所有验证和简单查询发送到一台服务器上的一个应用程序,并将所有事务调用发送到另一台服务器上的另一个应用程序。
如果在zaptel / dahdi频道上有大量来电,那么进行负载均衡的粗略方法是为频道使用不同的组。例如,假设您有2个FastAGI服务器和4个E1接收呼叫。您可以在组g1中设置2个E1,在组g2中设置另外2个E1。然后你声明这样的全局变量:
[globals] serverg1=ip_of_server1 serverg2=ip_of_server2
然后在你的拨号方案上,你可以这样打电话给FastAGI:
AGI(agi://${server${CHANNEL(callgroup)}}/some_action)
在属于组g1的通道上,将解析为将解析为ip_of_server1的serverg1;在属于g2组的频道上,CHANNEL(callgroup)将解析为g2,因此你得到$ {serverg2},它解析为ip_of_server2。
这不是最好的解决方案,因为通常调用会在一个范围内开始,然后是另一个,等等,因此一个服务器将获得更多工作,但这是一些东西。
为了获得真正的负载平衡,我想我们必须编写一个FastAGI负载均衡网关,根本不是一个坏主意......
答案 2 :(得分:1)
Mehhh ...使用与网页请求等负载平衡相同的结构。
一种方法是在DNS中循环。因此,如果您有vru1.example.com 10.0.1.100和vru2.example.com 10.0.1.101,则在DNS中放入两个条目,如...
fastagi.example.com 10.0.1.100
fastagi.example.com 10.0.1.101
...然后从拨号计划agi(agi://fastagi.example.com/youagi)理论上应该在10.0.1.100和10.0.1.101之间交替。您可以根据需要添加任意数量的主机。
另一种方法是在这里解释一些有点太复杂的东西,但是像HAProxy这样的代理工具应该能够在多个服务器之间进行路由,并且能够“混合使用”混合物进行维护或者做更高级的平衡,比如根据当前负载平均分配。