JMS和AWS SQS的更多高级内容

aws_icon-sqs_white-320x320 如您所知, AWS中的SQS SQS代表“简单队列服务”。 最近,在使用它的同时,我发现了将其称为“简单”的原因之一。 在之前的两篇文章( 此处和此处 )中,我展示了结合Spring Framework将SQS用作JMS队列提供程序 。 通过这个基本设置,我决定更进一步,并开始结合JMS(利用JMS属性'JMSReplyTo'和临时队列)一起尝试请求-响应模式 。 在这篇相当经典的文章中 ,很好地解释了它是如何工作的以及为什么这样工作。
为了显示它应该如何工作,我首先显示与Apache ActiveMQ一起使用的设置。 让我展示一下从队列中挑选消息,对内容执行操作并将答复发送回JMS标头中的JMSReplyTo的bean。 自从我使用Spring以来,这听起来比实际要难。 首先是Java代码:

package net.pascalalma.aws.sqs.requestresponse;import org.springframework.stereotype.Service;@Service
public class MyMessageService implements ResponsiveTextMessageDelegate {public String onMessage(String txt) {return String.valueOf(txt.length());}
}

我要说的是一门很简单的课。 它实现了ResponsiveTextMessageDelegate(此接口的详细信息在此处描述),并仅返回传入消息内容的长度。 Spring框架会处理所有其他需要完成的事情。 该服务的Spring配置如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><context:component-scan base-package="net.pascalalma.aws.sqs.requestresponse"></context:component-scan><context:annotation-config/><!-- ActiveMQ config --><bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory"><property name="brokerURL"><value>tcp://localhost:61616</value></property></bean><bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"><property name="connectionFactory" ref="jmsFactory"/></bean><bean id="requestQueueName" class="java.lang.String"><constructor-arg value="DefaultDemoQueue"/></bean><bean id="myMessageService" class="net.pascalalma.aws.sqs.requestresponse.MyMessageService" /><bean id="messageListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter"><property name="delegate" ref="myMessageService"/><property name="defaultListenerMethod" value="onMessage"/><property name="messageConverter" ref="messageConverter" /></bean><bean id="messageConverter" class="org.springframework.jms.support.converter.SimpleMessageConverter" /><bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"><property name="connectionFactory" ref="jmsFactory"/><property name="destinationName" ref="requestQueueName"/><property name="messageListener" ref="messageListener"/></bean>
</beans>

这与我上一篇文章中描述的配置基本相同。 唯一的区别是,我现在使用一个转换器,即SimpleMessageConverter,该转换器负责将返回的String转换为TextMessage。 如果我们不定义此转换器,则会收到以下错误:

