2015年1月9日 星期五

logstash 對於 RabbitMQ 足夠的知識

logstash 對於 RabbitMQ 足夠的知識

在這邊稍微翻譯一下這篇文章,方便大家使用 rabbitmq 來當作 logstash 的輸出或是輸入,文章網址在這裡,如果有哪邊語義不順或是翻譯錯誤請告訴我
Rabbiemq 的設定已經超出了使用logstash的範圍,但是在使用logstash的時候,它依然扮演了很重要的角色,所以特別寫了這篇文章來使大家能更好的了解AMQP 在RabbitMQ的官方網站也有一篇文章在講解,有興趣可以到這裡來看

交換,佇列與連結

你有很長的一段時間可以了解這短短幾個字的意思

交換器(Exchanges)

交換是給訊息製造者(以下簡稱製造者)使用的,在logstash中,我們把交換器使用到輸出模組,logstash會將訊息送到交換器,我們有許多不同的交換器種類會在下面的文章裡討論。

佇列(Queues)

佇列是給訊息接收者(以下簡稱接收者)使用的,在logstash,我們把佇列使用在輸入的模組,logstash會從佇列讀取訊息,或是讀取佇列裡面一部份的訊息,讀取部分訊息的功能是透過路由關鍵字來達成的。

連結(Bindings)

光有製造者跟接收者是沒用的,我們必須將佇列連結到交換器上面,當我們做這件事的時候,可以另外指定一個路由關鍵字,路由關鍵字會在下面討論。

經紀人 (Broker)

經紀人是個簡單的AMQP伺服器軟體,網路上有許多的AMQP伺服器軟體,我們在這邊會討論到的是RabbitMQ

路由關鍵字(Routing Keys)

簡單來說,路由關鍵字是用來把你的訊息打上標簽用的,在以往的經驗裡,我們可以很簡單地利用點(dot)來把訊息放入一個階層式架構當中,像是:
  • messages.servers.production
  • sports.atlanta.baseball
  • company.myorg.mydepartment
路由關鍵字是個好用的設定,它讓你可以利用程式,在特定的事件設定路由關鍵字,像是:
  • logs.servers.production.host1
  • logs.servers.development.host1.syslog
  • logs.servers.application_foo.critical
對於接收者或是佇列來說,路由關鍵字還有兩種萬用字元,#和*
  • *(星號)對應到任意一個字詞(word)
  • #(井號)對應到任意數量的字詞,行為跟傳統的萬用字元一樣
以下將使用一些例子,幫助你了解上面的內容。 如果你想連結到交換,並且只想看有關於production的內容,你應該把路由關鍵字設定成logs.servers.production.* 如果你想看主機host1所發出的任何版本的訊息,你應該將路由關鍵字設定成logs.servers.*.host1.#
使用星號當做萬用字元的結果可能使你困惑,但是當你知道你的訊息階層需要把星號放在哪邊時,他是個很好用的規則,記得它對應到是一個字詞就對了。另一個萬用字元是井號,當你需要比對任意數量的字詞時將會用到它。 要注意的一點是,萬用字元只會在接收者跟佇列連結的時候生效,在製造者跟交換器的時候它是沒有作用的。
下面我們將會更仔細的講解RabbitMQ的組件,到這裡為止,你所獲取的知識已經足夠你了解路由關鍵字的概念了。

交換

