I. Qu'est-ce que le failover ?▲
Littéralement le terme " failover " signifie basculement. La signification de failover appliqué à WCF 4 en est proche puisqu'il s'agit de la capacité du Routing Service de WCF 4 à savoir basculer d'un service à un autre quand le service initial est défaillant. En clair, si un service est indisponible, le Routing Service de WCF 4 saura rediriger le message vers un autre service disponible. Il est très facile d'imaginer la robustesse et le haut niveau de disponibilité qu'une telle fonctionnalité peut donner à nos applications. Voyons cela plus en détail, et surtout comment WCF 4 en tire parti.
II. WCF 4 et le service failover▲
Nous avons vu au travers de précédents articles les nombreuses fonctionnalités qu'apportent le Routing Service de WCF 4. Nous allons découvrir celle du " Service Failover ". Le Routing Service qui sert d'intermédiaire entre le client et le service, va être capable d'identifier qu'un service est indisponible (une exception est levée et interceptée) et va alors router le message vers un autre service, qui sera un service de secours.
Comme pour quasiment l'ensemble des fonctionnalités du Routing Service cela se passe au niveau du fichier de configuration. Voyons comment procéder pour faire en sorte que le service de routage de WCF 4 soit capable de diriger un message vers un autre service en cas d'indisponibilité du service initial.
III. Implémentation du Service Failover avec WCF 4▲
L'implémentation du Service Failover va se passer en intégralité dans le fichier de configuration du service de routage (app.config ou web.config) et va être totalement transparent pour le client et le service. Voici un schéma présentant l'architecture ciblée après activation du Service Failover :
Comme indiqué sur le schéma nous avons un client qui se connecte au Service 1 par le biais d'un routeur WCF (Routing Service). Si jamais le Service 1 n'est pas disponible alors le Routing Service va renvoyer automatiquement le message vers Backup Service 2, si jamais ce dernier n'est pas disponible alors le Routing Service va renvoyer le message vers Backup Service 3 et ainsi de suite... L'ordre de basculement vers les services " de secours " est basé sur l'ordre des endpoints déclarés dans la Backup List dans le fichier de configuration.
L'avantage du Service Failover de WCF est que cela est totalement transparent pour le client et pour les services, seul le service de routage a connaissance de la configuration du basculement des services. Toute la configuration est centralisée dans le fichier de configuration et facile à maintenir et à faire évoluer, pas la peine de compiler et de redéployer du code. Il est possible de définir autant de BackupList que nécessaire, de plus les bindings des " services de secours " ne doivent pas forcément être les mêmes que celui du service initial. Par exemple un service défaillant qui utilise basic http pourra être secondé par un service utilisant TCP. La seule contrainte est, qu'évidemment tous les services doivent implémenter le même contrat (interface).
Voici à quoi doit ressembler le fichier de configuration du service de routage :
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service
name
=
"System.ServiceModel.Routing.RoutingService"
behaviorConfiguration
=
"MyRoutingServiceBehavior"
>
<endpoint
address
=
"http://localhost:8000/RoutingService/applicationA"
binding
=
"basicHttpBinding"
contract
=
"System.ServiceModel.Routing.ISimplexDatagramRouter"
/>
</service>
</services>
<client>
<endpoint
address
=
"http://localhost:8001/ServiceS1"
binding
=
"basicHttpBinding"
contract
=
"*"
name
=
"ServiceS1"
>
</endpoint>
<endpoint
address
=
"http://localhost:8002/ServiceBackup2"
binding
=
"basicHttpBinding"
contract
=
"*"
name
=
"ServiceBackup2"
>
</endpoint>
<endpoint
address
=
"http://localhost:8003/ServiceBackup3"
binding
=
"basicHttpBinding"
contract
=
"*"
name
=
"ServiceBackup3"
>
</endpoint>
<endpoint
address
=
"http://localhost:8004/ServiceBackup4"
binding
=
"basicHttpBinding"
contract
=
"*"
name
=
"ServiceBackup4"
>
</endpoint>
</client>
<behaviors>
<serviceBehaviors>
<behavior
name
=
"MyRoutingServiceBehavior"
>
<serviceMetadata
httpGetEnabled
=
"True"
httpGetUrl
=
"http://localhost:8000/RoutingService/applicationA"
/>
<routing
filterTableName
=
"RoutingServiceFilterTable"
/>
<serviceDebug
includeExceptionDetailInFaults
=
"true"
/>
</behavior>
</serviceBehaviors>
</behaviors>
<routing>
<filterTables>
<filterTable
name
=
"RoutingServiceFilterTable"
>
<add
filterName
=
"MyFailoverFilter"
endpointName
=
"ServiceS1"
backupList
=
"servicesBackupList"
/>
</filterTable>
</filterTables>
<filters>
<filter
name
=
"MyFailoverFilter"
filterType
=
"MatchAll"
/>
</filters>
<backupLists>
<backupList name
=
"servicesBackupList"
>
<add
endpointName
=
"ServiceBackup2"
/>
<add
endpointName
=
"ServiceBackup3"
/>
<add
endpointName
=
"ServiceBackup4"
/>
</backupList>
</backupLists>
</routing>
</system.serviceModel>
</configuration>
Voyons plus en détail les éléments importants qui permettent d'activer le failover sur le service de routage.
III-A. Définition de la liste de backup▲
La baliste BackupList contient la liste des endpoints qui serviront de service de secours en cas d'indisponibilité du service principal. Ils seront appelés en respectant l'ordre de la liste. Il est possible de définir plusieurs listes à hauteur d'une liste par endpoint de type "service".
<backupLists>
<backupList name
=
"servicesBackupList"
>
<add
endpointName
=
"ServiceBackup2"
/>
<add
endpointName
=
"ServiceBackup3"
/>
<add
endpointName
=
"ServiceBackup4"
/>
</backupList>
</backupLists>
III-B. Modification du endpoint▲
Pour que la liste des services de backup déclarés précédemment soit liée à un service il faut modifier le endpoint associé à ce même service. Cela s'effectue en ajoutant dans la section 'filterTable', une variable BackupList qui pointe vers une BackupList existante.
<routing>
<filterTables>
<filterTable
name
=
"RoutingServiceFilterTable"
>
<add
filterName
=
"MyFailoverFilter"
endpointName
=
"ServiceS1"
backupList
=
"servicesBackupList"
/>
</filterTable>
</filterTables>
<filters>
<filter
name
=
"MyFailoverFilter"
filterType
=
"MatchAll"
/>
</filters>
<backupLists>
<backupList name
=
"servicesBackupList"
>
<add
endpointName
=
"ServiceBackup2"
/>
<add
endpointName
=
"ServiceBackup3"
/>
<add
endpointName
=
"ServiceBackup4"
/>
</backupList>
</backupLists>
</routing>
Pour valider le fonctionnement du Service Failover ouvrez la solution incluse avec cet article, appuyez sur F5, envoyez un message depuis le client WinForms, le Service S1 reçoit le message.
Maintenant fermez la console hôte du service S1, envoyez un message, le message est alors réceptionné par le " Backup Service 2 " ; procédez de la sorte avec Backup Service 3 et Backup Service 4 pour valider le basculement automatique du Routing Service en cas d'indisponibilité d'un service.
IV. Conclusion▲
Vous avez pu voir qu'il est facile d'implémenter le Service Failover avec WCF 4, de plus la transparence pour le service, comme pour le client, fait que cette solution permet de construire des infrastructures de services robustes et hautement disponibles, ne vous en privez pas ! Rendez-vous prochainement pour d'autres tutoriels présentant les nouveautés de WCF 4.