java.lang.NoSuchMethodException: net.pascalalma.aws.sqs.requestresponse.MyMessageService.onMessage(org.apache.activemq.command.ActiveMQTextMessage

接下来,我们需要一个可以与我们的服务“对话”的Service客户端bean。 在Java中可能看起来像这样:

package net.pascalalma.aws.sqs.requestresponse;import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.jms.core.SessionCallback;
import org.springframework.jms.support.JmsUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;import javax.annotation.Resource;
import javax.jms.*;
import java.util.Random;@Component
public class MyMessageServiceClient {final static Logger logger = Logger.getLogger(MyMessageServiceClient.class);@Resourceprivate JmsTemplate jmsTemplate;@Autowiredprivate String requestQueueName;public String process(final String txt) {//Setup a message producer to send message to the queue the server is consuming fromMessage response = jmsTemplate.sendAndReceive(requestQueueName,new MessageCreator() {public Message createMessage(Session session) throws JMSException {TextMessage message = session.createTextMessage();message.setText(txt);return message;}});String result = null;try {result = ((TextMessage) response).getText();} catch (JMSException e) {logger.error(e);}return result;}
}

我们看到的是,我们利用jmsTemplate的sendAndReceive来发送在MessageCreator回调中创建的消息,并等待响应消息。 此类的相应Spring配置为:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><context:component-scan base-package="net.pascalalma.aws.sqs.requestresponse"></context:component-scan><context:annotation-config/><!-- ActiveMQ config --><bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory"><property name="brokerURL"><value>tcp://localhost:61616</value></property></bean><!-- End ActiveMQ specific --><bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"><property name="connectionFactory" ref="jmsFactory"/></bean><bean id="requestQueueName" class="java.lang.String"><constructor-arg value="DefaultDemoQueue"/></bean><bean id="myMessageServiceClient" class="net.pascalalma.aws.sqs.requestresponse.MyMessageServiceClient"/>
</beans>

现在剩下的是一些“容器”,可以在我为“服务器”部分创建主类的操作中查看这些bean:

package net.pascalalma.aws.sqs.requestresponse;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MessageServiceMain {public static void main(String[] args) {//Build application context by reading spring-config.xmlApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"requestresponse/application-context.xml"});}
}

在您的IDE或终端中运行此类仅读取SPring配置并实例化服务bean。 客户的Main类还有更多代码:

package net.pascalalma.aws.sqs.requestresponse;import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import java.util.HashMap;
import java.util.Map;
import java.util.Random;public class MessageServiceClientMain {final static Logger logger = Logger.getLogger(MessageServiceClientMain.class);public static void main(String[] args) {//Build application context by reading spring-config.xmlApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"requestresponse/application-context-client.xml"});//Get an instance of ProductService class;MyMessageServiceClient messageServiceClient = (MyMessageServiceClient) ctx.getBean("myMessageServiceClient");//Call getProduct method of ProductServiceString random = createRandomString();for (int i=0; i<16; i++) {String key = random.substring(i);logger.info("Sending to service: " + key);logger.info("Sending to service with length: " + key.length());String result = messageServiceClient.process(key);logger.info("Received from service: " + result);logger.info("======================================================");}}private static String createRandomString() {Random random = new Random(System.currentTimeMillis());long randomLong = random.nextLong();return Long.toHexString(randomLong);}
}

运行此类将生成消息,并将其发送到服务,并打印从服务接收的结果,如下所示:

2015-04-20 20:29:14 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(27) - Sending to service: 42fdcd4355cc5314
2015-04-20 20:29:14 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(28) - Sending to service with length: 16
2015-04-20 20:29:15 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(30) - Received from service: 16
2015-04-20 20:29:15 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(31) - ======================================================
2015-04-20 20:29:15 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(27) - Sending to service: 2fdcd4355cc5314
2015-04-20 20:29:15 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(28) - Sending to service with length: 15
2015-04-20 20:29:15 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(30) - Received from service: 15
2015-04-20 20:29:15 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(31) - ======================================================

到目前为止,一切都很好。 现在,让我们使用AWS SQS代替本地Active MQ实例。 只需在两个Spring配置中简单地修改所用JmsFactory的配置即可轻松实现:

...<bean id="credentialsProviderBean" class="com.amazonaws.auth.DefaultAWSCredentialsProviderChain"/><bean id="connectionFactoryBuilder" class="com.amazon.sqs.javamessaging.SQSConnectionFactory$Builder"><property name="regionName" value="eu-west-1"/><property name="numberOfMessagesToPrefetch" value="5"/><property name="awsCredentialsProvider" ref="credentialsProviderBean"/></bean><bean id="jmsFactory" class="com.amazon.sqs.javamessaging.SQSConnectionFactory"factory-bean="connectionFactoryBuilder"factory-method="build"/>
...

现在,如果我们启动“服务器”应用程序和“客户端”应用程序,我们将获得以下输出:

2015-04-25 20:22:49 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(27) - Sending to service: f1db848691a26c85
2015-04-25 20:22:49 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(28) - Sending to service with length: 16
Exception in thread "main" org.springframework.jms.UncategorizedJmsException: Uncategorized exception occured during JMS processing; nested exception is javax.jms.JMSException: Unsupported Methodat org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:316)at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)at org.springframework.jms.core.JmsTemplate.executeLocal(JmsTemplate.java:986)at org.springframework.jms.core.JmsTemplate.sendAndReceive(JmsTemplate.java:922)at net.pascalalma.aws.sqs.requestresponse.MyMessageServiceClient.process(MyMessageServiceClient.java:29)at net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain.main(MessageServiceClientMain.java:29)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:606)at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: javax.jms.JMSException: Unsupported Methodat com.amazon.sqs.javamessaging.SQSSession.createTemporaryQueue(SQSSession.java:744)at org.springframework.jms.core.JmsTemplate.doSendAndReceive(JmsTemplate.java:946)at org.springframework.jms.core.JmsTemplate$12.doInJms(JmsTemplate.java:926)at org.springframework.jms.core.JmsTemplate$12.doInJms(JmsTemplate.java:922)at org.springframework.jms.core.JmsTemplate.executeLocal(JmsTemplate.java:983)... 8 more

如您所见,我们得到了一个堆栈跟踪,告诉我们SQS不支持JMS方法“ createTemporaryQueue”! 到目前为止,对JMS的支持。 我猜这就是为什么他们称其为简单队列服务,因为仅实现了一些可能的JMS方法;-)。 我搜索了有关此的更多信息,但没有任何运气。 但是,我确实遇到了这个框架: Nevado JMS 。 他们声称是AWS SQS / SNS的JMS驱动程序,所以我决定尝试一下。 首先,我在项目的pom中添加了以下依赖项:

