#はじめに
使ってみたというより、必要に迫られて、調査して使用した次第です。
チュートリアルを色々いじってみたり、DocumentをGoogle先生で翻訳して
偏差値40の頭で読んで色々模索した結果、私に用意された時間では以下の方法で精一杯でした。。
その他の活用事例や、ここが違う!云々カンヌンなどありましたら
説教混じりに解説お待ちしております。
なんで、jarじゃなくてwar使ってんだ!とかは却下させて下さい。
#参考
- 多分こちらの方の情報を参考にさせて頂きました。大感謝。 (3〜4ヶ月くらい前の事なので記憶が曖昧)
#環境とか
- SpringBoot 1.5.3
- RabbitMQ:インストール済
- Hoge.warにBroker、Publisher、Consumerが入っている。
- RabbitMQとHoge.warは同じIPのサーバーにいる。
RabbitMQ、Broker、Publisher は 別々なサーバーに居てもOKなそうな。
ちなみに最新のSpringAMQPは、RabbitMQのVersionに依存しない作りになっているそうな。 - 求められた要件、、、
- 大量の年賀状が1つのポストに継続的に投函される・・
- 年賀状の数だけ各都道府県に配達する人がいては、ちょっと困る。それヤメて。
- 各都道府県って入場規制規制かかってんだ。だから、北海道に配達担当者は2名、青森は1名、東京は5名・・とかでよろしゅう。各人は、ハガキ1枚だけ持って届けてね。届けたらまたポストまで戻ってきて、また配達な。
- RabbitMQがダウンしたらRabbitMqExeptionだっけかな。それくらいでしか検知する方法今のところ知らん。どうしたら良いのか。そもそもダウンするのか?
Code
RabbitMQ接続情報
- RabbitMQインストール後のデフォルトが以下の通り。
- 確か、SpringBootで以下の設定値はデフォルトで行ってくれていた気がするのであえてプロパティに書かなくても良い気がしたが、詳しくはBootのCodeでも調べて下さい。
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
Broker
RabbitMQに、ExchangeとQueuを作成する設定です。
アプリケーションが起動する際に作成されます。
↓postというExchangeが作成され、そこにhokkaidoというキューが作成されて
バインドされる。with()に設定しているのは、ルーティングキー。このルーティングキー
と同じ文字列をConsumer側に定義する認識でおります。以下では北海道の例だけ。
@Configuration
public class AmqpConfig{
@Bean
public DirectExchang direct(){
return new DirectExchang("post");
}
@Bean
public Queu hokkaido(){
return new Queu("hokkaido");
}
@Bean
public Binding hokkaidoBinding(DirectExchang de, Queu hokkaido){
return BindingBuilder.bind(hokkaido).to(de).with("hokkaido");
}
}
Publisher
RabbitMQにデータを突っ込む側。年賀はがきのポスト投函が
バシバシ行われる。
Consumerから処理結果をもらうメソッドもあったはずだが
以下ではConsumerにNengaHagakiインスタンスを渡して処理宜しくって
依頼してPublisherはお役御免。
第一引数のhokkaidoは、aomoriだったりtokyoも指定するイメージ。
説明の便宜上、hokkaidoオンリーの例になってます。
@Autowired
RabbitTemplate rabbitTemplate;
@PostMapping("hoge/recv")
public String oredayoOreOre(HogeForm hogeForm, Model model){
・・・なんか色々あるんでしょう・・・
//引数にルーティングキーと、Lisnerに処理してもらうデータをSET
rabbitTemplate.converAndSend("hokkaido", nengaHagaki);
・・・なんか色々あるんでしょう・・・
}
Consumer
RabbitMQに突っ込まれたデータを取得して処理をする側。
指定のキューにデータが入ったら、以下のメソッドは勝手に処理を開始。
クラスは、シングルトンじゃなきゃ駄目っぽい。実験して、そうだった気がするのでそうしてるし
動いている様子から考えたら、なんとなく、ああそうだなって納得している自分がいるの。。ええ。
シングルトンだから、各メソッドからServiceクラスなどDIコンテナ管理のクラスを呼ぶ場合は
ルックアップが必要。
各メソッドは、Publisherとは別スレッドよ。
北海道の配達員は2人なので、メソッド2つ準備している。これらはパラレルに動く。
メソッド処理終了次第、キューに入っているデータを取得してまた処理をする。
@Component
public class PostConsumer {
@RabbitListener(queus="hokkaido")
public void hokkaidoLisner1(NengaHagaki nengaHagaki){
・・・処理・・・
}
@RabbitListener(queus="hokkaido")
public void hokkaidoLisner2(NengaHagaki nengaHagaki){
・・・処理・・・
}
}