{"id":73065,"date":"2020-03-06T20:42:13","date_gmt":"2020-03-06T17:42:13","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings"},"modified":"2020-03-06T20:42:13","modified_gmt":"2020-03-06T17:42:13","slug":"rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings","title":{"rendered":"RabbitMQ. Cz\u0119\u015b\u0107 3. Zrozumienie kolejek i powi\u0105za\u0144","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><code>Kolejka<\/code> (kolejka) \u2014 struktura danych na dysku lub w pami\u0119ci operacyjnej, kt\u00f3ra przechowuje odno\u015bniki do wiadomo\u015bci i udost\u0119pnia ich kopie <code>consumers<\/code> (konsumentom). <code>Kolejka<\/code> to <noindex><a rel=\"nofollow\" href=\"http:\/\/erlang.org\/doc\/reference_manual\/processes.html\">proces Erlang<\/a><\/noindex> ze stanem (gdzie mog\u0105 by\u0107 buforowane same wiadomo\u015bci). 1 tysi\u0105c kolejek mo\u017ce zajmowa\u0107 oko\u0142o 80Mb.<\/p>\n<p><\/p>\n<p><code>Binding<\/code> (wi\u0105zanie) \u2014 regu\u0142a, kt\u00f3ra informuje wymiennik, do kt\u00f3rej z kolejek maj\u0105 trafia\u0107 wiadomo\u015bci.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3 id=\"oglavlenie\">Spis tre\u015bci<\/h3>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/488654\/\">RabbitMQ. Cz\u0119\u015b\u0107 1. Wprowadzenie. Erlang, AMQP i RPC<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/489086\/\">RabbitMQ. Cz\u0119\u015b\u0107 2. Zg\u0142\u0119biamy temat Exchanges<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/490960\/\">RabbitMQ. Cz\u0119\u015b\u0107 3. Zrozumienie kolejek i powi\u0105za\u0144<\/a><\/noindex><\/li>\n<li>RabbitMQ. Cz\u0119\u015b\u0107 4. Zrozumienie, czym s\u0105 wiadomo\u015bci i ramki<\/li>\n<li>RabbitMQ. Cz\u0119\u015b\u0107 5. Wydajno\u015b\u0107 publikacji i konsumpcji wiadomo\u015bci<\/li>\n<li>RabbitMQ. Cz\u0119\u015b\u0107 6. Przegl\u0105d modu\u0142\u00f3w Federation i Shovel<\/li>\n<li>RabbitMQ. Cz\u0119\u015b\u0107 7. Szczeg\u00f3\u0142owe informacje na temat po\u0142\u0105czenia i kana\u0142u<\/li>\n<li>RabbitMQ. Cz\u0119\u015b\u0107 8. RabbitMQ w .NET<\/li>\n<li>RabbitMQ. Cz\u0119\u015b\u0107 9. Monitorowanie<\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"vremennye-ocheredi\"><em>Kolejki tymczasowe<\/em><\/h4>\n<p><\/p>\n<p>Je\u015bli tworzenie kolejki jest realizowane z ustawionym parametrem <code>autoDelete<\/code>, to taka kolejka zyskuje zdolno\u015b\u0107 <strong>automatycznego usuwania si\u0119<\/strong>. Takie kolejki zwykle s\u0105 tworzone w momencie pod\u0142\u0105czenia pierwszego klienta i usuwane w momencie, gdy wszyscy klienci si\u0119 roz\u0142\u0105czaj\u0105. <\/p>\n<p><\/p>\n<p>Je\u015bli tworzenie kolejki jest realizowane z ustawionym parametrem <code>ekskluzywna<\/code>, to taka kolejka <strong>pozwala na pod\u0142\u0105czenie tylko jednego konsumenta<\/strong> i jest usuwana, gdy kana\u0142 zostanie zamkni\u0119ty. Dop\u00f3ki kana\u0142 nie zostanie zamkni\u0119ty, klient mo\u017ce si\u0119 roz\u0142\u0105cza\u0107\/pod\u0142\u0105cza\u0107, ale tylko w ramach tego samego po\u0142\u0105czenia. Je\u015bli parametr <code>ekskluzywna<\/code> jest ustawiony, to parametr <code>autoDelete<\/code> nie ma \u017cadnego efektu.<\/p>\n<p><\/p>\n<p>Cechy:<\/p>\n<p><\/p>\n<ul>\n<li>przy kr\u00f3tkotrwa\u0142ym przerwaniu \u0142\u0105czno\u015bci stracimy wiadomo\u015bci, kt\u00f3re jeszcze nie dotar\u0142y do konsumenta<\/li>\n<li>mo\u017cna uchwyci\u0107 zjawisko <code>binding churn<\/code>. Zjawisko wyst\u0119puje, gdy liczba operacji tworzenia\/usuwania kolejek i wi\u0105za\u0144 osi\u0105ga bardzo du\u017ce warto\u015bci. W trybie klastrowym taki strumie\u0144 operacji b\u0119dzie si\u0119 rozprzestrzenia\u0142 po wszystkich w\u0119z\u0142ach i stworzy du\u017ce obci\u0105\u017cenie. Ten proces mo\u017cna zoptymalizowa\u0107 poprzez kontrolowanie liczby subskrypcji<\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"postoyannye-ocheredi\"><em>Sta\u0142e kolejki<\/em><\/h4>\n<p><\/p>\n<p>Je\u015bli tworzenie kolejki jest realizowane z ustawionym parametrem <code>durable<\/code>, to taka kolejka <strong>zachowuj\u0105 sw\u00f3j stan<\/strong> i przywracaj\u0105 si\u0119 po ponownym uruchomieniu serwera\/brokera. Taka kolejka b\u0119dzie istnia\u0142a, dop\u00f3ki nie zostanie wywo\u0142ana komenda <code>Queue.Delete<\/code>. <\/p>\n<p><\/p>\n<h4 id=\"highly-available-ocheredi\"><em>Kolejki wysoko dost\u0119pne<\/em><\/h4>\n<p><\/p>\n<p>Kolejki HA wymagaj\u0105 klastra RabbitMQ. W trybie klastrowym wszystkie informacje o wymiennikach, kolejkach, wi\u0105zaniach i konsumentach b\u0119d\u0105 kopiowane na wszystkie w\u0119z\u0142y.<\/p>\n<p><\/p>\n<p>Gdy wiadomo\u015b\u0107 jest publikowana w jakiej\u015b kolejce HA, jest przechowywana na ka\u017cdym w\u0119\u017ale, kt\u00f3ry nale\u017cy do kolejki HA. Po tym, jak wiadomo\u015b\u0107 jest konsumowana na kt\u00f3rym\u015b z w\u0119z\u0142\u00f3w, wszystkie kopie tej wiadomo\u015bci s\u0105 usuwane na innych w\u0119z\u0142ach. <\/p>\n<p><\/p>\n<p>Kolejki HA mog\u0105 obejmowa\u0107 wszystkie w\u0119z\u0142y w danym klastrze lub tylko poszczeg\u00f3lne. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Cz\u0119\u015b\u0107 3. Zrozumienie kolejek i powi\u0105za\u0144\" src=\"\/wp-content\/uploads\/2020\/03\/46d560ab33e686ddf9adb0b18b4bb0b0.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cechy:<\/p>\n<p><\/p>\n<ul>\n<li>u\u017cywanie kolejek HA prowadzi do kar w wydajno\u015bci. Przy umieszczaniu wiadomo\u015bci w jakiej\u015b kolejce HA lub przy pobieraniu wiadomo\u015bci z kolejki HA, RabbitMQ musi koordynowa\u0107 wszystkie w\u0119z\u0142y (2-3 w\u0119z\u0142y zazwyczaj wystarcz\u0105)<\/li>\n<\/ul>\n<p><\/p>\n<h4 id=\"sozdanie-ocheredi\"><em>Tworzenie kolejki<\/em><\/h4>\n<p><\/p>\n<p>Tworzenie kolejki odbywa si\u0119 za pomoc\u0105 synchronizacji <code>RPC<\/code> \u017c\u0105dania do serwera. \u017b\u0105danie jest realizowane przy u\u017cyciu metody <code>Queue.Declare<\/code>, wywo\u0142ywanej z parametrami:<\/p>\n<p><\/p>\n<ul>\n<li>nazwa kolejki<\/li>\n<li>inne parametry<\/li>\n<\/ul>\n<p><\/p>\n<p>Przyk\u0142ad tworzenia kolejki za pomoc\u0105 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/dotnet.html\">RabbitMQ.Client<\/a><\/noindex>:<\/p>\n<p><\/p>\n<pre><code class=\"cs\">\/\/ ...\nchannel.QueueDeclare(\n    queue: &quot;my_queue&quot;,\n    durable: false,\n    exclusive: false,\n    autoDelete: false,\n    arguments: null\n);\n\/\/ ...<\/code><\/pre>\n<p><\/p>\n<ul>\n<li><code>queue<\/code> \u2014 nazwa kolejki, kt\u00f3r\u0105 chcemy stworzy\u0107. Nazwa musi by\u0107 unikalna i nie mo\u017ce by\u0107 taka sama jak systemowa nazwa kolejki<\/li>\n<li><code>durable<\/code> \u2014 je\u015bli true, to kolejka b\u0119dzie <strong>zachowywa\u0107 swoje state<\/strong> i b\u0119dzie przywracana po ponownym uruchomieniu serwera\/brokera<\/li>\n<li><code>ekskluzywna<\/code> \u2014 je\u015bli true, to kolejka b\u0119dzie pozwala\u0107 na pod\u0142\u0105czenie tylko jednego konsumenta<\/li>\n<li><code>autoDelete<\/code> \u2014 je\u015bli true, to kolejka uzyskuje zdolno\u015b\u0107 <strong>automatycznego usuwania si\u0119<\/strong><\/li>\n<li><code>arguments<\/code> \u2014 opcjonalne argumenty. Poni\u017cej om\u00f3wimy to bardziej szczeg\u00f3\u0142owo.<\/li>\n<\/ul>\n<p><\/p>\n<h5 id=\"arguments\"><em>arguments<\/em><\/h5>\n<p><\/p>\n<ul>\n<li><code>x-message-ttl<\/code>(<code>x-message-time-to-live<\/code>) \u2014 pozwala ustawi\u0107 czas \u017cycia wiadomo\u015bci w milisekundach. Je\u015bli tworzenie kolejki odbywa si\u0119 z ustawion\u0105 warto\u015bci\u0105 argumentu <code>x-message-ttl<\/code>, to taka kolejka b\u0119dzie <strong>automatycznie usuwa\u0107 wiadomo\u015bci, kt\u00f3rych czas wa\u017cno\u015bci up\u0142yn\u0105\u0142<\/strong>. Ustawienie warto\u015bci argumentu <code>x-message-ttl<\/code> okre\u015bla maksymalny wiek dla wszystkich wiadomo\u015bci w tej kolejce. Tworzenie takiej kolejki <strong>umo\u017cliwia zapobieganie otrzymywaniu przestarza\u0142ych informacji<\/strong>. Mo\u017cna to wykorzysta\u0107 w systemach rzeczywistych. Je\u015bli dla kolejki, kt\u00f3ra ma wymiennik do odrzuconych wiadomo\u015bci, ustawi\u0107 warto\u015b\u0107 argumentu <code>x-message-ttl<\/code>, to odrzucone wiadomo\u015bci w tej kolejce <strong>zaczn\u0105 mie\u0107 czas \u017cycia<\/strong>.<\/li>\n<li><code>x-expires<\/code> \u2014 ustawia warto\u015b\u0107 w milisekundach, po kt\u00f3rej zachodzi usuni\u0119cie kolejki. Kolejka mo\u017ce wyda\u0107 sw\u00f3j czas \u017cycia tylko wtedy, gdy nie ma \u017cadnych subskrybent\u00f3w. Je\u015bli do kolejki s\u0105 pod\u0142\u0105czeni subskrybenci, mo\u017ce ona automatycznie usun\u0105\u0107 si\u0119 tylko wtedy, gdy wszyscy subskrybenci wywo\u0142aj\u0105 <code>Basic.Cancel<\/code> lub si\u0119 od\u0142\u0105cz\u0105. Czas \u017cycia kolejki mo\u017ce si\u0119 zako\u0144czy\u0107 tylko w przypadku, gdy nie by\u0142o do niej zapytania <code>Basic.Get<\/code>. W przeciwnym razie obecna warto\u015b\u0107 ustawienia czasu \u017cycia zostaje zresetowana, a kolejka nie b\u0119dzie ju\u017c automatycznie usuwana. R\u00f3wnie\u017c <strong>nie ma gwarancji, jak szybko nast\u0105pi usuni\u0119cie kolejki po up\u0142ywie jej czasu \u017cycia<\/strong>.<\/li>\n<li><code>x-max-length<\/code> \u2014 ustala maksymaln\u0105 liczb\u0119 wiadomo\u015bci w kolejce. Gdy liczba wiadomo\u015bci w kolejce zacznie przekracza\u0107 maksymaln\u0105 ilo\u015b\u0107, usuwane b\u0119d\u0105 najstarsze.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Cz\u0119\u015b\u0107 3. Zrozumienie kolejek i powi\u0105za\u0144\" src=\"\/wp-content\/uploads\/2020\/03\/738f23dcfdd173a66be619032b46c5cc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li><code>x-max-length-bytes<\/code> \u2014 ustala maksymalny dozwolony sumaryczny rozmiar \u0142adunku wiadomo\u015bci w kolejce. Po przekroczeniu ustalonej warto\u015bci (wyst\u0105pi\u0142o przepe\u0142nienie kolejki podczas publikacji wiadomo\u015bci), najstarsze wiadomo\u015bci zaczn\u0105 by\u0107 usuwane.<\/li>\n<li><code>x-overflow<\/code> \u2014 ten argument s\u0142u\u017cy do konfiguracji zachowania w przypadku przepe\u0142nienia kolejki. Dost\u0119pne s\u0105 dwie warto\u015bci: <code>drop-head<\/code> (warto\u015b\u0107 domy\u015blna) oraz <code>reject-publish<\/code>. Je\u015bli wybierzesz <code>drop-head<\/code>, najstarsze wiadomo\u015bci b\u0119d\u0105 usuwane. Je\u015bli wybierzesz <code>reject-publish<\/code>, przyjmowanie wiadomo\u015bci zostanie wstrzymane.<\/li>\n<li><code>x-dead-letter-exchange<\/code> \u2014 ustala exchange, do kt\u00f3rego kierowane s\u0105 odrzucone wiadomo\u015bci, kt\u00f3re nie zosta\u0142y ponownie w\u0142o\u017cone do kolejki.<\/li>\n<li><code>x-dead-letter-routing-key<\/code> \u2014 ustala opcjonalny klucz routingu dla odrzuconych wiadomo\u015bci.<\/li>\n<li><code>x-max-priority<\/code> \u2014 umo\u017cliwia sortowanie wed\u0142ug priorytet\u00f3w w kolejce z maksymaln\u0105 warto\u015bci\u0105 priorytetu 255 (RabbitMQ wersje 3.5.0 i wy\u017csze). Liczba wskazuje maksymalny priorytet, kt\u00f3ry b\u0119dzie wspierany przez kolejk\u0119. Je\u015bli argument nie jest ustawiony, kolejka nie b\u0119dzie wspiera\u0107 priorytet\u00f3w wiadomo\u015bci.<\/li>\n<li><code>x-queue-mode<\/code> \u2014 umo\u017cliwia prze\u0142\u0105czenie kolejki w <strong>tryb leniwy<\/strong>. W tym trybie jak najwi\u0119cej wiadomo\u015bci b\u0119dzie przechowywanych na dysku. U\u017cycie pami\u0119ci operacyjnej b\u0119dzie minimalne. W przypadku, gdy nie jest ustawiony, kolejka b\u0119dzie przechowywa\u0107 wiadomo\u015bci w pami\u0119ci, aby dostarcza\u0107 wiadomo\u015bci jak najszybciej.<\/li>\n<li><code>x-queue-master-locator<\/code> \u2014 je\u015bli mamy klaster, mo\u017cna ustawi\u0107 master queue.<\/li>\n<li><code>x-ha-policy<\/code> \u2014 jest u\u017cywany podczas tworzenia HA kolejek i okre\u015bla, jak wiadomo\u015b\u0107 b\u0119dzie rozpowszechniana na w\u0119z\u0142ach. Je\u015bli ustawiona jest warto\u015b\u0107 <code>wszystko<\/code>, wiadomo\u015b\u0107 b\u0119dzie przechowywana na wszystkich w\u0119z\u0142ach. Je\u015bli ustawiona jest warto\u015b\u0107 <code>nodes<\/code>, wiadomo\u015b\u0107 b\u0119dzie przechowywana na okre\u015blonych w\u0119z\u0142ach klastra.<\/li>\n<li><code>x-ha-nodes<\/code> \u2014 ustala w\u0119z\u0142y, do kt\u00f3rych b\u0119dzie nale\u017ca\u0142a dana kolejka. <code>HA<\/code><\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Cz\u0119\u015b\u0107 3. Zrozumienie kolejek i powi\u0105za\u0144\" src=\"\/wp-content\/uploads\/2020\/03\/a8f660b6c0a43626e4025cf7769a4425.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Je\u015bli utworzenie kolejki <strong>by\u0107 mo\u017ce<\/strong>, to serwer wy\u015ble do klienta synchronizowane <code>RPC<\/code> odpowiedzi <code>Queue.DeclareOk<\/code>. Je\u015bli utworzenie kolejki <strong>niemo\u017cliwe<\/strong> (wyst\u0105pi\u0142 b\u0142\u0105d w \u017c\u0105daniu <code>Queue.Declare<\/code>), to <strong>kana\u0142 zostanie zamkni\u0119ty<\/strong> serwerem za pomoc\u0105 polecenia <code>Channel.Close<\/code> i klient otrzyma wyj\u0105tek <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/releases\/rabbitmq-dotnet-client\/v3.6.10\/rabbitmq-dotnet-client-3.6.10-client-htmldoc\/html\/type-RabbitMQ.Client.Exceptions.OperationInterruptedException.html\">OperationInterruptedException<\/a><\/noindex>, kt\u00f3ry b\u0119dzie zawiera\u0142 kod b\u0142\u0119du i jego opis. <\/p>\n<p><\/p>\n<p><strong>Ponowne wywo\u0142anie<\/strong> <code>Queue.Declare<\/code> <strong>z tymi samymi parametrami<\/strong> zwr\u00f3ci u\u017cyteczne informacje o tej kolejce. Na przyk\u0142ad, og\u00f3ln\u0105 liczb\u0119 wiadomo\u015bci oczekuj\u0105cych w danej kolejce oraz og\u00f3ln\u0105 liczb\u0119 subskrybent\u00f3w na ni\u0105. <\/p>\n<p><\/p>\n<p>Wywo\u0142anie <code>Queue.Declare<\/code> z danymi logowania u\u017cytkownika, kt\u00f3remu nie przypisano wymaganych uprawnie\u0144 <strong>zamknie kana\u0142<\/strong> za pomoc\u0105 polecenia <code>Channel.Close<\/code> i klient otrzyma wyj\u0105tek <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/releases\/rabbitmq-dotnet-client\/v3.6.10\/rabbitmq-dotnet-client-3.6.10-client-htmldoc\/html\/type-RabbitMQ.Client.Exceptions.OperationInterruptedException.html\">OperationInterruptedException<\/a><\/noindex>, kt\u00f3ry b\u0119dzie zawiera\u0142 kod b\u0142\u0119du <noindex><a rel=\"nofollow\" href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/HTTP\/Status\/403\">403<\/a><\/noindex> i jego opis.<\/p>\n<p><\/p>\n<p>Po tym, jak kolejka jest bezczynna przez &gt;= 10 sekund, wchodzi <strong>w stan u\u015bpienia<\/strong>, wywo\u0142uj\u0105c GC w kolejce, co prowadzi do znacznego zmniejszenia pami\u0119ci potrzebnej dla tej kolejki.<\/p>\n<p><\/p>\n<h4 id=\"sozdanie-queue-cherez-graficheskiy-interfeys\"><em>Tworzenie kolejki za pomoc\u0105 interfejsu graficznego<\/em><\/h4>\n<p><\/p>\n<p>Zaloguj si\u0119 do panelu administracyjnego <code>RabbitMQ<\/code> jako u\u017cytkownik <code>go\u015b\u0107<\/code> (nazwa u\u017cytkownika: <code>go\u015b\u0107<\/code> i has\u0142o: <code>go\u015b\u0107<\/code>). Zauwa\u017c, \u017ce u\u017cytkownik <code>go\u015b\u0107<\/code> mo\u017ce \u0142\u0105czy\u0107 si\u0119 tylko z lokalnego hosta. Teraz przejd\u017a do zak\u0142adki <code>Kolejki<\/code> i kliknij na <code>Dodaj now\u0105 kolejk\u0119<\/code>. Wype\u0142nij w\u0142a\u015bciwo\u015bci:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Cz\u0119\u015b\u0107 3. Zrozumienie kolejek i powi\u0105za\u0144\" src=\"\/wp-content\/uploads\/2020\/03\/ea77a406ad16f0871c7197e96a66818f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Po wprowadzeniu wszystkich wymaganych danych i naci\u015bni\u0119ciu na <code>Dodaj kolejki<\/code>, kolejka pojawi si\u0119 na og\u00f3lnej li\u015bcie.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Cz\u0119\u015b\u0107 3. Zrozumienie kolejek i powi\u0105za\u0144\" src=\"\/wp-content\/uploads\/2020\/03\/8342e044a0d6c0a035a2c9f646035cad.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Klikni\u0119cie na nazw\u0119 kolejki poka\u017ce jej szczeg\u00f3\u0142owe informacje. Tutaj mo\u017cna skonfigurowa\u0107 powi\u0105zanie mi\u0119dzy wymian\u0105 a kolejk\u0105, zobaczy\u0107 list\u0119 <code>consumers<\/code>, publikowa\u0107\/odbiera\u0107 wiadomo\u015bci, usun\u0105\u0107 kolejk\u0119 i zobaczy\u0107 statystyki.<\/p>\n<p><\/p>\n<h4 id=\"sozdanie-binding\"><em>Tworzenie powi\u0105zania<\/em><\/h4>\n<p><\/p>\n<p>Tworzenie powi\u0105zania odbywa si\u0119 za pomoc\u0105 synchronizacji <code>RPC<\/code> \u017c\u0105dania do serwera. \u017b\u0105danie jest realizowane przy u\u017cyciu metody <code>Queue.Bind<\/code>, wywo\u0142ywanej z parametrami:<\/p>\n<p><\/p>\n<ul>\n<li>nazwa kolejki<\/li>\n<li>nazwa punktu wymiany<\/li>\n<li>inne parametry<\/li>\n<\/ul>\n<p><\/p>\n<p>Przyk\u0142ad tworzenia powi\u0105zania za pomoc\u0105 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.rabbitmq.com\/dotnet.html\">RabbitMQ.Client<\/a><\/noindex>:<\/p>\n<p><\/p>\n<pre><code class=\"cs\">\/\/...\nchannel.QueueBind(\n    queue: queueName,\n    exchange: &quot;my_exchange&quot;,\n    routingKey: &quot;my_key&quot;,\n    arguments: null\n);\n\/\/...<\/code><\/pre>\n<p><\/p>\n<ul>\n<li><code>queue<\/code> \u2014 nazwa kolejki<\/li>\n<li><code>exchange<\/code> \u2014 nazwa wymiennika<\/li>\n<li><code>routingKey<\/code> \u2014 klucz routingu<\/li>\n<li><code>arguments<\/code> \u2014 opcjonalne argumenty<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Cz\u0119\u015b\u0107 3. Zrozumienie kolejek i powi\u0105za\u0144\" src=\"\/wp-content\/uploads\/2020\/03\/9123186c94a822309b679f26c2e511ea.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Je\u015bli tworzenie powi\u0105zania <strong>by\u0107 mo\u017ce<\/strong>, to serwer wy\u015ble do klienta synchronizowane <code>RPC<\/code> odpowiedzi <code>Queue.BindOk<\/code>.<\/p>\n<p><\/p>\n<h4 id=\"sozdanie-binding-cherez-graficheskiy-interfeys\"><em>Tworzenie powi\u0105zania za pomoc\u0105 interfejsu graficznego<\/em><\/h4>\n<p><\/p>\n<p>Zaloguj si\u0119 do panelu administracyjnego <code>RabbitMQ<\/code> jako u\u017cytkownik <code>go\u015b\u0107<\/code> (nazwa u\u017cytkownika: <code>go\u015b\u0107<\/code> i has\u0142o: <code>go\u015b\u0107<\/code>). Zauwa\u017c, \u017ce u\u017cytkownik <code>go\u015b\u0107<\/code> mo\u017ce \u0142\u0105czy\u0107 si\u0119 tylko z lokalnego hosta. Teraz przejd\u017a do zak\u0142adki <code>Kolejki<\/code> i klikamy na kolejk\u0119 <code>my_queue<\/code>. Wype\u0142niamy pola sekcji <code>bindings<\/code>:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Cz\u0119\u015b\u0107 3. Zrozumienie kolejek i powi\u0105za\u0144\" src=\"\/wp-content\/uploads\/2020\/03\/7db6b42a4f29a1860aabe54ade0b6833.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Po wprowadzeniu wszystkich wymaganych danych i naci\u015bni\u0119ciu na <code>Powi\u0105\u017c<\/code>, powi\u0105zanie pojawi si\u0119 na og\u00f3lnej li\u015bcie:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"RabbitMQ. Cz\u0119\u015b\u0107 3. Zrozumienie kolejek i powi\u0105za\u0144\" src=\"\/wp-content\/uploads\/2020\/03\/499eda8e8cb061e6feb75c471eb64b92.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h3 id=\"code\">Kod<\/h3>\n<p><\/p>\n<p>W tej sekcji opiszemy kolejk\u0119 i powi\u0105zanie z kodem w C#, tak jakby\u015bmy musieli stworzy\u0107 bibliotek\u0119. Mo\u017ce to by\u0107 przydatne dla zrozumienia.<\/p>\n<p><\/p>\n<pre><code class=\"cs\">public interface IQueue\n    {        \n        string Name { get; }\n\n        \/\/ <summary>\n        \/\/     Je\u015bli ustawi\u0107 na true, kolejka b\u0119dzie trwa\u0142a.\n        \/\/     B\u0119dzie przechowywana na dysku i mo\u017ce\n        \/\/     przetrwa\u0107 restart serwera\/brokera.\n        \/\/     Je\u015bli warto\u015b\u0107 to false, kolejka jest tymczasowa i b\u0119dzie usuwana,\n        \/\/     gdy serwer\/broker zostanie ponownie uruchomiony\n        \/\/ <\/summary>\n        bool IsDurable { get; }\n\n        \/\/ <summary>\n        \/\/     Je\u015bli warto\u015b\u0107 to true,\n        \/\/     ta kolejka b\u0119dzie pozwala\u0107 na pod\u0142\u0105czenie\n        \/\/     tylko jednemu consumer-owi\n        \/\/ <\/summary>\n        bool IsExclusive { get; }\n\n        \/\/ <summary>\n        \/\/     Automatyczne usuni\u0119cie.\n        \/\/     Kolejka zostanie usuni\u0119ta, gdy wszyscy klienci si\u0119 od\u0142\u0105cz\u0105.\n        \/\/ <\/summary>\n        bool IsAutoDelete { get; }\n\n        \/\/ <summary>\n        \/\/     Opcjonalne argumenty\n        \/\/ <\/summary>\n        IDictionary Arguments { get; }\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public class Queue : IQueue\n    {\n        public Queue(\n             string name, \n             bool isDurable = true, \n             bool isExclusive = false, \n             bool isAutoDelete = false, \n             IDictionary&lt;string, object&gt; arguments = null)\n        {\n            Name = name ??\n                throw new ArgumentNullException(name, $&quot;{name} must not be null&quot;);\n\n            IsDurable = isDurable;\n            IsExclusive = isExclusive;\n            IsAutoDelete = isAutoDelete;\n            Arguments = arguments ?? new Dictionary&lt;string, object&gt;();\n        }\n\n        public string Name { get; }\n        public bool IsDurable { get; }\n        public bool IsExclusive { get; }\n        public bool IsAutoDelete { get; }\n        public IDictionary&lt;string, object&gt; Arguments { get; }\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public static class QueueMode\n    {       \n        public const string Default = &quot;default&quot;;\n        \/\/\/ &lt;summary&gt;\n        \/\/\/     \u041b\u0435\u043d\u0438\u0432\u044b\u0439 \u0440\u0435\u0436\u0438\u043c. \u041b\u0435\u043d\u0438\u0432\u044b\u0439 \u0440\u0435\u0436\u0438\u043c \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \n        \/\/\/     \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435, \u0447\u0442\u043e\u0431\u044b \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \n        \/\/\/     \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438\n        \/\/\/ &lt;\/summary&gt;\n        public const string Lazy = &quot;lazy&quot;;\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public interface IBinding\n    {\n        \/\/ <summary>\n        \/\/     Wymiennik, kt\u00f3ry b\u0119dzie wi\u0105zany z powi\u0105zaniem\n        \/\/ <\/summary>\n        IExchange Exchange { get; }\n\n        \/\/ <summary>\n        \/\/     Klucz routingu\n        \/\/ <\/summary>\n        string RoutingKey { get; }\n\n        \/\/ <summary>\n        \/\/     Opcjonalne argumenty\n        \/\/ <\/summary>\n        IDictionary Arguments { get; }\n    }<\/code><\/pre>\n<p><\/p>\n<pre><code class=\"cs\">public class Binding : IBinding\n    {\n        public Binding(\n             IExchange exchange, \n             string routingKey, \n             IDictionary arguments)\n        {\n            Exchange = exchange;\n            RoutingKey = routingKey;\n            Arguments = arguments;\n        }\n\n        public IExchange Exchange { get; }\n        public string RoutingKey { get; }\n        public IDictionary Arguments { get; }\n    }<\/code><\/pre>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/490960\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>Queue (\u043e\u0447\u0435\u0440\u0435\u0434\u044c) \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0438\u0445 \u043a\u043e\u043f\u0438\u0438 consumers (\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u043c). Queue \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 Erlang-\u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c (\u0433\u0434\u0435 \u043c\u043e\u0433\u0443\u0442 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u0441\u0430\u043c\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f). 1 \u0442\u044b\u0441\u044f\u0447\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043a\u0430 80Mb. Binding (\u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430) \u2014 \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u043e\u0431\u043c\u0435\u043d\u043d\u0438\u043a\u0443 \u0432 \u043a\u0430\u043a\u0443\u044e \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":73066,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-73065","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"Queue (\u043e\u0447\u0435\u0440\u0435\u0434\u044c) \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0438\u0445 \u043a\u043e\u043f\u0438\u0438 consumers (\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u043c).\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47RabbitMQ. \u0427\u0430\u0441\u0442\u044c 3. \u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0441 Queues \u0438 Bindings | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"Queue (\u043e\u0447\u0435\u0440\u0435\u0434\u044c) \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0438\u0445 \u043a\u043e\u043f\u0438\u0438 consumers (\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u043c).\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-03-06T17:42:13+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-06T17:42:13+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47RabbitMQ. Cz\u0119\u015b\u0107 3. Rozwa\u017camy Queues i Bindings | ProHoster","description":"Kolejka \u2014 struktura danych na dysku lub w pami\u0119ci RAM, kt\u00f3ra przechowuje odno\u015bniki do wiadomo\u015bci i dostarcza ich kopie do konsument\u00f3w.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47RabbitMQ. \u0427\u0430\u0441\u0442\u044c 3. \u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0441 Queues \u0438 Bindings | ProHoster","og:description":"Queue (\u043e\u0447\u0435\u0440\u0435\u0434\u044c) \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u0438\u0445 \u043a\u043e\u043f\u0438\u0438 consumers (\u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u043c).","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/rabbitmq-chast-3-razbiraemsya-s-queues-i-bindings","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-03-06T17:42:13+00:00","article:modified_time":"2020-03-06T17:42:13+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"73065","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 18:41:06","updated":"2022-09-30 05:07:23","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/73065","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=73065"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/73065\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/73066"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=73065"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=73065"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=73065"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}