Petals en distribué sur des Machines Virtuelles

Il se trouve qu’au début de l’été, j’ai eu à expérimenter certaines choses avec Petals.
Rien de révolutionnaire, mais il s’agissait de choses que je n’avais jamais tentées.

L’une d’elles concernaient l’utilisation de Petals avec des machines virtuelles. Je savais que cela était possible, plusieurs personnes l’ayant déjà fait par le passé. Cela ne m’a d’ailleurs pas pris très longtemps, mais je préfère me laisser des notes au cas où j’aurais à le refaire plus tard. Ce blog fera très bien l’affaire pour cette tâche. Et si jamais vous voulez valider le fonctionnement de Petals sur des VM, ce post pourra vous aider.

 

Installation des VM

D’abord, j’ai testé le tout sur Ubuntu (10.04 LTS).
J’ai installé VirtualBox pour émuler un deuxième hôte sur ma machine (ce deuxième hôte était une autre version d’Ubuntu dont j’avais récupérée l’image sur le net). Pour ces étapes, le mieux est de s’inspirer de la documentation assez riche sur le sujet.

http://doc.ubuntu-fr.org/virtualbox
http://www.siteduzero.com/tutoriel-3-36484-virtualisez-un-systeme-d-exploitation-avec-virtualbox.html#ss_part_2
http://videonoob.fr/tutoriel/virtualbox-installer-ubuntu
http://www.virtualbox.org/manual/ch06.html

En gros, cette étape consiste à installer dans une machine virtuelle un système d’exploitation donné.
Le principe du test, celui qui permet de vérifier le fonctionnement de Petals sur des VM, est d’avoir une topologie distribuée sur 2 noeuds : un noeud sur l’hôte courant et l’autre sur une VM (on peut aussi s’amuser à créer plusieurs VM). Dans la mesure où l’on fait du distribué, il faut que chaque VM puisse communiquer avec l’hôte courant et les autres VM. Pour cela, il faut penser à activer la bonne configuration réseau dans VirtualBox. J’avais pour ma part utilisé le mode Host-only networking de VirtualBox.

 

Installation de Petals en distribué

Une fois qu’on a nos VM, il faut maintenant installer Petals et le paramétrer pour fonctionner en distribué.
L’installation consiste à dézipper l’archive de Petals sur chaque VM. Puis on met à jour le fichier topology.xml.

<?xml version="1.0" encoding="UTF-8"?>
<tns:topology xmlns:tns="http://petals.ow2.org/topology"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://petals.ow2.org/topology petalsTopology.xsd">
	<tns:domain mode="static" name="PEtALS">
		<tns:description>The static domain configuration</tns:description>

		<!--
			defaut configuration to use MySql as centralize petals registry
			<tns:jndi>
			<tns:factory>org.ow2.petals.registry.database.RegistryInitialContextFactory</tns:factory>
			<tns:provider-url>jdbc:mysql://localhost:3306/mysql</tns:provider-url>
			<tns:security-principal>root</tns:security-principal>
			<tns:security-credentials>mysql</tns:security-credentials>
			<tns:pool-size>5</tns:pool-size> <tns:batch-size>10</tns:batch-size>
			</tns:jndi>
		-->

		<tns:sub-domain name="subdomain1" mode="master-slave">
			<tns:description>description of the subdomain</tns:description>
			<tns:container name="0" type="master">
				<tns:description>description of the container 0</tns:description>
				<tns:host>192.168.38.100</tns:host>
				<tns:user>petals</tns:user>
				<tns:password>petals</tns:password>
				<tns:webservice-service>
					<tns:port>7600</tns:port>
					<tns:prefix>petals/ws</tns:prefix>
				</tns:webservice-service>
				<tns:jmx-service>
					<tns:rmi-port>7700</tns:rmi-port>
				</tns:jmx-service>
				<tns:transport-service>
					<tns:tcp-port>7800</tns:tcp-port>
				</tns:transport-service>
				<tns:registry-service>
					<tns:port>7900</tns:port>
				</tns:registry-service>
			</tns:container>

			<tns:container name="1" type="slave">
				<tns:description>description of the container 1</tns:description>
				<tns:host>192.168.38.106</tns:host>
				<tns:user>petals</tns:user>
				<tns:password>petals</tns:password>
				<tns:webservice-service>
					<tns:port>7601</tns:port>
					<tns:prefix>petals/ws</tns:prefix>
				</tns:webservice-service>
				<tns:jmx-service>
					<tns:rmi-port>7701</tns:rmi-port>
				</tns:jmx-service>
				<tns:transport-service>
					<tns:tcp-port>7801</tns:tcp-port>
				</tns:transport-service>
				<tns:registry-service>
					<tns:port>7901</tns:port>
				</tns:registry-service>
			</tns:container>

			<!--
			<tns:container name="2" type="slave">
				<tns:description>description of the container 2</tns:description>
				<tns:host>localhost</tns:host>
				<tns:user>petals</tns:user>
				<tns:password>petals</tns:password>
				<tns:webservice-service>
					<tns:port>7602</tns:port>
					<tns:prefix>petals/ws</tns:prefix>
				</tns:webservice-service>
				<tns:jmx-service>
					<tns:rmi-port>7702</tns:rmi-port>
				</tns:jmx-service>
				<tns:transport-service>
					<tns:tcp-port>7802</tns:tcp-port>
				</tns:transport-service>
				<tns:registry-service>
					<tns:port>7902</tns:port>
				</tns:registry-service>
			</tns:container>
			-->
		</tns:sub-domain>
	</tns:domain>
</tns:topology>

