af83

De la répartition de charge en Ruby on Rails 2/2

L'architecture.

Les bots

Il ne reste qu'à  exploiter les capacités de Rails et de XMPP afin de développer les bots qui vont effectuer les traitements.

Exemple :

#!/usr/bin/env ruby
#
# MonBot save message through ActiveRecord

require 'rubygems'
require 'xmpp4r-simple'
require 'daemons'
require 'yaml'
require 'logger'

RAILS_ENV = ARGV[0] || 'development'
require File.dirname(__FILE__) + '/../config/environment'

require 'mysql_retry_lost_connection'

class MonBot
  @@bot_jid = "monbot@jabber.toto.com/1"
  @@bot_password = '123'
  @@logger = Logger.new("monbot.log")

  def initialize
    @@logger.info('initialize') { "Initializing in #{RAILS_ENV} mode ..." }
    @jabber = Jabber::Simple.new(@@bot_jid, @@bot_password)
  end

  def receive_msg
    loop do
      @jabber.received_messages do |message|

        # on désérialise le message s'il a été transmis de la sorte
        obj = YAML.load(message.body)

        mon_traitement(obj)

      end
      sleep 0.5
    end
  end

  private

  def mon_traitement(obj)
    obj.find_by_login("toto")
  end

end

bot = MonBot.new
bot.receive_msg
RAILS_ENV = ARGV[0]
require File.dirname(__FILE__) + '/../config/environment'

Ces lignes permettent à  un script Ruby de charger l'environnement Rails du projet. Le bot est alors capable d'attaquer notre modèle de données via ActiveRecord.

require 'xmpp4r-simple'

Ce gem nous permet de communiquer vers le compte Jabber du bot. Il peut donc dépiler les objets qui lui sont destiné et les désérialiser pour les traiter.

require 'daemons'

Ce gem permet de gérer le bot en tant que service (stop/start/restart).

require 'yaml'

Pour sérialiser/désérialiser vos objets Ruby / Rails.

require 'mysql_retry_lost_connection'

Ce gem sert à  intercepter une coupure de la connexion vers MySQL. Il surcharge ActiveRecord afin de renégocier une connexion.

Avec ces outils nous avons la capacité de créer des services exploitant une file d'attente Jabber et fonctionnant en parallèle. Ainsi, si la charge vient à  augmenter, les messages en attente de traitement ne seront pas perdus, puisqu'en attente dans les comptes Jabber stockés par ejabberd. De plus il est possible de multiplier un même bot en exploitant les ressources du protocole Jabber, chaque bot écoutant sur sa propre ressource (bot@monserveurjabber.com/1, bot@monserveurjabber.com/2, …).

Résumé

Pour Noumba, nous avons développé un projet en Rails, le Hub, qui gère la file d'attente Jabber, et communique en REST avec le frontal Noumba. Si cette architecture est sur-dimensionnée pour votre projet, nul besoin d'un backend. Votre site et des bots suffisent amplement. De même quelques comptes Gmail suffisent si vos ne souhaitez pas déployer votre propre serveur Jabber.

Si un backend en Rails s'avère nécessaire il n'est pas conseillé de dupliquer les modèles de votre site principal vers celui-ci. Cela fonctionne mais le principe DRY est de fait supprimé. Cependant un outil tel que Piston permet de temporiser cette affirmation.

Les autres

Après divers essais Twitter a fini par développer son propre serveur de file qui exploite memcached, starling

Un développeur de Seesmic indique utiliser ActiveMQ et RabbitMQ mais semble vouloir migrer vers une solution XMPP : scaling-questions-and-issues

Il existe un grand nombre d'alternatives, on peut citer :

Les deux premiers utilisent le twisted like eventmachine

Bémol

Une telle architecture implique la gestion d'un serveur Jabber, ce qui peut s'avérer une tà¢che plus complexe et lourde qu'un réel MoM dédié. De plus la stabilité de la bibliothèque xmpp4r ainsi que le plugin ActionMessenger est à  surveiller de près. Pour ce dernier, il a été nécessaire de le patcher afin qu'il puisse supporter plusieurs instances Rails.

Avenir

XMPP est un protocole standard et ouvert très répandu ce qui en fait un candidat idéal si l'on souhaite une architecture pérenne et évolutive. L'architecture décentralisée de Jabber et ses capacités à  se connecter à  des services externes tel que OpenID (xmppid.net) ouvre la porte à  une multitude de possibilités.

Ses nombreuses fonctionnalités dédiés au chat (room, pub/sub, voIP, …) sont toutes indiquées pour des sites communautaires et sociaux à  tel point que le projet DiSo souhaite l'utiliser en son coeur, mais ceci est un autre sujet.

blog comments powered by Disqus