基于JMS消息中间件的分布式系统初探究(一) - 通过JMS实现Web服务器与服务框架的通讯
2015-03-24 00:47
1001 查看
在一个大型网站中,如果要把整个业务拆分成N个子业务,每个业务单独部署到一台服务器上,那么需要解决的问题有:
自身的部署。是部署到JavaEE容器中随容器启动,还是做为一个standalone程序单独启动?
子系统如何暴露服务接口(如何与其它系统进行通讯)。服务请求者直接通过Socket直连,还是通过Web Service, RMI等技术?
这里我们尝试通过standalone方式部署,通过JMS中间件实现通讯。如图所示:
在客户端(运行Web服务)和服务端,我们使用Spring, Spring JMS框架简化消息收发过程,JMS Provider使用ActiveMQ。
在服务端,需要手动创建Spring的ApplicationContext:
然后编写一个组件作为JMS消息处理器:
我们希望Spring能在从
同时,我们还要配置
到这里我们再一次看到了Spring低侵入式框架的优点,即上面的消息处理组件没有任何JMS的痕迹,完全是一个普通的POJO。
做好上面的工作后,当Spring收到ActiveMQ来自
在客户端的配置与上面相同,只是需要使用Spring JMS提供的
当我们调用
以上只是一个模型,我们可以在服务端消息处理方法(如
自身的部署。是部署到JavaEE容器中随容器启动,还是做为一个standalone程序单独启动?
子系统如何暴露服务接口(如何与其它系统进行通讯)。服务请求者直接通过Socket直连,还是通过Web Service, RMI等技术?
这里我们尝试通过standalone方式部署,通过JMS中间件实现通讯。如图所示:
在客户端(运行Web服务)和服务端,我们使用Spring, Spring JMS框架简化消息收发过程,JMS Provider使用ActiveMQ。
在服务端,需要手动创建Spring的ApplicationContext:
@Component public class Bootstrap { private static ApplicationContext ctx; public static void main(String[] args) { initSpring("spring-config.xml"); } public static void initSpring(String configPath) { ctx = new ClassPathXmlApplicationContext(configPath); } }
然后编写一个组件作为JMS消息处理器:
@Component public class SayHelloHandler { public String onSaveMember(String username) { return "OK"; } }
我们希望Spring能在从
taolijie.member.request.queue消息队列收到一条消息时调用上述方法,则需在
spring-config.xml中做如下配置:
<jms:listener-container connection-factory="connectionFactory"> <jms:listener destination="taolijie.member.request.queue" ref="sayHelloHandler" method="onSaveMember" /> </jms:listener-container>
同时,我们还要配置
ConnectionFactory和
JmsTemplate:
<!-- 配置ActiveMQ --> <amq:connectionFactory id="connectionFactory" brokerURL="tcp://localhost:61616" /> <amq:queue id="member-request-queue" physicalName="taolijie.member.request.queue" /> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="connectionFactory" /> </bean>
到这里我们再一次看到了Spring低侵入式框架的优点,即上面的消息处理组件没有任何JMS的痕迹,完全是一个普通的POJO。
做好上面的工作后,当Spring收到ActiveMQ来自
taolijie.member.request.queue队列的一条消息时就会调用
onSaveMember方法,将消息中的payload转换成String类型传入到方法中。如果该方法有返回值,Spring JMS会自动将返回值封装成Message对象并设置JMSReplayTo消息头,ActiveMQ则会按照该消息头将返回的消息投递给发送端。
在客户端的配置与上面相同,只是需要使用Spring JMS提供的
JmsTemplate编写发送一个发送消息组件:
@Component public class DefaultHelloService implements HelloService { @Autowired private JmsTemplate jmsTemplate; @Override public void sayHello(String name) { System.out.println("sending persistence request"); Message msg = jmsTemplate.sendAndReceive("taolijie.member.request.queue", (Session session) -> { return session.createObjectMessage(new String("hello")); }); TextMessage txt = (TextMessage) msg; try { System.out.println("done. " + txt.getText()); } catch (JMSException e) { // ... ... } } }
当我们调用
JmsTemplate的
sendAndReceive()方法时,Spring会帮我们创建一个临时的队列用于接收返回消息,并时同该方法阻塞,等待返回消息。如果不想发送同步消息,可以改为调用
send(),该方法会立即返回。
以上只是一个模型,我们可以在服务端消息处理方法(如
onSaveMember())中添加我们需要的业务逻辑方法,处理完成后返回信息给客户端。所有服务端应用都可以单独部署在一台服务器中,这样就简单实现了一个分布式系统。
相关文章推荐
- 基于JMS消息中间件的分布式系统初探究(二) - 服务端反射调用组件方法
- 使用 Apache MINA2 实现 Web 系统的消息中间件
- 第5章分布式系统模式 使用服务器激活对象通过 .NET Remoting 实现 Broker
- 采用Best effort 1pc + 回滚补偿机制实现的一个distributed transaction (分布式事务框架).基于dubbo rpc服务上实现。
- [大型网站系统与Java中间件实践]--分布式服务框架(RPC)
- 消息服务框架(MSF)应用实例之分布式事务三阶段提交协议的实现
- java分布式开发TCP/IP NIO无阻塞 Socket((基于消息方式实现系统间的通信) )(转)
- TCP/IP协议学习(七) 基于C# Socket的Web服务器---动态通讯实现
- 跨数据库分布式实时事务 - 基于RabbitMQ实时消息队列服务实现
- 使用 Apache MINA2 实现 Web 系统的消息中间件
- 【转载】使用 Apache MINA2 实现 Web 系统的消息中间件
- 基于CentOS 7系统的两部LAMP服务器,通过NFS共享同一个php网页的实现
- [分布式java]基于JavaAPI实现消息方式的系统间通信:TCP/IP+NIO
- IOS开发-基于WebDriverAgent代理服务,实现iOS手机app自动化测试的框架搭建
- 第5章分布式系统模式 使用服务器激活对象通过 .NET Remoting 实现 Broker
- [分布式java]基于JavaAPI实现消息方式的系统间通信:TCP/IP+BIO
- 使用 Apache MINA2 实现 Web 系统的消息中间件
- 基于Dubbo的分布式系统架构(二)-消息中间件在分布式系统中的作用及介绍
- 基于Spring-DM实现分布式服务框架(DSF)(一)
- 使用 Apache MINA2 实现 Web 系统的消息中间件