2009-06-11 24 views
3

J'écris plusieurs AGI en utilisant Perl qui sera appelé à partir du plan de numérotation Asterisk. Je m'attends à recevoir de nombreux appels similaires, j'ai donc besoin d'un moyen de les équilibrer. On m'a conseillé d'utiliser FastAGI au lieu de AGI. Le problème est que mes AGI seront distribués sur de nombreux serveurs et pas seulement sur un, et j'ai besoin que mon point d'entrée Asterisk répartisse les appels entre ces serveurs (où les agis résident) en fonction de leur disponibilité. J'ai donc pensé à fournir à l'application FastAGI plusieurs adresses IP au lieu d'une seule. C'est possible?Comment puis-je équilibrer la charge FastAGI?

Répondre

1

J'ai une grande implémentation IVR en utilisant FastAGI (24 E1 tous les appels FastAGI, pics à environ 80%, soit près de 600 canaux Asterisk appelant FastAGI). Je n'ai pas trouvé un moyen facile d'équilibrer la charge, mais dans mon cas il y a différents appels FastAGI: un au début de l'appel pour valider l'utilisateur dans une base de données, puis un autre pour vérifier l'équilibre de l'utilisateur transactions récentes, et un autre pour effectuer une transaction. J'ai donc envoyé toutes les requêtes de validation et simples à une application sur un serveur et tous les appels de transaction à une application différente sur un serveur différent.

Un moyen brut d'équilibrer la charge si vous avez beaucoup d'appels entrants sur les canaux zaptel/dahdi serait d'utiliser des groupes différents pour les canaux. Supposons par exemple que vous ayez 2 serveurs FastAGI et 4 E1 recevant des appels. Vous pouvez configurer 2 E1 dans le groupe g1 et les 2 autres E1 dans le groupe g2. Ensuite, vous déclarez les variables globales comme ceci:

[globals] 
serverg1=ip_of_server1 
serverg2=ip_of_server2 

ensuite sur votre dialplan vous appelez FastAGI comme ceci:

AGI(agi://${server${CHANNEL(callgroup)}}/some_action)

Sur les canaux appartenant au groupe g1, qui résoudra à serverg1 qui tranchera à ip_of_server1; sur les canaux appartenant au groupe g2, CHANNEL (callgroup) se résoudra en g2 pour que vous obteniez $ {serverg2} qui se résout en ip_of_server2.

Ce n'est pas la meilleure solution parce que les appels commencent généralement à arriver sur une travée, puis sur une autre, etc. Ainsi, un serveur aura plus de travail, mais c'est quelque chose.

Pour obtenir l'équilibrage de charge réelle, je suppose que nous devrions écrire une passerelle d'équilibrage de charge FastAGI, pas une mauvaise idée du tout ...

1

Mehhh ... utiliser les mêmes constructions qui s'appliqueraient pour charger quelque chose d'équilibrage comme les demandes de pages Web.

L'une des façons est de faire un round robin dans le DNS. Donc, si vous avez vru1.example.com 10.0.1.100 et vru2.example.com 10.0.1.101 vous mettez deux entrées dans le DNS comme ...

fastagi.example.com 10.0.1.100

fastagi.example .com 10.0.1.101

... puis à partir du plan de numérotation agi (agi: //fastagi.example.com/youagi) devrait en théorie alterner entre 10.0.1.100 et 10.0.1.101. Et vous pouvez ajouter autant d'hôtes que vous le souhaitez. L'autre voie à suivre est quelque chose d'un peu trop compliqué à expliquer ici, mais des outils de proxy comme HAProxy devraient pouvoir acheminer entre plusieurs serveurs avec l'avantage supplémentaire de pouvoir "retirer" le mélange pour la maintenance ou faire un équilibrage plus avancé comme distribuer également en fonction de la charge actuelle.

+0

No Good. Le client (c'est-à-dire Asterisk) est le plus susceptible de mettre en cache les requêtes DNS et donc d'utiliser toujours la même adresse IP à plusieurs reprises. Même avec un court TTL. – pdeschen

2

Tout proxy inverse TCP ferait l'affaire.HAProxy étant un et nginx avec le TCP module étant un autre. Il y a quelque temps, j'ai créé mon propre proxy FastAGI en utilisant node.js (nodast) pour résoudre ce problème très spécifique et un peu plus, y compris la possibilité d'exécuter le protocole FastAGI via SSL et de router les requêtes en fonction de la requête AGI l'emplacement et les paramètres (tels que $ dnis, $ channel, $ language, ...)

De plus, comme la configuration du proxy est essentiellement javascript, vous pouvez réellement charger l'équilibre de manière très intéressante.

Une config Sample est comme suit:

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;