Ici, j’ai une topologie de 2 noeuds, avec une relation maitre / esclave. On peut évidemment rajouter d’autres noeuds, qui seront configurés en esclave. Il n’y a qu’un maître par topologie, et celui-ci sert de référent aux autres noeuds pour synchroniser leur annuaire de services. Cela permet à chaque noeud d’être indépendant tout en étant capable de communiquer avec les autres. Un des inconvénients toutefois, c’est que le noeud maître revêt une importance plus grande que les autres. On peut cependant s’assurer de sa haute disponibilité avec un outil tel que Heartbeat. Et cela dépend aussi de la fréquence des déploiements sur la topologie. La synchronisation entre les noeuds n’est nécessaire que lors de l’installation ou la désinstallation de services sur le bus.

Une fois que l’on a défini sa topologie, on peut soit la copier dans chaque installation de Petals (dossier conf), soit la mettre sur un serveur web et faire pointer chaque noeud sur l’adresse du fichier. Cette deuxième méthode est la plus pratique en mode distribué. L’adresse est définie dans le fichier conf/server.properties de chaque noeud.

# Alternate topology configuration file URL. This value must be a valid URL like :
#  - http://localhost:8080/petals/topology.xml
#  - file:///home/petals/config/topology.xml
#  - or any valid URL (java.net.URL validation)
# If not specified, the local topology.xml file is used
petals.topology.url=http://192.168.38.106:8080/petals/topology.xml

 

Déploiement de services

Résumons…
Nous avons installé nos serveurs virtuels.
Nous avons installé Petals et l’avons configuré en distribué.

On va maintenant faire un petit test mettant en oeuvre le routage interne de Petals. Pour cela, on va déployer le composant Clock de Petals. Ce composant, véritable concentré de technologie, fournit un service qui donne l’heure. On le déploie donc sur chaque instance de Petals (chaque noeud).

Du point de vue de l’annuaire de services, on a la hiérarchie suivante :

  • Interface : Clock
  • Service : ClockService
  • End-points : edpt-1, edpt-2, …, edpt-n, où chaque edpt pointe vers un noeud Petals.

A chaque fois que l’on déploie notre composant, le même service est enregistré dans Petals. Ce service est identifié par un nom d’interface (un contrat technique, cad une liste d’opérations, chaque opération ayant des paramètres d’entrée et/ou de sortie), un nom de service (qui identifie une implémentation) et un nom d’end-point (qui identifie un point de déploiement). Comme c’est le même service qui est déployé à chaque fois, le nom d’interface et de service est le même pour chaque enregistrement. Seul change le nom d’end-point, qui est généré au déploiement (c’est un comportement par défaut de ce composant Clock).

On a donc un service à invoquer, service qui est répliqué sur chaque noeud du bus.
Il reste à l’invoquer. Pour cela, on utilise le sample client, un autre composant de Petals, qui est à la fois rustique et pratique. On le déploie une seule fois, sur l’hôte courant. Une fenêtre Swing s’ouvre (c’est le comportement du composant, lorsqu’il est démarré, il montre une petite console graphique).

Dans l’onglet Query, cliquer sur Get all the endpoints.
Tous les services du bus sont alors listés. On peut alors en sélectionner un. En mettant à jour les propriétés d’invocation, et plus exactement en n’invoquant que par nom d’interface et nom de service, on peut alors demander au bus de choisir un service qui vérifie ces critères parmi ceux disponibles. Le service finalement choisi par le bus (selon les critères fournis par le consommateur) peut être situé sur le même noeud que le consommateur ou bien être sur un autre noeud de la topologie. En fait, tout cela est transparent pour le consommateur de service (ici, le sample client).

En réitérant l’appel, on peut ainsi vérifier les capacités en distribué de Petals.
Exemple : en invoquant un service ClockService qui implémente le contrat Clock

  • Appel 1 : on tombe sur edpt-2
  • Appel 2 : on tombe sur edpt-1
  • Appel 3 : on tombe sur edpt-1 (encore).
  • etc…

A noter !

Suite à un commentaire, je me dois de préciser que le fichier server.properties du noeud sur lequel a été déployé le sample client a été modifié pour pouvoir appeler de manière aléatoire n’importe quel service de toute la topologie. Il suffit pour cela de mettre

petals.router.strategy=random,2,2,1

La configuration du routeur de Petals sera bientôt documentée sur le wiki de Petals…

Donc ici, comme il y a plusieurs services « ClockService implémentant le contrat Clock », et que l’invocation ne spécifie pas le end-point à appeler, alors c’est le bus qui le choisit pour nous. En cas d’équivalence de service, le choix est effectué de manière aléatoire. D’autres stratégies pourraient être utilisées, comme un round-robin, la qualité de service ou basé sur la consommation des ressources. Cependant, ces autres stratégies ne sont pour le moment pas implémentées.

On peut aussi suivre et visualiser les appels avec la web console de Petals.
Je ne l’ai pas fait ici, mais pour les curieux, il y a un guide de démarrage pour Petals qui contient entre autres des exercices avec la web console.

 

Au sujet de la synchronisation…

J’ai dit plus haut qu’en distribué, le noeud maître servait de référent pour synchroniser les annuaires de services. Cette synchronisation est périodique et configurée dans le fichier server.properties de chaque noeud esclave. Lorsque l’on déploie un service, il faut donc attendre que la période se soit écoulée pour que le service déployé soit visible depuis les autres noeuds.

Cependant, il est possible de forcer une synchronisation, soit avec JMX, soit en mode console (option de démarrage avec Petals 3.x, et possibilité d’utiliser une console externe, que l’on appelle Petals-CLI, et qui sera promue avec la version 4 de Petals ESB).

Publicités

About this entry