Хранилище параметров AWS: AWSSimpleSystemsManagementException: превышена скорость - PullRequest
1 голос
/ 01 апреля 2019

На данный момент мне нужно получить последние 10 значений некоторых параметров в хранилище параметров AWS

Я использую следующий код в kotlin:

    val p1 = retrieveAllValidVersions("P1")
    val p2 = retrieveAllValidVersions("P2")
    val p3 = retrieveAllValidVersions("P3")

Вот код полученияAllValidVersions

    private fun retrieveAllValidVersions(paramName: String): List<ParameterHistory> {
        val res = mutableListOf<ParameterHistory>()
        val ssmClient = AWSSimpleSystemsManagementClientBuilder.defaultClient()
        var nextToken : String? = null
        do {
            val ssmParams = ssmClient.getParameterHistory(GetParameterHistoryRequest()
                    .withName(paramName)
                    .withWithDecryption(true)
                    .withNextToken(nextToken)
            )
            res.addAll(ssmParams.parameters)
            nextToken = ssmParams.nextToken
        } while (nextToken != null)


        return validVersions.sortedByDescending { it.version }.take(10)
    }

Как описано в https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#limits_ssm,, максимальное количество версий для параметра составляет 100

И, как описано в https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_GetParameterHistory.html,, вы можете получить только 50 значений в maxResults, поэтому мне нужно сделать 2 вызова для каждого параметра (потому что у меня более 50 версий)

Таким образом, каждый поиск 3 моих параметров стоит 6 запросов к SSM

Я кеширую последние 10 значений каждого параметра в памяти на 5 минут

Проблема в том, что, когда несколько экземпляров моих лямбдодов истекают из своего кэша в одно и то же время, они выполняют поиск одновременно и

com.amazonaws.services.simplesystemsmanagement.model.AWSSimpleSystemsManagementException: Rate exceeded (Service: AWSSimpleSystemsManagement; Status Code: 400; Error Code: ThrottlingException; Request ID: xxx)

Например, если речь идет о 3 экземплярах, это сделает 18 запросов менее чем за секунду, и я обнаружу ошибку (примечание: я точно не знаю, равно ли количество экземпляров, которые одновременно обращаются к этому коду) 3, это всего лишь предположение, иллюстрирующее, что в какой-то момент вы нажали ошибку)

Итак, у меня есть 2 вопроса:

Во-первых, есть ли способ сначала извлечь последние версии параметра?

Таким образом, я сделаю половину запросов, чтобы реже решать проблему!

Во-вторых, как мне автоматически повторить ошибку регулирования?

Я нашел этот пост в блоге AWS [1], в котором говорится, что мне нужно разобрать сообщение об ошибке, но это старый пост (2013), и это очень уродливо (в момент, когда AWS меняет сообщение, весь механизм рушится)!

[1]: https://aws.amazon.com/fr/blogs/messaging-and-targeting/how-to-handle-a-throttling-maximum-sending-rate-exceeded-error/

Последнее замечание: я использую хранилище параметров с «автошифрованием» и IAM, я не хочу ни хранить параметры в своей собственной базе данных, ни кэшировать их в кеше общей памяти, как redis!

1 Ответ

0 голосов
/ 02 апреля 2019

Я нашел решение / обходной путь, которым я поделюсь здесь.

Пожалуйста, не стесняйтесь комментировать, если вы найдете лучший способ!

TL; DR: обходной путь работает, потому что он делает только 1 запрос к SSM (на лямбду) вместо 6 благодаря рекурсиву GetParametersByPath вместо GetParameterHistory.

Итак, чтобы упростить мой вариант использованиябыло хранить секрет для шифрования токена и использовать его в течение 10 часов.

Примечание: IRL, я использую 3 разных секрета, следовательно, P1, P2, P3 в вопросе.Далее я буду упрощать и говорить только об 1 секрете, поскольку он работает аналогично для любого количества секретов (пока вы не достигнете максимального количества параметров в SSM, которое составляет 10K ...)

Ранее оно работало какэто: я вращаю секрет каждый час, я дешифрую токен против последних 10 версий -> если пользователь отправляет токен, которому 11 часов или больше, я больше не могу расшифровать его.

Теперь вместоимея один параметр с несколькими версиями, у меня есть несколько параметров, из которых безопасно использовать только последнюю версию.

Мое хранилище параметров SSM ранее выглядело (для каждого параметра)

/secret/P1

А теперь это выглядит как

/secrets/P1/s1 -> a secret
/secrets/P1/s2 -> a secret
...
/secrets/P1/s10 -> a secret
/secrets/P1/current -> s4 

Мой код теперь выполняет GetParametersByPath ("/ secrets") с рекурсией, чтобы получить в одном запросе все действительные секреты для всех параметров (то есть P1, P2, P3).

Таким образом, каждая лямбда выполняет один запрос, есть небольшой шанс нажать RateExceeded.

Когда клиент отправляет токен, я пытаюсьpt против 10 текущих секретов.

Секретное вращение изменилось на: получить / текущий и изменить следующий (т. е. если ток равен s4, мы изменим s5 и установим / current на s5)

В качестве последнего замечания, я также реализовал улучшение, которое заключается в добавлении / токе в токен (незашифрованный).

При этом мне не нужно проверять 10 секретов, а только тот, который содержится втокен.

Обратите внимание, что я мог бы сделать это улучшение раньше (отправив незашифрованный номер версии в токене), я просто не думал об этом раньше.

Надеюсь, это кому-то поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...