<dependency><groupId>org.skyscreamer</groupId><artifactId>nevado-jms</artifactId><version>1.3.1</version>
</dependency>

然后再次在两个Spring配置中修改JmsFactory,这次是:

...<bean id="sqsConnectorFactory" class="org.skyscreamer.nevado.jms.connector.amazonaws.AmazonAwsSQSConnectorFactory" /><bean id="jmsFactory" class="org.skyscreamer.nevado.jms.NevadoConnectionFactory"><property name="sqsConnectorFactory" ref="sqsConnectorFactory" /><property name="awsAccessKey" value="${aws.accessKey}" /><property name="awsSecretKey" value="${aws.secretKey}" /></bean>    
...

现在,当我运行主类时,我得到了预期的结果:

2015-04-25 20:33:27 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(27) - Sending to service: dad74fbff8e0a2f2
2015-04-25 20:33:27 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(28) - Sending to service with length: 16
2015-04-25 20:33:53 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(30) - Received from service: 16
2015-04-25 20:33:53 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(31) - ======================================================
2015-04-25 20:33:53 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(27) - Sending to service: ad74fbff8e0a2f2
2015-04-25 20:33:53 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(28) - Sending to service with length: 15
2015-04-25 20:34:04 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(30) - Received from service: 15
2015-04-25 20:34:04 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(31) - ======================================================
2015-04-25 20:34:04 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(27) - Sending to service: d74fbff8e0a2f2
2015-04-25 20:34:04 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(28) - Sending to service with length: 14
2015-04-25 20:34:09 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(30) - Received from service: 14
2015-04-25 20:34:09 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(31) - ======================================================
2015-04-25 20:34:09 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(27) - Sending to service: 74fbff8e0a2f2
2015-04-25 20:34:09 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(28) - Sending to service with length: 13
2015-04-25 20:34:17 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(30) - Received from service: 13
2015-04-25 20:34:17 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(31) - ======================================================
2015-04-25 20:34:17 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(27) - Sending to service: 4fbff8e0a2f2
2015-04-25 20:34:17 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(28) - Sending to service with length: 12
2015-04-25 20:34:21 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(30) - Received from service: 12
2015-04-25 20:34:21 INFO  net.pascalalma.aws.sqs.requestresponse.MessageServiceClientMain(31) - ======================================================

因此,这表明,尽管需要本地社区的一些帮助,但所谓的“简单”服务仍然可以使用更高级的东西:-)

