- Оригинальный адрес:Courier: Dropbox migration to gRPC
- Оригинальный автор:blogs.dropbox.com
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:kasheemlew
- Корректор:shixi-li
Dropbox запускает сотни сервисов, написанных на разных языках, которые обмениваются миллионами запросов в секунду. В центре нашей сервис-ориентированной архитектуры находится Courier, наша платформа удаленного вызова процедур (RPC) на основе gRPC. В ходе разработки Courier мы многое узнали о расширении RPC и оптимизации производительности, а также о сопряжении с устаревшими системами RPC.
Примечание. В этой статье показаны только примеры сгенерированного кода для Python и Go. Мы также поддерживаем Rust и Java.
The road to gRPC
Courier — не первая RPC-инфраструктура Dropbox. Прежде чем мы официально начали разбивать огромную программу Python на несколько сервисов, мы поняли, что связь между сервисами должна иметь прочную основу, поэтому выбор высоконадежной RPC-инфраструктуры особенно важен.
Прежде чем приступить к работе, Dropbox изучил несколько фреймворков RPC. Во-первых, мы начинаем с традиционного протокола ручной сериализации и десериализации, такого как мы используемApache ThriftпостроенКонвейер ведения журналов на основе Scribeтакие услуги. Но наш основной фреймворк RPC (традиционный RPC) основан на протоколе HTTP/1.1 и использует protobuf для кодирования сообщений.
Есть несколько кандидатов для нашего нового фреймворка. Мы можем обновить устаревшие фреймворки RPC, чтобы они были совместимы с Swagger (теперь он называетсяOpenAPI),илиустановить новые стандарты, также можно рассмотреть разработку на базе Thrift и gRPC.
В итоге мы выбрали gRPC главным образом потому, что он позволил нам придерживаться protobuf. В нашем случае также привлекательны несколько транспортов HTTP/2 и двунаправленная потоковая передача.
Если бы былиfbthriftЕсли это так, мы могли бы присмотреться к решениям на основе Thrift.
Что Courier привносит в gRPC
Courier — это не новый протокол RPC — это просто решение Dropbox для совместимости с gRPC и устаревшей инфраструктурой. Например, это будет работать только при использовании указанной версии аутентификации, авторизации и обнаружения служб. Он также должен быть совместим с нашей статистикой, регистрацией событий и инструментами отслеживания. Выполнение всех этих условий и есть то, что мы называем Курьером.
Хотя мы поддерживаем использование в некоторых особых случаяхBandaidДействует как прокси-сервер gRPC, но для уменьшения задержки RPC в большинстве случаев взаимодействия между службами прокси-сервер не используется.
Мы хотим уменьшить количество шаблонов, которые необходимо написать. В качестве общей основы для разработки наших услуг Courier обладает всеми функциями, которые необходимы сервису. Большинство функций включены по умолчанию и ими можно управлять с помощью аргументов командной строки. Некоторые также могут быть динамически включены с помощью флагов функций.
Безопасность: идентификация службы и взаимная аутентификация TLS
Courier реализует наш стандартный механизм идентификации службы. И наши серверы, и клиенты имеют собственные сертификаты TLS, которые выдаются нашим внутренним органом. Каждый сервер и клиент также имеют удостоверение, зашифрованное с помощью этого сертификата для взаимной аутентификации между ними.
Мы контролируем оба конца связи на стороне TLS и применяем некоторые ограничения по умолчанию. Внутренняя связь RPC обязательна для использованияPFSшифрование. Версия TLS зафиксирована на уровне 1.2+. Мы также ограничиваем шифрование безопасным подмножеством симметричных/асимметричных алгоритмов, которые здесь предпочтительны.
ECDHE-ECDSA-AES128-GCM-SHA256
.
После завершения аутентификации и декодирования запроса сервер выполнит проверку авторизации на клиенте. Списки контроля доступа (ACL) и ограничение скорости могут быть установлены как на уровне службы, так и в автономном режиме, а также могут быть обновлены с помощью нашей системы распределенной конфигурации (AFS). Таким образом, даже если диспетчер служб не перезапустит процесс, разгрузка может быть завершена за несколько секунд. Подписка на уведомления и обновление конфигурации осуществляется фреймворком Courier.
«Идентификация» службы — это глобальный идентификатор, используемый для ACL, ограничения скорости, статистики и т. д. Кроме того, он также криптографически безопасен.
нашОптическое распознавание символов (OCR)В сервисе есть пример такого определения конфигурации Courier ACL/Rate Limit:
limits:
dropbox_engine_ocr:
# 所有的 RPC 方法。
default:
max_concurrency: 32
queue_timeout_ms: 1000
rate_acls:
# OCR 客户端无限制。
ocr: -1
# 没有其他人与我们通信。
authenticated: 0
unauthenticated: 0
мы рассматриваем возможность использованияКонцепция безопасной производственной маркировки, которой должен пользоваться каждыйSPIFFE в (SPIFFE) Поддающийся проверке документ, удостоверяющий личность. Это сделает нашу структуру RPC совместимой с многочисленными проектами с открытым исходным кодом.
Наблюдаемость: статистика и отслеживание
Благодаря идентификации мы можем легко найти стандартные журналы, статистику, записи и другую полезную информацию, относящуюся к курьерской службе.
Наша генерация кода добавляет статистику к каждому сервису и методу на клиенте и сервере. Статистика на стороне сервера классифицируется по идентификаторам на стороне клиента. Детальная атрибуция нагрузки, ошибок и задержек для каждой службы Courier работает «из коробки».
Статистика Courier включает доступность на стороне клиента, задержку, частоту запросов на стороне сервера и размеры очередей. Существуют также различные классификации, такие как гистограммы задержек на запрос, рукопожатия TLS на клиента и т. д.
Одним из преимуществ собственной генерации кода является то, что мы можем статически инициализировать эти структуры данных, включая гистограммы и диапазоны трассировки. Это снижает влияние на производительность.
Наши традиционные RPC работают только на границах APIrequest_id
, поэтому логи можно добавлять из разных сервисов. В Курьере мы используемOpenTracingСобранный API подмножества спецификации. На клиенте мы написали свою библиотеку, на сервере мы опираемся на Cassandra иJaegerразвивать. Нам нужна отдельная статья о том, как оптимизировать работу этой системы отслеживания.
Трассировка позволяет нам создать граф зависимостей службы во время выполнения, который помогает инженерам понять все транзитивные зависимости службы и может использоваться для проверки и предотвращения ненужных зависимостей после развертывания.
Надежность: сроки и пределы разомкнутой цепи
Courier централизованно управляет всеми языковыми функциями на стороне клиента, такими как тайм-ауты. Со временем мы также добавили в этот слой такие функции, как проверенные элементы задач.
Срок
каждыйgRPC запрос содержит Срок, используется для указания того, как долго клиент ожидает ответа. Поскольку Courier автоматически передает все известные метаданные, сроки могут существовать только в запросах, даже через границы API. В ходе процесса сроки переводятся в конкретные представления. Например, в Go вы должны использоватьWithDeadline
возвращаемая структура методаcontext.Context
выражать.
На практике мы просим инженеров включать сроки в определение услуг, чтобы все классы были надежными.
Этот контекст может быть передан даже за пределы уровня RPC! Например, наша традиционная MySQL ORM сериализует контекст RPC и крайние сроки в комментарии для SQL-запросов, а наш SQLProxy может анализировать эти комментарии и, после превышения крайних сроков,
杀死
эти запросы. Дополнительным преимуществом является то, что мы можем найти причину каждого запроса при отладке запроса к базе данных.
предел разомкнутой цепи
Другая распространенная проблема заключается в том, что традиционные RPC-клиенты должны реализовывать пользовательскую экспоненциальную отсрочку и дрожание при повторных попытках.
В Courier мы хотели более общий подход к проблеме предела выключателя, поэтому использовали очередь LIFO между слушателем и рабочим пулом.
Эта очередь LIFO работает как автоматический выключатель, когда служба перегружена. Мало того, что эта очередь имеет ограничение по размеру, она также имеет более строгие правила.лимит времени. Запрос может находиться в очереди только указанное время.
LIFO имеет недостатки в запросах на заказ. Если вы хотите поддерживать порядок, вы можете попробоватьCoDel. Он также имеет функцию ограничения автоматического выключателя и не нарушает порядок запросов.
Самоанализ: отладка конечных точек
Конечные точки отладки широко используются в Dropbox, хотя и не являются частью самого Courier. Они настолько полезны, что я не могу не упомянуть их! Вот несколько примеров полезного самоанализа.
Из соображений безопасности вы можете захотеть открыть для них отдельный порт (возможно, просто петлевой интерфейс) или даже сокет Unix (который можно контролировать с помощью файловой системы Unix). Вам также обязательно следует рассмотреть возможность использования взаимной аутентификации TLS, требуя от разработчиков предоставления свои учетные данные при доступе к конечным точкам отладки (особенно тем, которые не доступны только для чтения).
Время выполнения
Возможность видеть состояние во время выполнения очень полезна. НапримерФайлы кучи и ЦП могут быть представлены как конечные точки HTTP или gRPC..
Мы намерены использовать этот метод для автоматизации сравнения старой и новой версий кода на этапе проверки оттенков серого.
Эти конечные точки отладки позволяют изменять состояние во время выполнения, например, служба, разработанная в golang, может быть динамически установлена.GCPercent.
библиотека
Авторам библиотек полезно динамически экспортировать некоторые данные, относящиеся к библиотеке, в качестве конечных точек RPC.Библиотека malloc сбрасывает внутреннее состояниехороший пример.
RPC
Учитывая, что устранение неполадок с зашифрованными и двоично-кодированными протоколами немного сложно, вам следует добавить столько инструментов на уровень RPC, сколько позволяет производительность. Недавний пример такого API самоанализа:Предложение gRPC по каналам.
применение
Также полезно посмотреть параметры на уровне API. Хорошим примером является использование хэшей сборки/источника, командных строк и т. д. для общих конечных точек информации о приложении. Система оркестрации может использовать эту информацию для проверки согласованности развертывания службы.
оптимизация производительности
При масштабировании gRPC в Dropbox мы обнаружили множество узких мест в производительности.
Накладные расходы на рукопожатие TLS
Поскольку служба обрабатывает большое количество подключений, накопленные накладные расходы на рукопожатие TLS не являются незначительными. Это особенно верно во время крупномасштабных перезапусков службы.
Чтобы повысить производительность операции подписи, мы заменили пару ключей RSA 2048 на ECDSA P-256. Вот пример производительности BoringSSL (хотя RSA все еще немного быстрее, чем проверка подписи):
RSA:
𝛌 ~/c0d3/boringssl bazel run -- //:bssl speed -filter 'RSA 2048'
Did ... RSA 2048 signing operations in .............. (1527.9 ops/sec)
Did ... RSA 2048 verify (same key) operations in .... (37066.4 ops/sec)
Did ... RSA 2048 verify (fresh key) operations in ... (25887.6 ops/sec)
ECDSA:
𝛌 ~/c0d3/boringssl bazel run -- //:bssl speed -filter 'ECDSA P-256'
Did ... ECDSA P-256 signing operations in ... (40410.9 ops/sec)
Did ... ECDSA P-256 verify operations in .... (17037.5 ops/sec)
С точки зрения производительности аутентификация RSA 2048 примерно в 3 раза быстрее, чем ECDSA P-256, поэтому вы можете рассмотреть возможность использования RSA для корневых/конечных сертификатов. Однако с точки зрения безопасности переключение примитивов безопасности может быть затруднено и обеспечивает минимальные свойства безопасности. Также, учитывая производительность, следует дважды подумать, прежде чем использовать сертификаты RSA 4096 (или выше).
Мы также обнаружили, что библиотеки TLS (и флаги сборки) сильно влияют на производительность и безопасность. Например, ниже сравнивается сборка LibreSSL для MacOS X Mojave и самодельный OpenSSL на одном и том же оборудовании:
LibreSSL 2.6.4:
𝛌 ~ openssl speed rsa2048
LibreSSL 2.6.4
...
sign verify sign/s verify/s
rsa 2048 bits 0.032491s 0.001505s 30.8 664.3
OpenSSL 1.1.1a:
𝛌 ~ openssl speed rsa2048
OpenSSL 1.1.1a 20 Nov 2018
...
sign verify sign/s verify/s
rsa 2048 bits 0.000992s 0.000029s 1208.0 34454.8
Но самый быстрый способ — не использовать рукопожатие TLS! Для поддержки возобновления сеанса,Мы модифицировали gRPC-core и gRPC-python, что снижает нагрузку на ЦП при запуске службы.
Накладные расходы на шифрование не высоки
Существует распространенное заблуждение, что шифрование стоит дорого. На самом деле симметричное шифрование довольно быстро работает на современном оборудовании. Процессор настольного класса может шифровать и аутентифицировать со скоростью 40 Гбит/с, используя одно ядро.
𝛌 ~/c0d3/boringssl bazel run -- //:bssl speed -filter 'AES'
Did ... AES-128-GCM (8192 bytes) seal operations in ... 4534.4 MB/s
Тем не менее, в итоге мы адаптировали gRPC к нашимЯщик для хранения 50Gb/s. Мы узнали, что когда скорость шифрования сравнима со скоростью копирования в память, снижениеmemcpy
Количество операций имеет решающее значение. Кроме того, мыМодификации также были внесены в сам gRPC.
Протоколы аутентификации и шифрования имеют некоторые каверзные проблемы. Например, повреждение процессора, DMA и сетевых данных. Даже если вы не используете gRPC, рекомендуется использовать TLS для внутренней связи.
Ссылка на продукт с высокой пропускной способностью
Dropbox владеетБольшое количество центров обработки данных, связанных магистральной сетью. Иногда узлам в разных регионах может потребоваться обмен данными с помощью RPC, например, для репликации. Ядро, использующее TCP, должно ограничивать определенные соединения (ограничено до/proc/sys/net/ipv4/tcp_{r,w}mem
) данных в пути. Поскольку gRPC основан на HTTP/2, он также имеет собственное уникальное управление потоком поверх TCP.Верхний предел BDP жестко запрограммирован в grpc-go весит 16 Мб., что может стать узким местом для одного соединения с высоким BDP.
Сравнение Golang net.Server и grpc.Server
В нашем коде Go мы изначально поддерживали HTTP/1.1 и gRPC, используя один и тот жеnet.Server. Логически это имеет смысл, но работает не очень хорошо. Разделите HTTP/1.1 и gRPC на разные пути, управляйте разными серверами и замените gRPC наgrpc.ServerЗначительно улучшена пропускная способность и объем памяти службы Courier.
Сравнение golang/protobuf и gogo/protobuf
Маршаллинг и демаршаллинг могут быть дорогими, если вы используете gRPC. Для нашего кода Go мы использовалиgogo/protobuf, что значительно снижает нагрузку на ЦП на наших самых загруженных серверах Courier.
такой же,Есть также некоторые предостережения при использовании gogo/protobuf., но придерживаться нормального подмножества функций должно быть хорошо.
детали реализации
Отсюда мы углубимся во внутренности Courier, чтобы увидеть примеры шаблонов protobuf и заглушек на разных языках. Во всех приведенных ниже примерах будет использоваться нашTest
Сервисы (мы используем это в Courier для интеграционного тестирования)
Описание услуг
service Test {
option (rpc_core.service_default_deadline_ms) = 1000;
rpc UnaryUnary(TestRequest) returns (TestResponse) {
option (rpc_core.method_default_deadline_ms) = 5000;
}
rpc UnaryStream(TestRequest) returns (stream TestResponse) {
option (rpc_core.method_no_deadline) = true;
}
...
}
В главе об удобстве использования мы упомянули, что все методы Courier должны иметь крайние сроки. Всю службу можно настроить с помощью следующих опций protobuf.
option (rpc_core.service_default_deadline_ms) = 1000;
Крайние сроки также можно установить индивидуально для каждого метода и переопределить настройки всей службы (если они есть).
option (rpc_core.method_default_deadline_ms) = 5000;
В тех редких случаях, когда крайний срок действительно бесполезен (например, способ мониторинга ресурса), разработчик может явно отключить его:
option (rpc_core.method_no_deadline) = true;
Настоящее определение службы будет иметь подробную документацию по API и даже примеры использования.
генерация заглушки
Courier не полагается на перехватчики (за исключением Java, чей API-интерфейс перехватчика достаточно мощный) и генерирует собственные заглушки, что дает нам большую гибкость. Давайте сравним нашу заглушку с заглушкой Golang по умолчанию.
Вот заглушка сервера gRPC по умолчанию:
func _Test_UnaryUnary_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(TestRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TestServer).UnaryUnary(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/test.Test/UnaryUnary",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TestServer).UnaryUnary(ctx, req.(*TestRequest))
}
return interceptor(ctx, in, info, handler)
}
Здесь вся обработка происходит в одну строку: декодировать protobuf, запустить перехватчик, вызватьUnaryUnary
процессор.
Давайте еще раз посмотрим на заготовку Courier:
func _Test_UnaryUnary_dbxHandler(
srv interface{},
ctx context.Context,
dec func(interface{}) error,
interceptor grpc.UnaryServerInterceptor) (
interface{},
error) {
defer processor.PanicHandler()
impl := srv.(*dbxTestServerImpl)
metadata := impl.testUnaryUnaryMetadata
ctx = metadata.SetupContext(ctx)
clientId = client_info.ClientId(ctx)
stats := metadata.StatsMap.GetOrCreatePerClientStats(clientId)
stats.TotalCount.Inc()
req := &processor.UnaryUnaryRequest{
Srv: srv,
Ctx: ctx,
Dec: dec,
Interceptor: interceptor,
RpcStats: stats,
Metadata: metadata,
FullMethodPath: "/test.Test/UnaryUnary",
Req: &test.TestRequest{},
Handler: impl._UnaryUnary_internalHandler,
ClientId: clientId,
EnqueueTime: time.Now(),
}
metadata.WorkPool.Process(req).Wait()
return req.Resp, req.Err
}
Здесь много кода, давайте рассмотрим его построчно.
Во-первых, мы откладываем аварийные обработчики для сбора ошибок. Это позволяет отправлять неперехваченные исключения в централизованное место для последующей агрегации и составления отчетов:
defer processor.PanicHandler()
Еще одна причина иметь собственный обработчик паники — гарантировать, что мы завершим приложение в случае ошибки. Поведение обработчика HTTP golang/net по умолчанию заключается в игнорировании этих ошибок и продолжении обработки новых запросов (что может привести к сбоям и несогласованному состоянию).
Затем мы передаем контекст, переопределяя значение в метаданных запроса:
ctx = metadata.SetupContext(ctx)
clientId = client_info.ClientId(ctx)
Мы также добавили статистику по каждому клиенту на стороне сервера для более точной атрибуции:
stats := metadata.StatsMap.GetOrCreatePerClientStats(clientId)
Это динамически добавляет статистику к каждому клиенту (то есть к каждому идентификатору TLS) во время выполнения. Также будет статистика для каждого метода каждой службы, а поскольку генератор заглушек имеет доступ ко всем методам при генерации кода, мы можем добавить их статически, чтобы избежать накладных расходов во время выполнения.
Затем мы создаем структуру запроса, передаем ее в рабочий пул и ждем ее завершения.
req := &processor.UnaryUnaryRequest{
Srv: srv,
Ctx: ctx,
Dec: dec,
Interceptor: interceptor,
RpcStats: stats,
Metadata: metadata,
...
}
metadata.WorkPool.Process(req).Wait()
Обратите внимание, что вся работа не сделана прямо сейчас: не декодируется protobuf, не выполняются перехватчики и т.д. При использовании списков ACL в рабочих пулах приоритеты и ограничение скорости выполняются до этого.
Уведомление,поддержка библиотеки golang gRPCэто Коснитесь интерфейса, что делает возможным перехват начального запроса и обеспечивает основу для создания эффективного и недорогого контроллера скорости.
Коды ошибок для конкретных приложений
Наш генератор заглушек позволяет разработчикам определять коды ошибок для конкретных приложений с помощью настраиваемых параметров.
enum ErrorCode {
option (rpc_core.rpc_error) = true;
UNKNOWN = 0;
NOT_FOUND = 1 [(rpc_core.grpc_code)="NOT_FOUND"];
ALREADY_EXISTS = 2 [(rpc_core.grpc_code)="ALREADY_EXISTS"];
...
STALE_READ = 7 [(rpc_core.grpc_code)="UNAVAILABLE"];
SHUTTING_DOWN = 8 [(rpc_core.grpc_code)="CANCELLED"];
}
В одном и том же сервисе распространяются ошибки gRPC и приложения, но все ошибки заменяются на UNKOWN на границе API. Это позволяет избежать проблемы случайных ложных прокси-серверов между различными службами, изменяя семантическое значение.
Модификации для Python
Мы добавляем явные параметры контекста ко всем обработчикам Courier в заглушке Python, например:
from dropbox.context import Context
from dropbox.proto.test.service_pb2 import (
TestRequest,
TestResponse,
)
from typing_extensions import Protocol
class TestCourierClient(Protocol):
def UnaryUnary(
self,
ctx, # 类型:Context
request, # 类型:TestRequest
):
# 类型: (...) -> TestResponse
...
Поначалу это казалось странным, но потом разработчики привыкли к явномуctx
, как привыклиself
Такой же.
Обратите внимание, что все наши заглушки также относятся к типу mypy, что хорошо окупается при масштабном рефакторинге. И mypy уже хорошо интегрирован в такие IDE, как PyCharm.
Продолжая тенденцию статической типизации, мы также можем добавить аннотации из mypy в proto.
class TestMessage(Message):
field: int
def __init__(self,
field : Optional[int] = ...,
) -> None: ...
@staticmethod
def FromString(s: bytes) -> TestMessage: ...
Эти аннотации позволяют избежать многих распространенных уязвимостей, таких как добавлениеNone
назначить в Pythonstring
поле.
Эти коды находятся вdropbox/mypy-protobufОткрытый источник.
Процесс миграции
Написание нового стека RPC — непростая задача, но с точки зрения операционной сложности он все же не сравнится с межобластной миграцией. Чтобы обеспечить успех проекта, мы стараемся упростить процесс миграции разработчиков с традиционного RPC на Courier. Поскольку миграция сама по себе является процессом, подверженным ошибкам, мы решили выполнить ее в несколько этапов.
Шаг 0. Заморозьте традиционный RPC
Прежде чем начать, мы заморозим набор функций традиционного RPC, чтобы он не менялся. Таким образом, люди будут более склонны переходить на Courier, поскольку новые функции, такие как отслеживание и потоковая передача, доступны только в службах Courier.
Шаг 1: Общий интерфейс для традиционных RPC и Courier
Начнем с определения общего интерфейса для традиционных RPC и Courier. Наша генерация кода генерирует заглушки для обеих версий интерфейса:
type TestServer interface {
UnaryUnary(
ctx context.Context,
req *test.TestRequest) (
*test.TestResponse,
error)
...
}
Шаг 2. Перейдите на новый интерфейс
Затем мы переключили каждую службу на новый интерфейс, но по-прежнему использовали традиционный RPC. Как правило, это имеет большое значение для методов во всех службах и клиентах. Этот процесс подвержен ошибкам, и для сведения к минимуму риска мы изменяем только один параметр за раз.
Есть только несколько способов справиться иАльтернативный бюджет ошибокМиграцию низкоуровневых служб можно выполнить за один шаг, независимо от этого предупреждения.
Шаг 3. Переключите клиентов на Courier RPC
В рамках перехода на Courier нам нужно было запускать как старые, так и бинарные файлы сервера Courier на разных портах. Затем измените строку реализации RPC в клиенте.
class MyClient(object):
def __init__(self):
- self.client = LegacyRPCClient('myservice')
+ self.client = CourierRPCClient('myservice')
Обратите внимание, что, используя приведенную выше модель для переноса одного клиента за раз, мы можем начать с более низкого SLA для пакетных процессов и некоторых других асинхронных задач и т. д.
Шаг 4: Очистка
После миграции всех клиентов службы нам необходимо доказать, что традиционный RPC больше не используется (это можно сделать статически, проверив код, или динамически, проверив традиционную статистику сервера). продолжить очистку и удалить старый код.
уроки выучены
В конце концов, Courier предлагает нам единую структуру RPC, которая ускоряет разработку сервисов, упрощает операции и повышает надежность Dropbox.
Здесь мы суммируем основные уроки, извлеченные из разработки и развертывания Courier:
- Наблюдаемость — это свойство. Все готовые метрики и сбои бесценны при устранении неполадок.
- Важны стандартизация и последовательность. Они снижают когнитивный стресс и упрощают операции и обслуживание кода.
- Постарайтесь свести к минимуму шаблонный код, который необходимо написать разработчикам кода. Генератор кодов — ваш партнер.
- Постарайтесь сделать миграцию максимально простой. Миграция обычно занимает больше времени, чем разработка. При этом миграция не заканчивается, пока не завершится процесс очистки.
- Улучшения надежности всей инфраструктуры, такие как установление сроков, защита от перегрузок и т. д., могут быть реализованы в среде RPC. Общие проблемы с надежностью можно выявить с помощью ежеквартальных отчетов об инцидентах.
Перспективы работы
Как Courier, так и gRPC сами по себе постоянно меняются, поэтому давайте в заключение подведем итоги того, что делают группы времени выполнения и надежности.
В ближайшем будущем мы добавим правильный API парсера в код Python gRPC, переключимся на привязки C++ в Python/Rust и добавим поддержку полного управления автоматическим выключателем и внедрения ошибок. В следующем году мы собираемся исследоватьALTS и перенести рукопожатие TLS в отдельный процесс(Возможно, даже отдельно от служебного контейнера.)
Мы нанимаем!
Вы хотите выполнять работу, связанную с выполнением? Небольшие команды Dropbox в Маунтин-Вью и Сан-Франциско отвечают за глобально распределенную пограничную сеть, мегабитный трафик, миллионы запросов в секунду.
Команды по трафику/среде выполнения/надежности нанимают SWE и SRE, отвечающий за разработку обработчиков пакетов TCP/IP и балансировщиков нагрузки, прокси-серверов HTTP/gRPC и нашей внутренней сетки сервисов времени выполнения: Courier/gRPC, обнаружение сервисов и AFS. Чувствуете себя не на своем месте? мыОфисы в Сан-Франциско, Нью-Йорке, Сиэтле, Телави и др., а также позиции во всех направлениях.
Благодарность
участник проекта: Ашвин Амит, Джан Берк Гудер, Дэйв Збарски, Джианг Нгуен, Мехрдад Афшари, Патрик Ли, Росс Делинджер, Руслан Нигматуллин, Расс Олбери и Сантош Анантакришнан.
Также большое спасибо команде gRPC за их поддержку.
Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.