以下我們將講解三種交換的差異
直接交換(Direct)
普遍來說,最常使用的交換是直接交換。訊息進來伺服器之後,預期會被放進一個佇列。你可以把一個直接交換連結到許多佇列,你可以想像成有一群工人,正等待著從交換那裡拿到工作來做,但是一個訊息只有一個接收者會看到直接交換裡面的訊息。
你可以設定路由關鍵字給訊息之後,再將它送到直接交換裡面。這個動作讓你可以使用同一個佇列,將工作交給不同的工人,只有特定的工人知道怎麼閱讀特定的(使用路由關鍵字)訊息。
RabbitMQ的官方網站提供了很好的描述,並且以視覺化的方式呈現連結在此
擴散(Fanout)
擴散是另一種交換的形式,跟直接交換不同,每一個連結到擴散交換的都會看到相同的訊息,這個動作很像你去註冊一個郵件論壇,當你註冊上去,他就會把訊息丟給你。這個交換方法在你需要廣播訊息給很多有興趣的組件的時候非常有用。
擴散交換不支援路由關鍵字,所有連結到他的佇列都會看到所有的訊息。
主題(Topic)
主題交換是擴散交換的特別形態,擴散交換不支援路由關鍵字,但主題交換支援它。跟擴散交換有點像,所有連結到他的佇列可以看到所有的訊息,但是會經過路由關鍵字的過濾。

Logstash 裡面的 RabbitMQ

如同先前所說的,在Logstash裡面,我們將logstash的輸出模組對應到RabbitMQ的交換。而從佇列中讀取的輸入模組是連結到交換上。Logstash使用bunny函式庫來當作經紀人,logstash提供許多關於交換跟佇列的設定。它提供了許多你也許會有興趣的設定,像是訊息的持久性或是佇列或交換的持續性。你可以從RabbbitMQ的官方文件裡面查到完整的設定值清單。
設定範例以及小技巧
以下提供幾個範例,幫助你了解如何設定RabbitMQ
檢查你的連結
如果logstash發送了一個訊息,要接收這個訊息的logstash輸入模組必須跟發送的logstash輸出模組設定相同的交換名稱
發送端
input { stdin { type = "test" } }
output {
  rabbitmq {
    exchange => "test_exchange"
    host => "my_rabbitmq_server"
    exchange_type => "fanout"
  }
}
接收端
input {
  rabbitmq {
    queue => "test_queue"
    host => "my_rabbitmq_server"
    exchange => "test_exchange" # This matches the exchange declared above
  }
}
output { stdout { debug => true }}
訊息的持久性
Logstash預設會確保你不遺失訊息,這也反映了RabbitMQ的預設值。但是在某些情況下你或許不想要這樣,像是你的RabbitMQ並不是你的主要訊息來源的時候。
在以下的例子裡面,我們會使用RabbitMQ來當作監聽界面。訊息主要會送到ElasticSearch界面,訊息會複製一份,送到RabbitMQ來當作第二訊息界面。在這個例子裡面,我們關閉了RabbitMQ持續性及持久性的設定,所以訊息不會被堆積在RabbitMQ裡面等待傳送。我們僅僅將RabbitMQ當作一個即時的監控界面。 我們會額外加入路由關鍵藝,讓我們過濾進來的訊息,這個例子裡面我們將輸入模組留給你自己填寫你所想要的資料來源。
input { 
  # 輸入你自己的資料輸入設定
}

output {
  elasticsearch { embedded => true }
  rabbitmq {
    exchange => "logtail"
    host => "my_rabbitmq_server"
    exchange_type => "topic" # 我們使用主題交換以搭配下面的路由關鍵字
    key => "logs.%{host}"
    durable => false # 如果RabbitMQ重開,這個交換會被刪除
    auto_delete => true # 如果logstash跟,RabbitMQ的連線斷掉,這個交匯會被刪除
    persistent => false # 訊息不會被儲存到硬碟上
  }
}
現在你如果想要即時傳送記錄檔,你可以用你喜歡的程式語言,把佇列連結到名字叫做logtail的交換上。如果你沒有指定路由關鍵字,你會看到每個訊息都被logstash接收到。你可以指定路由關鍵字像是logs.apache1並且只觀看來自apache1這檯機器的訊息。
注意:任何logstash的變數都是合法的路由關鍵字,這個特性讓你能夠製作複雜的分層式路由關鍵字,用來做進階的過濾器設定。
注意:RabbitMQ對於持續性及持久性有特別的規範,不論是對佇列或是交換而言都是。你需要閱讀RabbitMQ的文件來確保你不會損壞你的RabbitMQ伺服器,造成訊息一直在伺服器裡面持續等待著被取出。