翻译自: https://www.javacodegeeks.com/2015/05/more-advanced-stuff-with-jms-and-aws-sqs.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/358809.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

w10家庭版安装java不_小编为你分析win10系统安装不了java的设置办法

许多win10系统用户在工作中经常会遇到win10系统安装不了java的情况&#xff0c;想必大家都遇到过win10系统安装不了java的情况吧&#xff0c;那么应该怎么处理win10系统安装不了java呢&#xff1f;我们依照1、查看自己的电脑是32位的还是64位的(x86代表32位的)。java安装要求比…

用C语言实现津巴布韦这道算法题?

粉丝求助: 题目内容如下: 5、津巴布韦 由于计划经济失败,津巴布韦称为世界上通胀率最高的国家。这里的物价即使在一天中也会持续上涨,所以必须实时更新物品价格。例如:1个鸡蛋的价格为35亿津巴布韦元,所以超市做了每位数字的活动标价牌。 钟旭在穆加贝超市打工,有一天遇…

dnslog盲注

dnslog盲注dnslog注入原理DNSlog工具什么情况下使用dnslog注入&#xff1f;Mysql DNSlog原理图DNSlog盲注利用条件DNSlog盲注操作方式实战演练查询当前数据库名&#xff1a;查询当前数据库的第一个表名&#xff1a;查询第users表一个列名&#xff1a;查询users表的username列的…

Python在cmd中配置虚拟环境ERROR: Command errored out with exit status 1:

粉丝求助: 解决办法: 具体步骤: 1.查看Python版本 2.Pythonlibs 中找到对应版本的whl文件,cp37代表3.7版本,win32代表Windows系统32位机,根据自己的电脑位数选择。

java sqlserver ssl_拦截SQLSERVER的SSL加密通道替换传输过程中的用户名密码实现运维审计(一)...

工作准备•一台SQLSERVER 2005/SQLSERVER 2008服务•SQLSERVER jdbc驱动程序•Java开发环境eclipse jdk1.8•java反编译工具JD-Core反编译JDBC分析SQLSERVER客户端与服务器通信原理SQLServerConnection.class1、经过反编译分析SQLServerConnection.class文件我们可以看到登录时…

1-9其他数据库注入

文章目录 数据库注入access数据库判断access数据库常用函数查询语句构造联合查询布尔型盲注 mssql数据库mssql数据库判断环境---靶机-2k3_sp2常用函数查询语句构造联合查询报错注入布尔型盲注 数据库注入 access数据库 判断access数据库 根据url的后缀。ASP为后缀名…

自动化专业向往硬件方面靠,有什么好的建议?

我的建议是: 有能力考研就先考研,考不上可以选择就业,学历还是很重要的,门槛。自动化可以找一些相关的知名企业,按照他们的招聘要求要求自己,往这个方法发展,垂直领域研究很深,你就是大佬和专家。 有个帖子讲的挺全的,虽然是文章:自动化人生 下面是理论内容,我直接…

Linux下编译安装以及配置PHP环境

安装准备 依次执行下面命令,不存在的就搜差不多的就行,下面安装的都是后面安装环境可能需要用上的依赖,不管37是不是21,复制粘贴就是了 Ubuntu安装: sudo apt-get update sudo apt-get install gcc autoconf openssl libssl-dev curl libcurl4-gnutls-de…

有什么好一点的方法读jdk源码吗?

