ActiveMQ与REST API实践

摘要

1. 如何搭建Active REST服务的环境

2. REST API以及相关配置参数介绍

3. ActiveMQ中optimizeAck机制介绍

 

    ActiveMQ实现了基于RESTFUL的API,允许开发者可以直接通过HTTP POST/GET方式发布消息和消费消息,这是一种基于文本(/文件)传输的协议.因为在某些特定的环境中,通过HTTP方式操作消息更加便捷,比如基于HTML5的移动终端上,通过javascript或者窗体事件来获取消息.

 

    通常,在开放互联网环境中,非核心消息/类日志系统中,我们会使用ActiveMQ REST来push(保存)/delete(消费)消息。我们可以将REST服务伪装成一个日志存储与分发系统,我们不需要额外的框架支撑,就能实现基于大数据消息的存储与分发。同时也可以在web brower中使用REST,通过轮询或者keepAlive来实现消息的实时推送。

 

    REST协议的最大特点就是更加面向互联网应用(而非企业级应用),其交互便捷, 数据可读性强.当然其局限性也很明显: 在安全上/消息ACK机制上/对事务的支持上/还有消息的异步操作上都有所欠缺(相对于openwire).无论消费者还是生产者,都需要通过URL来描述操作,这就局限了在REST协议下client端调优的情况,同时它还受限于HTTP协议(:keep-alive)以及servlet容器对异步的支持能力。

 

    每个ActiveMQ broker都集成了servlet环境(默认为jetty环境),在启动activeMQ broker的时候,默认挂载启动.org.apache.activemq.web.MessageServlet是官方已经实现的REST代理类,用来代理REST请求.实现原理也非常简单,servlet接收到请求后,内部将使用普通的JMS API + openwire协议与broker通讯.在REST协议中,AcitveMQ约定了URL格式以及参数列表,以及发布消息必须基于HTTP POST,消费消息可以基于GET/DELETE方式.

>>>http://localhost:8161/api/message/test-queue?type=queue&clientId=test1&json=true  
Hello,Restful! 

 

1. 环境准备

   AcitveMQ broker在启动的时候,会挂载启动多个web系统,其中一个web系统就是"api",你可以参看{activemq}/webapps/api中查看相应的配置.这个api系统,就是为REST协议而服务的.{activemq}/conf/activemq.xml文件,是activemq所有配置文件的入口,文件中通过配置引入jetty环境即可使用api系统.

<import resource="jetty.xml"/>

 

<transportConnector name="rest" uri="tcp://0.0.0.0:51616?maximumConnections=1000&wireformat.maxFrameSize=1048576&keepAlive =true&soTimeout =30000"/>

    此外,因为REST底层仍然基于openwire(tcp通道)支持,且REST的特性需要贴近HTTP的“短期”/“小数据”等特性,所以我们在transportConnector中,将uri中增加soTimeout=3000,以及控制最大数据尺寸为1M。

 

    从jetty.xml中,我们可以看到所有web系统的配置信息:

<bean id="securityConstraint" class="org.eclipse.jetty.util.security.Constraint">
	<property name="name" value="BASIC" />
	<property name="roles" value="admin" />
	<!-- 是否使用安全认证 -->
	<property name="authenticate" value="true" />
</bean>
<bean id="securityConstraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
	<property name="constraint" ref="securityConstraint" />
	<property name="pathSpec" value="/*" />
</bean>

 

    5.8之后,jetty环境中所有的web系统默认都是需要授权的,这就意味着,使用REST API时需要提供"name" + "password"校验信息,否则将REST请求将会被拒绝.当然,开发者可以通过注释如下参数式REST不再需要认证.

<!-- 是否使用授权认证,"true"/"false" -->
<!--
<property name="authenticate" value="true" />
-->

 

    此外,让ActiveMQ broker来提供REST服务似乎不是一种良好的架构设计,这将很大程度上限制了开发者对REST服务的扩展性,在很多情况下,我们需要把REST服务迁移到专门的web应用中,那么我们就不需要让jetty环境挂载启动api系统.

<!--
<bean class="org.eclipse.jetty.webapp.WebAppContext">
	<property name="contextPath" value="/api" />
	<property name="resourceBase" value="${activemq.home}/webapps/api" />
	<property name="logUrlOnStart" value="true" />
</bean>
-->

    接下来,我们将自己搭建ActiveMQ REST服务环境。

2.配置文件

    如果你基于activeMQ jetty环境,你可能需要查看一下{activemq}/webapps/api/WEB-INF/web.xml文件,如果你的REST server是自己搭建的,你可能需要把此web.xml文件中的核心信息copy到自己的项目中.无论如何,你都需要在servlet环境中,配置并启动"org.apache.activemq.web.MessageServlet". 其中"org.jolokia.http.AgentServlet"仅作为可选,对于自己搭建REST服务,jolokia就无须配置了。

 

    构建一个servlet系统,我们必须首先确定servlet版本,因为这将直接关系到REST的异步特性,目前比较稳定的版本组合为:servlet 2.4(2.5) + tomcat 6.x,servlet 3.0.1 + tomcat7.x,servlet 3.1 + tomcat8.x。在servlet2.x与servlet3.x中,web.xml配置有少许的差别,主要是因为它们对“异步”操作的控制方式不同,所谓异步,就是当REST请求中消费消息时,如果此时Queue/Topic中没有消息,那么此次请求是否挂起直到有消息可供消费。

 

    Tomcat配置(Tomcat 6.x+)

 

    <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" 
               URIEncoding="utf-8" 
               useBodyEncodingForURI="false"
               maxThreads="120" maxKeepAliveRequests="60"/>
    protocol协议为“HTTP/1.1",如果你指定了"HTTP/1.0",那么可能无法良好的使用"keep-alive",需要一些额外的控制,在此就不再赘言。其中connectionTimeout可以根据实际情况调整,用来控制connector释放链接前阻塞的时间,默认情况下keepAliveTimeout和connectionTimeout值一样,用来描述链接保持活性的时间。

猜你喜欢

转载自shift-alt-ctrl.iteye.com/blog/2017728