<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Marshal&#039;s Blog &#187; jms</title>
	<atom:link href="http://marshal.easymorse.com/archives/tag/jms/feed" rel="self" type="application/rss+xml" />
	<link>http://marshal.easymorse.com</link>
	<description>It&#039;s swap of marshal&#039;s memory.</description>
	<lastBuildDate>Mon, 30 Jan 2012 07:03:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>实现groovy通过队列消息转换视频</title>
		<link>http://marshal.easymorse.com/archives/1992?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e5%25ae%259e%25e7%258e%25b0groovy%25e9%2580%259a%25e8%25bf%2587%25e9%2598%259f%25e5%2588%2597%25e6%25b6%2588%25e6%2581%25af%25e8%25bd%25ac%25e6%258d%25a2%25e8%25a7%2586%25e9%25a2%2591</link>
		<comments>http://marshal.easymorse.com/archives/1992#comments</comments>
		<pubDate>Wed, 25 Nov 2009 04:02:12 +0000</pubDate>
		<dc:creator>Marshal</dc:creator>
				<category><![CDATA[计算机技术]]></category>
		<category><![CDATA[activemq]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[jms]]></category>

		<guid isPermaLink="false">http://marshal.easymorse.com/archives/1992</guid>
		<description><![CDATA[上文实现转换视频的最简单groovy程序实现了简单的转换视频功能，只能根据参数做一次转换。需要实现的需求是，跑在后台，根据要求转换视频。 可以自己实现这样的生产者消费者模式，实现一个队列机制，然后启动线程阻塞在空队列上，有生产者放到队列里一条消息，比如转换test.mov为test.mp4，然后线程得到通知消费这个消息，并从队列中删除消息。 这个思路是好的，但是不需要自己写这些代码，可以借助第三方API，使用JMS，这里用到的是JMS的开源免费实现ActiveMQ。具体安装参见tomcat下部署activemq。 好处是省去了自己写底层代码和相关的测试维护工作。而且，activemq自带web管理界面，我们可以先实现消费者（也就是转换视频功能），而通过web管理界面手工生成消息。 生成一条消息，消息正文很简单： test.mov;test.mp4 分号隔开，前者是需要转换的视频文件路径，后者是转换的文件路径。 在activemq的web console中填写并发送这条消息。 然后，启动VideoConvertor.groovy，可以看到这样的日志： marshal@ubuntu-desktop:~/workspace/vp/vp-backend/bin$ ./VideoConvertor.groovy 09-11-25 11:37:29&#160; INFO (Convertor:?) &#8211; 启动视频转换器&#8230; 09-11-25 11:37:29&#160; INFO (Convertor:?) &#8211; 视频转换器启动完毕。 09-11-25 11:37:52 DEBUG (Convertor:?) &#8211; 收到消息，正文是：test.mov;test.mp4 09-11-25 11:38:18 DEBUG (Convertor:?) &#8211; 生成test.mp4成功，耗时25905毫秒。 09-11-25 11:38:18 DEBUG (Convertor:?) &#8211; 提交会话。 &#160; 如果再发送一条jms消息，会有类似的日志，VideoConvertor也不再是执行一次，而是一直监控jms队列，接收消息，转换视频。如果需要将VideoConvertor程序设置为后台应用，可以参照简化groovy原型的jms消费者部分中的做法。 VideoConvertor.groovy源代码： #!/usr/bin/env groovy import groovy.lang.Grab; import org.apache.log4j.* import javax.jms.* import org.apache.activemq.ActiveMQConnectionFactory [...]]]></description>
			<content:encoded><![CDATA[<p>上文<a href="http://marshal.easymorse.com/archives/1989" title="实现转换视频的最简单groovy程序">实现转换视频的最简单groovy程序</a>实现了简单的转换视频功能，只能根据参数做一次转换。需要实现的需求是，跑在后台，根据要求转换视频。</p>
<p>可以自己实现这样的生产者消费者模式，实现一个队列机制，然后启动线程阻塞在空队列上，有生产者放到队列里一条消息，比如转换test.mov为test.mp4，然后线程得到通知消费这个消息，并从队列中删除消息。</p>
<p>这个思路是好的，但是不需要自己写这些代码，可以借助第三方API，使用JMS，这里用到的是JMS的开源免费实现ActiveMQ。具体安装参见<a href="http://marshal.easymorse.com/archives/1414" title="tomcat下部署activemq">tomcat下部署activemq</a>。</p>
<p>好处是省去了自己写底层代码和相关的测试维护工作。而且，activemq自带web管理界面，我们可以先实现消费者（也就是转换视频功能），而通过web管理界面手工生成消息。</p>
<p>生成一条消息，消息正文很简单：</p>
<blockquote><p><font style="background-color: #ffffff">test.mov;test.mp4</font></p>
</blockquote>
<p>分号隔开，前者是需要转换的视频文件路径，后者是转换的文件路径。</p>
<p>在activemq的web console中填写并发送这条消息。</p>
<p><a href="http://marshal.easymorse.com/wp-content/uploads/2009/11/image73.png" rel="lightbox"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://marshal.easymorse.com/wp-content/uploads/2009/11/image_thumb70.png" width="391" height="294" /></a> </p>
<p> <span id="more-1992"></span>
<p>然后，启动VideoConvertor.groovy，可以看到这样的日志：</p>
<blockquote><p>marshal@ubuntu-desktop:~/workspace/vp/vp-backend/bin$ ./VideoConvertor.groovy      <br />09-11-25 11:37:29&#160; INFO (Convertor:?) &#8211; 启动视频转换器&#8230;       <br />09-11-25 11:37:29&#160; INFO (Convertor:?) &#8211; 视频转换器启动完毕。       <br />09-11-25 11:37:52 DEBUG (Convertor:?) &#8211; 收到消息，正文是：test.mov;test.mp4       <br />09-11-25 11:38:18 DEBUG (Convertor:?) &#8211; 生成test.mp4成功，耗时25905毫秒。       <br />09-11-25 11:38:18 DEBUG (Convertor:?) &#8211; 提交会话。</p>
<p>&#160;</p>
</blockquote>
<p>如果再发送一条jms消息，会有类似的日志，VideoConvertor也不再是执行一次，而是一直监控jms队列，接收消息，转换视频。如果需要将VideoConvertor程序设置为后台应用，可以参照<a href="http://marshal.easymorse.com/archives/1888" title="简化groovy原型的jms消费者部分">简化groovy原型的jms消费者部分</a>中的做法。</p>
<p>VideoConvertor.groovy源代码：</p>
<blockquote><p>#!/usr/bin/env groovy </p>
<p>import groovy.lang.Grab;      <br />import org.apache.log4j.*       <br />import javax.jms.*       <br />import org.apache.activemq.ActiveMQConnectionFactory </p>
<p>@Grab(group=&quot;log4j&quot;,module=&quot;log4j&quot;,version=&quot;1.2.12&quot;)      <br />@Grab(group=&quot;org.apache.activemq&quot;,module=&quot;activemq-core&quot;,version=&quot;5.3.0&quot;)       <br />class Convertor implements MessageListener{       <br />&#160;&#160;&#160; private static Logger logger=Logger.getLogger(Convertor.class)       <br />&#160;&#160;&#160; static{       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; PropertyConfigurator.configure(&quot;log4j.properties&quot;);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160; }       <br />&#160;&#160;&#160; def connection       <br />&#160;&#160;&#160; def session       <br />&#160;&#160;&#160; def start(){       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; logger.info(&quot;启动视频转换器&#8230;&quot;)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; def connectionFactory=new ActiveMQConnectionFactory(&quot;tcp://localhost:61616&quot;)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; connection=connectionFactory.createConnection()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; connection.start()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; session=connection.createSession(true,Session.AUTO_ACKNOWLEDGE)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; def destination=session.createQueue(&quot;video_convert&quot;)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; def consumer=session.createConsumer(destination)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; consumer.setMessageListener(this)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; logger.info(&quot;视频转换器启动完毕。&quot;)       <br />&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160; public void onMessage(Message message){      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; logger.debug(&quot;收到消息，正文是：${message.text}&quot;)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; def parameters=message.text.split(&quot;;&quot;)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; convert(parameters[0],parameters[1])       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.commit()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; logger.debug(&quot;提交会话。&quot;)       <br />&#160;&#160;&#160; }       <br />&#160;&#160;&#160; def convert(input,output){       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; def time=new Date().time       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; def file=new File(output)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(file.exists()){       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; file.delete()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; logger.debug(&quot;删除已经存在的输出文件 ${output}。&quot;)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; def process=&quot;ffmpeg -i ${input} ${output}&quot;.execute()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; process.waitFor()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; logger.debug(&quot;生成${output}成功，耗时${new Date().time-time}毫秒。&quot;)       <br />&#160;&#160;&#160; }       <br />} </p>
<p>new Convertor().start()</p>
<p>&#160;</p>
</blockquote>
<p>可以在这里下载源代码：</p>
<blockquote><p><a href="http://easymorse.googlecode.com/svn/tags/vp_m0_2/">http://easymorse.googlecode.com/svn/tags/vp_m0_2/</a></p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://marshal.easymorse.com/archives/1992/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>为groovy原型增加前端同步接收消息示例</title>
		<link>http://marshal.easymorse.com/archives/1974?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e4%25b8%25bagroovy%25e5%258e%259f%25e5%259e%258b%25e5%25a2%259e%25e5%258a%25a0%25e5%2589%258d%25e7%25ab%25af%25e5%2590%258c%25e6%25ad%25a5%25e6%258e%25a5%25e6%2594%25b6%25e6%25b6%2588%25e6%2581%25af%25e7%25a4%25ba%25e4%25be%258b</link>
		<comments>http://marshal.easymorse.com/archives/1974#comments</comments>
		<pubDate>Tue, 24 Nov 2009 02:02:52 +0000</pubDate>
		<dc:creator>Marshal</dc:creator>
				<category><![CDATA[计算机技术]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[jms]]></category>

		<guid isPermaLink="false">http://marshal.easymorse.com/archives/1974</guid>
		<description><![CDATA[groovy原型的前端部分，手机端会通过http定时发送请求并获取相应。从jms队列中取走一个消息。这个过程，因为是http协议，不能保持连接，因此只能同步的获取jms消息。 增加的代码见sms_send.gsp： import org.apache.log4j.Logger; def log=Logger.getLogger(this.getClass()) log.debug(&#8216;sms send &#8230;&#8217;) def message if(request.parameters.phone){ &#160;&#160;&#160; log.debug(&#34;phone number: ${request.parameters.phone}&#34;) &#160;&#160;&#160; message=receiveMessage(request.parameters.phone) &#160;&#160;&#160; if(!message){ &#160;&#160;&#160;&#160;&#160;&#160;&#160; message=&#8217;&#8211;&#8217; &#160;&#160;&#160; }else{ &#160;&#160;&#160;&#160;&#160;&#160;&#160; message=message.text &#160;&#160;&#160; } } println &#34;收到消息，内容是：${message}&#34; log.debug(&#8216;sms finished.&#8217;) def receiveMessage(phone){ &#160;&#160;&#160; def connectionFactory=new GroovyClassLoader().parseClass(new File(&#34;${application.getRealPath(”)}/WEB-INF/groovy/JMSService.groovy&#34;)).newInstance().connectionFactory &#160;&#160;&#160; def connection=connectionFactory.createConnection() &#160;&#160;&#160; connection.start() &#160;&#160;&#160; def session=connection.createSession(true,javax.jms.Session.AUTO_ACKNOWLEDGE) &#160;&#160;&#160; def destination=session.createQueue(&#34;outbound-${phone}&#34;) &#160;&#160;&#160; def consumer=session.createConsumer(destination) &#160;&#160;&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>groovy原型的前端部分，手机端会通过http定时发送请求并获取相应。从jms队列中取走一个消息。这个过程，因为是http协议，不能保持连接，因此只能同步的获取jms消息。</p>
<p>增加的代码见sms_send.gsp：</p>
<p> <span id="more-1974"></span><br />
<blockquote>
<p>import org.apache.log4j.Logger; </p>
<p>def log=Logger.getLogger(this.getClass())     <br />log.debug(&#8216;sms send &#8230;&#8217;) </p>
<p>def message </p>
<p>if(request.parameters.phone){     <br />&#160;&#160;&#160; log.debug(&quot;phone number: ${request.parameters.phone}&quot;)      <br />&#160;&#160;&#160; message=receiveMessage(request.parameters.phone)      <br />&#160;&#160;&#160; if(!message){      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; message=&#8217;&#8211;&#8217;      <br />&#160;&#160;&#160; }else{      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; message=message.text      <br />&#160;&#160;&#160; }      <br />} </p>
<p>println &quot;收到消息，内容是：${message}&quot; </p>
<p>log.debug(&#8216;sms finished.&#8217;) </p>
<p>def receiveMessage(phone){     <br />&#160;&#160;&#160; def connectionFactory=new GroovyClassLoader().parseClass(new File(&quot;${application.getRealPath(”)}/WEB-INF/groovy/JMSService.groovy&quot;)).newInstance().connectionFactory      <br />&#160;&#160;&#160; def connection=connectionFactory.createConnection()      <br />&#160;&#160;&#160; connection.start()      <br />&#160;&#160;&#160; def session=connection.createSession(true,javax.jms.Session.AUTO_ACKNOWLEDGE)      <br />&#160;&#160;&#160; def destination=session.createQueue(&quot;outbound-${phone}&quot;)      <br />&#160;&#160;&#160; def consumer=session.createConsumer(destination)      <br />&#160;&#160;&#160; def message=consumer.receiveNoWait()      <br />&#160;&#160;&#160; session.commit()      <br />&#160;&#160;&#160; connection.close()      <br />&#160;&#160;&#160; message      <br />}</p>
</blockquote>
<p>源代码见：</p>
<blockquote><p><a href="http://easymorse.googlecode.com/svn/tags/sms-service_1.2/">http://easymorse.googlecode.com/svn/tags/sms-service_1.2/</a></p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://marshal.easymorse.com/archives/1974/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>groovy原型修改了个别地方</title>
		<link>http://marshal.easymorse.com/archives/1969?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy%25e5%258e%259f%25e5%259e%258b%25e4%25bf%25ae%25e6%2594%25b9%25e4%25ba%2586%25e4%25b8%25aa%25e5%2588%25ab%25e5%259c%25b0%25e6%2596%25b9</link>
		<comments>http://marshal.easymorse.com/archives/1969#comments</comments>
		<pubDate>Mon, 23 Nov 2009 13:31:08 +0000</pubDate>
		<dc:creator>Marshal</dc:creator>
				<category><![CDATA[计算机技术]]></category>
		<category><![CDATA[activemq]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[jms]]></category>

		<guid isPermaLink="false">http://marshal.easymorse.com/archives/1969</guid>
		<description><![CDATA[groovy原型修改了个别地方，比如队列名称，原来叫myqueue，改为inbound，入站的意思，这样比较符合需求。出站队列outbound，因为是和手机号对应的，因此增加了手机号，比如13701234567的出站队列就是outbound-13701234567。 代码见： http://easymorse.googlecode.com/svn/tags/sms-service_1.1/]]></description>
			<content:encoded><![CDATA[<p>groovy原型修改了个别地方，比如队列名称，原来叫myqueue，改为inbound，入站的意思，这样比较符合需求。出站队列outbound，因为是和手机号对应的，因此增加了手机号，比如13701234567的出站队列就是outbound-13701234567。</p>
<p>代码见：</p>
<blockquote><p><a href="http://easymorse.googlecode.com/svn/tags/sms-service_1.1/">http://easymorse.googlecode.com/svn/tags/sms-service_1.1/</a></p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://marshal.easymorse.com/archives/1969/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>简化groovy原型的jms消费者部分</title>
		<link>http://marshal.easymorse.com/archives/1888?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e7%25ae%2580%25e5%258c%2596groovy%25e5%258e%259f%25e5%259e%258b%25e7%259a%2584jms%25e6%25b6%2588%25e8%25b4%25b9%25e8%2580%2585%25e9%2583%25a8%25e5%2588%2586</link>
		<comments>http://marshal.easymorse.com/archives/1888#comments</comments>
		<pubDate>Fri, 20 Nov 2009 15:27:44 +0000</pubDate>
		<dc:creator>Marshal</dc:creator>
				<category><![CDATA[计算机技术]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[jms]]></category>

		<guid isPermaLink="false">http://marshal.easymorse.com/archives/1888</guid>
		<description><![CDATA[在groovy原型监听ServletContext的属性变化中，jms消费者部分，被复杂化了。另外，groovy原型增加收到jms消息后发送确认消息的示例中的关闭消费者进程的方式也复杂了。现在做了一个改善这个的原型。 基本思路就是消费者还是单起进程处理，并且可以通过操作系统普通的方式杀掉这个进程。和web应用部分没有直接的耦合关系。 由于这两个应用程序，分别扮演着生产者和消费者的角色，即独立又有关联，比如类库依赖基本一样。因此考虑使用maven的多模块方式，即在一个maven项目中包含多个子项目，父项目包含子项目都需要的类库依赖关系和其他共享信息。 在本示例中，有一个父项目，两个子项目，分别是front-end，用于web应用，back-end，用于消费者部分。 有关多模块maven项目的创建和配置，可参见创建支持eclipse的多模块maven项目。 本文示例源代码见： http://easymorse.googlecode.com/svn/tags/sms-service_1.0/ 下载这个代码： svn co http://easymorse.googlecode.com/svn/tags/sms-service_1.0/ 然后进入项目目录： cd sms-service_1.0 生成eclipse项目： mvn eclipse:eclipse 注意，两个子项目都会级联生成eclipse项目文件。然后，可以通过eclipse的导入已存在项目的功能一次导入进来。 导入的两个项目会共享相同的类库依赖，很方便。但是，要想运行back-end中的脚本，需要在sms-service_1.0目录下执行： mvn dependency:copy-dependencies 然后，将target/dependency目录设置到groovy的类库加载配置文件中，和groovy原型增加接收消息示例中的配置类似。 执行脚本需要进入back-end/bin目录下再执行，因为脚本中使用了相对路径。执行前需要给脚本文件增加可执行权限： chmod +x ./ConsumerService.groovy 然后，可以直接Ctrl+c关闭该脚本。可以看到会执行释放资源的代码并有日志提示。 marshal@ubuntu-desktop:~/workspace/sms-service/back-end/bin$ ./ConsumerService.groovy 09-11-20 23:20:22 DEBUG (JMSConsumer:?) &#8211; start consumer&#8230; 09-11-20 23:20:23 DEBUG (JMSConsumer:?) &#8211; start ok. ^C09-11-20 23:21:29 DEBUG (ShutdownThread:?) &#8211; shutdown consumer&#8230; 09-11-20 23:21:29 DEBUG (ShutdownThread:?) &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>在<a href="http://marshal.easymorse.com/archives/1887" title="groovy原型监听ServletContext的属性变化">groovy原型监听ServletContext的属性变化</a>中，jms消费者部分，被复杂化了。另外，<a href="http://marshal.easymorse.com/archives/1880" title="groovy原型增加收到jms消息后发送确认消息的示例">groovy原型增加收到jms消息后发送确认消息的示例</a>中的关闭消费者进程的方式也复杂了。现在做了一个改善这个的原型。</p>
<p>基本思路就是消费者还是单起进程处理，并且可以通过操作系统普通的方式杀掉这个进程。和web应用部分没有直接的耦合关系。</p>
<p>由于这两个应用程序，分别扮演着生产者和消费者的角色，即独立又有关联，比如类库依赖基本一样。因此考虑使用maven的多模块方式，即在一个maven项目中包含多个子项目，父项目包含子项目都需要的类库依赖关系和其他共享信息。</p>
<p>在本示例中，有一个父项目，两个子项目，分别是front-end，用于web应用，back-end，用于消费者部分。</p>
<p> <span id="more-1888"></span>
<p>有关多模块maven项目的创建和配置，可参见<a href="http://marshal.easymorse.com/archives/873" title="创建支持eclipse的多模块maven项目">创建支持eclipse的多模块maven项目</a>。</p>
<p>本文示例源代码见：</p>
<blockquote><p><a href="http://easymorse.googlecode.com/svn/tags/sms-service_1.0/">http://easymorse.googlecode.com/svn/tags/sms-service_1.0/</a></p>
</blockquote>
<p>下载这个代码：</p>
<blockquote><p><font style="background-color: #ffffff">svn co <a href="http://easymorse.googlecode.com/svn/tags/sms-service_1.0/">http://easymorse.googlecode.com/svn/tags/sms-service_1.0/</a></font></p>
</blockquote>
<p>然后进入项目目录：</p>
<blockquote><p><font style="background-color: #ffffff">cd sms-service_1.0</font></p>
</blockquote>
<p>生成eclipse项目：</p>
<blockquote><p><font style="background-color: #ffffff">mvn eclipse:eclipse</font></p>
</blockquote>
<p>注意，两个子项目都会级联生成eclipse项目文件。然后，可以通过eclipse的导入已存在项目的功能一次导入进来。</p>
<p>导入的两个项目会共享相同的类库依赖，很方便。但是，要想运行back-end中的脚本，需要在sms-service_1.0目录下执行：</p>
<blockquote><p>mvn dependency:copy-dependencies</p>
</blockquote>
<p>然后，将target/dependency目录设置到groovy的类库加载配置文件中，和<a href="http://marshal.easymorse.com/archives/1813" title="groovy原型增加接收消息示例">groovy原型增加接收消息示例</a>中的配置类似。</p>
<p>执行脚本需要进入back-end/bin目录下再执行，因为脚本中使用了相对路径。执行前需要给脚本文件增加可执行权限：</p>
<blockquote><p><font style="background-color: #ffffff">chmod +x ./ConsumerService.groovy</font></p>
</blockquote>
<p>然后，可以直接Ctrl+c关闭该脚本。可以看到会执行释放资源的代码并有日志提示。</p>
<blockquote><p>marshal@ubuntu-desktop:~/workspace/sms-service/back-end/bin$ ./ConsumerService.groovy      <br />09-11-20 23:20:22 DEBUG (JMSConsumer:?) &#8211; start consumer&#8230;      <br />09-11-20 23:20:23 DEBUG (JMSConsumer:?) &#8211; start ok.      <br />^C09-11-20 23:21:29 DEBUG (ShutdownThread:?) &#8211; shutdown consumer&#8230;      <br />09-11-20 23:21:29 DEBUG (ShutdownThread:?) &#8211; shutdown succesful.</p>
<p>&#160;</p>
</blockquote>
<p>这是因为脚本中使用了钩子线程，当进程关闭的时候会被执行。</p>
<blockquote><p>Runtime.runtime.addShutdownHook(new ShutdownThread(consumer)) </p>
<p>class ShutdownThread extends Thread{     <br />&#160;&#160;&#160; private static final Logger logger=Logger.getLogger(ShutdownThread.class)      <br />&#160;&#160;&#160; def consumer      <br />&#160;&#160;&#160; ShutdownThread(consumer){      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.consumer=consumer      <br />&#160;&#160;&#160; }      <br />&#160;&#160;&#160; public void run(){      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; logger.debug(&quot;shutdown consumer&#8230;&quot;)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.consumer.connection.close()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; logger.debug(&quot;shutdown succesful.&quot;)      <br />&#160;&#160;&#160; }      <br />}</p>
<p>&#160;</p>
</blockquote>
<p>如果想后台执行代码，可以这样：</p>
<blockquote><p><font style="background-color: #ffffff">nohup ./ConsumerService.groovy &amp;</font></p>
</blockquote>
<p>关闭这个脚本进程，需要先找到进程号：</p>
<blockquote><p>ps -ef|grep groovy</p>
</blockquote>
<p>然后，这样杀掉进程：</p>
<blockquote><p>kill -15 your_pid</p>
</blockquote>
<p>这样，进程会调用shutdown线程正常释放和关闭进程。这里不能使用-9参数杀进程，这会立即杀掉进程，不能执行shutdown线程释放资源。</p>
]]></content:encoded>
			<wfw:commentRss>http://marshal.easymorse.com/archives/1888/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>groovy原型增加收到jms消息后发送确认消息的示例</title>
		<link>http://marshal.easymorse.com/archives/1880?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy%25e5%258e%259f%25e5%259e%258b%25e5%25a2%259e%25e5%258a%25a0%25e6%2594%25b6%25e5%2588%25b0jms%25e6%25b6%2588%25e6%2581%25af%25e5%2590%258e%25e5%258f%2591%25e9%2580%2581%25e7%25a1%25ae%25e8%25ae%25a4%25e6%25b6%2588%25e6%2581%25af%25e7%259a%2584%25e7%25a4%25ba%25e4%25be%258b</link>
		<comments>http://marshal.easymorse.com/archives/1880#comments</comments>
		<pubDate>Thu, 19 Nov 2009 04:37:41 +0000</pubDate>
		<dc:creator>Marshal</dc:creator>
				<category><![CDATA[计算机技术]]></category>
		<category><![CDATA[activemq]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[jms]]></category>

		<guid isPermaLink="false">http://marshal.easymorse.com/archives/1880</guid>
		<description><![CDATA[源代码见： http://easymorse.googlecode.com/svn/tags/groovy.proto.1.4/ 主要修改的是两部分代码： 通过hello.gsp增加发送xml文本消息的代码，具体写法可参见groovy生成xml； 主要部分，修改TestScript.groovy文件。 TestScript代码主要修改的代码片段： &#160;&#160;&#160;&#160; public void onMessage(Message message) { &#160;&#160;&#160;&#160;&#160;&#160;&#160; if(message.destination.equals(destination)){ &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; println &#34;&#34;&#34; 收到消息：${message.text} &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#34;&#34;&#34; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sendMessageToQueue(&#8216;receive.confirm&#8217;,'&#8211;&#8217;,'ok.&#8217;) &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.commit() &#160;&#160;&#160;&#160;&#160;&#160;&#160; }else if (message.destination.equals(shutdownDestination)){ &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; print (&#8216;shutdown &#8230;&#8217;) &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.commit() &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; connection.close() &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; println (&#8216;ok.&#8217;) &#160;&#160;&#160;&#160;&#160;&#160;&#160; } &#160;&#160;&#160;&#160; } &#160;&#160;&#160;&#160; def sendMessageToQueue(queueName,tag,text){ &#160;&#160;&#160;&#160;&#160;&#160;&#160; def destination=session.createQueue(queueName) &#160;&#160;&#160;&#160;&#160;&#160;&#160; def producer=session.createProducer(destination) &#160;&#160;&#160;&#160;&#160;&#160;&#160; producer.setDeliveryMode(javax.jms.DeliveryMode.PERSISTENT) &#160;&#160;&#160;&#160;&#160;&#160;&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>源代码见：</p>
<blockquote><p><a href="http://easymorse.googlecode.com/svn/tags/groovy.proto.1.4/">http://easymorse.googlecode.com/svn/tags/groovy.proto.1.4/</a></p>
</blockquote>
<p>主要修改的是两部分代码：</p>
<ul>
<li>通过hello.gsp增加发送xml文本消息的代码，具体写法可参见<a href="http://marshal.easymorse.com/archives/1377" title="groovy生成xml">groovy生成xml</a>；</li>
<li>主要部分，修改TestScript.groovy文件。</li>
</ul>
<p> <span id="more-1880"></span>
<p>TestScript代码主要修改的代码片段：</p>
<blockquote><p>&#160;&#160;&#160;&#160; public void onMessage(Message message) {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(message.destination.equals(destination)){      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; println &quot;&quot;&quot;      <br />收到消息：${message.text}      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;&quot;&quot;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sendMessageToQueue(&#8216;receive.confirm&#8217;,'&#8211;&#8217;,'ok.&#8217;)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.commit()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }else if (message.destination.equals(shutdownDestination)){      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; print (&#8216;shutdown &#8230;&#8217;)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.commit()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; connection.close()      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; println (&#8216;ok.&#8217;)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; def sendMessageToQueue(queueName,tag,text){     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; def destination=session.createQueue(queueName)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; def producer=session.createProducer(destination)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; producer.setDeliveryMode(javax.jms.DeliveryMode.PERSISTENT) </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; def out=new StringWriter()     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; def xmlResults=new MarkupBuilder(out)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; xmlResults.messages{      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; message text      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; def message=session.createTextMessage(out.toString())      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; message.setStringProperty(&#8216;tag&#8217;,tag)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; producer.send(message)      <br />&#160;&#160;&#160; }</p>
</blockquote>
<p>这里收到消息和发送确认消息是在一个事务当中。</p>
]]></content:encoded>
			<wfw:commentRss>http://marshal.easymorse.com/archives/1880/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>groovy原型增加接收消息示例</title>
		<link>http://marshal.easymorse.com/archives/1813?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy%25e5%258e%259f%25e5%259e%258b%25e5%25a2%259e%25e5%258a%25a0%25e6%258e%25a5%25e6%2594%25b6%25e6%25b6%2588%25e6%2581%25af%25e7%25a4%25ba%25e4%25be%258b</link>
		<comments>http://marshal.easymorse.com/archives/1813#comments</comments>
		<pubDate>Mon, 16 Nov 2009 05:37:33 +0000</pubDate>
		<dc:creator>Marshal</dc:creator>
				<category><![CDATA[计算机技术]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[jms]]></category>

		<guid isPermaLink="false">http://marshal.easymorse.com/archives/1813</guid>
		<description><![CDATA[前文groovy开发原型增加jms发送消息示例已经增加了发送消息的示例。一般jms应用，采取的是同步的发送，异步的接收。这里考虑通过单独的进程实现异步接收jms消息功能。 使用groovy脚本，类似sh脚本，在操作系统下可直接启动运行，实现这些，需要： 在操作系统中安装groovy，比如在ubuntu下手工安装groovy 编写脚本文件，参考ubuntu建立简单的groovy环境的编写groovy脚本部分 异步接收进程会在后台启动，一直监听队列的消息，收到消息后做后续处理。那么如何关闭该进程呢？这里采用一个简单的办法，创建一个shutdown主题（topic），该进程订阅这个主题，如果从主题收到消息，就立即关闭进程。 主要源代码见：TestScript.groovy #!/usr/bin/env groovy import groovy.sql.Sql; import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; class MyBiz implements MessageListener{ &#160;&#160;&#160; def classloader=new GroovyClassLoader() &#160;&#160;&#160; def connectionFactory=classloader.parseClass(new File(&#34;JMSService.groovy&#34;)).newInstance().connectionFactory &#160;&#160;&#160; def sql=classloader.parseClass(new File(&#34;DBService.groovy&#34;)).newInstance().sql &#160;&#160;&#160; def connection &#160;&#160;&#160; def session &#160;&#160;&#160; def consumer &#160;&#160;&#160; def destination &#160;&#160;&#160; def shutdownDestination &#160;&#160;&#160; def shutdownConsumer &#160;&#160;&#160; def runConsume(){ &#160;&#160;&#160;&#160;&#160;&#160;&#160; println &#34;启动监听器&#34; &#160;&#160;&#160;&#160;&#160;&#160;&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>前文<a href="http://marshal.easymorse.com/archives/1802" title="groovy开发原型增加jms发送消息示例">groovy开发原型增加jms发送消息示例</a>已经增加了发送消息的示例。一般jms应用，采取的是同步的发送，异步的接收。这里考虑通过单独的进程实现异步接收jms消息功能。</p>
<p>使用groovy脚本，类似sh脚本，在操作系统下可直接启动运行，实现这些，需要：</p>
<ul>
<li>在操作系统中安装groovy，比如<a href="http://marshal.easymorse.com/archives/1355" title="在ubuntu下手工安装groovy">在ubuntu下手工安装groovy</a> </li>
<li>编写脚本文件，参考<a href="http://marshal.easymorse.com/archives/1352" title="ubuntu建立简单的groovy环境">ubuntu建立简单的groovy环境</a>的编写groovy脚本部分 </li>
</ul>
<p>异步接收进程会在后台启动，一直监听队列的消息，收到消息后做后续处理。那么如何关闭该进程呢？这里采用一个简单的办法，创建一个shutdown主题（topic），该进程订阅这个主题，如果从主题收到消息，就立即关闭进程。</p>
<p> <span id="more-1813"></span>
<p>主要源代码见：TestScript.groovy</p>
<blockquote><p>#!/usr/bin/env groovy </p>
<p>import groovy.sql.Sql;      <br />import org.apache.activemq.ActiveMQConnectionFactory;       <br />import javax.jms.*; </p>
<p>class MyBiz implements MessageListener{      <br />&#160;&#160;&#160; def classloader=new GroovyClassLoader()       <br />&#160;&#160;&#160; def connectionFactory=classloader.parseClass(new File(&quot;JMSService.groovy&quot;)).newInstance().connectionFactory       <br />&#160;&#160;&#160; def sql=classloader.parseClass(new File(&quot;DBService.groovy&quot;)).newInstance().sql       <br />&#160;&#160;&#160; def connection       <br />&#160;&#160;&#160; def session       <br />&#160;&#160;&#160; def consumer       <br />&#160;&#160;&#160; def destination       <br />&#160;&#160;&#160; def shutdownDestination       <br />&#160;&#160;&#160; def shutdownConsumer       <br />&#160;&#160;&#160; def runConsume(){       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; println &quot;启动监听器&quot;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; connection=connectionFactory.createConnection()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; connection.start()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; session=connection.createSession(true,javax.jms.Session.AUTO_ACKNOWLEDGE) </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; destination=session.createQueue(&quot;myqueue&quot;)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; consumer=session.createConsumer(destination)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; consumer.setMessageListener(this) </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; shutdownDestination=session.createTopic(&quot;shutdownTopic&quot;)      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; shutdownConsumer=session.createConsumer(shutdownDestination)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; shutdownConsumer.setMessageListener(this)       <br />&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160; public void onMessage(Message message) {      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(message.destination.equals(destination)){       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; println &quot;&quot;&quot;       <br />收到消息：${message.text}       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;&quot;&quot;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.commit()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }else if (message.destination.equals(shutdownDestination)){       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; print (&#8216;shutdown &#8230;&#8217;)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; session.commit()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; connection.close()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; println (&#8216;ok.&#8217;)       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160; }       <br />} </p>
<p>def biz=new MyBiz()      <br />def time=new Date().time </p>
<p>println &quot;&quot;&quot;      <br />获取到sql连接对象：${biz.sql}，数据库正常。       <br />获取到消息服务器工厂对象：${biz.connectionFactory}，消息服务器正常。       <br />&quot;&quot;&quot; </p>
<p>biz.runConsume() </p>
<p>println &quot;&quot;&quot;      <br />耗时：${new Date().time-time}&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&quot;&quot;&quot; </p>
<p>&#160;</p>
</blockquote>
<p>使用这个代码，需要先设置为可执行权限：</p>
<blockquote><p><font style="background-color: #ffffff">chmod +x ./TestScript.groovy</font></p>
</blockquote>
<p>然后，需要在该目录下执行，因为代码内部使用的是相对路径：</p>
<blockquote><p><font style="background-color: #ffffff">./TestScript.groovy</font></p>
</blockquote>
<p>执行效果类似这样：</p>
<p><a href="http://marshal.easymorse.com/wp-content/uploads/2009/11/image22.png" rel="lightbox"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://marshal.easymorse.com/wp-content/uploads/2009/11/image_thumb22.png" width="459" height="131" /></a> </p>
<p>当向shutdown topic发送任意消息，该进程关闭。</p>
<p><a href="http://marshal.easymorse.com/wp-content/uploads/2009/11/image23.png" rel="lightbox"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://marshal.easymorse.com/wp-content/uploads/2009/11/image_thumb23.png" width="456" height="85" /></a> </p>
<p>这里还碰到一个问题，就是类加载问题。独立的进程，无法享受到Servlet容器提供的类加载支持。需要自行解决。groovy在这方面有一些方法，但都不是很方便。比如有自动加载的脚本，见<a href="http://groovy.codehaus.org/Auto+setup+and+download+dependencies+jars">:</a></p>
<blockquote><p><a href="http://groovy.codehaus.org/Auto+setup+and+download+dependencies+jars">http://groovy.codehaus.org/Auto+setup+and+download+dependencies+jars</a></p>
</blockquote>
<p>在这个原型中，本身已经使用了maven，所以打算直接利用maven的自动类库依赖加载机制，执行命令：</p>
<blockquote><p>mvn dependency:copy-dependencies</p>
</blockquote>
<p>在项目的target/dependency目录下，将生成所有依赖类库的拷贝。然后，根据<a href="http://marshal.easymorse.com/archives/1366" title="groovy脚本的类加载">groovy脚本的类加载</a>，将该目录设置到groovy类加载配置文件中即可。</p>
<p>源代码见：</p>
<blockquote><p><a href="http://easymorse.googlecode.com/svn/tags/groovy.proto.1.3/">http://easymorse.googlecode.com/svn/tags/groovy.proto.1.3/</a></p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://marshal.easymorse.com/archives/1813/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>groovy开发原型增加jms发送消息示例</title>
		<link>http://marshal.easymorse.com/archives/1802?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy%25e5%25bc%2580%25e5%258f%2591%25e5%258e%259f%25e5%259e%258b%25e5%25a2%259e%25e5%258a%25a0jms%25e5%258f%2591%25e9%2580%2581%25e6%25b6%2588%25e6%2581%25af%25e7%25a4%25ba%25e4%25be%258b</link>
		<comments>http://marshal.easymorse.com/archives/1802#comments</comments>
		<pubDate>Thu, 12 Nov 2009 12:15:35 +0000</pubDate>
		<dc:creator>Marshal</dc:creator>
				<category><![CDATA[计算机技术]]></category>
		<category><![CDATA[activemq]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[jms]]></category>

		<guid isPermaLink="false">http://marshal.easymorse.com/archives/1802</guid>
		<description><![CDATA[通过jms消息队列，可以可靠传输消息，另外，可以异步传输，简化编程模型。在为groovy原型增加sql示例原型基础上，增加了对jms的支持，并且写了个发送的简单示例。 示例运行效果： 消息服务器使用了activemq，需要提前部署一个activemq-web-console的war文件到tomcat中，这样不但可以提供activemq消息服务器，还带一个web界面的监控应用。类似这样： 消息正文如果是中文，会是问号，实际上没有问题，是该web应用显示的编码问题。 activemq-web-console的安装过程见tomcat下部署activemq。 涉及groovy发送消息的文件有两个。第一个，配置activemq信息和获取ConnectionFactory方法，实现类似sql部分。见JMSService.groovy： import org.apache.activemq.ActiveMQConnectionFactory; class JMSService{ &#160;&#160;&#160; private static connectionFactory &#160;&#160;&#160; def url=&#34;tcp://localhost:61616&#34; &#160;&#160;&#160; def username=&#34;&#34; &#160;&#160;&#160; def password=&#34;&#34; &#160;&#160;&#160; def initConnectionFactory(){ &#160;&#160;&#160;&#160;&#160;&#160;&#160; connectionFactory=new ActiveMQConnectionFactory(url) &#160;&#160;&#160; } &#160;&#160;&#160; def getConnectionFactory(){ &#160;&#160;&#160;&#160;&#160;&#160;&#160; if(!connectionFactory){ &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; initConnectionFactory() &#160;&#160;&#160;&#160;&#160;&#160;&#160; } &#160;&#160;&#160;&#160;&#160;&#160;&#160; connectionFactory &#160;&#160;&#160; } } &#160; 另外一个，就是hello.gsp中的调用： def connectionFactory=classloader.parseClass(new File(&#34;${realpath}/WEB-INF/groovy/JMSService.groovy&#34;)).newInstance().connectionFactory … def sendMessageToQueue(connectionFactory,queueName,tag,text){ &#160;&#160;&#160; def [...]]]></description>
			<content:encoded><![CDATA[<p>通过jms消息队列，可以可靠传输消息，另外，可以异步传输，简化编程模型。在<a href="http://marshal.easymorse.com/archives/1791" title="为groovy原型增加sql示例">为groovy原型增加sql示例</a>原型基础上，增加了对jms的支持，并且写了个发送的简单示例。</p>
<p>示例运行效果：</p>
<p><a href="http://marshal.easymorse.com/wp-content/uploads/2009/11/image19.png" rel="lightbox"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://marshal.easymorse.com/wp-content/uploads/2009/11/image_thumb19.png" width="262" height="254" /></a> </p>
<p>消息服务器使用了activemq，需要提前部署一个activemq-web-console的war文件到tomcat中，这样不但可以提供activemq消息服务器，还带一个web界面的监控应用。类似这样：</p>
<p><a href="http://marshal.easymorse.com/wp-content/uploads/2009/11/image20.png" rel="lightbox"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://marshal.easymorse.com/wp-content/uploads/2009/11/image_thumb20.png" width="331" height="208" /></a> </p>
<p> <span id="more-1802"></span>
</p>
<p>消息正文如果是中文，会是问号，实际上没有问题，是该web应用显示的编码问题。</p>
<p>activemq-web-console的安装过程见<a href="http://marshal.easymorse.com/archives/1414" title="tomcat下部署activemq">tomcat下部署activemq</a>。</p>
<p>涉及groovy发送消息的文件有两个。第一个，配置activemq信息和获取ConnectionFactory方法，实现类似sql部分。见JMSService.groovy：</p>
<blockquote><p>import org.apache.activemq.ActiveMQConnectionFactory; </p>
<p>class JMSService{      <br />&#160;&#160;&#160; private static connectionFactory       <br />&#160;&#160;&#160; def url=&quot;tcp://localhost:61616&quot;       <br />&#160;&#160;&#160; def username=&quot;&quot;       <br />&#160;&#160;&#160; def password=&quot;&quot;       <br />&#160;&#160;&#160; def initConnectionFactory(){       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; connectionFactory=new ActiveMQConnectionFactory(url)       <br />&#160;&#160;&#160; }       <br />&#160;&#160;&#160; def getConnectionFactory(){       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if(!connectionFactory){       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; initConnectionFactory()       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; connectionFactory       <br />&#160;&#160;&#160; }       <br />}</p>
<p>&#160;</p>
</blockquote>
<p>另外一个，就是hello.gsp中的调用：</p>
<blockquote><p>def connectionFactory=classloader.parseClass(new File(&quot;${realpath}/WEB-INF/groovy/JMSService.groovy&quot;)).newInstance().connectionFactory</p>
<p>…</p>
<p>def sendMessageToQueue(connectionFactory,queueName,tag,text){      <br />&#160;&#160;&#160; def connection=connectionFactory.createConnection()       <br />&#160;&#160;&#160; connection.start()       <br />&#160;&#160;&#160; def session=connection.createSession(true,javax.jms.Session.AUTO_ACKNOWLEDGE)       <br />&#160;&#160;&#160; def destination=session.createQueue(queueName)       <br />&#160;&#160;&#160; def producer=session.createProducer(destination)       <br />&#160;&#160;&#160; producer.setDeliveryMode(javax.jms.DeliveryMode.PERSISTENT)       <br />&#160;&#160;&#160; def message=session.createTextMessage(text)       <br />&#160;&#160;&#160; message.setStringProperty(&#8216;tag&#8217;,tag)       <br />&#160;&#160;&#160; producer.send(message)       <br />&#160;&#160;&#160; session.commit()       <br />&#160;&#160;&#160; connection.close()       <br />&#160;&#160;&#160; &#8216;sucess.&#8217;       <br />}</p>
<p>&#160;</p>
<p>…</p>
<p>println &quot;&quot;&quot;      <br />&lt;div&gt;       <br />发送消息到队列&#160; &#8230; ${sendMessageToQueue(connectionFactory,&#8217;myqueue&#8217;,&#8217;15201234567&#8242;,&#8217;你好&#8217;)}       <br />&lt;/div&gt;       <br />&quot;&quot;&quot;</p>
<p>&#160;</p>
</blockquote>
<p>源代码见：</p>
<blockquote><p><a href="http://easymorse.googlecode.com/svn/tags/groovy.proto.1.2/">http://easymorse.googlecode.com/svn/tags/groovy.proto.1.2/</a></p>
</blockquote>
<blockquote><p><font style="background-color: #ffffff"></font></p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://marshal.easymorse.com/archives/1802/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>tomcat下部署activemq</title>
		<link>http://marshal.easymorse.com/archives/1414?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tomcat%25e4%25b8%258b%25e9%2583%25a8%25e7%25bd%25b2activemq</link>
		<comments>http://marshal.easymorse.com/archives/1414#comments</comments>
		<pubDate>Mon, 13 Jul 2009 16:41:57 +0000</pubDate>
		<dc:creator>Marshal</dc:creator>
				<category><![CDATA[计算机技术]]></category>
		<category><![CDATA[activemq]]></category>
		<category><![CDATA[jms]]></category>

		<guid isPermaLink="false">http://marshal.easymorse.com/archives/1414</guid>
		<description><![CDATA[activemq可以单独部署和执行，比如类似ActiveMQ的最简单应用中提到的安装和执行方式。但是有时候需要作为一个web应用部署在servlet容器中，这样利于和其他web应用的配合。 官方文档上有一个针对这种需求的文档： http://activemq.apache.org/web-console.html 根据文档，使用tomcat 6.0.20，activemq 5.2.0。实现了上述需求。首先需要下载： activemq-web-console activemq-all 前者直接复制到tomcat的webapps目录下即可。后者复制到tomcat/lib目录下。 文档中没有提到的但是tomcat6.0.20中需要增加的类库是有关jstl支持的： jstl-1.1.0.jar standard-1.1.0.jar 然后启动tomcat，就可以通过如下链接访问： http://localhost:8080/activemq-web-console-5.2.0 和上述官方文档不同的是，不需要设置这个内容： set JAVA_OPTS=”-Dwebconsole.type=properties -Dwebconsole.jms.url=tcp://localhost:61616 -Dwebconsole.jmx.url=service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi -Dwebconsole.jmx.role= -Dwebconsole.jmx.password=” 设置了反而报错。如果不设置的话，activemq默认启动61616端口。并且能顺利执行。]]></description>
			<content:encoded><![CDATA[<p>activemq可以单独部署和执行，比如类似<a href="http://marshal.easymorse.com/archives/1399" title="ActiveMQ的最简单应用">ActiveMQ的最简单应用</a>中提到的安装和执行方式。但是有时候需要作为一个web应用部署在servlet容器中，这样利于和其他web应用的配合。</p>
<p>官方文档上有一个针对这种需求的文档：</p>
<blockquote><p><a href="http://activemq.apache.org/web-console.html">http://activemq.apache.org/web-console.html</a></p>
</blockquote>
<p><span id="more-1414"></span>
<p>根据文档，使用tomcat 6.0.20，activemq 5.2.0。实现了上述需求。首先需要下载：</p>
<ul>
<li><a href="http://repo1.maven.org/maven2/org/apache/activemq/activemq-web-console/">activemq-web-console</a></li>
<li><a href="http://repo1.maven.org/maven2/org/apache/activemq/activemq-all/">activemq-all</a></li>
</ul>
<p>前者直接复制到tomcat的webapps目录下即可。后者复制到tomcat/lib目录下。</p>
<p>文档中没有提到的但是tomcat6.0.20中需要增加的类库是有关jstl支持的：</p>
<ul>
<li>jstl-1.1.0.jar</li>
<li>standard-1.1.0.jar</li>
</ul>
<p>然后启动tomcat，就可以通过如下链接访问：</p>
<blockquote><p><a title="http://localhost:8080/activemq-web-console-5.2.0" href="http://localhost:8080/activemq-web-console-5.2.0">http://localhost:8080/activemq-web-console-5.2.0</a></p>
</blockquote>
<p>和上述官方文档不同的是，不需要设置这个内容：</p>
<blockquote><p>set JAVA_OPTS=”-Dwebconsole.type=properties -Dwebconsole.jms.url=tcp://localhost:61616 -Dwebconsole.jmx.url=service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi -Dwebconsole.jmx.role= -Dwebconsole.jmx.password=”</p>
</blockquote>
<p>设置了反而报错。如果不设置的话，activemq默认启动61616端口。并且能顺利执行。</p>
]]></content:encoded>
			<wfw:commentRss>http://marshal.easymorse.com/archives/1414/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>通过spring开发ActiveMQ简单应用</title>
		<link>http://marshal.easymorse.com/archives/1400?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e9%2580%259a%25e8%25bf%2587spring%25e5%25bc%2580%25e5%258f%2591activemq%25e7%25ae%2580%25e5%258d%2595%25e5%25ba%2594%25e7%2594%25a8</link>
		<comments>http://marshal.easymorse.com/archives/1400#comments</comments>
		<pubDate>Mon, 06 Jul 2009 04:41:18 +0000</pubDate>
		<dc:creator>Marshal</dc:creator>
				<category><![CDATA[计算机技术]]></category>
		<category><![CDATA[activemq]]></category>
		<category><![CDATA[jms]]></category>

		<guid isPermaLink="false">http://marshal.easymorse.com/archives/1400</guid>
		<description><![CDATA[使用spring的支持类开发JMS程序可以简化代码，确保开发质量。以下是使用ActiveMQ作为JMS实现的示例。 首先需要确保如下类库，这里使用maven的pom： &#60;dependency&#62; &#60;groupId&#62;org.springframework&#60;/groupId&#62; &#60;artifactId&#62;spring-jms&#60;/artifactId&#62; &#60;version&#62;2.5.6&#60;/version&#62; &#60;/dependency&#62; &#60;dependency&#62; &#60;groupId&#62;org.apache.xbean&#60;/groupId&#62; &#60;artifactId&#62;xbean-spring&#60;/artifactId&#62; &#60;version&#62;3.5&#60;/version&#62; &#60;/dependency&#62; &#60;dependency&#62; &#60;groupId&#62;org.apache.activemq&#60;/groupId&#62; &#60;artifactId&#62;activemq-core&#60;/artifactId&#62; &#60;version&#62;5.2.0&#60;/version&#62; &#60;/dependency&#62; 编写消息生产者的代码： @Component public class MyMessageProducer { @Resource(name = &#34;Queue&#34;) private Destination destination; @Autowired private JmsTemplate jmsTemplate; public void sendMessage(final String message) { this.jmsTemplate.send(this.destination, new MessageCreator() { @Override public Message createMessage(Session session) throws JMSException { TextMessage textMessage = session.createTextMessage(); [...]]]></description>
			<content:encoded><![CDATA[<p>使用spring的支持类开发JMS程序可以简化代码，确保开发质量。以下是使用ActiveMQ作为JMS实现的示例。</p>
<p>首先需要确保如下类库，这里使用maven的pom：</p>
<p>
<div class="wlWriterSmartContent" id="scid:F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:747a552c-afb7-4d74-97f5-2d3ba9031477" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre  style="width:100%;;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">&lt;</span><span style="color: #000000;">dependency</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">groupId</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">org.springframework</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">groupId</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">artifactId</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">spring</span><span style="color: #000000;">-</span><span style="color: #000000;">jms</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">artifactId</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">version</span><span style="color: #000000;">&gt;</span><span style="color: #800080;">2.5</span><span style="color: #000000;">.</span><span style="color: #800080;">6</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">version</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">dependency</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">dependency</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">groupId</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">org.apache.xbean</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">groupId</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">artifactId</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">xbean</span><span style="color: #000000;">-</span><span style="color: #000000;">spring</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">artifactId</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">version</span><span style="color: #000000;">&gt;</span><span style="color: #800080;">3.5</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">version</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">dependency</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">dependency</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">groupId</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">org.apache.activemq</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">groupId</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">artifactId</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">activemq</span><span style="color: #000000;">-</span><span style="color: #000000;">core</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">artifactId</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #000000;">&lt;</span><span style="color: #000000;">version</span><span style="color: #000000;">&gt;</span><span style="color: #800080;">5.2</span><span style="color: #000000;">.</span><span style="color: #800080;">0</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">version</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">dependency</span><span style="color: #000000;">&gt;</span></div>
</pre>
</div>
<p><span id="more-1400"></span></p>
<p>编写消息生产者的代码：</p>
<p><div class="wlWriterSmartContent" id="scid:F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:3159bbe9-51c5-447e-9c20-1ff393421a1d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre  style="width:100%;;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">@Component
</span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">class</span><span style="color: #000000;"> MyMessageProducer {
    @Resource(name </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #000000;">&quot;</span><span style="color: #000000;">Queue</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">)
    </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> Destination destination;

    @Autowired
    </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> JmsTemplate jmsTemplate;

    </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> sendMessage(</span><span style="color: #0000FF;">final</span><span style="color: #000000;"> String message) {
        </span><span style="color: #0000FF;">this</span><span style="color: #000000;">.jmsTemplate.send(</span><span style="color: #0000FF;">this</span><span style="color: #000000;">.destination, </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> MessageCreator() {
            @Override
            </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> Message createMessage(Session session) </span><span style="color: #0000FF;">throws</span><span style="color: #000000;"> JMSException {
                TextMessage textMessage </span><span style="color: #000000;">=</span><span style="color: #000000;"> session.createTextMessage();
                textMessage.setText(message);
                </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> textMessage;
            }
        });
    }
}</span></div>
</pre>
</div>
<p>有关生产者部分spring的配置文件内容：</p>
<p><div class="wlWriterSmartContent" id="scid:F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:229ef70b-4785-4673-a9f5-fd5fac93be4e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre  style="width:100%;;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #0000FF;">&lt;?</span><span style="color: #FF00FF;">xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;</span><span style="color: #0000FF;">?&gt;</span><span style="color: #000000;">

</span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">beans </span><span style="color: #FF0000;">xmlns</span><span style="color: #0000FF;">=&quot;http://www.springframework.org/schema/beans&quot;</span><span style="color: #FF0000;">
    xmlns:amq</span><span style="color: #0000FF;">=&quot;http://activemq.apache.org/schema/core&quot;</span><span style="color: #FF0000;"> xmlns:lang</span><span style="color: #0000FF;">=&quot;http://www.springframework.org/schema/lang&quot;</span><span style="color: #FF0000;">
    xmlns:context</span><span style="color: #0000FF;">=&quot;http://www.springframework.org/schema/context&quot;</span><span style="color: #FF0000;">
    xmlns:xsi</span><span style="color: #0000FF;">=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span><span style="color: #FF0000;"> xmlns:aop</span><span style="color: #0000FF;">=&quot;http://www.springframework.org/schema/aop&quot;</span><span style="color: #FF0000;">
    xmlns:tx</span><span style="color: #0000FF;">=&quot;http://www.springframework.org/schema/tx&quot;</span><span style="color: #FF0000;"> xmlns:util</span><span style="color: #0000FF;">=&quot;http://www.springframework.org/schema/util&quot;</span><span style="color: #FF0000;">
    xsi:schemaLocation</span><span style="color: #0000FF;">=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
     http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
     http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd&quot;</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">

    </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">context:annotation-config </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;">
    </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">context:component-scan </span><span style="color: #FF0000;">base-package</span><span style="color: #0000FF;">=&quot;activemq.demo.spring&quot;</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;">

    </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">bean </span><span style="color: #FF0000;">id</span><span style="color: #0000FF;">=&quot;jmsFactory&quot;</span><span style="color: #FF0000;"> class</span><span style="color: #0000FF;">=&quot;org.apache.activemq.ActiveMQConnectionFactory&quot;</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">property </span><span style="color: #FF0000;">name</span><span style="color: #0000FF;">=&quot;brokerURL&quot;</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">
            </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">value</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">tcp://localhost:61616</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">value</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">property</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">bean</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">

    </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">bean </span><span style="color: #FF0000;">id</span><span style="color: #0000FF;">=&quot;myJmsTemplate&quot;</span><span style="color: #FF0000;"> class</span><span style="color: #0000FF;">=&quot;org.springframework.jms.core.JmsTemplate&quot;</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">property </span><span style="color: #FF0000;">name</span><span style="color: #0000FF;">=&quot;connectionFactory&quot;</span><span style="color: #FF0000;"> ref</span><span style="color: #0000FF;">=&quot;jmsFactory&quot;</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;">
    </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">bean</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">
    </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">amq:queue </span><span style="color: #FF0000;">name</span><span style="color: #0000FF;">=&quot;Queue&quot;</span><span style="color: #FF0000;"> physicalName</span><span style="color: #0000FF;">=&quot;example.D&quot;</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span></div>
</pre>
</div>
<p>这样，执行发送代码，在activemq的admin界面中可以观察到发送成功的消息。</p>
<p>异步接收的代码：</p>
<p><div class="wlWriterSmartContent" id="scid:F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:b0d423fa-3160-41f5-af4f-478ea4cfb3c6" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre  style="width:100%;;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">class</span><span style="color: #000000;"> MyMessageConsumer </span><span style="color: #0000FF;">implements</span><span style="color: #000000;"> MessageListener {

    @Override
    </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> onMessage(Message message) {
        TextMessage textMessage </span><span style="color: #000000;">=</span><span style="color: #000000;"> (TextMessage) message;
        </span><span style="color: #0000FF;">try</span><span style="color: #000000;"> {
            System.out.println(</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">&gt;&gt;&gt;&gt;&gt;&gt;&gt;</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">+</span><span style="color: #000000;">textMessage.getText());
</span><span style="color: #008000;">//</span><span style="color: #008000;">            throw new RuntimeException(&quot;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;test error&quot;);</span><span style="color: #008000;">
</span><span style="color: #000000;">        } </span><span style="color: #0000FF;">catch</span><span style="color: #000000;"> (JMSException e) {
            </span><span style="color: #0000FF;">throw</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> RuntimeException(e);
        }
    }

}</span></div>
</pre>
</div>
<p>有关异步接收代码的spring配置：</p>
<p><div class="wlWriterSmartContent" id="scid:F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:2ab2cf80-9a02-4fab-933a-925dfad7012c" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre  style="width:100%;;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">    </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">bean </span><span style="color: #FF0000;">id</span><span style="color: #0000FF;">=&quot;myMessageConsumer&quot;</span><span style="color: #FF0000;"> class</span><span style="color: #0000FF;">=&quot;activemq.demo.spring.MyMessageConsumer&quot;</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;">
    </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">bean </span><span style="color: #FF0000;">id</span><span style="color: #0000FF;">=&quot;jmsContainer&quot;</span><span style="color: #FF0000;">
        class</span><span style="color: #0000FF;">=&quot;org.springframework.jms.listener.DefaultMessageListenerContainer&quot;</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">
        </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">property </span><span style="color: #FF0000;">name</span><span style="color: #0000FF;">=&quot;connectionFactory&quot;</span><span style="color: #FF0000;"> ref</span><span style="color: #0000FF;">=&quot;jmsFactory&quot;</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;">
        </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">property </span><span style="color: #FF0000;">name</span><span style="color: #0000FF;">=&quot;destination&quot;</span><span style="color: #FF0000;"> ref</span><span style="color: #0000FF;">=&quot;Queue&quot;</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;">
        </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">property </span><span style="color: #FF0000;">name</span><span style="color: #0000FF;">=&quot;messageListener&quot;</span><span style="color: #FF0000;"> ref</span><span style="color: #0000FF;">=&quot;myMessageConsumer&quot;</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;">
        </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">property </span><span style="color: #FF0000;">name</span><span style="color: #0000FF;">=&quot;sessionTransacted&quot;</span><span style="color: #FF0000;"> value</span><span style="color: #0000FF;">=&quot;true&quot;</span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;">
    </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">bean</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">

</span></div>
</pre>
</div>
<p>这样，就实现了基于spring和activemq的JMS的同步发送和异步提交。如果将MyMessageConsumer的抛出异常部分取消注释，则接收信息后，spring捕获到该异常并自动回滚事务。通过activemq的admin界面会监控到消息依然留在队列中。</p>
<p>可下载本文中的示例项目：<code>[Download not found]，可通过：</code></p>
<blockquote>
<p><code><font color="#333333">mvn test</font></code></p>
</blockquote>
<p><code>执行测试代码。并以测试代码为线索理解本项目。</code></p>
]]></content:encoded>
			<wfw:commentRss>http://marshal.easymorse.com/archives/1400/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ActiveMQ的最简单应用</title>
		<link>http://marshal.easymorse.com/archives/1399?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=activemq%25e7%259a%2584%25e6%259c%2580%25e7%25ae%2580%25e5%258d%2595%25e5%25ba%2594%25e7%2594%25a8</link>
		<comments>http://marshal.easymorse.com/archives/1399#comments</comments>
		<pubDate>Fri, 03 Jul 2009 07:49:14 +0000</pubDate>
		<dc:creator>Marshal</dc:creator>
				<category><![CDATA[计算机技术]]></category>
		<category><![CDATA[activemq]]></category>
		<category><![CDATA[jms]]></category>

		<guid isPermaLink="false">http://marshal.easymorse.com/archives/1399</guid>
		<description><![CDATA[有一段时间不使用JMS了。现在的项目又有可能需要应用JMS，来提高服务质量和提高系统资源的利用率。 提高服务质量，主要是保证不间断的服务。用JMS服务器接收任务，排成队列。应用服务可以暂停做维护，不影响接收的任务。应用服务运行后，再从队列中获取任务。 提高系统资源的利用率，主要是任务的派发不是24小时平均的，而是高峰时期任务量很多，比如1秒1000多个，有的时候很低，比如十几秒钟才来一个。应用服务通过JMS队列一个一个的取任务，做完一个再领一个，使系统资源的运用趋于平均。而JMS，比如JMS接收消息的效率是很高的，比如ActiveMQ，在赛扬（2.40GHz）机器上能够达到2000/s，消息大小为1-2k。好一些的服务器可以达到2万以上/秒。 ActiveMQ是开源免费的JMS实现，并且有很多扩展功能。地址： http://activemq.apache.org 安装和运行很简单，下载后解压缩，执行： activemq.bat 将启动默认配置的activemq。可以通过： http://localhost:8161/admin 访问activemq的管理界面。查看队列（queue）和主题（topic）下的消息内容。 编写ActiveMQ程序前需要准备类库，如果使用maven就简单了： &#60;dependency&#62; &#60;groupId&#62;org.apache.activemq&#60;/groupId&#62; &#60;artifactId&#62;activemq-core&#60;/artifactId&#62; &#60;version&#62;5.2.0&#60;/version&#62; &#60;/dependency&#62; 编写最简单的向JMS队列发送文本消息的程序： ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory( &#34;tcp://localhost:61616&#34;); Connection connection = connectionFactory.createConnection(); connection.start(); System.out.println(&#34;start...&#34;); Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); Queue destination = session.createQueue(&#34;example.C&#34;); MessageProducer producer = session.createProducer(destination); producer.setDeliveryMode(DeliveryMode.PERSISTENT); TextMessage message = session.createTextMessage(&#34;中文&#34;); producer.send(message); session.commit(); connection.close(); System.out.println(&#34;send text ok.&#34;); 执行程序后可通过上面提到的web界面查看example.C队列中收到的消息。不过中文信息显示的是??。这没有关系，是admin web应用自身的问题（使用的是iso-8859-1编码）。队列里的数据是对的。 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://marshal.easymorse.com/wp-content/uploads/2009/07/activemq-logo.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="71" alt="activemq-logo" src="http://marshal.easymorse.com/wp-content/uploads/2009/07/activemq-logo-thumb.png" width="240" border="0"></a> </p>
<p>有一段时间不使用JMS了。现在的项目又有可能需要应用JMS，来提高服务质量和提高系统资源的利用率。</p>
<p>提高服务质量，主要是保证不间断的服务。用JMS服务器接收任务，排成队列。应用服务可以暂停做维护，不影响接收的任务。应用服务运行后，再从队列中获取任务。</p>
<p>提高系统资源的利用率，主要是任务的派发不是24小时平均的，而是高峰时期任务量很多，比如1秒1000多个，有的时候很低，比如十几秒钟才来一个。应用服务通过JMS队列一个一个的取任务，做完一个再领一个，使系统资源的运用趋于平均。而JMS，比如JMS接收消息的效率是很高的，比如ActiveMQ，在赛扬（2.40GHz）机器上能够达到2000/s，消息大小为1-2k。好一些的服务器可以达到2万以上/秒。</p>
<p><span id="more-1399"></span>
<p>ActiveMQ是开源免费的JMS实现，并且有很多扩展功能。地址：</p>
<blockquote><p><a title="http://activemq.apache.org" href="http://activemq.apache.org">http://activemq.apache.org</a></p>
</blockquote>
<p>安装和运行很简单，下载后解压缩，执行：</p>
<blockquote><p>activemq.bat</p>
</blockquote>
<p>将启动默认配置的activemq。可以通过：</p>
<blockquote><p><a title="http://localhost:8161/admin" href="http://localhost:8161/admin">http://localhost:8161/admin</a></p>
</blockquote>
<p>访问activemq的管理界面。查看队列（queue）和主题（topic）下的消息内容。</p>
<p>编写ActiveMQ程序前需要准备类库，如果使用maven就简单了：</p>
<div class="wlWriterSmartContent" id="scid:F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:7aa33399-5fd4-4578-9087-d3e36f6c6942" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre  style="width:100%;;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">dependency</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">groupId</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">org.apache.activemq</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">groupId</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">artifactId</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">activemq-core</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">artifactId</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">
  </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">version</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">5.2.0</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">version</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">
</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">dependency</span><span style="color: #0000FF;">&gt;</span></div>
</pre>
</div>
<p>编写最简单的向JMS队列发送文本消息的程序：</p>
<p><div class="wlWriterSmartContent" id="scid:F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:860111f4-a434-47cd-a062-303df27a4b6f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre  style="width:100%;;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">ActiveMQConnectionFactory connectionFactory </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> ActiveMQConnectionFactory(
        </span><span style="color: #000000;">&quot;</span><span style="color: #000000;">tcp://localhost:61616</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">);
Connection connection </span><span style="color: #000000;">=</span><span style="color: #000000;"> connectionFactory.createConnection();
connection.start();
System.out.println(</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">start...</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">);

Session session </span><span style="color: #000000;">=</span><span style="color: #000000;"> connection.createSession(</span><span style="color: #0000FF;">true</span><span style="color: #000000;">,
        Session.AUTO_ACKNOWLEDGE);
Queue destination </span><span style="color: #000000;">=</span><span style="color: #000000;"> session.createQueue(</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">example.C</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">);

MessageProducer producer </span><span style="color: #000000;">=</span><span style="color: #000000;"> session.createProducer(destination);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);

TextMessage message </span><span style="color: #000000;">=</span><span style="color: #000000;"> session.createTextMessage(</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">中文</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">);
producer.send(message);
session.commit();

connection.close();
System.out.println(</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">send text ok.</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">);</span></div>
</pre>
</div>
<p>执行程序后可通过上面提到的web界面查看example.C队列中收到的消息。不过中文信息显示的是??。这没有关系，是admin web应用自身的问题（使用的是iso-8859-1编码）。队列里的数据是对的。</p>
<p>异步接收数据的代码如下：</p>
<div class="wlWriterSmartContent" id="scid:F2210F5F-69EB-4d4c-AFF7-B8A050E9CC72:cea010bd-4bcd-45ab-9d71-e3eabcab8946" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre  style="width:100%;;">
<div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/

--><span style="color: #000000;">ActiveMQConnectionFactory connectionFactory </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> ActiveMQConnectionFactory(
        </span><span style="color: #000000;">&quot;</span><span style="color: #000000;">tcp://localhost:61616</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">);
Connection connection </span><span style="color: #000000;">=</span><span style="color: #000000;"> connectionFactory.createConnection();
connection.start();
</span><span style="color: #0000FF;">final</span><span style="color: #000000;"> Session session </span><span style="color: #000000;">=</span><span style="color: #000000;"> connection.createSession(</span><span style="color: #0000FF;">true</span><span style="color: #000000;">,
        Session.AUTO_ACKNOWLEDGE);
Queue destination </span><span style="color: #000000;">=</span><span style="color: #000000;"> session.createQueue(</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">example.C</span><span style="color: #000000;">&quot;</span><span style="color: #000000;">);

MessageConsumer consumer </span><span style="color: #000000;">=</span><span style="color: #000000;"> session.createConsumer(destination);
consumer.setMessageListener(</span><span style="color: #0000FF;">new</span><span style="color: #000000;"> MessageListener(){
    @Override
    </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> onMessage(Message message) {
        System.out.println(message);
        </span><span style="color: #0000FF;">try</span><span style="color: #000000;"> {
            session.commit();
        } </span><span style="color: #0000FF;">catch</span><span style="color: #000000;"> (JMSException e) {
            e.printStackTrace();
        }
    }
});</span></div>
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://marshal.easymorse.com/archives/1399/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

