В течение последних 6 месяцев мы в Micro много работали над созданием глобальной сервисной сети для создания, совместного использования и совместной работы над микросервисами.

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

Мотивации

Возможности совместной разработки в значительной степени ограничены доверенными средами внутри организаций. Если все сделано правильно, эти частные внутренние платформы открывают невероятную производительность и увеличивают ценность с каждой добавленной услугой. Они обеспечивают постоянную среду выполнения и известный рабочий процесс разработчика, чтобы инженеры могли сотрудничать и предоставлять новые функции своим клиентам.

Исторически этого было довольно сложно достичь вне организаций. Когда разработчики решают работать над новыми сервисами, им часто приходится иметь дело с большим количеством ненужной работы, когда дело доходит до предоставления услуг другим для использования и совместной работы. Поставщики общедоступного облака слишком сложны, и сложные настройки при самостоятельном размещении вещей тоже не упрощают задачу. В Микро мы почувствовали эту боль и решили что-то с этим делать. Мы построили сеть микросервисов!

Микросеть пытается решить эти проблемы, используя общую глобальную сеть для микросервисов. Давайте посмотрим, как мы воплотили эту мечту в реальность!

Дизайн

Микросеть - это глобально распределенная сеть, основанная на go-micro, инфраструктуре микросервисов Go, которая позволяет разработчикам быстро создавать сервисы, не обращая внимания на сложность распределенных систем. Go Micro предоставляет строго самоуверенные интерфейсы, которые могут быть заменены, но также имеют нормальные настройки по умолчанию. Это позволяет создавать сервисы Go Micro один раз и развертывать их где угодно без изменения кода.

Микросеть использует пять основных примитивов: реестр, транспорт, брокер, клиент и сервер. Наши реализации по умолчанию можно найти в каждом пакете в рамках go-micro. Плагины, поддерживаемые сообществом, живут в репозитории go-plugins.

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

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

Есть четыре фундаментальных концепции, которые делают возможной микросеть. Они совершенно новые и встроены в Go Micro за последние 6 месяцев:

Туннель - туннелирование точка-точка

Прокси - прозрачное проксирование rpc

Маршрутизатор - агрегация маршрутов и реклама

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

Каждый из этих компонентов такой же, как и любой другой компонент Go Micro - подключаемый, с готовой реализацией по умолчанию для начала. В нашем случае для микросети было важно, чтобы настройки по умолчанию работали в масштабах всего мира.

Давайте углубимся в подробности.

Туннель

С высокой точки зрения микросеть - это оверлейная сеть, охватывающая Интернет. Все узлы микросети поддерживают безопасные туннельные соединения между собой, чтобы обеспечить безопасную связь между службами, работающими в сети. Go Micro предоставляет реализацию туннеля по умолчанию с использованием протокола QUIC вместе с настраиваемым управлением сеансом.

Мы выбрали QUIC, потому что он обеспечивает отличные свойства, особенно когда речь идет о сетях с высокой задержкой, что является важным свойством при работе с работающими службами в больших распределенных сетях. QUIC работает через UDP, но, добавляя некоторую семантику соединения, он поддерживает надежную доставку пакетов. QUIC также поддерживает несколько потоков без блокировки заголовка строки и изначально предназначен для работы с шифрованием. Наконец, QUIC работает в пользовательском пространстве, а не в пространстве ядра в обычных системах, поэтому он может обеспечить как производительность, так и дополнительную безопасность.

Микротуннель использует quic-go, который является наиболее полной Go-реализацией QUIC, которую мы могли найти при создании микросети. Мы знаем, что работа над быстрым переходом еще не завершена, и иногда он может выйти из строя, но мы счастливы оплатить стоимость раннего внедрения, поскольку считаем, что в будущем QUIC станет стандартным протоколом интернет-связи де-факто, позволяя создавать крупномасштабные сети, такие как микросеть.

Давайте посмотрим на интерфейс туннеля Go Micro:

// Tunnel creates a gre tunnel on top of the go-micro/transport.
// It establishes multiple streams using the Micro-Tunnel-Channel header
// and Micro-Tunnel-Session header. The tunnel id is a hash of
// the address being requested.
type Tunnel interface {
	// Address the tunnel is listening on
	Address() string
	// Connect connects the tunnel
	Connect() error
	// Close closes the tunnel
	Close() error
	// Links returns all the links the tunnel is connected to
	Links() []Link
	// Dial to a tunnel channel
	Dial(channel string, opts ...DialOption) (Session, error)
	// Accept connections on a channel
	Listen(channel string, opts ...ListenOption) (Listener, error)
}

Разработчикам Go это может показаться довольно знакомым. В Go Micro мы постарались поддерживать общие интерфейсы в соответствии с разработкой распределенных систем, при этом переходя на более низкий уровень, чтобы решить некоторые мелкие детали.

Мы надеемся, что большинство методов интерфейса не требуют пояснений, но вы можете задаться вопросом о каналах и сеансах. Каналы во многом похожи на адреса, предоставляя способ сегментировать различные потоки сообщений по туннелю. Слушатели прослушивают данный канал и возвращают уникальный сеанс, когда клиент подключается к каналу. Сеанс используется для связи между одноранговыми узлами по одному туннельному каналу. Туннель Go Micro также обеспечивает другую семантику связи. Вы можете выбрать одноадресную или многоадресную рассылку.

Кроме того, туннели позволяют осуществлять двунаправленные соединения; сеансы можно набирать или прослушивать с любой стороны. Это позволяет менять местами соединения, так что все, что находится за NAT или без общедоступного IP-адреса, может стать сервером.

Маршрутизатор

Микро-роутер - важный компонент микросети. Он обеспечивает плоскость маршрутизации сети. Без маршрутизатора мы не знали бы, куда отправлять сообщения. Он создает таблицу маршрутизации на основе реестра локальных служб (компонент Go Micro). Таблица маршрутизации поддерживает маршруты к службам, доступным в локальной сети. С помощью туннеля он также может обрабатывать сообщения из любого другого центра обработки данных или сети, по умолчанию активируя глобальную маршрутизацию.

В нашей реализации таблицы маршрутизации по умолчанию используется простая карта памяти Go, но, как и все в Go Micro, маршрутизатор и таблица маршрутизации являются подключаемыми. По мере масштабирования мы думаем об альтернативных реализациях и даже о возможности динамического переключения в зависимости от размера сетей.

Интерфейс роутера Go Micro выглядит следующим образом:

// Router is an interface for a routing control plane
type Router interface {
	// The routing table
	Table() Table
	// Advertise advertises routes to the network
	Advertise() (<-chan *Advert, error)
	// Process processes incoming adverts
	Process(*Advert) error
	// Solicit advertises the whole routing table to the network
	Solicit() error
	// Lookup queries routes in the routing table
	Lookup(...QueryOption) ([]Route, error)
	// Watch returns a watcher which tracks updates to the routing table
	Watch(opts ...WatchOption) (Watcher, error)
}

Когда маршрутизатор запускается, он автоматически создает наблюдателя для своего локального реестра. Микро-реестр генерирует события каждый раз, когда службы создаются, обновляются или удаляются. Маршрутизатор обрабатывает эти события и затем соответствующим образом применяет действия к своей таблице маршрутизации. Сам маршрутизатор объявляет события таблицы маршрутизации, которые вы можете рассматривать как урезанную версию реестра, занимающуюся исключительно маршрутизацией запросов, тогда как реестр предоставляет более многофункциональную информацию, такую ​​как конечные точки api.

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

Вот типичный маршрут:

// Route is a network route
type Route struct {
	// Service is destination service name
	Service string
	// Address is service node address
	Address string
	// Gateway is route gateway
	Gateway string
	// Network is the network name
	Network string
	// Router is router id
	Router string
	// Link is networks link
	Link string
	// Metric is the route cost
	Metric int64
}

