SpringBoot链接SQS队列
SpringBoot链接SQS队列
- 创建配置文件
- 导入依赖
- 拷贝代码
- 消息丢失及解决
创建配置文件
配置文件一共两个:
config
地址:Windows 上的 C:\Users\USERNAME.aws\credentials
不同的系统位置不一样,需要创建对应的文件
https://docs.aws.amazon.com/zh_cn/sdk-for-java/v1/developer-guide/setup-credentials.html
文件内容:
地域信息
[default]
region=us-east-1
output=json
credentials文件
地址:Windows 上的 C:\Users\USERNAME.aws\credentials
不同的系统位置不一样,需要创建对应的文件
https://docs.aws.amazon.com/zh_cn/sdk-for-java/v1/developer-guide/setup-credentials.html
文件内容:
账号、密码
[default]
aws_access_key_id=<value from AWS access portal>
aws_secret_access_key=<value from AWS access portal>
导入依赖
依赖
<!--aws sqs依赖-->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sqs</artifactId>
<version>1.11.106</version>
</dependency>
拷贝代码
我要写的是收信和删除的功能,在官方API都有现成的,其他的功能也有,可以自行查看:
官方讲解:https://docs.aws.amazon.com/zh_cn/sdk-for-java/v1/developer-guide/examples-sqs-messages.html
官方代码:https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/java/example_code/sqs/src/main/java/aws/example/sqs/SendReceiveMessages.java
//snippet-sourcedescription:[<<FILENAME>> demonstrates how to send, receive and delete messages from a queue.]
//snippet-keyword:[Java]
//snippet-sourcesyntax:[java]
//snippet-keyword:[Code Sample]
//snippet-keyword:[Amazon Simple Queue Service]
//snippet-service:[sqs]
//snippet-sourcetype:[full-example]
//snippet-sourcedate:[]
//snippet-sourceauthor:[soo-aws]
/*
* Copyright 2011-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://aws.amazon.com/apache2.0
*
* This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and
* limitations under the License.
*/
package aws.example.sqs;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.AmazonSQSException;
import com.amazonaws.services.sqs.model.CreateQueueResult;
import com.amazonaws.services.sqs.model.Message;
import com.amazonaws.services.sqs.model.SendMessageBatchRequest;
import com.amazonaws.services.sqs.model.SendMessageBatchRequestEntry;
import com.amazonaws.services.sqs.model.SendMessageRequest;
import java.util.Date;
import java.util.List;
public class SendReceiveMessages
{
private static final String QUEUE_NAME = "testQueue" + new Date().getTime();// 这个可以没有。。。
public static void main(String[] args)
{
final AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();
try {
CreateQueueResult create_result = sqs.createQueue(QUEUE_NAME);
} catch (AmazonSQSException e) {
if (!e.getErrorCode().equals("QueueAlreadyExists")) {
throw e;
}
}
// 这个是你要访问的SQS队列的地址 url 直接替换成对应的url即可
String queueUrl = sqs.getQueueUrl(QUEUE_NAME).getQueueUrl();
SendMessageRequest send_msg_request = new SendMessageRequest()
.withQueueUrl(queueUrl)
.withMessageBody("hello world")
.withDelaySeconds(5);
sqs.sendMessage(send_msg_request);
// Send multiple messages to the queue
SendMessageBatchRequest send_batch_request = new SendMessageBatchRequest()
.withQueueUrl(queueUrl)
.withEntries(
new SendMessageBatchRequestEntry(
"msg_1", "Hello from message 1"),
new SendMessageBatchRequestEntry(
"msg_2", "Hello from message 2")
.withDelaySeconds(10));
sqs.sendMessageBatch(send_batch_request);
// receive messages from the queue
List<Message> messages = sqs.receiveMessage(queueUrl).getMessages();
// delete messages from the queue
for (Message m : messages) {
sqs.deleteMessage(queueUrl, m.getReceiptHandle());
}
}
}
消息丢失及解决
遇到的问题:
功能描述:我们的方法是通过前端JS发送消息到SQS,同时调用后端API,后端被调用后拿到消息,然后存入数据库。
问题:发现在调用API后有时API拿不到数据,导致20次请求或许接到14次,6次在SQS队列中。
解决:我们可以在发送请求获取SQS消息的时候设置为长轮询
// 设置5秒的长轮询
ReceiveMessageRequest receive_request = new ReceiveMessageRequest()
.withQueueUrl(queueUrl)
.withWaitTimeSeconds(5);
ReceiveMessageResult receiveMessageResult = sqs.receiveMessage(receive_request);
// 获取消息
List<Message> messages;
messages = receiveMessageResult.getMessages();
PS:长轮询:
我认为长轮询是一直搜索,一直到:(查询的消息个数==设置的个数||查询的时长==设置的时长)
上述代码:查询的消息个数,没有设置,默认为1