Я пишу HTTP-сервер для обработки API сканирования Cisco Meraki. Это push-API, в котором Cisco периодически вызывает вашу конечную точку с помощью запроса POST и тела JSON. API должен быть в состоянии ответить на этот запрос POST менее чем за 500 мс. Если нет, Cisco прекратит отправку вам данных, и вы не сможете восстановить эту информацию.
Итак, я искал способы обработать эти запросы как можно быстрее.
Первым делом я отделил обработку тела JSON с помощью очереди. Я беру тело из запроса, помещаю его в очередь и отвечаю. Затем несколько рабочих будут обрабатывать тело и асинхронно сохранять его на S3. Я также попытался сделать сервер максимально простым.
Большинство запросов работают менее чем за 500 мс, но некоторые - нет. Глядя на то, где я нахожусь, единственное, что приходит в голову, чтобы улучшить это время, это быстрее обработать тело запроса.
Весь сервер доступен по этой ссылке: meraki_endpoint.go . И вот как я сейчас обрабатываю тело запроса:
func handleData(w http.ResponseWriter, r *http.Request, jobs chan job) {
var devicesSeen DevicesSeen
// I am using "github.com/json-iterator/go" instead of "encoding/json"
err := json.NewDecoder(r.Body).Decode(&devicesSeen)
if err != nil {
http.Error(w, "Bad request - Can't Decode!", 400)
panic(err)
}
// Create Job and push the work into the Job Channel
go func() {
jobs <- job{devicesSeen}
}()
// Render success
w.WriteHeader(http.StatusAccepted)
}
В данный момент я декодирую JSON при чтении из тела вместо чтения и сохраняю его как список байтов, используя ioutil.ReadAll(r.Body)
. Попробовав оба пути, я не смог найти существенного улучшения скорости.
Как я могу улучшить производительность сервера? Или как я могу быстрее прочитать тело запроса, чтобы потом работать с ним в очереди?
Редактировать # 1
Я переместил свой стек в другой регион AWS, ближе к источнику данных, и время туда и обратно сократилось до одной пятой от того, что было раньше.