В первую очередь нас интересует маршрутизация по имени службы, поиск ее адреса, будь то локальный или шлюз, если нам нужно пройти через какую-то удаленную конечную точку или другую сеть. Мы также хотим знать, какой тип ссылки использовать, например, идет ли маршрутизация через наш туннель, туннель Cloudflare Argo или какую-либо другую сетевую реализацию. И, самое главное, метрика, известная как стоимость маршрутизации к этому узлу. У нас может быть много маршрутов, и мы хотим выбирать маршруты с оптимальной стоимостью, чтобы обеспечить минимальную задержку. Однако это не всегда означает, что ваш запрос отправляется в локальную сеть! Представьте себе ситуацию, когда сервис, работающий в вашей локальной сети, перегружен. Мы всегда выберем маршрут с наименьшей стоимостью, независимо от того, где работает сервис.

Прокси

Мы уже обсуждали туннель - как сообщения передаются от точки к точке и маршрутизацию - подробно рассказывая, как найти, где находятся службы, но тогда вопрос в том, как службы на самом деле используют это? Для этого нам действительно нужен прокси.

При построении микросети для нас было важно, чтобы мы построили что-то родное для микро и способное понимать наш протокол маршрутизации. Нашей целью не было создание другого сетевого решения на основе VPN или IP. Вместо этого мы хотели облегчить связь между сервисами.

Когда сервису необходимо взаимодействовать с другими сервисами в сети, он использует микропрокси.

Прокси-сервер - это собственная реализация прокси-сервера RPC, построенная на интерфейсах Go Micro Client и Server. Он инкапсулирует основные средства связи для наших служб и обеспечивает механизм пересылки запросов на основе имени службы и конечных точек. Кроме того, он может также действовать как обмен сообщениями для асинхронной связи, поскольку Go Micro поддерживает как запрос / ответ, так и общение между публикациями и подписками. Это встроено в Go Micro и является мощным строительным блоком для маршрутизации запросов.

Сам интерфейс прост и инкапсулирует сложность проксирования.

// Proxy can be used as a proxy server for go-micro services
type Proxy interface {
	// ProcessMessage handles inbound messages
	ProcessMessage(context.Context, server.Message) error
	// ServeRequest handles inbound requests
	ServeRequest(context.Context, server.Request, server.Response) error
}

Прокси-сервер получает запросы RPC и направляет их в конечную точку. Он запрашивает у маршрутизатора местоположение службы (при необходимости кэширует) и решает на основе поля Link в таблице маршрутизации, следует ли отправлять запрос локально или через туннель через глобальную сеть. Значение поля Link - либо “local" (для локальных служб), либо “network", если служба доступна только через сеть.

Как и все остальное, мы создали автономный прокси-сервер, который может работать между службами в одном центре обработки данных, но также и во многих при использовании вместе с туннелем и маршрутизатором.

И, наконец, мы подошли к пьесе сопротивления. Сетевой интерфейс.

Сеть

Сетевые узлы - это магия, которая связывает все основные компоненты вместе. Создание поистине глобальной сервисной сети. При создании сетевого интерфейса было действительно важно, чтобы он соответствовал нашим существующим предположениям и представлениям о Go Micro и разработке распределенных систем. Мы действительно хотели охватить существующие интерфейсы фреймворка и разработать что-то симметричное в отношении Сервиса.

Мы пришли к чему-то очень похожему на сам интерфейс micro.Service.

// Network is a micro network
type Network interface {
	// Node is network node
	Node
	// Name of the network
	Name() string
	// Connect starts the resolver and tunnel server
	Connect() error
	// Close stops the tunnel and resolving
	Close() error
	// Client is micro client
	Client() client.Client
	// Server is micro server
	Server() server.Server
}
// Node is a network node
type Node interface {
	// Id is node id
	Id() string
	// Address is node bind address
	Address() string
	// Peers returns node peers
	Peers() []Node
	// Network is the network node is in
	Network() Network
}

