[英]Spring boot and asynchronous RabbitMQ RPC
我正在嘗試實施 RabbitMQ RPC 模式(請求/響應)。
這對我來說是全新的技術。 所以我很難過。
這是一個 web 應用程序,內置於 spring 啟動。
結構:
用戶用一些信息填寫表單並提交表單,調用處理 controller 例如@{/processUser}
Object 將表單中的信息發送到 RabbitMQ 隊列
響應部分發生在其他 spring 項目服務中,即獲取請求、構建響應並將其發回。
建築響應應該在給定的時間范圍內對另一個 spring 項目做另一個用戶,如果沒有,則發回通用響應。
所以我假設響應代碼,因為它需要在一個線程上等待整個時間請求,我需要主線程運行 spring 啟動應用程序,應該在后台的單獨線程上。 因為我需要它是異步的。
這段代碼按照我的意願“異步”工作,但我覺得有更好的方法我只是不知道。 我不知道這個匿名線程將如何處理多個使用 web 應用程序的用戶。 它不需要完美,但可以接受:)
下面的代碼沒有完成,也沒有完成所有的事情(發送 object,動態做出響應......)這只是測試階段。
請求代碼:
public String call(String message) throws Exception{
final String corrID = UUID.randomUUID().toString();
String replayQueueName = channel.queueDeclare().getQueue();
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder().correlationId(corrID).replyTo(replayQueueName).build();
channel.basicPublish("", requestQueueName,props,message.getBytes());
final BlockingQueue<String> response = new ArrayBlockingQueue<>(1);
String ctag = channel.basicConsume(replayQueueName, true, (consumerTag, delivery) -> {
if (delivery.getProperties().getCorrelationId().equals(corrID)) {
response.offer(new String(delivery.getBody(), "UTF-8"));
}
}, consumerTag -> {
});
String result = response.take();
channel.basicCancel(ctag);
return result;
並且在處理controller時調用了這個方法:
try(Connection connection = factory.newConnection()){
channel = connection.createChannel();
System.out.println("Sending request...");
String response = call("Test_Message");
System.out.println(response);
}catch (Exception e){
e.printStackTrace();
}
響應代碼:
@Bean
public ConnectionFactory startFactory(){
return new ConnectionFactory();
}
@Bean
public Connection startCon(ConnectionFactory factory) throws Exception{
return factory.newConnection();
}
@Bean
public void reciver(){
new Thread(new Runnable() {
@Override
public void run() {
try{
Channel channel = connection.createChannel();
channel.queueDeclare(RPC_QUEUE_NAME,false,false,false,null);
channel.queuePurge(RPC_QUEUE_NAME);
channel.basicQos(1);
System.out.println("Awaiting rpc requests");
Object monitor = new Object();
DeliverCallback deliverCallback = (consumerTag, delivery) ->{
AMQP.BasicProperties replayProps = new AMQP.BasicProperties.Builder()
.correlationId(delivery.getProperties().getCorrelationId())
.build();
String response = "RESPONSE_TESTING";
String message = new String(delivery.getBody(),"UTF-8");
System.out.println(message);
channel.basicPublish("",delivery.getProperties().getReplyTo(), replayProps, response.getBytes());
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
synchronized (monitor){
monitor.notify();
}
};
channel.basicConsume(RPC_QUEUE_NAME, false, deliverCallback, (consumerTag -> {}));
while(true){
synchronized (monitor){
try{
monitor.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}).start();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.