跨进程调用实现之消息组件RabbitMq实例
发布日期:2021-05-10 05:11:27 浏览次数:9 分类:技术文章

本文共 5312 字,大约阅读时间需要 17 分钟。

我们都知道完成一个模块不可能都在一个方法里面完成所有事情,需要将代码按各个维度拆分细化出来,保证系统的松耦合,比如设计模式中的模板模式就体现了这点, 既然是独立模块,那么这时候就需要通过去调用别的类或接口的方法来完成所要完成的事。

图一:

这里写图片描述

上图是一个类的方法要调用另外一个类里面叫call的方法,接收返回结果,很简单嘛,因为都在一个进程空间,两个类都是同一个java虚拟机实例并且都帮我们解析好了,只要调用一下就可以。但是假如不在同一个进程空间呢?还能这样来达到我们要的效果吗?很明显不行。

如图二:

这里写图片描述

因为两个类分别在不同的进程空间,这时候我们不能像之前那样简单调用了,那怎么办呢?很多人可能会想到现在流行的微服务,的确微服务是可以完美的解决这种跨进程服务分别分布在不同应用上面的问题。

在当今互联网当道的环境下,分布式系统已经是被广泛接受和使用,各种分布式架构也是层出不穷,支持各种微服务、SOA架构的技术也应运而生。从最初的Spring Cloud到现在流行的阿里巴巴开源框架Dubbo都明显的说明了分布式系统的重要性。

但我现在想说的不是分布式服务框架,而是消息服务组件——RabbitMQ

通过消息组件方式也可以完成我们上面出现的问题,下面我结合一个例子来说明怎么使用rabbitMq,算是入门吧,哈哈。

直接上代码解决一切问题-_-

导入需要的maven依赖,顺便把spring和junit包也引入,用来跑单元测试
pom.xml

3.2.8.RELEASE
1.1.5
7.0.81
com.rabbitmq
amqp-client
4.0.2
com.alibaba
fastjson
1.2.24
junit
junit
4.12
org.springframework
spring-test
4.0.7.RELEASE
org.springframework
spring-core
4.0.7.RELEASE
org.springframework
spring-web
${spring.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-beans
${spring.version}
org.apache.tomcat
tomcat-servlet-api
${tomcat.version}
provided
ch.qos.logback
logback-core
${logback.version}
ch.qos.logback
logback-classic
${logback.version}

因为是用spring集成,引入rabbitmq.xml

60000

applicationContext-test.xml

生产者

Producer

public abstract class Producer {    @Resource(name = "programTemplate")    AmqpTemplate amqpTemplate;    protected abstract String routeKey();    public void produce(Programmer log) {        try {            Message message = MessageBuilder.withBody(JSON.toJSONString(log).getBytes())                    .setContentType(MessageProperties.CONTENT_TYPE_JSON)                    .setDeliveryMode(MessageDeliveryMode.PERSISTENT)                    .setMessageId(UUID.randomUUID().toString())                    .build();            amqpTemplate.convertAndSend(routeKey(), message);        } catch (Exception e) {            e.printStackTrace();        }    }}

JavaProducer

@Component    public class JavaProducer extends Producer {
@Override protected String routeKey() { return "java"; }}

UML图

这里写图片描述

还差监听,一鼓作气搞定它

ProgramListener

public abstract class ProgramListener implements ChannelAwareMessageListener {
final Logger logger = LoggerFactory.getLogger(this.getClass()); public void onMessage(Message message, Channel channel) throws Exception { try { logger.info("Receive message, message body -> {}", new String(message.getBody())); channel.basicAck(message.getMessageProperties().getDeliveryTag(), true); } catch (Exception e) { logger.error("exception", e); channel.basicReject(message.getMessageProperties().getDeliveryTag(), false); } }}

JavaListener

public class JavaListener extends ProgramListener {
}

到这一步就已经完成了rabbitmq的配置和监听了,配置是采用了了rabbitmq中的direct模式

写个单元测试来验证下

RabbitMqMain

package com;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import rabbitmq.spring.entity.Programmer;import rabbitmq.spring.producer.JavaProducer;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "/applicationContext-test.xml")//@TestExecutionListeners({
/*ServletTestExecutionListener.class, */DependencyInjectionTestExecutionListener.class/*,// DirtiesContextTestExecutionListener.class*/})public class RabbitMqMain { @Autowired JavaProducer javaProducer; @Test public void testSend() { Programmer programmer = new Programmer(); programmer.setMessage("i am java, do u know me?"); javaProducer.produce(programmer); }}

这里写图片描述

可以正常跑起来。

附上rabbitmq控制台信息:
这里写图片描述

这里写图片描述

转载地址:https://blog.csdn.net/vipshop_fin_dev/article/details/80040706 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:董遇巧用“三余”
下一篇:大数据量业务报表实现思考

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2023年11月19日 07时26分07秒