{"id":8735,"date":"2017-08-04T13:35:51","date_gmt":"2017-08-04T11:35:51","guid":{"rendered":"http:\/\/blog.wenzlaff.de\/?p=8735"},"modified":"2018-09-14T08:34:21","modified_gmt":"2018-09-14T06:34:21","slug":"jenkins-pipeline-optimieren-mit-parallele-ausfuehrung-auf-dem-raspberry-pi","status":"publish","type":"post","link":"http:\/\/blog.wenzlaff.de\/?p=8735","title":{"rendered":"Jenkins Pipeline optimieren mit parallele Ausf\u00fchrung auf dem Raspberry Pi"},"content":{"rendered":"<p>In <a href=\"http:\/\/blog.wenzlaff.de\/?p=8703\" target=\"_blank\" rel=\"noopener\">diesem Blog Beitrag<\/a> hatte ich gezeigt, wie man auf einem Raspberry Pi einen aktuellen Jenkins installieren kann.<\/p>\n<p>Nun m\u00f6chte ich mal zeigen, wie Aufgabe parallelisiert werden k\u00f6nnen.<\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Parallelisieren.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-8737\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Parallelisieren.png\" alt=\"Parallelisieren von Jenkins Stages\" width=\"2732\" height=\"2048\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Parallelisieren.png 2732w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Parallelisieren-300x225.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Parallelisieren-768x576.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Parallelisieren-1024x768.png 1024w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n<p>Ein Jenkins Jobs der folgendes macht, soll mal als Beispiel dienen, um parallele Pipeline zu demonstrieren.<\/p>\n<p>Ein einfacher Job der<\/p>\n<ul>\n<li>Flugdaten aus Hannover abfragt<\/li>\n<li>mein Kaffee verbrauch ermittelt<\/li>\n<li>Temperatur und Luftfeuchte in HAJ abfragt<\/li>\n<li>Umweltdaten des Lufthygienisches \u00dcberwachungssystem Niedersachsen abfragt<\/li>\n<li>meine drei Server per Ping 10 mal checkt<\/li>\n<li>und das Ergebnis aller Abfragen per E-Mail versendet<\/li>\n<\/ul>\n<p>Dazu das kleine Groovy Script, das die \u00f6ffentlichen Daten abfragt, in den Job eintragen:<!--more--><\/p>\n<pre class=\"lang:js decode:true \" >node{\r\n    stage('Flugdaten HAJ abfragen') { \r\n    echo 'Max Summe Flugzeuge in EDDV'\r\n    httpRequest consoleLogResponseBody: true, ignoreSslErrors: true, outputFile: 'flugdaten.txt', responseHandle: 'NONE', timeout: 10, url: 'https:\/\/api.thingspeak.com\/channels\/44177\/feeds\/last.json'\r\n   }\r\n    stage('Kaffee verbrauch abfragen') { \r\n    echo 'Kaffee verbrauch Summe'\r\n    httpRequest consoleLogResponseBody: true, ignoreSslErrors: true, outputFile: 'kaffeedaten.txt', responseHandle: 'NONE', timeout: 10, url: 'https:\/\/api.thingspeak.com\/channels\/242708\/feeds\/last.json'\r\n   }\r\n    stage('Temperatur und Luftfeuchte abfragen') { \r\n    echo 'Temperatur und Luftfeuchte'\r\n    httpRequest consoleLogResponseBody: true, ignoreSslErrors: true, outputFile: 'temperaturdaten.txt', responseHandle: 'NONE', timeout: 10, url: 'https:\/\/api.thingspeak.com\/channels\/44925\/feeds\/last.json'\r\n   }\r\n   stage('Umweltdaten abfragen') { \r\n    echo 'Umweltdaten'\r\n    httpRequest consoleLogResponseBody: true, ignoreSslErrors: true, outputFile: 'messdaten.txt', responseHandle: 'NONE', timeout: 10, url: 'https:\/\/www.luen-ni.de\/JSON.txt'\r\n   }\r\n   stage('Server home, bplus, flug checken ') { \r\n      \r\n          echo 'Check Server home'\r\n          sh 'ping -c 10 home'\r\n          echo 'Check Server bplus'\r\n          sh 'ping -c 10 bplus'\r\n          echo 'Check Server flug'\r\n          sh 'ping -c 10 flug'\r\n   }\r\n   stage('Ergebnisse per E-Mail versenden') {\r\n   emailext attachLog: true, body: '', subject: 'Autom. check', to: 'jenkins@wenzlaff.de'\r\n   }\r\n}<\/pre>\n<p>Hier die Job Pipeline:<\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Bildschirmfoto-2017-08-04-um-12.55.45.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Bildschirmfoto-2017-08-04-um-12.55.45.png\" alt=\"Pipeline\" width=\"1078\" height=\"328\" class=\"aligncenter size-full wp-image-8741\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Bildschirmfoto-2017-08-04-um-12.55.45.png 1078w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Bildschirmfoto-2017-08-04-um-12.55.45-300x91.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Bildschirmfoto-2017-08-04-um-12.55.45-768x234.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Bildschirmfoto-2017-08-04-um-12.55.45-1024x312.png 1024w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n<p>Der Stage mit dem drei mal zehn Ping dauert <strong>29<\/strong> Sekunden. Den Ping wollen wir nun parallel laufen lassen, um zu sehen, wie man Jobs parallelisieren kann. Dazu brauchen wir in dem Stage nur den Befehl <strong>parallel<\/strong> mit Klammern aufrufen. Hier die Syntax:<\/p>\n<pre class=\"lang:default decode:true \" >parallel (\r\n     \"stream 1\" : { ... parallele Befehle ...  },\r\n     \"stream 2\" : { ... parallele Befehle ...  }\r\n   )\r\n<\/pre>\n<p>Der neue modifizierte Job:<\/p>\n<pre class=\"lang:default decode:true \" >node{\r\n    stage('Flugdaten HAJ abfragen') { \r\n    echo 'Max Summe Flugzeuge in EDDV'\r\n    httpRequest consoleLogResponseBody: true, ignoreSslErrors: true, outputFile: 'flugdaten.txt', responseHandle: 'NONE', timeout: 10, url: 'https:\/\/api.thingspeak.com\/channels\/44177\/feeds\/last.json'\r\n   }\r\n    stage('Kaffee verbrauch abfragen') { \r\n    echo 'Kaffee verbrauch Summe'\r\n    httpRequest consoleLogResponseBody: true, ignoreSslErrors: true, outputFile: 'kaffeedaten.txt', responseHandle: 'NONE', timeout: 10, url: 'https:\/\/api.thingspeak.com\/channels\/242708\/feeds\/last.json'\r\n   }\r\n    stage('Temperatur und Luftfeuchte abfragen') { \r\n    echo 'Temperatur und Luftfeuchte'\r\n    httpRequest consoleLogResponseBody: true, ignoreSslErrors: true, outputFile: 'temperaturdaten.txt', responseHandle: 'NONE', timeout: 10, url: 'https:\/\/api.thingspeak.com\/channels\/44925\/feeds\/last.json'\r\n   }\r\n   stage('Umweltdaten abfragen') { \r\n    echo 'Umweltdaten'\r\n    httpRequest consoleLogResponseBody: true, ignoreSslErrors: true, outputFile: 'messdaten.txt', responseHandle: 'NONE', timeout: 10, url: 'https:\/\/www.luen-ni.de\/JSON.txt'\r\n   }\r\n   stage('Server home, bplus, flug checken ') { \r\n         parallel (\r\n           \"home\" : { echo 'Check Server home'\r\n            sh 'ping -c 10 home'},\r\n           \"pi-bplus\" : { echo 'Check Server bplus'\r\n            sh 'ping -c 10 bplus'},\r\n            \"pi-flug\": {echo 'Check Server flug'\r\n            sh 'ping -c 10 flug'}\r\n            )\r\n   }\r\n   stage('Ergebnisse per E-Mail versenden') {\r\n    emailext attachLog: true, body: '', subject: 'Autom. check', to: 'jenkins@wenzlaff.de'\r\n   }\r\n}<\/pre>\n<p>Das Ergebnis. Ein Stage mit dem check dauert nun nur noch <strong>11<\/strong> Sekunden:<br \/>\n<a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Bildschirmfoto-2017-08-04-um-13.03.32.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Bildschirmfoto-2017-08-04-um-13.03.32.png\" alt=\"Jenkins Job\" width=\"1076\" height=\"324\" class=\"aligncenter size-full wp-image-8742\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Bildschirmfoto-2017-08-04-um-13.03.32.png 1076w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Bildschirmfoto-2017-08-04-um-13.03.32-300x90.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Bildschirmfoto-2017-08-04-um-13.03.32-768x231.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/Bildschirmfoto-2017-08-04-um-13.03.32-1024x308.png 1024w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n<p>Das die Ping Befehle parallel abgearbeitet werden, kann man am Log gut sehen, welches per E-Mail bei mir einmal am Tag zugesendet wir:<\/p>\n<pre class=\"lang:default decode:true \" >\r\n[flug] 64 bytes from flug.router.de (ADRESSE.32): icmp_seq=6 ttl=64 time=5.03 ms\r\n[home] 64 bytes from home.router.de (ADRESSE.39): icmp_seq=8 ttl=64 time=2.27 ms\r\n[bplus] 64 bytes from bplus.router.de (ADRESSE.43): icmp_seq=7 ttl=64 time=4.92 ms\r\n[bplus] 64 bytes from bplus.router.de (ADRESSE.43): icmp_seq=8 ttl=64 time=5.23 ms\r\n[flug] 64 bytes from flug.router.de (ADRESSE.32): icmp_seq=7 ttl=64 time=5.34 ms\r\n[home] 64 bytes from home.router.de (ADRESSE.39): icmp_seq=9 ttl=64 time=4.41 ms\r\n[bplus] 64 bytes from bplus.router.de (ADRESSE.43): icmp_seq=9 ttl=64 time=4.85 ms\r\n[flug] 64 bytes from flug.router.de (ADRESSE.32): icmp_seq=8 ttl=64 time=5.15 ms\r\n[home] 64 bytes from home.router.de (ADRESSE.39): icmp_seq=10 ttl=64 time=5.20 ms\r\n[home] \r\n[home] --- home.router.de ping statistics ---\r\n[home] 10 packets transmitted, 10 received, 0% packet loss, time 9012ms\r\n[home] rtt min\/avg\/max\/mdev = 2.030\/4.287\/5.200\/1.120 ms\r\n[flug] 64 bytes from flug.router.de (ADRESSE.32): icmp_seq=9 ttl=64 time=5.15 ms\r\n[Pipeline] [home] }\r\n[bplus] 64 bytes from bplus.router.de (ADRESSE.43): icmp_seq=10 ttl=64 time=5.72 ms\r\n[bplus] \r\n[bplus] --- bplus.router.de ping statistics ---\r\n[bplus] 10 packets transmitted, 10 received, 0% packet loss, time 9011ms\r\n[bplus] rtt min\/avg\/max\/mdev = 2.206\/4.782\/6.395\/1.034 ms\r\n[Pipeline] [bplus] }\r\n[flug] 64 bytes from flug.router.de (ADRESSE.32): icmp_seq=10 ttl=64 time=5.07 ms\r\n<\/pre>\n<p>In der ersten Version hingegen werden alle drei Server nach einander angepingt.<\/p>\n<p>Es k\u00f6nnen auch noch <strong>Nodes<\/strong> parallel abgearbeitet werden.<\/p>\n<p>Hier noch der direkte Vergleich:<\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/jenkins-parallel-vergleich.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/jenkins-parallel-vergleich.png\" alt=\"\" width=\"1069\" height=\"439\" class=\"aligncenter size-full wp-image-8746\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/jenkins-parallel-vergleich.png 1069w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/jenkins-parallel-vergleich-300x123.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/jenkins-parallel-vergleich-768x315.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2017\/08\/jenkins-parallel-vergleich-1024x421.png 1024w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In diesem Blog Beitrag hatte ich gezeigt, wie man auf einem Raspberry Pi einen aktuellen Jenkins installieren kann. Nun m\u00f6chte ich mal zeigen, wie Aufgabe parallelisiert werden k\u00f6nnen. Ein Jenkins Jobs der folgendes macht, soll mal als Beispiel dienen, um parallele Pipeline zu demonstrieren. Ein einfacher Job der Flugdaten aus Hannover abfragt mein Kaffee verbrauch &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/blog.wenzlaff.de\/?p=8735\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eJenkins Pipeline optimieren mit parallele Ausf\u00fchrung auf dem Raspberry Pi\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[220,852,2983,79,1023,2752],"tags":[231,61,2976,2978,2977,2979],"class_list":["post-8735","post","type-post","status-publish","format-standard","hentry","category-anleitung","category-heimautomatisierung","category-jenkins","category-programmierung","category-raspberry-pi","category-raspberry-pi-zero-w","tag-jenkins","tag-job","tag-parallel","tag-parallel-pipelines","tag-pipelines","tag-stage"],"_links":{"self":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/8735","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=8735"}],"version-history":[{"count":0,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/8735\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=8735"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=8735"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=8735"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}