Как видите, Network имеет Имя, Клиент и Сервер, очень похоже на Service, поэтому он обеспечивает аналогичный метод связи. Это означает, что мы можем повторно использовать большую часть существующей кодовой базы, но это также идет намного дальше. Network включает понятие Node непосредственно в интерфейсе, у которого есть одноранговые узлы и которые могут принадлежать той же сети или другим. Это означает, что сети являются одноранговыми, в то время как службы в основном ориентированы на клиент / сервер. Изо дня в день разработчики сосредоточены на создании сервисов, но когда они созданы для глобального взаимодействия, они должны работать в сетях, состоящих из идентичных узлов.

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

Так как же все это работает вместе?

В сетях есть список одноранговых узлов, с которыми можно разговаривать. В случае реализации по умолчанию список одноранговых узлов берется из реестра с другими сетевыми узлами с тем же именем (именем самой сети). Когда узел запускается, он «подключается» к сети, устанавливая свой туннель, разрешая узлы и затем соединяясь с ними. После подключения узлы взаимодействуют в двух многоадресных сеансах, один для объявлений одноранговых узлов, а другой для объявлений маршрутов. По мере их распространения сеть начинает сходиться на идентичной информации маршрутизации, выстраивая полную сеть, которая позволяет маршрутизировать услуги от одного узла к другому.

Узлы поддерживают пакеты поддержки активности, периодически объявляют полную таблицу маршрутизации и сбрасывают все события по мере их возникновения. Узлы нашей базовой сети используют несколько преобразователей для поиска друг друга, включая DNS и локальный реестр. В случае одноранговых узлов, которые присоединяются к нашей сети, мы настроили их для использования http-преобразователя, который получает геоуправление через Cloudflare anycast DNS и глобальную нагрузку, сбалансированную для самого локального региона. Оттуда они извлекают список узлов и подключаются к узлам с наименьшей метрикой. Затем они повторяют ту же песню и танец, что и выше, чтобы продолжить рост сети и участвовать в маршрутизации услуг.

Каждый узел поддерживает свой собственный сетевой граф на основе получаемых одноранговых сообщений. Одноранговые сообщения содержат график каждого однорангового узла до трех переходов, что позволяет каждому узлу создавать локальное представление сети. Одноранговые узлы игнорируют все, что имеет радиус более 3 переходов. Это сделано для того, чтобы избежать потенциальных проблем с производительностью.

Мы немного упомянули о одноранговой и маршрутной рекламе. Так каким же сообщением на самом деле обмениваются сетевые узлы? Во-первых, в сеть встроен интерфейс маршрутизатора, через который она объявляет свои локальные маршруты другим сетевым узлам. Затем эти маршруты распространяются по всей сети, как и в Интернете. Сам узел получает объявления о маршруте от своих партнеров и применяет объявленные изменения к своей собственной таблице маршрутизации. Типы сообщений - это «запрос» для запроса маршрутов и «объявление» для широковещательной рассылки обновлений.

Сетевые узлы отправляют сообщения «подключиться» при запуске и «закрыть» при выходе. На протяжении всей своей жизни они периодически рассылают «одноранговые» сообщения, чтобы другие могли их обнаружить, и все они могли построить топологию сети.

Когда сеть создается и сходится, службы могут отправлять по ней сообщения. Когда службе в сети необходимо связаться с какой-либо другой службой в сети, она отправляет запрос на сетевой узел. Узел микросети встраивает микропрокси и, таким образом, имеет возможность пересылать запрос через сеть или локально, если он сочтет это более подходящим на основе показателей, которые он извлекает после поиска маршрутов в таблице маршрутизации.

Это в целом составляет нашу сеть микросервисов.

Вызовы

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

Начальная реализация

Фактическая задача, которую мы поставили перед собой, была довольно грандиозной, и мы недооценили, сколько усилий потребуется даже на этапе MVP первой реализации.

