2

我的应用程序向 Amazon Simple Notification Service (SNS) 主题发送消息,但有时(6/10)我收到 java.net.UnknownHostException:sqs.ap-southeast-1.amazonaws.com。异常原因在亚马逊网络服务讨论论坛中有描述,请查看:https ://forums.aws.amazon.com/thread.jspa?messageID=499290鹚 。

我的问题类似于亚马逊论坛中描述的问题,但我向主题发布消息的速度非常动态。它可以是 1 条消息/秒或 1 条消息/分钟或一小时内没有消息。我正在寻找一种更清洁、更好和安全的方法,以保证向 SNS 主题发送消息。

问题详细描述:

Topic_Arn= 应用程序要发布消息的 SNS 主题的 arn

msg = 要在主题中发送的消息

// Just a sample example which publish message to Amazon SNS topic
class SimpleNotificationService {
    AmazonSNSClient mSnsClient = null;

    static {
        createSnsClient()
    }

    private void static createSnsClient() {
        Region region = Region.getRegion(Regions.AP_SOUTHEAST_1);
        AWSCredentials credentials = new 
                BasicAWSCredentials(AwsPropertyLoader.getInstance().getAccessKey(),        
                        AwsPropertyLoader.getInstance().getSecretKey());
        mSqsClient = new AmazonSQSClient(credentials);
        mSqsClient.setRegion(region);
    }

    public void static publishMessage(String Topic_Arn, String msg) {
        PublishRequest req = new PublishRequest(Topic_Arn, msg);
        mSnsClient.publish(req);
    }
}

调用 SimpleNotificationService 的类

class MessagingManager {

     public void sendMessage(String message) {
           String topic_arn = "arn:of:amazon:sns:topic";
           SimpleNotificationService.publishMessage(topic_arn, message);
     }
}

请注意,这是一个示例代码,而不是我的实际代码。这里可能是类设计问题,但如果它们与问题无关,请忽略它们。

我的思考过程说在 sendMessage 中有 try-catch 块,所以当我们捕获 UnknownHostException 然后再次重试,但我不确定如何以更安全、更清洁和更好的方式编写它。

所以 MessagingManager 类看起来像这样:

class MessagingManager {

     public void sendMessage(String message) {
           String topic_arn = "arn:of:amazon:sns:topic";
           try {
               SimpleNotificationService.publishMessage(topic_arn, message);
           } catch (UnknownHostException uhe) { 
               // I need to catch AmazonClientException as aws throws
               //AmazonClientException when sees UnknownHostException. 
               // I am mentioning UnknownHostException for non-aws user to understand
               // my problem in better way.
               sendMessage(message); // Isn't unsafe? - may falls into infinite loop
           }
     }
}

我愿意接受这样的答案:java.net.UnknownHostException: Invalid hostname for server: local但我担心的是依赖于应用程序代码级别的解决方案,而不是依赖于对机器的更改。因为我的服务器应用程序将在许多盒子(开发盒子、测试盒子或生产盒子)中运行。如果机器主机文件等的更改只是有保证的解决方案,那么我更喜欢将其包含在代码级别的更改中。

4

2 回答 2

3

每个 AWS 开发工具包都实施自动重试逻辑。AWS SDK for Java 自动重试请求,您可以使用 ClientConfiguration 类配置重试设置。

下面是创建 SNS 客户端的示例。如果遇到 UnKnownHostException,它会重试 25 次。它使用默认的 BackOff 和重试策略。如果你想拥有自己的,那么你需要实现这两个接口:http ://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/retry/RetryPolicy.html

private void static createSnsClient() {
    Region region = Region.getRegion(Regions.AP_SOUTHEAST_1);
    AWSCredentials credentials = new 
            BasicAWSCredentials(AwsPropertyLoader.getInstance().getAccessKey(),        
                    AwsPropertyLoader.getInstance().getSecretKey());
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        clientConfiguration.setMaxErrorRetry(25);
        clientConfiguration.setRetryPolicy(new RetryPolicy(null, null, 25, true));
        mSnsClient = new AmazonSNSClient(credentials, clientConfiguration);
        mSnsClient.setRegion(region);
}
于 2014-03-03T11:18:18.773 回答
0

您是否考虑查看 DNS 缓存的 JVM TTL?

http://docs.aws.amazon.com/AWSSdkDocsJava/latest//DeveloperGuide/java-dg-jvm-ttl.html

于 2015-03-20T15:02:33.183 回答