У меня есть сервер, который делает частые вызовы к микросервисам (фактически, функции AWS Lambda написаны на python) с необработанными данными JSON и ответами порядка 5-10 МБ. Эти полезные данные сжаты, чтобы привести их общий размер к пределу 6 МБ лямбды.
В настоящее время полезные данные сериализуются в JSON, распаковываются и отправляются в Lambda. Затем ответы распаковываются и десериализуются из JSON обратно в Java POJO.
Посредством профилирования мы обнаружили, что этот процесс сериализации, gzipping, gunzipping и deserializaing является основной нагрузкой на большинство наших серверов. Поиск путей повышения эффективности сериализации привел меня к protobufs.
Переключение нашей сериализации с JSON на protobufs, безусловно, сделает нашу (де) сериализацию более эффективной, а также может иметь дополнительное преимущество, заключающееся в устранении необходимости gzip для получения полезных нагрузок менее 6 МБ (задержка сети здесь не имеет значения).
Указанные POJO выглядят примерно так (Java):
public class InputObject {
... 5-10 metadata fields containing primitives or other simple objects ...
List<Slots> slots; // usually around 2000
}
public class Slot {
public double field1; //20ish fields with a single double
public double[] field2; //10ish double arrays of length 5
public double[][] field3; //1 2x2 matrix of doubles
}
С JSON это очень просто, gson.toJson(inputObj)
и все готово. Protobufs кажутся совершенно другим зверем, требующим от вас использования сгенерированных классов и засорения вашего кода такими вещами, как
Blah blah = Blah.newBuilder()
.setFoo(f)
.setBar(b)
.build()
Кроме того, в результате получается неизменный объект, для обновления которого требуется больше прыжков с обручем. Просто кажется плохой вещью помещать весь этот зависимый от транспортного уровня код в бизнес-логику.
Я видел, как некоторые люди рекомендуют писать обертки вокруг сгенерированных классов, чтобы вся протобуфинг не проникала в остальную часть кода, и это казалось хорошей идеей. Но тогда я не уверен, как можно сериализовать верхний уровень InputObject
за один раз.
Возможно, protobufs не является подходящим инструментом для этой работы, но кажется, что это идеальное решение для межсервисного общения, когда вы начинаете смотреть на повышение эффективности.
Я что-то упустил?