建议是: 1:找相关的书在看相关源码时应该对程序有整体了解,比如看虚拟机时至少要知道:垃圾回收算法,Java内存布局,class文件格式,加载连接的过程...很多人看源码一点头绪都没有,就是因为不了解对应的模块是干嘛的(比如Ja

给女朋友道歉的java代码_跟女朋友道歉的话,高情商的哄人句子

女朋友生气了&#xff0c;而且很严重。在这种情况下&#xff0c;不知道做什么挽回她。第一诚实的道歉可以缓和彼此紧张的气氛。重要的是&#xff0c;道歉完就需要说一些话语去哄她&#xff0c;至于怎么哄又是一个技术性的问题了&#xff0c;下面一起来看看跟女朋友道歉的话,高情…

使用Myeclipse完成Hibernate的逆向工程

Hibernate的开发流程一般有两种&#xff1a; 1、由Domain object > mapping > db 2、由db开始&#xff0c;用工具生成生成mapping 和Domain object。 在实际的开发过程中&#xff0c;涉及的表太多了&#xff0c;一个一个的写java实体类很费事费时的。Myeclipse提供了一个…

kali安装docker(有效详细的教程)

前记&#xff1a; 博主有着多次安装docker的丰富经验&#xff0c;曾经为了在kali成功安装docker花费不少时间。在kali2016.3一直到最新的kali2019.4都通吃&#xff01;所以跟着下面的步骤走&#xff0c;绝对不会出错。&#xff08;该机子此前没装过docker&#xff0c;并且配置好…

java中菜单分几级_JavaWeb三级菜单分类查询详解

废话不多说&#xff0c;直接贴代码&#xff1a;dao层代码&#xff1a;mapper&#xff1a;ListselectByParentId(Integer id);mapper.xmlselectfrom easybuy_product_categorywhere parentId #{parentId,jdbcTypeINTEGER}Test:import cn.hd.entity.ProductCategory;import cn.h…

使用Javaslang进行Java 8中的函数式编程

我们非常高兴地在jOOQ博客上宣布一个客座帖子&#xff0c;该帖子由HSH Nordbank的高级软件工程师&#xff0c;三个孩子的父亲&#xff0c; Daniel Dietrich撰写。 他目前作为项目负责人和首席开发人员为金融产品创建定价框架。 除工作外&#xff0c;他还对编程语言&#xff0c…

HFS远程命令执行漏洞复现

漏洞程序下载地址:Http File Server 这里说一下&#xff0c;在Windows server 2003中复现时&#xff0c;我直接使用Administrator用户登录&#xff0c;然后复现&#xff0c;未出现权限问题。再Windows 10中尝试复现时发现权限不足&#xff0c;需要以管理员权限执行漏洞程序。 运…

HTML标签速查表

有时候,学习的前端的标签太多,容易记不牢,这里整理一份标签速查表,便于查阅。不区分html或html5.

java解析java源码_JAVA语言-Java源码解析-Stack源码分析

一、简介stack类图.png栈是数据结构中一种很重要的数据结构类型&#xff0c;因为栈的后进先出功能是实际的开发中有很多的应用场景。Java API中提供了栈(Stacck)的实现。Stack类继承了Vector类&#xff0c;而Vector类继承了AbstractList抽象类&#xff0c;实现了List类&#xf…

渗透测试神器CS(4.0)的使用

CS CS简介CS功能安装CSCS的基本使用深入标题介绍 Beacon Commands基础操作演示 CS简介 CS 是Cobalt Strike的简称&#xff0c;是一款渗透测试神器&#xff0c;常被业界人称为CS神器。Cobalt Strike已经不再使用MSF而是作为单独的平台使用&#xff0c;它分为客户端与服务端&…

UTF-8和GBK有啥区别?

粉丝求助: 如何解决: 把编辑器和浏览器的字符集统一设置成utf-8或者gbk即可。 主要区别: 1.GBK是在bai国家标准GB2312基础上扩容后兼容GB2312的标准(好像还不du是国家标准)。zhiGBK编码dao专门用来解决中文编码的,是双字节的。不论中英文都是双字节的。 2. UTF-8 编码是…

Java反射(Reflection)

基本概念 在Java运行时环境中&#xff0c;对于任意一个类&#xff0c;能否知道这个类有哪些属性和方法&#xff1f;对于任意一个对象&#xff0c;能否调用它的任意一个方法&#xff1f; 答案是肯定的。 这种动态获取类的信息以及动态调用对象的方法的功能来自于Java语言的反射&…