Каждый раз, когда мы пытались перейти от схемы дизайна к реализации кода, мы застревали. Теоретически все имело смысл, но сколько бы раз мы ни пытались написать код, ничего не получалось.

Мы написали 3–4 реализации, которые, по сути, были отброшены, прежде чем выяснили, что лучший подход - сначала заставить работать локальную сеть, а затем постепенно выявлять конкретные проблемы для решения. Итак, проксирование, затем маршрутизация, а затем сетевой интерфейс. В конце концов, когда все эти элементы были готовы, мы смогли перейти к мультиоблачным или глобальным сетям, реализовав туннель для выполнения тяжелой работы.

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

Многоточечное туннелирование

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

Сложность написания сетевых протоколов действительно проявилась в этих усилиях из-за попытки НЕ переопределить tcp, crypto или что-то еще, но также найти путь к рабочему решению. В конце концов, мы смогли создать подмножество команд, которые сформировали достаточное количество двунаправленного и многосессионного туннеля через QUIC. Мы оставили большую часть тяжелой работы на QUIC, но нам также нужна была возможность делать многоадресную рассылку.

Для нас не имело смысла полагаться только на одноадресную рассылку, учитывая семантику на основе async и pubsub, встроенную в Go Micro, мы были непреклонны в том, что она должна быть частью базовой сетевой маршрутизации. Таким образом, необходимо было повторно реализовать сеансы поверх QUIC.

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

Буря событий

Когда все работает, они работают, а когда ломаются, ломаются плохо. Для нас все рухнуло, когда мы начали сталкиваться с широковещательными штормами, вызванными переработкой сервисов. Когда служба создается, реестр служб запускает событие создания, а при завершении работы автоматически отменяет регистрацию в реестре служб, что вызывает событие удаления. Может быть, вы увидите, к чему все идет. По мере того, как сервисы циклически включаются в нашей сети, они генерируют эти события, что приводит к тому, что маршрутизаторы генерируют новые события маршрута, которые затем распространяются каждые 5 секунд на все остальные узлы сети.

Это звучит нормально, если сеть сходится и они перестают распространять события, но в нашем случае последовательность событий наблюдается и применяется через случайные интервалы времени на каждом узле. По сути, это может привести к бесконечной широковещательной буре. Понять и решить эту задачу - невероятно трудная.

Для нас это действительно привело к исследованию интернет-маршрутизации BGP, в котором они определили алгоритмы обнаружения сбоев для решения этой проблемы. Мы прочитали несколько технических документов, чтобы познакомиться с концепциями и взломали простой алгоритм обнаружения закрылков в маршрутизаторе.

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

На рисунке ниже показано, как на самом деле работает распад.

источник: http://linuxczar.net/blog/2016/01/31/flap-detection/

Это оказало огромное влияние на проблемы, с которыми мы сталкивались в сети. Узлы больше не подвергались безумным бурям событий, сеть стабилизировалась и продолжала работать без перебоев. Счастливые дни!

Архитектура

Наша общая цель - построить сеть микросервисов, которая управляет не только коммуникациями, но и всеми аспектами работы сервисов, управления и т. Д. Чтобы добиться этого, мы начали с решения сетевых проблем с нуля для сервисов Go Micro. Не только для локального общения в одной частной сети, но и для того, чтобы иметь возможность делать это во многих сетях.

Для этого мы создали глобальную мультиоблачную сеть, которая позволяет общаться из любого места и с кем угодно. Это фундаментально для архитектуры сети микросервисов.

Наша следующая цель будет заключаться в рассмотрении аспектов времени выполнения, чтобы мы могли предлагать возможность размещать службы без необходимости управлять ими. Это можно представить как основу бессерверной платформы микросервисов, которую мы планируем запустить в ближайшее время.

Платформа предназначена быть открытой. Любой должен иметь возможность запускать службы на платформе или присоединяться к глобальной сети, используя свой собственный узел. Более того, вы даже можете взять открытый исходный код и построить свои собственные частные сети или присоединить их к нашей общедоступной.

