add rabbitmq rpc sample

This commit is contained in:
Xiong Neng
2018-05-17 15:11:08 +08:00
parent 66c4d7ae39
commit f8e958fa71
21 changed files with 933 additions and 0 deletions

View File

@ -0,0 +1,12 @@
package com.xncoding.pos;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@ -0,0 +1,89 @@
package com.xncoding.pos.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.AnonymousQueue;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.AsyncRabbitTemplate;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.scheduling.annotation.EnableAsync;
import javax.annotation.Resource;
/**
* RabbitConfig
*
* @author XiongNeng
* @version 1.0
* @since 2018/3/1
*/
@Configuration
public class RabbitConfig {
/**
* 同步RPC队列
*/
public static final String QUEUE_SYNC_RPC = "rpc.sync";
/**
* 异步RPC队列使用临时回复队列或者使用“Direct reply-to”特性
*/
public static final String QUEUE_ASYNC_RPC = "rpc.async";
/**
* 异步RPC队列每个客户端使用不同的固定回复队列需要额外提供correlationId以关联请求和响应
*/
public static final String QUEUE_ASYNC_RPC_WITH_FIXED_REPLY = "rpc.with.fixed.reply";
@Bean
public Queue syncRPCQueue() {
return new Queue(QUEUE_SYNC_RPC);
}
@Bean
public Queue asyncRPCQueue() {
return new Queue(QUEUE_ASYNC_RPC);
}
@Bean
public Queue fixedReplyRPCQueue() {
return new Queue(QUEUE_ASYNC_RPC_WITH_FIXED_REPLY);
}
@Bean
public Queue repliesQueue() {
return new AnonymousQueue();
}
@Bean
public MessageConverter jsonMessageConverter(){
return new Jackson2JsonMessageConverter();
}
@Bean
@Primary
public SimpleMessageListenerContainer replyContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
container.setQueueNames(repliesQueue().getName());
return container;
}
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(jsonMessageConverter());
return rabbitTemplate;
}
@Bean
public AsyncRabbitTemplate asyncRabbitTemplate(RabbitTemplate template, SimpleMessageListenerContainer container) {
return new AsyncRabbitTemplate(template, container);
}
}

View File

@ -0,0 +1,29 @@
package com.xncoding.pos.model;
/**
* User
*
* @author XiongNeng
* @version 1.0
* @since 2018/5/17
*/
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}

View File

@ -0,0 +1,51 @@
package com.xncoding.pos.service;
import com.xncoding.pos.model.User;
import com.xncoding.pos.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.AsyncRabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.util.concurrent.ListenableFuture;
import java.util.concurrent.Future;
import static com.xncoding.pos.config.RabbitConfig.QUEUE_ASYNC_RPC;
import static com.xncoding.pos.config.RabbitConfig.QUEUE_ASYNC_RPC_WITH_FIXED_REPLY;
/**
* 消息发送服务
*/
@Service
public class SenderService {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
AsyncRabbitTemplate asyncRabbitTemplate;
@Autowired
AmqpTemplate amqpTemplate;
@Async
public Future<String> sendAsync(User message) {
// String result = (String) amqpTemplate.convertSendAndReceive(QUEUE_ASYNC_RPC, message, m -> {
// m.getMessageProperties().setCorrelationIdString(StringUtil.generateUUId());
// return m;
// });
String result = (String) amqpTemplate.convertSendAndReceive(QUEUE_ASYNC_RPC, message);
return new AsyncResult<>(result);
}
public Future<String> sendWithFixedReplay(User message) {
// ListenableFuture<String> future = asyncRabbitTemplate.convertSendAndReceive(QUEUE_ASYNC_RPC_WITH_FIXED_REPLY, message, m -> {
// m.getMessageProperties().setCorrelationIdString(StringUtil.generateUUId());
// return m;
// });
return asyncRabbitTemplate.convertSendAndReceive(QUEUE_ASYNC_RPC_WITH_FIXED_REPLY, message);
}
}

View File

@ -0,0 +1,16 @@
package com.xncoding.pos.util;
import java.util.UUID;
/**
* StringUtil
*
* @author XiongNeng
* @version 1.0
* @since 2018/5/17
*/
public class StringUtil {
public static String generateUUId() {
return UUID.randomUUID().toString();
}
}

View File

@ -0,0 +1,29 @@
##########################################################
################## 所有profile共有的配置 #################
##########################################################
################### spring配置 ###################
spring:
profiles:
active: dev
---
#####################################################################
######################## 开发环境profile ##########################
#####################################################################
spring:
profiles: dev
rabbitmq:
host: 119.29.12.177
port: 5672
username: guest
password: guest
logging:
level:
ROOT: INFO
com:
xncoding: DEBUG
file: D:/logs/rabbitmq-rpc-client.log

View File

@ -0,0 +1,90 @@
package com.xncoding.service;
import com.xncoding.pos.Application;
import com.xncoding.pos.model.User;
import com.xncoding.pos.service.SenderService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
/**
* SenderServiceTest
*
* @author XiongNeng
* @version 1.0
* @since 2018/2/2
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class SenderServiceTest {
Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private SenderService senderService;
private List<User> users;
@Before
public void prepare() {
users = new ArrayList<>();
User user1 = new User();
user1.setName("用户1");
user1.setAge(19);
users.add(user1);
User user2 = new User();
user2.setName("用户2");
user2.setAge(20);
users.add(user2);
}
@Test
public void testSendAsync() throws InterruptedException, ExecutionException {
List<Future<String>> results = new ArrayList<>();
for (User user : users) {
Future<String> result = senderService.sendAsync(user);
results.add(result);
}
for (Future<String> future : results) {
String result = future.get();
if (result == null) {
Assert.fail("message will not timeout");
} else {
logger.info("tttttttttttt=" + result);
}
}
}
@Test
public void testSendWithFixedReplay() throws InterruptedException, ExecutionException{
List<Future<String>> results = new ArrayList<>();
for (User user : users) {
Future<String> result = senderService.sendWithFixedReplay(user);
results.add(result);
}
for (Future<String> future : results) {
String result = future.get();
if (result == null) {
Assert.fail("message will not timeout");
} else {
logger.info("tttttttttttt=" + result);
}
}
}
}