代码整合
首先创建一个新的包(tut2),我们将在这里放置我们的三个类。在配置类 Tut2Config 中,我们设置了两个配置文件 ——tut2 和 work-queues。我们利用 Spring 来将队列 Queue 暴露为一个 bean。我们配置消费者,并定义两个 bean 以对应于上图中的工作进程 receiver1 和 receiver2。了解springcloud架构可以加求求:三五三六二四七二五九
配置类
@Profile({"tut2", "work-queues"})
@Configuration
public class Tut2Config {
@Bean
public Queue queue() {
return new Queue("work-queues");
}
/**
* 定义两个消费者,并且给了他们不同的标识
*/
@Profile ("receiver")
private static class ReceiverConfig {
@Bean
public Tut2Receiver receiver1() {
return new Tut2Receiver(1);
}
@Bean
public Tut2Receiver receiver2() {
return new Tut2Receiver(2);
}
}
@Profile("sender")
@Bean
public Tut2Sender sender() {
return new Tut2Sender();
}
}
生产者
我们简单修改一下生产者的代码,以添加点号(.)的方式来人为的增加该任务的时长,字符串中的每个点号(.)都会增加 1s 的耗时。
public class Tut2Sender {
@Autowired
private AmqpTemplate template;
@Autowired
private Queue queue;
int dots = 0;
int count = 0;
@Scheduled(fixedDelay = 1000, initialDelay = 500)
public void send(){
StringBuilder builder = new StringBuilder("Hello");
if (dots++ == 3) {
dots = 1;
}
for (int i = 0; i < dots; i++) {
builder.append('.');
}
builder.append(Integer.toString(++count));
String message = builder.toString();
template.convertAndSend(queue.getName(), message);
System.out.println(" [x] Sent '" + message + "'");
}
}
消费者
我们的消费者 Tut2Receiver 通过 doWork () 方法模拟了一个耗时的虚假任务,它需要为消息体中每一个点号(.)模拟 1 秒钟的操作。并且我们为消费者增加了一个实例编号,以知道是哪个实例消费了消息和处理的时长。
@RebbitListener(queues = "work-queues")
public class Tut2Receiver {
private int instance;
public Tut2Receiver(int instance) {
this.instance = instance;
}
@RabbitHandler
public void receive(String in) throws InterruptedException {
StopWatch watch = new StopWatch();
watch.start();
System.out.println("instance " + this.instance +
" [x] Received '" + in + "'");
doWork(in);
watch.stop();
System.out.println("instance " + this.instance +
" [x] Done in " + watch.getTotalTimeSeconds() + "s");
}
private void doWork(String in) throws InterruptedException {
for (char ch : in.toCharArray()) {
if (ch == '.') {
Thread.sleep(1000);
}
}
}
}