{"id":863,"date":"2011-03-19T10:07:11","date_gmt":"2011-03-19T10:07:11","guid":{"rendered":"http:\/\/blog.milamberspace.net\/?p=863"},"modified":"2011-03-19T10:10:39","modified_gmt":"2011-03-19T10:10:39","slug":"jmeter-et-groovy-avoir-des-requetes-http-concurrentes","status":"publish","type":"post","link":"https:\/\/blog.milamberspace.net\/index.php\/2011\/03\/19\/jmeter-et-groovy-avoir-des-requetes-http-concurrentes-863.html","title":{"rendered":"JMeter et Groovy\u00a0: avoir des requ\u00eates HTTP concurrentes"},"content":{"rendered":"<p><!-- p { margin-bottom: 0.21cm; } -->Maintenant que nous avons vu comment <a title=\"JMeter et Groovy\u00a0: exemple d\u2019\u00e9chantillon BSF\/Groovy\" href=\"http:\/\/blog.milamberspace.net\/index.php\/2011\/03\/11\/jmeter-et-groovy-exemple-d-echantillon-bsf-groovy-834.html\">faire des scripts Groovy dans JMeter<\/a>, utilisons Groovy pour faire des requ\u00eates HTTP <em>parall\u00e8les<\/em> avec JMeter.<\/p>\n<p>Oh\u00a0! Des requ\u00eates parall\u00e8les\u00a0!? Le vieux r\u00eave dans JMeter&#8230; certainement<a href=\"http:\/\/mail-archives.apache.org\/mod_mbox\/jakarta-jmeter-user\/200808.mbox\/%3C25aac9fc0808151340v4c9309bcs54195d562cbe1ec6@mail.gmail.com%3E\"> l&rsquo;une des premi\u00e8res questions que j&rsquo;ai pos\u00e9 <\/a>sur la <a href=\"http:\/\/jakarta.apache.org\/site\/mail2.html#JMeter\">mailing-list des utilisateurs<\/a> JMeter (jmeter-user).<\/p>\n<p>Bon, je vous pr\u00e9viens, il ne s&rsquo;agit pas encore de faire un m\u00e9ga test de charge avec ce genre de requ\u00eates parall\u00e8les, mais cela peut aider pour des tests ayant des besoins de lancement simultan\u00e9 de requ\u00eates, ou toute autre id\u00e9e qui vous vient \u00e0 l&rsquo;esprit.<\/p>\n<p>Le premier pr\u00e9-requis est donc d&rsquo;avoir un <a title=\"JMeter et Groovy\u00a0: exemple d\u2019\u00e9chantillon BSF\/Groovy\" href=\"http:\/\/blog.milamberspace.net\/index.php\/2011\/03\/11\/jmeter-et-groovy-exemple-d-echantillon-bsf-groovy-834.html\">JMeter pr\u00eat pour faire du Groovy<\/a>.<\/p>\n<p>Ensuite, nous allons utiliser <a href=\"http:\/\/groovy.codehaus.org\/modules\/http-builder\/home.html\">HTTPBuilder<\/a>, qui est une couche API bas\u00e9e sur <a href=\"http:\/\/hc.apache.org\/httpcomponents-client-ga\/index.html\">Apache HttpClient<\/a>, et accessible en Groovy. HTTPBuilder sait faire pas mal de choses (comme du<a href=\"http:\/\/groovy.codehaus.org\/modules\/http-builder\/doc\/contentTypes.html\"> parsing automatique <\/a>de requ\u00eates JSON), etc. Ici, nous allons dans ce billet seulement nous int\u00e9resser \u00e0 sa capacit\u00e9 \u00e0 faire des requ\u00eates HTTP de mani\u00e8re asynchrone.<\/p>\n<p>Le petit nom de ce type de requ\u00eate dans HTTPBuilder est <a href=\"http:\/\/groovy.codehaus.org\/modules\/http-builder\/doc\/async.html\">AsyncHTTPBuilder<\/a>. C&rsquo;est une requ\u00eate HTTP qui, au lieu d&rsquo;\u00eatre ex\u00e9cut\u00e9e en premier plan, est envoy\u00e9e en arri\u00e8re-plan via une ex\u00e9cution dans un pool d&rsquo;ex\u00e9cution (\u00e9l\u00e9ment <a href=\"http:\/\/download.oracle.com\/javase\/1.5.0\/docs\/api\/java\/util\/concurrent\/Executor.html\">Executor<\/a> dans l&rsquo;API Java) et l&rsquo;utilisation d&rsquo;un type particulier\u00a0: <a href=\"http:\/\/download.oracle.com\/javase\/1.5.0\/docs\/api\/index.html?java\/util\/concurrent\/Future.html\">java.util.concurrent.Future<\/a> pour le r\u00e9sultat de l&rsquo;ex\u00e9cution de la requ\u00eate. Ce &lsquo;future&rsquo; permet d&rsquo;avoir la possibilit\u00e9 de lancer plusieurs requ\u00eates HTTP asynchrones (quasiment en m\u00eame temps), puis de r\u00e9colter le r\u00e9sultat de leurs ex\u00e9cutions ensuite.<!--more--><\/p>\n<p>Pour utiliser le HTTPBuilder, il faut donc aller <a href=\"http:\/\/snapshots.repository.codehaus.org\/org\/codehaus\/groovy\/modules\/http-builder\/http-builder\/\">t\u00e9l\u00e9charger son archive<\/a> (<em>au moins la version 0.5.2 SNAPSHOT, car il y a un bug dans la version 0.5.1 sur le AsyncHTTPBuilder)<\/em>, puis la d\u00e9compresser dans un r\u00e9pertoire temporaire.<\/p>\n<p>Au niveau des fichiers JAR n\u00e9cessaires au bon fonctionnement de HTTPBuilder, le plus simple est\u00a0: 1\/ copier le <em>http-builder-0.5.2.jar<\/em> dans le r\u00e9pertoire JMETER_HOME\/lib, 2\/ copier l&rsquo;ensemble de fichiers JAR situ\u00e9s dans le sous-r\u00e9pertoire HTTPBUILDER\/dependencies dans le r\u00e9pertoire JMETER_HOME\/lib. On relance ensuite JMeter.<\/p>\n<p>Voici l&rsquo;arbre JMeter pour ce billet\u00a0:<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"Arbre JMeter pour ce script Groovy\" src=\"\/wp-content\/images\/jmeter-33-groovy-parallele\/jmeter-groovy-http_035.png\" alt=\"\" width=\"295\" height=\"163\" \/><\/p>\n<p>Dans le <strong>Plan de test<\/strong>, on place trois variables JMeter qui seront utilis\u00e9es par le script Groovy. Ce sont tout simplement le nom du site, son port et une URI.<\/p>\n<p style=\"text-align: center;\"><a href=\"http:\/\/\/wp-content\/images\/jmeter-33-groovy-parallele\/jmeter-groovy-http_036.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"Plan de test JMeter\" src=\"\/wp-content\/images\/jmeter-33-groovy-parallele\/jmeter-groovy-http_036.png\" alt=\"\" width=\"684\" height=\"190\" \/><br \/>\n<\/a><\/p>\n<p>Au niveau du <strong>Groupes d&rsquo;unit\u00e9s<\/strong>, on laisse le 1-1-1 histoire de faciliter le cot\u00e9 d\u00e9monstration de ce sc\u00e9nario.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"Groupe d'unit\u00e9s JMeter pour le script Groovy\" src=\"\/wp-content\/images\/jmeter-33-groovy-parallele\/jmeter-groovy-http_037.png\" alt=\"\" width=\"532\" height=\"263\" \/><\/p>\n<p>L&rsquo;\u00e9chantillon <strong>Requ\u00eate HTTP <\/strong>va permettre de r\u00e9cup\u00e9rer une page HTML qui contient des liens.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"Simple requ\u00eate HTTP pour r\u00e9cup\u00e9rer les URI\" src=\"\/wp-content\/images\/jmeter-33-groovy-parallele\/jmeter-groovy-http_038.png\" alt=\"\" width=\"635\" height=\"241\" \/><br \/>\n<a href=\"http:\/\/\/wp-content\/images\/jmeter-33-groovy-parallele\/jmeter-groovy-http_038.png\"><\/a><\/p>\n<p>En fils de la <strong>Requ\u00eate HTTP<\/strong>, on place un \u00e9l\u00e9ment post-processeur <strong>Extracteur Expression r\u00e9guli\u00e8re<\/strong> qui est charg\u00e9 de r\u00e9cup\u00e9rer avec une expression r\u00e9guli\u00e8re les liens de la page HTML<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"Extracteur de RegExp\" src=\"\/wp-content\/images\/jmeter-33-groovy-parallele\/jmeter-groovy-http_039.png\" alt=\"\" width=\"555\" height=\"278\" \/><\/p>\n<p>L&rsquo;\u00e9chantillon <strong>D\u00e9bogage<\/strong> est bien entendu l\u00e0 \u00e0 des fins de d\u00e9bogage, histoire de voir si l&rsquo;extracteur RegExp fait bien son travail.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"L'\u00e9chantillon d\u00e9bogage (non obligatoire)\" src=\"\/wp-content\/images\/jmeter-33-groovy-parallele\/jmeter-groovy-http_040.png\" alt=\"\" width=\"262\" height=\"160\" \/><\/p>\n<p>Ensuite, vient l&rsquo;\u00e9l\u00e9ment principal de ce sc\u00e9nario\u00a0: l&rsquo;\u00e9chantillon BSF abritant un script Groovy.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"L'\u00e9chantillon BSF \/ Groovy pour des requ\u00eates HTTP parall\u00e8les\" src=\"\/wp-content\/images\/jmeter-33-groovy-parallele\/jmeter-groovy-http_041.png\" alt=\"\" width=\"608\" height=\"326\" \/><\/p>\n<p>Voici donc ce fameux script, les commentaires sont directement dedans\u00a0:<\/p>\n<pre><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #972c78;\"><strong>import<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #972c78;\"><strong>static<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">groovyx.net.http.ContentType.HTML<\/span><span style=\"color: #972c78;\"><strong>\r\nimport<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">groovyx.net.http.AsyncHTTPBuilder<\/span><\/span><\/span><span style=\"color: #3f7f5f;\"><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\">\r\n\/\/ R\u00e9cup\u00e9ration des variables JMeter<\/span><\/span><\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #972c78;\"><strong>\r\ndef<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">myHost<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">=<\/span><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">vars<\/span><\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">get<\/span><\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #ff00cc;\">\"MY_HOST\"<\/span><span style=\"color: #000000;\">)<\/span><span style=\"color: #972c78;\"><strong>\r\ndef<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">myPort<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">=<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">vars<\/span><\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">get<\/span><\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #ff00cc;\">\"MY_PORT\"<\/span><span style=\"color: #000000;\">)<\/span><\/span><\/span><span style=\"color: #3f7f5f;\"><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\">\r\n\/\/ Construction du debut de l'URL<\/span><\/span><\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #972c78;\"><strong>\r\ndef<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">myURL<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">=<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #ff00cc;\">\"http:\/\/\"<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">+<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">myHost<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">+<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #ff00cc;\">\":\"<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">+<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">myPort<\/span><\/span><\/span><span style=\"color: #3f7f5f;\"><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\">\r\n\/\/ Recuperation du nombre d'elements, puis generation de la liste des URI<\/span><\/span><\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #972c78;\"><strong>\r\ndef<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">listUri<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">=<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">[]<\/span><span style=\"color: #972c78;\"><strong>\r\ndef<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">nbPage<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">=<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">Integer.<\/span><span style=\"color: #000000;\"><em>parseInt<\/em><\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">vars<\/span><\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">get<\/span><\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #ff00cc;\">\"PAGE_matchNr\"<\/span><span style=\"color: #000000;\">))<\/span><span style=\"color: #972c78;\"><strong>\r\nfor<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #972c78;\"><strong>def<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">i<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">=<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #cd3200;\">1<\/span><span style=\"color: #000000;\">;<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">i<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">&lt;=<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">nbPage;<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">i++)<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">{<\/span><\/span><\/span><span style=\"color: #1a1a1a;\">\r\n <\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #000000;\">listUri<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">&lt;&lt;<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #ff00cc;\">\"\/\"<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">+<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">vars<\/span><\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">get<\/span><\/span><span style=\"color: #000000;\">(<\/span><span style=\"color: #ff00cc;\">\"PAGE_\"<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">+<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">i)<\/span><\/span><\/span><span style=\"color: #000000;\"><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\">\r\n}<\/span><\/span><\/span><span style=\"color: #3f7f5f;\"><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\">\r\n\/\/ Creation d'un pool d'unites d'execution de requetes HTTP asynchrones<\/span><\/span><\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #972c78;\"><strong>\r\ndef<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">http<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">=<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #972c78;\"><strong>new<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">AsyncHTTPBuilder(<\/span><\/span><\/span><span style=\"color: #1a1a1a;\">\r\n\u00a0<\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #000000;\">poolSize<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">:<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">args<\/span><\/span><span style=\"color: #000000;\">[<\/span><span style=\"color: #cd3200;\">0<\/span><span style=\"color: #000000;\">],<\/span><\/span><\/span><span style=\"color: #1a1a1a;\">\r\n\u00a0<\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #000000;\">uri<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">:<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">myURL,<\/span><\/span><\/span><span style=\"color: #1a1a1a;\">\r\n\u00a0<\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #000000;\">contentType<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">:<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #0000c0;\"><em>HTML<\/em><\/span><span style=\"color: #000000;\">,<\/span><\/span><\/span><span style=\"color: #1a1a1a;\">\r\n\u00a0<\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #000000;\">timeout<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">:<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #cd3200;\">20000<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">)<\/span><\/span><\/span><span style=\"color: #3f7f5f;\"><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\">\r\n\/\/ Generation des requetes et lancer de chaque requete<\/span><\/span><\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #972c78;\"><strong>\r\ndef<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">listResult<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">=<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">[]<\/span><span style=\"color: #972c78;\"><strong>\r\ndef<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">reqElt<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">=<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #ff00cc;\">\"\"<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #3f7f5f;\">\/\/ generation de la liste des requetes<\/span><span style=\"color: #000000;\">\r\nlistUri.<\/span><span style=\"color: #000000;\"><em>each<\/em><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">{<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">uriPage<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">-&gt;<\/span><\/span><\/span><span style=\"color: #1a1a1a;\">\r\n\u00a0<\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #000000;\">listResult<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">&lt;&lt;<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">http.get(path:uriPage)<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">{<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">resp,<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">html<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">-&gt;<\/span><\/span><\/span><span style=\"color: #1a1a1a;\">\r\n\u00a0<\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #000000;\"><em>println<\/em><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #ff00cc;\">'Recuperation de '<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">+<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">uriPage<\/span><\/span><\/span><span style=\"color: #1a1a1a;\">\r\n\u00a0<\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #972c78;\"><strong>return<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">html<\/span><\/span><\/span><span style=\"color: #1a1a1a;\">\r\n\u00a0<\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #000000;\">}<\/span><\/span><\/span><span style=\"color: #1a1a1a;\">\r\n\u00a0<\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #000000;\">reqElt<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">=<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">reqElt<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">+<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">myURL<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">+<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">uriPage<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">+<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #ff00cc;\">\"\\n\"<\/span><\/span><\/span><span style=\"color: #000000;\"><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\">\r\n}<\/span><\/span><\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">\r\nSampleResult<\/span><\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">setSamplerData<\/span><\/span><span style=\"color: #000000;\">(reqElt)<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #3f7f5f;\">\/\/ pour rendre visible dans JMeter les requetes transmises<\/span><\/span><\/span><span style=\"color: #3f7f5f;\"><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\">\r\n\/\/ Constrution des donnees de reponses\r\n\/\/ NB: l'appel \u00e0 it.get() pour chaque element va le faire patienter jusqu'a la fin d'execution de la requ\u00eate<\/span><\/span><\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #972c78;\"><strong>\r\ndef<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">responseData<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">=<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #ff00cc;\">\"\"<\/span><span style=\"color: #000000;\">\r\nlistResult.<\/span><span style=\"color: #000000;\"><em>each<\/em><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">{<\/span><\/span><\/span><span style=\"color: #1a1a1a;\">\r\n\u00a0<\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #972c78;\"><strong>def<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">resp<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">=<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #66ccff;\">it<\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">get<\/span><\/span><span style=\"color: #000000;\">()<\/span><\/span><\/span><span style=\"color: #1a1a1a;\">\r\n\u00a0<\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #000000;\">responseData<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">=<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">responseData<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">+<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #ff00cc;\">\"=============\\n\"<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">+<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">resp<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">+<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #ff00cc;\">\"\\n\"<\/span><\/span><\/span><span style=\"color: #1a1a1a;\">\r\n\u00a0<\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #972c78;\"><strong>assert<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">resp<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #972c78;\"><strong>instanceof<\/strong><\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #000000;\">groovy.util.slurpersupport.GPathResult<\/span><\/span><\/span><span style=\"color: #000000;\"><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\">\r\n}<\/span><\/span><\/span><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">\r\nSampleResult<\/span><\/span><span style=\"color: #000000;\">.<\/span><span style=\"color: #000000;\"><span style=\"text-decoration: underline;\">setResponseData<\/span><\/span><span style=\"color: #000000;\">(responseData)<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #3f7f5f;\">\/\/ envoi de la concatenation des resultats \u00e0 JMeter<\/span><span style=\"color: #000000;\">\r\nprintln<\/span><span style=\"color: #1a1a1a;\"> <\/span><span style=\"color: #ff00cc;\">'done.'<\/span><\/span><\/span><span style=\"color: #000000;\"><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\">\r\nhttp.shutdown()<\/span><\/span><\/span><span style=\"color: #1a1a1a;\"><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\"> <\/span><\/span><\/span><span style=\"color: #3f7f5f;\"><span style=\"font-family: Sans,sans-serif;\"><span style=\"font-size: x-small;\">\/\/ Arret du pool d'unites<\/span><\/span><\/span><\/pre>\n<p><span style=\"text-decoration: underline;\">En compl\u00e9ment\u00a0:<\/span><\/p>\n<ul>\n<li>le script Groovy prend comme arguments, le nombre d&rsquo;unit\u00e9s d&rsquo;ex\u00e9cution pour le pool d&rsquo;unit\u00e9s. Ici il est \u00e0 4 (champ \u00ab\u00a0<em>Param\u00e8tres \u00e0 passer au script\/fichier<\/em> \u00bb dans la capture de l&rsquo;\u00e9chantillon BSF).<\/li>\n<li>On peut jouer avec ce param\u00e8tre (unit\u00e9s d&rsquo;ex\u00e9cution) pour observer ou non le parall\u00e9lisme des requ\u00eates envoy\u00e9es.<\/li>\n<li>Dans cet exemple, il n&rsquo;y a pas de param\u00e8tres pass\u00e9s lors de l&rsquo;ex\u00e9cution des requ\u00eates HTTP. C&rsquo;est bien entendu possible. <a href=\"http:\/\/groovy.codehaus.org\/modules\/http-builder\/doc\/index.html\">Voir la doc<\/a>.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>Avant de passer \u00e0 l&rsquo;ex\u00e9cution du test, on n&rsquo;oublie pas le r\u00e9cepteur Arbre de r\u00e9sultats, et on peut lancer ensuite.<\/p>\n<p>Voici le r\u00e9sultat pour une ex\u00e9cution avec 1 seule unit\u00e9<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"R\u00e9sultat avec 1 seule unit\u00e9 d'ex\u00e9cution\" src=\"\/wp-content\/images\/jmeter-33-groovy-parallele\/jmeter-groovy-http_042.png\" alt=\"\" width=\"769\" height=\"328\" \/><\/p>\n<p>Voici le r\u00e9sultat pour une ex\u00e9cution avec 3 unit\u00e9s<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"R\u00e9sultat avec 3 unit\u00e9s d'ex\u00e9cution\" src=\"\/wp-content\/images\/jmeter-33-groovy-parallele\/jmeter-groovy-http_043.png\" alt=\"\" width=\"712\" height=\"332\" \/><\/p>\n<p>Le temps de r\u00e9ponses est bien meilleur avec 3 unit\u00e9s.<\/p>\n<p>La petite explication c&rsquo;est que mes pages \u00ab\u00a0\/pageX.shtml\u00a0\u00bb ont un petit script d&rsquo;attente de X secondes (voir annexe ci-dessous). Ainsi, la page 1 attend 1 sec, la page 2 attend 2 secs et la page 3 attends 3 secs.<\/p>\n<p>Donc il est normal d&rsquo;avoir environ 6 secondes avec 1 seule unit\u00e9 et 3 secondes pour 3 unit\u00e9s.<\/p>\n<p><em>Voil\u00e0 pour ce petit script Groovy qui permet d&rsquo;avoir des requ\u00eates concurrentes.<\/em><\/p>\n<ul>\n<li>Veuillez noter que Groovy \u00e9tant bas\u00e9 sur Java, il est bien entendu possible de transformer ce script Groovy en code Java \u00e0 ex\u00e9cuter dans un \u00e9chantillon BeanShell ou carr\u00e9ment dans un \u00e9chantillon Java.<\/li>\n<li>Veuillez noter que ce sc\u00e9nario <em>(qui mijotait depuis 3 semaines sur mon ordinateur)<\/em> m&rsquo;a donner l&rsquo;id\u00e9e de parall\u00e9liser le t\u00e9l\u00e9chargement des ressources li\u00e9es \u00e0 une page HTML dans une requ\u00eate HTTP <em>(la case \u00e0 cocher en bas dans l&rsquo;\u00e9l\u00e9ment)<\/em>. J&rsquo;ai donc d\u00e9velopper <a href=\"https:\/\/issues.apache.org\/bugzilla\/show_bug.cgi?id=50943\">le patch en question<\/a>, et je devrais le committer la semaine prochaine pour son inclusion dans la prochaine version de JMeter.<\/li>\n<li>Veuillez noter que\u00a0: non ce n&rsquo;est pas aussi simple de mettre en place des requ\u00eates parall\u00e8les pour un m\u00eame utilisateur virtuel dans JMeter. Notamment \u00e0 cause des \u00e9l\u00e9ments &lsquo;pr\u00e9&rsquo; et &lsquo;post&rsquo; ex\u00e9cution d&rsquo;une requ\u00eate (pr\u00e9-processeurs, post-processeur et assertion en autres)<\/li>\n<\/ul>\n<p>Bon courage dans vos p\u00e9rip\u00e9ties JMeter.<\/p>\n<p>.\/<\/p>\n<p><strong><span style=\"text-decoration: underline;\">[Annexe : une des pages html demand\u00e9es]<\/span><\/strong><\/p>\n<pre>&lt;!DOCTYPE HTML PUBLIC \"-\/\/W3C\/\/DTD HTML 4.01 Transitional\/\/EN\"&gt;\r\n&lt;html&gt;&lt;head&gt;\r\n&lt;meta content=\"text\/html; charset=UTF-8\" http-equiv=\"content-type\"&gt;\r\n&lt;title&gt;Page 1&lt;\/html&gt;\r\n&lt;\/head&gt;&lt;body&gt;\r\nP1 AVANT : &lt;!--#exec cmd=\"date\" --&gt;\r\n&lt;!--#exec cmd=\"sleep 1\" --&gt;\r\nP1 APRES : &lt;!--#exec cmd=\"date\" --&gt;\r\n&lt;\/body&gt;&lt;\/html&gt;\r\n<\/pre>\n<p>(noter que c&rsquo;est du <a href=\"http:\/\/httpd.apache.org\/docs\/2.2\/howto\/ssi.html\">Sever Side Include avec Apache<\/a>)<\/p>\n<p><strong><span style=\"text-decoration: underline;\">[Annexe : le r\u00e9sultat dans l&rsquo;onglet r\u00e9ponse de JMeter, avec 3 unit\u00e9s d&rsquo;ex\u00e9cutions]<\/span><\/strong><\/p>\n<p>On voit bien que la date de lancement est la m\u00eame pour les trois pages.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"R\u00e9sultat de l'ex\u00e9cution des requ\u00eates parall\u00e8les avec JMeter\/Groovy\" src=\"\/wp-content\/images\/jmeter-33-groovy-parallele\/jmeter-groovy-http_044.png\" alt=\"\" width=\"486\" height=\"416\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>.\/<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Maintenant que nous avons vu comment faire des scripts Groovy dans JMeter, utilisons Groovy pour faire des requ\u00eates HTTP parall\u00e8les avec JMeter. Oh\u00a0! Des requ\u00eates parall\u00e8les\u00a0!? Le vieux r\u00eave dans JMeter&#8230; certainement l&rsquo;une des premi\u00e8res questions que j&rsquo;ai pos\u00e9 sur la mailing-list des utilisateurs JMeter (jmeter-user). Bon, je vous pr\u00e9viens, il ne s&rsquo;agit pas encore &hellip; <a href=\"https:\/\/blog.milamberspace.net\/index.php\/2011\/03\/19\/jmeter-et-groovy-avoir-des-requetes-http-concurrentes-863.html\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">JMeter et Groovy\u00a0: avoir des requ\u00eates HTTP concurrentes<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[32,256,33],"tags":[365,330,258],"class_list":["post-863","post","type-post","status-publish","format-standard","hentry","category-apache","category-groovy","category-jmeter","tag-groovy","tag-jmeter","tag-requete-http-parallele"],"_links":{"self":[{"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/posts\/863","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/comments?post=863"}],"version-history":[{"count":7,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/posts\/863\/revisions"}],"predecessor-version":[{"id":871,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/posts\/863\/revisions\/871"}],"wp:attachment":[{"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/media?parent=863"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/categories?post=863"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/tags?post=863"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}