{"id":1161,"date":"2012-07-14T21:18:31","date_gmt":"2012-07-14T20:18:31","guid":{"rendered":"http:\/\/blog.milamberspace.net\/?p=1161"},"modified":"2012-07-30T18:29:17","modified_gmt":"2012-07-30T17:29:17","slug":"rapport-de-tres-gros-test-de-charge-avec-la-solution-blazemeter","status":"publish","type":"post","link":"https:\/\/blog.milamberspace.net\/index.php\/2012\/07\/14\/rapport-de-tres-gros-test-de-charge-avec-la-solution-blazemeter-1161.html","title":{"rendered":"Rapport de (tr\u00e8s) gros test de charge avec la solution BlazeMeter"},"content":{"rendered":"<p>Dans <a title=\"Apache JMeter dans les nuages : BlazeMeter, mon premier test\" href=\"http:\/\/blog.milamberspace.net\/index.php\/2012\/06\/30\/apache-jmeter-dans-les-nuages-blazemeter-mon-premier-test-1141.html\">ce premier billet<\/a>, je vous pr\u00e9sentais la solution de test de charge dans les nuages <a title=\"BlazeMeter\" href=\"http:\/\/blazemeter.com\/\">BlazeMeter<\/a>, bas\u00e9e sur l&rsquo;outil <a href=\"http:\/\/jmeter.apache.org\/\">Apache JMeter<\/a>, illustr\u00e9 par un petit test. Dans ce nouveau billet, on passe aux choses s\u00e9rieuses\u00a0: <strong><em>le (tr\u00e8s) gros test de charge<\/em><\/strong>.<\/p>\n<p>Mon objectif \u00e9tait le suivant\u00a0: faire un tir de charge avec 100 000 utilisateurs virtuels actifs.<\/p>\n<p>Pour faire ce type de gros test, depuis les nuages, il faut un serveur cible (ou une solution cible). Pour ma part, j&rsquo;ai eu la possibilit\u00e9 d&rsquo;avoir un pr\u00eat d&rsquo;un tr\u00e8s gros serveur situ\u00e9 dans un centre de donn\u00e9es \u00e0 Poitiers\/France connect\u00e9 directement sur une importante dorsale Internet via une liaison \u00e0 100 MBits\/s. Autrement dit le serveur \u00e9tait bien plac\u00e9 sur Internet pour \u00eatre attaqu\u00e9 par la solution BlazeMeter.<\/p>\n<p>Le serveur en question est un Dell R815, ayant 4 CPU de 12 c\u0153urs chacun (AMD Opteron 6176), soit 48 coeurs, accompagn\u00e9 de 256 Go de m\u00e9moire RAM, connect\u00e9 \u00e0 1 Gbits\/s (en ip bonding) sur un commutateur en liaison avec un pare-feu BSD (en mode NAT). Le syst\u00e8me d&rsquo;exploitation dudit serveur est GNU\/Linux Debian 6.0.5 en 64 bits.<\/p>\n<p>Le serveur \u00e9tait totalement disponible pour ce test (pas d&rsquo;autres services tournant dessus).<\/p>\n<p>L&rsquo;id\u00e9e \u00e9tant de faire un test de charge pour \u00ab\u00a0tester\u00a0\u00bb la solution <a href=\"http:\/\/blazemeter.com\/\">BlazeMeter<\/a>, et non pas de tester la performance du serveur cible, j&rsquo;ai choisi de ne mettre qu&rsquo;un serveur Web Apache avec 3 pages HTML statiques. Le serveur Apache est configur\u00e9 avec mod_deflate et mod_cache.<\/p>\n<p>Le sc\u00e9nario de test sera le suivant\u00a0:<\/p>\n<ol>\n<li>page d&rsquo;accueil (+assertion r\u00e9ponse)<\/li>\n<li>page A (+assertion r\u00e9ponse)<\/li>\n<li>page B (+assertion r\u00e9ponse)<\/li>\n<\/ol>\n<p style=\"text-align: center;\">\u00a0<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"Sc\u00e9narion de test\" src=\"\/wp-content\/images\/jmeter-41-heavy-loadtest-blazemeter\/01_blazemeter_plan_de_test_heavy3.png\" alt=\"\" width=\"317\" height=\"385\" \/><\/p>\n<ul>\n<li>pas de ressources statiques (pour pr\u00e9server la bande passante)<\/li>\n<li>5 secondes de pause entre chaque page<\/li>\n<li>1 it\u00e9ration par minute pour chaque utilisateur virtuel<\/li>\n<li>les requ\u00eates HTTP utilisent l&rsquo;impl\u00e9mentation HttpClient 4<!--more--><\/li>\n<\/ul>\n<p>Concernant le nombre d&rsquo;utilisateurs, avec BlazeMeter il y a deux options possibles\u00a0:<\/p>\n<ul>\n<li>soit on surcharge les valeurs via l&rsquo;interface d&rsquo;administration Web,<\/li>\n<li>soit, comme d&rsquo;habitude, on le d\u00e9finit dans son sc\u00e9nario depuis son JMeter ;<\/li>\n<\/ul>\n<p>J&rsquo;ai choisi de configurer le plan de test avec 10 000 utilisateurs dans mon \u00e9l\u00e9ment Groupe d&rsquo;unit\u00e9s directement depuis JMeter. Sachant que le nombre de \u00ab\u00a0moteur\u00a0\u00bb (engine) JMeter dans BlazeMeter sera de 10 (cf capture suivante), cela fera ainsi 10 x 10 000 = 100 000 utilisateurs virtuels actifs pour mon gros sc\u00e9nario de tir.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"10 000 VU\" src=\"\/wp-content\/images\/jmeter-41-heavy-loadtest-blazemeter\/02_blazemeter_groupe_unites_heavy3.png\" alt=\"\" width=\"505\" height=\"387\" \/><\/p>\n<p><em>NB. 10 000 utilisateurs par injecteur, c&rsquo;est possible, car le sc\u00e9nario est simple\u00a0: juste 3 requ\u00eates+assertions, pas d&rsquo;extras.<\/em><\/p>\n<p>Voici ci-dessous le formulaire d&rsquo;envoi du sc\u00e9nario JMeter dans BlazeMeter. Ce sera donc 10 JMeterEngines (les injecteurs), plus 1 console (le contr\u00f4leur).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" title=\"10 Engines\" src=\"\/wp-content\/images\/jmeter-41-heavy-loadtest-blazemeter\/03_blazemeter_10engines.png\" alt=\"\" width=\"971\" height=\"646\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>\u00c9galement au niveau des propri\u00e9t\u00e9s avanc\u00e9es, j&rsquo;ai choisi des serveurs \u00ab\u00a0Large\u00a0\u00bb <em>(faisant r\u00e9f\u00e9rence \u00e0 la grille de tarifs Amazon EC2)<\/em> car 10 000 utilisateurs par injecteurs, il faut des serveurs costauds. Par ailleurs, j&rsquo;ai r\u00e9duit la dur\u00e9e de \u00ab\u00a0location\u00a0\u00bb des machines JMeterEngine \u00e0 1h, car mon tir est programm\u00e9 pour durer 3000 secondes (50 min). Ces options ont un impact sur le \u00ab\u00a0co\u00fbt\u00a0\u00bb du tir.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" title=\"10 engines BlazeMeter\" src=\"\/wp-content\/images\/jmeter-41-heavy-loadtest-blazemeter\/04_blazemeter_10engines_adv.png\" alt=\"\" width=\"974\" height=\"930\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Voil\u00e0 mon sc\u00e9nario est enregistr\u00e9 dans BlazeMeter, il va consommer 22 cr\u00e9dits de test\u00a0: 10 x 2 Large Servers + 1 x 2 Large Console = 22.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" title=\"Upload\" src=\"\/wp-content\/images\/jmeter-41-heavy-loadtest-blazemeter\/04_blazemeter_upload.png\" alt=\"\" width=\"965\" height=\"441\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><em>Ensuite, et bien, on lance le tir\u00a0! et on suit les r\u00e9sultats depuis la console BlazeMeter<br \/>\n<\/em><\/p>\n<p><em>[&#8230;wait&amp;see&#8230;]<\/em><\/p>\n<p>Et voici le graphique des r\u00e9sultats\u00a0:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" title=\"R\u00e9sultats BlazeMeter\" src=\"\/wp-content\/images\/jmeter-41-heavy-loadtest-blazemeter\/10_blazemeter_results_01.png\" alt=\"\" width=\"895\" height=\"408\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Sur ce graphique, on voit que\u00a0:<\/p>\n<ol>\n<li>J&rsquo;ai arr\u00eat\u00e9 volontairement le tir \u00e0 80 000 utilisateurs, car le temps de r\u00e9ponses \u00e9tait en train de se d\u00e9grader <em>(pas la peine de continuer)<\/em><\/li>\n<li>La d\u00e9gradation du temps de r\u00e9ponse a commenc\u00e9 vers 55 000 utilisateurs<\/li>\n<\/ol>\n<p>Sur le tableau ci-dessous, on voit de belles choses\u00a0:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" title=\"R\u00e9sultats BlazeMeter\" src=\"\/wp-content\/images\/jmeter-41-heavy-loadtest-blazemeter\/11_blazemeter_results_02.png\" alt=\"\" width=\"892\" height=\"272\" \/><\/p>\n<p>Au total, plus de 3 millions de requ\u00eates HTTP en 27 min, soit environ 117 000 requ\u00eates par min (~1940 requ\u00eates HTTP par seconde\u00a0!).<\/p>\n<p>Comme on peut le deviner \u00e0 travers les valeurs m\u00e9dianes et minimum, le temps de r\u00e9ponse quand tout va bien est inf\u00e9rieur \u00e0 100 ms. Bien entendu les valeurs moyenne et 90e centile sont hautes \u00e0 cause du probl\u00e8me vers 55 000 utilisateurs.<\/p>\n<p>En jouant un peu sur les courbes du graphique \u00e0 afficher, on voit que la latence <em>(les premiers 8192 bits re\u00e7us par JMeter pour la r\u00e9ponse HTTP)<\/em> se d\u00e9grade en m\u00eame temps et de la m\u00eame fa\u00e7on que le temps de r\u00e9ponse g\u00e9n\u00e9ral. On peut commencer \u00e0 penser que le probl\u00e8me vient du r\u00e9seau.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" title=\"R\u00e9sultats BlazeMeter\" src=\"\/wp-content\/images\/jmeter-41-heavy-loadtest-blazemeter\/12_blazemeter_results_03.png\" alt=\"\" width=\"887\" height=\"403\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Si on choisi de voir les erreurs \u00ab\u00a0NON_HTTP_RESPONSE\u00a0\u00bb, elles apparaissent \u00e9galement en m\u00eame que la d\u00e9gradation du temps de r\u00e9ponse.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" title=\"R\u00e9sultats BlazeMeter\" src=\"\/wp-content\/images\/jmeter-41-heavy-loadtest-blazemeter\/13_blazemeter_results_04.png\" alt=\"\" width=\"890\" height=\"405\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Le d\u00e9tail des messages <em>(BlazeMeter permet de t\u00e9l\u00e9charger l&rsquo;ensemble des fichiers jmeter.log des injecteurs)<\/em> \u00a0:<\/p>\n<ul>\n<li>\n<pre>I\/O exception (java.net.NoRouteToHostException) caught when connecting to the target host: No route to host<\/pre>\n<\/li>\n<li>\n<pre>I\/O exception (org.apache.http.NoHttpResponseException) caught when processing request: The target server failed to respond<\/pre>\n<\/li>\n<\/ul>\n<p>Visiblement il y a eu une saturation niveau r\u00e9seau.<\/p>\n<p>Ci-dessous, le graphique de la bande passante du pare-feu (mutualis\u00e9) devant le serveur, on voit que l&rsquo;on monte jusqu&rsquo;\u00e0 presque 70 Mbits\/s en d\u00e9bit sortant <em>(rappel, la liaison Internet est de 100 Mbit\/s)<\/em>. Donc \u00e0 priori la bande passante de liaison \u00e0 Internet n&rsquo;est pas (encore) satur\u00e9e.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"fw network\" src=\"\/wp-content\/images\/jmeter-41-heavy-loadtest-blazemeter\/20_firewall_network.png\" alt=\"\" width=\"173\" height=\"232\" \/><\/p>\n<p>Ci-dessous le graphique de l&rsquo;interface r\u00e9seau du serveur cibl\u00e9 <em>(interface 1 Gbits\/s en ip bonding sur 2 interfaces physiques)<\/em>. Noter que les valeurs sont en Mo\/s (MBps) donc il faut multipli\u00e9 par 8 (grossi\u00e8rement) pour avoit la valeur en Mbits\/s. Ici on voit bien qu&rsquo;un plafond a \u00e9t\u00e9 atteint niveau r\u00e9seau \u00e0 travers le sorte de <em>\u00ab\u00a0plat\u00a0\u00bb<\/em> apr\u00e8s 20 min de tir.<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"Apache network\" src=\"\/wp-content\/images\/jmeter-41-heavy-loadtest-blazemeter\/21_apachesvr_network.png\" alt=\"\" width=\"661\" height=\"314\" \/><\/p>\n<p>Cot\u00e9 CPU, on est tranquille. Normal, vu que ce sont des pages statiques et en cache Apache (sans parler de la configuration du serveur).<\/p>\n<p style=\"text-align: center;\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" style=\"border: 1px solid black;\" title=\"CPU Apache\" src=\"\/wp-content\/images\/jmeter-41-heavy-loadtest-blazemeter\/22_apachesvr_cpu.png\" alt=\"\" width=\"592\" height=\"317\" \/><\/p>\n<p>Bon, que conclure&#8230;\u00a0?<\/p>\n<p>Une chose est s\u00fbre, il y a eu de la saturation niveau r\u00e9seau. Par contre, difficile de savoir exactement de quel \u00e9l\u00e9ment du r\u00e9seau\u00a0: le parefeu, les commutateurs, les routeurs, les injecteurs JMeter (10 000 VU c&rsquo;est trop?)&#8230;. Je n&rsquo;ai pas malheureusement acc\u00e8s \u00e0 toute la supervision des \u00e9quipements r\u00e9seau.<\/p>\n<p>Si on veut r\u00e9ussir ce tir avec 100 000 utilisateurs, il faudrait mettre plus de JMeterEngine (disons 20), pour \u00e9carter un probl\u00e8me \u00e9ventuel de ce cot\u00e9. Et aussi avoir la supervision du routeur et des commutateurs sur le chemin r\u00e9seau.<\/p>\n<p>Mais cela peut aussi venir d&rsquo;un probl\u00e8me dans la pile TCP\/IP ou dans la configuration du Apache cibl\u00e9&#8230;<\/p>\n<p>Beaucoup de conjectures possibles.<\/p>\n<p>Bon, il ne s&rsquo;agit que d&rsquo;un test de \u00ab\u00a0test de charge\u00a0\u00bb avec BlazeMeter. Et ce test l\u00e0, il est r\u00e9ussi\u00a0: avec BlazeMeter on peut faire de tr\u00e8s gros volumes\u00a0!<\/p>\n<p>Pour aussi me d\u00e9douaner de ne pas avoir r\u00e9ussi \u00e0 faire les 100 000 utilisateurs, je rappelle qu&rsquo;il s&rsquo;agit d&rsquo;un seul serveur cibl\u00e9 derri\u00e8re une seule liaison Internet, et que g\u00e9n\u00e9ralement pour un tel nombre d&rsquo;utilisateurs ont des architectures distribu\u00e9es, d\u00e9coup\u00e9es et d\u00e9coupl\u00e9es, etc. ou bien carr\u00e9ment des CDN (content delivery network). En gros, on aurait une architecture d&rsquo;h\u00e9bergement dans les nuages, \u00e0 la BlazeMeter&#8230; tiens\u00a0!<\/p>\n<p>.\/<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><em>Post scriptum<\/em><\/p>\n<p>En r\u00e9alit\u00e9, j&rsquo;ai fait plusieurs ex\u00e9cutions de ce gros test de charge. Car j&rsquo;ai rencontr\u00e9 des probl\u00e8mes\u00a0! et oui, m\u00eame si le tir pr\u00e9sent\u00e9 ci-dessus n&rsquo;est pas all\u00e9 jusqu&rsquo;au bout, j&rsquo;ai d\u00fb faire quelques optimisations, suite \u00e0 des ex\u00e9cutions du tir n&rsquo;ayant pas r\u00e9ussies, pour avoir ce r\u00e9sultat.<\/p>\n<p>Voici quelques commentaires\u00a0:<\/p>\n<p>Tout d&rsquo;abord, j&rsquo;avais configur\u00e9 un Apache (le apache2-mpm-worker fourni par la distribution Debian 6) en d\u00e9sactivant les modules inutiles, et en changeant les valeurs habituelles pour la concurrence d&rsquo;acc\u00e8s<\/p>\n<p>J&rsquo;ai tout d&rsquo;abord eu ce message d&rsquo;erreur lors d&rsquo;un tir\u00a0:<\/p>\n<pre>(24)Too many open files: file permissions deny server access: \/var\/www\/pagea.html, referer: http:\/\/monsite\/index.html<\/pre>\n<p>Bien que le \u00ab\u00a0ulimit -n\u00a0\u00bb \u00e9taient \u00e0 65 535 (dans \/etc\/security\/limits.conf).<\/p>\n<p>Pour r\u00e9soudre ce probl\u00e8me, j&rsquo;ai activ\u00e9 le mod_cache d&rsquo;Apache, les fichiers ont \u00e9t\u00e9 plac\u00e9s en m\u00e9moire Apache, et donc plus d&rsquo;acc\u00e8s disque.<\/p>\n<p>Puis dans un second tir, c&rsquo;est le netfilter (iptables) qui a pos\u00e9 probl\u00e8me. En effet, j&rsquo;avais fait un \u00ab\u00a0iptables -nvL\u00a0\u00bb sur le serveur cible pour m&rsquo;assurer qu&rsquo;il n&rsquo;y avait pas de firewall Linux actif. Et ce que je ne savais pas, c&rsquo;est cette commande charge les module du noyau Linux li\u00e9s \u00e0 netfilter (le parefeu de Linux), m\u00eame si il n&rsquo;y a pas de r\u00e8gles.<\/p>\n<p>Du coup, j&rsquo;ai eu ce message dans les logs du kernel Linux du serveur apr\u00e8s un test de tir \u00e9chou\u00e9 :<\/p>\n<pre>nf_conntrack: table full, dropping packet.<\/pre>\n<p>La solution \u00e9tait de d\u00e9charger les modules netfilter et compagnie\u00a0:<\/p>\n<pre>rmmod iptable_nat\r\nrmmod ipt_MASQUERADE\r\nrmmod nf_nat\r\nrmmod nf_conntrack_ipv4\r\nrmmod nf_conntrack\r\nrmmod nf_defrag_ipv4<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Annexes\u00a0:<\/strong><\/p>\n<p>Extraits de la configuration Apache\u00a0:<\/p>\n<p>Valeurs totalement mises arbitairement\u00a0:<\/p>\n<pre>ServerLimit 1024\r\nStartServers 128\r\nMinSpareThreads 512\r\nMaxSpareThreads 1024\r\nThreadLimit 512\r\nThreadsPerChild 128\r\nMaxClients 131072\r\nMaxRequestsPerChild 16384\r\n\r\nCacheEnable mem \/\r\nMCacheSize 32768\r\nMCacheMaxObjectCount 1000\r\nMCacheMinObjectSize 1\r\nMCacheMaxObjectSize 30000<\/pre>\n<p>&nbsp;<\/p>\n<p>Pile TCP Linux sur le serveur (copi\u00e9\/coll\u00e9 de quelque part&#8230;)\u00a0:<\/p>\n<pre>net.ipv4.ip_local_port_range = 1024 65536\r\nnet.core.rmem_max=16777216\r\nnet.core.wmem_max=16777216\r\nnet.ipv4.tcp_rmem=4096 87380 16777216\r\nnet.ipv4.tcp_wmem=4096 65536 16777216\r\nnet.ipv4.tcp_fin_timeout = 3\r\nnet.core.netdev_max_backlog = 30000\r\nnet.ipv4.tcp_no_metrics_save=1\r\nnet.core.somaxconn = 262144\r\nnet.ipv4.tcp_max_orphans = 262144\r\nnet.ipv4.tcp_max_syn_backlog = 262144\r\nnet.ipv4.tcp_synack_retries = 2\r\nnet.ipv4.tcp_syn_retries = 2<\/pre>\n<p>&nbsp;<\/p>\n<p>Fichier \/etc\/security\/limits.conf<\/p>\n<pre>root hard nofile 65535\r\nroot soft nofile 65535\r\n* hard nofile 65535\r\n* soft nofile 65535<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Dans ce premier billet, je vous pr\u00e9sentais la solution de test de charge dans les nuages BlazeMeter, bas\u00e9e sur l&rsquo;outil Apache JMeter, illustr\u00e9 par un petit test. Dans ce nouveau billet, on passe aux choses s\u00e9rieuses\u00a0: le (tr\u00e8s) gros test de charge. Mon objectif \u00e9tait le suivant\u00a0: faire un tir de charge avec 100 000 &hellip; <a href=\"https:\/\/blog.milamberspace.net\/index.php\/2012\/07\/14\/rapport-de-tres-gros-test-de-charge-avec-la-solution-blazemeter-1161.html\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">Rapport de (tr\u00e8s) gros test de charge avec la solution BlazeMeter<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[32,33],"tags":[329,368,330],"class_list":["post-1161","post","type-post","status-publish","format-standard","hentry","category-apache","category-jmeter","tag-apache","tag-blazemeter","tag-jmeter"],"_links":{"self":[{"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/posts\/1161","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=1161"}],"version-history":[{"count":14,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/posts\/1161\/revisions"}],"predecessor-version":[{"id":1186,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/posts\/1161\/revisions\/1186"}],"wp:attachment":[{"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/media?parent=1161"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/categories?post=1161"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.milamberspace.net\/index.php\/wp-json\/wp\/v2\/tags?post=1161"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}