Что мы считаем довольно крутым и довольно уникальным в микросети, так это то, что сами сетевые узлы представляют собой обычные микросервисы, как и любые другие. Поскольку мы построили все с помощью Go Micro, они ведут себя так же, как и любой другой сервис. На самом деле, что еще более интересно, в микросети буквально все является услугой.

Это верно для всех отдельных компонентов, составляющих сеть. Если вы не хотите запускать полные сетевые узлы, вы также можете запускать отдельные компоненты сети отдельно как отдельные микросервисы, такие как туннель, маршрутизатор и прокси. Все компоненты регистрируются в локальном реестре, через который их можно обнаружить.

Конечный успех

29 августа 2019 года около 16:00 мы отправили первый успешный запрос RPC между нашими ноутбуками через Интернет с помощью микросети.

С тех пор мы устранили множество ошибок и развернули сетевые узлы по всему миру. В настоящее время мы запускаем микросеть в 4 облачных провайдерах в 4 географических регионах с 3 узлами в каждом регионе.

использование

Если вы заинтересованы в тестировании микро и сети, просто сделайте следующее.

# enable go modules
export GO111MODULE=on
# download micro
go get github.com/micro/micro@master
# connect to the network
micro --peer

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

# List the services in the network
micro network services
# See which nodes you're connected to
micro network connections
# List all the nodes in your network graph
micro network nodes
# See what the metrics look like to different service routes
micro network routes

Так как же выглядит рабочий процесс разработчика микросетей? Разработчики пишут свой код Go, используя фреймворк Go Micro, и как только они будут готовы, они могут сделать свои сервисы доступными в сети либо непосредственно со своего ноутбука, либо из любого места, где работает узел микросети (подробнее о том, какой узел микросети является позже) .

Вот пример простой службы, написанной с использованием go-micro:

package main
import (
	"context"
	"log"
	"time"
	hello "github.com/micro/examples/greeter/srv/proto/hello"
	"github.com/micro/go-micro"
)
type Say struct{}
func (s *Say) Hello(ctx context.Context, req *hello.Request, rsp *hello.Response) error {
	log.Print("Received Say.Hello request")
	rsp.Msg = "Hello " + req.Name
	return nil
}
func main() {
	service := micro.NewService(
		micro.Name("helloworld"),
	)
	// optionally setup command line usage
	service.Init()
	// Register Handlers
	hello.RegisterSayHandler(service.Server(), new(Say))
	// Run server
	if err := service.Run(); err != nil {
		log.Fatal(err)
	}
}

После запуска службы она автоматически регистрируется в реестре служб и мгновенно становится доступной для всех в сети для использования и совместной работы. Все это полностью прозрачно для разработчиков. Нет необходимости иметь дело с хламом низкоуровневых распределенных систем!

У нас уже есть служба приветствия в сети, так почему бы не попробовать позвонить ей.

# enable proxying through the network
export MICRO_PROXY=go.micro.network
# call a service
micro call go.micro.srv.greeter Say.Hello '{"name": "John"}'

Оно работает!

Заключение

Построение распределенных систем сложно, но оказывается, что построение сетей, по которым они взаимодействуют, - не менее, если не более сложная проблема. Классическое заблуждение сеть надежна продолжает действовать, как мы обнаружили при построении микросети. Однако также ясно, что наш мир и большинство технологий процветают за счет использования сетей. Они лежат в основе всего того, что мы узнали. Наша цель с микросетью - создать фундамент нового типа для открытых сервисов будущего. Надеюсь, этот пост пролил свет на технические достижения и проблемы, связанные с созданием такой штуки.

Чтобы узнать больше, загляните на сайт, подпишитесь на нас в twitter или присоединитесь к сообществу slack. Мы нанимаем!

Милош, Джейк и Асим

Команда основателей Micro Services, Inc.