java queue使用
Amazon Simple Queue Service或SQS是Amazon Webservice堆栈提供的高度可扩展的托管消息队列。 Amazon SQS可用于完全解耦系统内不同组件的操作,这些组件否则将交换数据以执行独立的任务。 Amazon SQS还可以帮助我们保存在应用程序关闭或组件之一不可用时丢失的数据。
Amazon SQS功能(直接从亚马逊网站复制)
- 冗余基础架构 —保证至少一次传递消息,对消息的高度并发访问以及发送和检索消息的高可用性
- 多位作者和读者-系统的多个部分可以同时发送或接收消息。 SQS在处理过程中锁定消息,使系统的其他部分无法同时处理消息。
- 每个队列的可配置设置 -您的所有队列不必完全相同。 例如,一个队列可以针对需要比其他队列更长的处理时间的消息进行优化。
- 可变的消息大小 -您的消息最大为65536字节(64 KiB)。 对于更大的消息,您可以使用Amazon Simple Storage Service(Amazon S3)或Amazon SimpleDB存储消息的内容,并使用Amazon SQS持有指向Amazon S3或Amazon SDB对象的指针。 或者,您可以将较大的消息拆分为较小的消息。
- 访问控制 -您可以控制谁可以向队列发送消息以及谁可以从队列接收消息
- 延迟队列 -延迟队列是用户在队列上设置默认延迟的延迟队列,以使所有排队的消息的发送都将延迟该时间段。 您可以使用CreateQueue创建队列时设置延迟值,也可以使用SetQueueAttributes更新该值。 如果更新该值,则新值仅影响更新后排队的消息。
有了上述知识,让我们尝试使用SQS创建简单的照片处理服务。
本教程的问题定义
我们将创建一个包含以下组件的简单照片处理应用程序。
- 照片上传器服务 –这是一项网络服务,允许用户将照片上传到系统。 照片上传后,它们将存储在临时存储中。 为简单起见,我们假设用户已经上传了照片并将其存储在预定义的位置。
- AWSSimpleQueueServiceUtil –这是一个实用程序类,用于包装Amazon SQS客户端并在SQS队列上执行基本的CRUD操作。
- PhotoProcessingManager –管理整个节目。 它将调用AWSSimpleQueueServiceUtil将消息发送/接收到SQS,并调用PhotoProcessor来处理照片,最后从队列中删除消息。 通常,我们应该打算让此类充当SQS的侦听器,但为简单起见,我们将仅使用轮询机制从SQS中提取消息。
- PhotoProcessor –通过PhotoProcessingManager从SQS获取照片消息并生成缩略图。
在开始之前,如果您通过以下链接观看视频,那就太好了: http : //docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSGettingStartedGuide/Welcome.html
入门步骤
- 创建一个亚马逊帐户。 您将需要一张信用卡
- 登录到控制台console.aws.amazon.com 。
- 在控制台仪表板上搜索SQS,然后单击它。 它会将您带到您的SQS家。
- 创建一个新的SQS队列,并将其命名为PhotoQueue。 将其余设置保留为默认设置。 我们还可以动态创建和删除SQS队列,但是在本教程中,我有一个预先创建的队列,该队列将在我的代码中使用。
- 现在我们有了一个队列,现在我们将在我们最喜欢的Java编辑器中创建一个简单的Java项目,并了解如何利用此队列。
- 完成后,您需要下载安全凭证。 为此,请转到“我的帐户” /“安全凭证”。 我们追求的是访问凭据。 您将看到有3种类型的访问凭据,其中一种是“访问密钥”。 我们需要它来访问和使用刚刚创建的PhotoQueue。 我们将创建一组新的访问密钥,并将访问密钥和秘密密钥存储在安全的位置。
- 现在,从此处下载适用于Java的SDK。 http://aws.amazon.com/sdkforjava 。 在sdk的lib文件夹中,将aws-java-sdk-1.3.33.jar复制到您的项目类路径。
Maven用户可以在其POM中添加以下依赖项
<dependency><groupId>com.amazonaws</groupId><artifactId>aws-java-sdk</artifactId><version>1.3.33</version> </dependency>
创建一个名为“ AwsCredentials.properties”的文件,将其存储在您的项目中。 该文件将包含以下属性
accessKey = secretKey =
这些属性的值是您在步骤6中生成的访问密钥。
- 对于照片处理,我正在使用imgscalr 。 它是Java中的一种轻量级且很棒的照片处理库,用于执行诸如调整大小,旋转,裁剪等简单任务。您可以从http://www.thebuzzmedia.com/software/imgscalr-java-image-scaling-library下载该jar /#download 。 Maven用户可以将以下内容添加到其依赖项列表中。
<dependency><groupId>org.imgscalr</groupId><artifactId>imgscalr-lib</artifactId><version>4.2</version><type>jar</type><scope>compile</scope></dependency>
现在,我们准备摇摆不定,并通过一些代码使我们的手变得肮脏。
AWSSimpleQueueServiceUtil.java
package com.aranin.adconnect.util.aws;import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClient;
import com.amazonaws.services.sqs.model.*;import java.io.FileInputStream;
import java.util.List;
import java.util.Properties;/*** Created by IntelliJ IDEA.* User: Niraj Singh* Date: 3/19/13* Time: 10:44 AM* To change this template use File | Settings | File Templates.*/
public class AWSSimpleQueueServiceUtil {private BasicAWSCredentials credentials;private AmazonSQS sqs;private String simpleQueue = "PhotoQueue";private static volatile AWSSimpleQueueServiceUtil awssqsUtil = new AWSSimpleQueueServiceUtil();/*** instantiates a AmazonSQSClient http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/sqs/AmazonSQSClient.html* Currently using BasicAWSCredentials to pass on the credentials.* For SQS you need to set your regions endpoint for sqs.*/private AWSSimpleQueueServiceUtil(){try{Properties properties = new Properties();properties.load(new FileInputStream("D:/samayik/adkonnection/src/main/resources/AwsCredentials.properties"));this.credentials = new BasicAWSCredentials(properties.getProperty("accessKey"),properties.getProperty("secretKey"));this.simpleQueue = "PhotoQueue";this.sqs = new AmazonSQSClient(this.credentials);/*** My queue is in singapore region which has following endpoint for sqs* https://sqs.ap-southeast-1.amazonaws.com* you can find your endpoints here* http://docs.aws.amazon.com/general/latest/gr/rande.html** Overrides the default endpoint for this client ("sqs.us-east-1.amazonaws.com")*/this.sqs.setEndpoint("https://sqs.ap-southeast-1.amazonaws.com");/**You can use this in your web app where AwsCredentials.properties is stored in web-inf/classes*///AmazonSQS sqs = new AmazonSQSClient(new ClasspathPropertiesFileCredentialsProvider());}catch(Exception e){System.out.println("exception while creating awss3client : " + e);}}public static AWSSimpleQueueServiceUtil getInstance(){return awssqsUtil;}public AmazonSQS getAWSSQSClient(){return awssqsUtil.sqs;}public String getQueueName(){return awssqsUtil.simpleQueue;}/*** Creates a queue in your region and returns the url of the queue* @param queueName* @return*/public String createQueue(String queueName){CreateQueueRequest createQueueRequest = new CreateQueueRequest(queueName);String queueUrl = this.sqs.createQueue(createQueueRequest).getQueueUrl();return queueUrl;}/*** returns the queueurl for for sqs queue if you pass in a name* @param queueName* @return*/public String getQueueUrl(String queueName){GetQueueUrlRequest getQueueUrlRequest = new GetQueueUrlRequest(queueName);return this.sqs.getQueueUrl(getQueueUrlRequest).getQueueUrl();}/*** lists all your queue.* @return*/public ListQueuesResult listQueues(){return this.sqs.listQueues();}/*** send a single message to your sqs queue* @param queueUrl* @param message*/public void sendMessageToQueue(String queueUrl, String message){SendMessageResult messageResult = this.sqs.sendMessage(new SendMessageRequest(queueUrl, message));System.out.println(messageResult.toString());}/*** gets messages from your queue* @param queueUrl* @return*/public List<Message> getMessagesFromQueue(String queueUrl){ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(queueUrl);List<Message> messages = sqs.receiveMessage(receiveMessageRequest).getMessages();return messages;}/*** deletes a single message from your queue.* @param queueUrl* @param message*/public void deleteMessageFromQueue(String queueUrl, Message message){String messageRecieptHandle = message.getReceiptHandle();System.out.println("message deleted : " + message.getBody() + "." + message.getReceiptHandle());sqs.deleteMessage(new DeleteMessageRequest(queueUrl, messageRecieptHandle));}public static void main(String[] args){}}
PhotoProcessor.java
package com.aranin.adconnect.util.aws;import org.imgscalr.Scalr;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;/*** Created by IntelliJ IDEA.* User: Niraj Singh* Date: 3/19/13* Time: 12:32 PM* To change this template use File | Settings | File Templates.*/
public class PhotoProcessor {public static void generateImage(String imagePath, String origName, String targetName, int scalabity){String origImage = null;String targetImage = null;File origFile = null;BufferedImage buffImg = null;File targetFile = null;try{origImage = imagePath + "/" + origName;targetImage = imagePath + "/" + targetName;origFile = new File(origImage);buffImg = ImageIO.read(origFile);buffImg = Scalr.resize(buffImg, Scalr.Method.SPEED, scalabity);targetFile = new File(targetImage);ImageIO.write(buffImg, "jpeg", targetFile);}catch (Exception e){System.out.println("Exception in processing image : " + e);}finally {buffImg = null;}}
}
PhotoFile.java
package com.aranin.adconnect.util.aws;/*** Created by IntelliJ IDEA.* User: Niraj Singh* Date: 3/19/13* Time: 12:29 PM* To change this template use File | Settings | File Templates.*/
public class PhotoFile {private String origName;private String targetName;public String imagePath;public String getOrigName() {return origName;}public void setOrigName(String origName) {this.origName = origName;}public String getTargetName() {return targetName;}public void setTargetName(String targetName) {this.targetName = targetName;}public String getImagePath() {return imagePath;}public void setImagePath(String imagePath) {this.imagePath = imagePath;}public String toString(){return origName + "," + targetName + "," + imagePath;}
}
SQSPhotoManager.java
package com.aranin.adconnect.util.aws;import com.amazonaws.services.sqs.model.Message;import java.util.List;
import java.util.StringTokenizer;/*** Created by IntelliJ IDEA.* User: Niraj Singh* Date: 3/20/13* Time: 11:38 AM* To change this template use File | Settings | File Templates.*/
public class SQSPhotoManager implements Runnable{private String queueUrl;public static void main(String[] args){AWSSimpleQueueServiceUtil awssqsUtil = AWSSimpleQueueServiceUtil.getInstance();/*** 1. get the url for your photo queue*/String queueUrl = awssqsUtil.getQueueUrl(awssqsUtil.getQueueName());System.out.println("queueUrl : " + queueUrl);/*** 2. Add a photo to the queue to be processed*/PhotoFile photo = new PhotoFile();photo.setImagePath("C:/Users/Public/Pictures/Sample Pictures");photo.setOrigName("Tree.jpg");photo.setTargetName("Tree_thumb.jpg");/*** 3. set the photofile in queue for processing*/awssqsUtil.sendMessageToQueue(queueUrl, photo.toString());/*** get the messages from queue*/Thread managerthread = new Thread(new SQSPhotoManager(queueUrl),"T2");managerthread.start();}public SQSPhotoManager(String queueUrl){this.queueUrl = queueUrl;}@Overridepublic void run() {AWSSimpleQueueServiceUtil awssqsUtil = AWSSimpleQueueServiceUtil.getInstance();boolean flag = true;while(flag){List<Message> messages = awssqsUtil.getMessagesFromQueue(this.queueUrl);if(messages == null || messages.size() == 0){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.}}else{flag = false;for (Message message : messages) {String messagePhoto = message.getBody();System.out.println("photo to be processed : " + messagePhoto);StringTokenizer photoTokenizer = new StringTokenizer(messagePhoto,",");String source = null;String target = null;String path = null;source = photoTokenizer.nextToken();target = photoTokenizer.nextToken();path = photoTokenizer.nextToken();System.out.println("source : " + source);System.out.println("target : " + target);System.out.println("path : " + path);/*** generate thumbmail within 150*150 container*/PhotoProcessor.generateImage(path, source, target, 150);}/*** finally delete the message*/for (Message message : messages) {awssqsUtil.deleteMessageFromQueue(this.queueUrl, message);}}}}
}
这将构成使用SQS的PhotoProcessor应用程序的核心。 此代码有一个明显的缺点。 它使用线程对SQS进行轮询,如果您可以在代码中创建一个侦听器来订阅您的队列并在收到新消息时采取必要的措施,那将是很好的选择。 这确实是我下一篇文章的主题。 然后,随时向我提问,我们可以共同找到答案。
翻译自: https://www.javacodegeeks.com/2013/06/working-with-amazon-simple-queue-service-using-java.html
java queue使用