
Dans cet article, je vais vous expliquer comment créer un graphique de route pour les applications avec Apache Camel, suivre le statut de ces routes et collecter des métriques pour elles.
Nous utilisons Apache Camel dans les applications de printemps et dans Apache ServiceMix. Et si les itinéraires d'un service séparé sont compréhensibles et facilement visibles, alors dans le bus de données, où il existe de nombreux itinéraires, ce n'est pas si simple.
Qu'est-ce qu'Apache ServiceMixApache Camel est un framework open-source pour l'intégration d'applications grâce à l'utilisation de DSL simple et d'un ensemble riche de composants d'accès aux données prêts à l'emploi.
Apache ServiceMix est une solution open source basée sur Apache ActiveMQ, Camel, CXF, Karaf, qui vous permet de créer une plate-forme pour des solutions d'intégration. Apache ServiceMix peut être utilisé comme bus de services d'entreprise. Camel dans ce cas simplifiera la création de routes dans le bus en utilisant dsl sous la forme de xml, java, scala, etc. Par exemple, si nous devons transférer des messages d'une file d'attente à une autre (ne pensons pas pourquoi nous en avons besoin), nous pouvons décrire l'itinéraire dans le fichier xml (exemple ci-dessous), le déposer dans le répertoire de service souhaité et il sera déployé.
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <route> <from uri="file:camel/input"/> <log message="Moving ${file:name} to the output directory"/> <to uri="file:camel/output"/> </route> </camelContext> </blueprint>
L'itinéraire décrit transfère les fichiers d'un répertoire à un autre.
Au fil des années d'utilisation, le pneu a accumulé plus d'une centaine d'itinéraires de complexité variable, et nous avons compris qu'il devient de plus en plus difficile de se souvenir de toutes ces connexions. Dessiner des schémas d'itinéraire avec vos mains ou les décrire sous forme de tableaux a cessé de sembler une solution pratique et facilement prise en charge. Mais il a commencé à sembler que la construction automatique d'un graphique d'itinéraire sauverait tout le monde.
Pour construire un graphique, vous avez besoin de sommets et d'arêtes. Et parmi ceux-ci, nous aveuglons quelque chose de beau!
Éléments de l'itinéraire
Le point d'entrée (c'est un) pour l'itinéraire est décrit par l'instruction from
avec une indication de point d'extrémité. C'est-à-dire pour
<from uri="file:camel/input"/>
le point final sera le file:camel/input
. Il nous dit qu'au début de la route les fichiers seront extraits du répertoire camel/input
.
Les points de sortie de l'itinéraire (il y en a beaucoup, c'est pourquoi j'ai indiqué le pluriel) sont déterminés différemment - en fonction du modèle de messagerie également avec le point de terminaison indiqué. Dans l'exemple ci-dessus, un tel point est décrit par to
. C'est-à-dire pour
<to uri="file:camel/output"/>
le point de terminaison sera le file:camel/output
. Il nous dit qu'à la fin de l'itinéraire, les fichiers seront enregistrés dans le répertoire camel/output
.
Les points de terminaison sont les sommets dont nous avons besoin. Les côtes détermineront les routes elles-mêmes.
Obtenir des descriptions d'itinéraire
Servicemix offre la possibilité d'accéder à diverses informations à l'aide de JMX et nous utiliserons jolokia pour accéder à ces informations via http.
À titre d'exemple, prenez cette description des itinéraires
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route id="the-clock-is-ticking"> <from uri="timer://foo?fixedRate=true&period=1000"/> <to uri="jms:topic:timer?connectionFactory=demo"/> </route> <route id="service-a"> <from uri="jms:topic:timer?connectionFactory=demo"/> <to uri="jms:queue:service-a?connectionFactory=demo"/> </route> <route id="service-a-log"> <from uri="jms:queue:service-a?connectionFactory=demo"/> <to uri="log:service-a"/> </route> </camelContext> </beans>
Liste des itinéraires
La méthode http://host:8181/jolokia/read/org.apache.camel:type=routes,*
renvoie une liste de routes avec des détails.
Exemple de données de retour pour l'itinéraire service-a
:
"org.apache.camel:context=a.xml,name=\"service-a\",type=routes": { "StatisticsEnabled": true, "EndpointUri": "jms:\/\/topic:timer?connectionFactory=demo", "CamelManagementName": "a.xml", "ExchangesCompleted": 173, "LastProcessingTime": 2, "ExchangesFailed": 0, "Description": null, "FirstExchangeCompletedExchangeId": "ID-...", "StartTimestamp": "2018-12-17T07:01:12Z", "FirstExchangeCompletedTimestamp": "2018-12-17T07:01:13Z", "LastExchangeFailureTimestamp": null, "MaxProcessingTime": 35, "LastExchangeCompletedTimestamp": "2018-12-17T07:04:05Z", "Load15": "", "DeltaProcessingTime": -8, "OldestInflightDuration": null, "ExternalRedeliveries": 0, "ExchangesTotal": 173, "ResetTimestamp": "2018-12-17T07:01:12Z", "ExchangesInflight": 0, "MeanProcessingTime": 4, "LastExchangeFailureExchangeId": null, "FirstExchangeFailureExchangeId": null, "Uptime": "2 minutes", "CamelId": "camel-3", "TotalProcessingTime": 827, "FirstExchangeFailureTimestamp": null, "RouteId": "service-a", "RoutePolicyList": "", "FailuresHandled": 0, "MessageHistory": true, "Load05": "", "OldestInflightExchangeId": null, "State": "Started", "InflightExchanges": 0, "Redeliveries": 0, "MinProcessingTime": 0, "LastExchangeCompletedExchangeId": "ID-...", "Tracing": false, "Load01": "" }
Il y a beaucoup de RouteId
et parmi eux, RouteId
, Context
, EndpointUri
, State
, Uptime
sont d'un intérêt particulier pour la construction de graphiques.
Il est important de mentionner que la méthode renvoie des métriques tout au long de l'itinéraire: ExchangesTotal
, ExchangesCompleted
, ExchangesFailed
, ExchangesInflight
, etc.
La méthode ci-dessus couvre 90% de nos besoins en données, mais elle ne renvoie pas d'informations sur les points de sortie de l'itinéraire. Pour obtenir ces informations, vous devez utiliser la méthode d'obtention des détails de l'itinéraire et la méthode d'obtention du schéma. Une des méthodes ne suffit pas, car dans certains cas, les méthodes ne renvoient pas toutes les données nécessaires pour former une liste de points de sortie.
Détails de l'itinéraire
Les détails de l'itinéraire sont obtenus à partir de la méthode.
http://host:8181/jolokia/exec/org.apache.camel:context=a.xml,type=routes,name="service-a"/createRouteStaticEndpointJson(boolean)/true
Exemple de données retournées:
{ "request": { "mbean": "org.apache.camel:context=a.xml,name=\"service-a\",type=routes", "arguments": ["true"], "type": "exec", "operation": "createRouteStaticEndpointJson(boolean)" }, "value": "{\"routes\": { \"service-a\": { \"inputs\": [ { \"uri\": \"jms:\/\/topic:timer?connectionFactory=demo\" } ], \"outputs\": [ { \"uri\": \"jms:\/\/queue:service-a?connectionFactory=demo\" } ] }}\n}\n", "timestamp": 1545040570, "status": 200 }
Carte d'itinéraire
Le diagramme d'itinéraire est obtenu à partir de la méthode
http://host:8181/jolokia/exec/org.apache.camel:context=a.xml,type=routes,name="service-a"/dumpRouteAsXml(boolean)/true
.
La méthode ne renvoie le diagramme de route au format xml que s'il y a été établi. Par exemple, si un itinéraire est décrit à l'aide de org.apache.camel.builder.RouteBuilder
(utilisé lors de la description des itinéraires dans une application Spring), la méthode ne renverra rien.
Exemple de données retournées:
{ "request": { "mbean": "org.apache.camel:context=a.xml,name=\"service-a\",type=routes", "arguments": ["true"], "type": "exec", "operation": "dumpRouteAsXml(boolean)" }, "value": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<route customId=\"true\" id=\"service-a\" xmlns=\"http:\/\/camel.apache.org\/schema\/spring\">\n <from uri=\"jms:topic:timer?connectionFactory=demo\"\/>\n <to uri=\"jms:queue:service-a?connectionFactory=demo\" id=\"to5\"\/>\n<\/route>\n", "timestamp": 1545040727, "status": 200 }
Dessinez un graphique
En combinant toutes les informations reçues, vous pouvez dessiner un graphique en toute sécurité, j'ai utilisé vis.js
et obtenu ce résultat

Les points sont des points d'entrée et de sortie, les bords sont des itinéraires et les nombres gris sur les itinéraires sont la métrique ExchangesTotal
.
Représentation graphique de plusieurs services
L'approche décrite de la construction graphique convient également au cas où le chameau est utilisé non seulement dans le bus de données, mais également dans les applications. Par exemple, après avoir décrit l'itinéraire dans l'application de cette manière:
@Component public class EventRoutes extends RouteBuilder { @Override public void configure() throws Exception { from("jms:topic:timer") .inOnly("bean:service?method=handle"); } }
Vous pouvez combiner toutes les données sur les itinéraires de servicemix
et de l'application et dessiner un graphique commun

Notez qu'une nouvelle route de jms:topic:timer
to bean:service
apparue sur le diagramme.
Conclusion
En mettant en œuvre l'approche décrite pour la construction d'un graphique d'itinéraire, nous avons pu obtenir une image globale à la fois du bus et des services intégrés. En fait, le graphique de notre pneu ressemble à ceci

Les applications de preuve de concept peuvent être vues ici - Github