- PVSM.RU - https://www.pvsm.ru -
Алексей Найдёнов, CEO ITooLabs [1], рассказывает про разработку телекоммуникационной платформы для операторов связи на языке программирования Go (Golang). Алексей также делится опытом развертывания и эксплуатации платформы в одном из крупнейших азиатских операторов связи, который использовал платформу для оказания услуг голосовой почты (VoiceMail) и Виртуальной АТС (Cloud PBX).
Алексей Найдёнов. ITooLabs. Кейс разработки на Go (Golang) телефонной платформы. Часть 1 [2]
Понятно, что когда у вас есть параллельное выполнение, вам нужны средства синхронизации. Go предоставляет все средства синхронизации, которые нужны: mutex’ы, разделяемая память… Но штатным механизмом для него являются каналы.
Канал можно рассматривать как однонаправленная типизированная очередь в n элементов (по умолчанию равно 1). Канал сам по себе может быть параметром, членом структуры. Более того, канал можно передать по каналу – при этом у этого канала будет тип «канал каналов такого-то типа».
Что делает этот пример в 20 строк? Это счётчик http-вызовов. Он просто считает там, где он запускает http-сервер, и показывает, сколько раз к этому серверу обратились. Каким образом это обычно делается? Обычно вы делаете переменную, оборачиваете mutex’ом и инкрементируете. Либо делаете атомарную переменную, инкрементируете атомарно.
В Go принято по-другому. Разработчик, попробовав в Go, очень быстро начинает писать именно так. В Go вы запускается функция goroutine, которая называется count (8-я строка) и go count (17-я); делаете переменную; а дальше просто инкрементируете локальную переменную – начинается отправка в канал следующего числа. Те из вас, кто вспомнил Atmos Script Generators, конечно, будут правы, но в Go каналы позволяют гораздо более широкое использование.
Есть, наконец, оператор Select, который позволяет выбирать из нескольких каналов сразу. Это типовой шаблон в Go, каким образом можно завершить выполнение какой-либо горутины:
Вы передаёте два канала. В один канал идут запросы, а в другой идут сигналы о том, что пора бы закруглиться.
Для нас, как для разработчиков платформы для телефонии, было важно, что в Go есть C API, который позволяет непосредственно в коде на Go писать какие-то куски на Си, которые будут потом нормально откомпилированы, нормально влинкуются и будут потом нормально работать.
То есть вы можете получать доступ ко всем Си-библиотекам, которые есть у вас на операционной системе. При этом они тоже будут влинкованы статически.
Инструментарий в Go – ещё одна причина, по которой его любят. Всё делается при помощи одной команды – (go). Есть команда go build, которая собирает, есть go test, запускающая специальные тестовые функции, описанные в конкретном package. Есть команда go run, которая запускает и собирает сразу. Есть команда, которая обновляет зависимости (go get).
Есть те, которые форматируют исходники: go fmt – у нас она стоит, например, на push’ах. Нет больше споров по поводу того, где, каким образом и какой стиль форматирования используем – tab или пробел: есть команда go fmt, есть определённый стиль, который она форматирует, и споров никаких нет. Не нравится что-то? Запусти go fmt – будет так, как должно быть.
Команда go doc позволяет читать документации и показывать её в html. Есть go tool pprof для профайлинга, генератор парсингов (go tool yacc) и много чего другого. Короче, инструментарий в Go очень развитой для такого молодого языка. Многие идеи в нём были не то чтобы новаторские, но очень интересные, которые мигрировали потом в другие системы – например, тот же самый Goget и возможность указывать непосредственный репозиторий в качестве имени package.
Вообще, я предпочитаю Emacs. Если тут есть любители – можем потом подраться. Но для разработки я предпочитаю «взрослый» IDE:
Я пробовал их все, включая VIM. Могу сказать, что на текущий момент самый крутой IDE – это обычный, какая-нибудь IDEA Edition с плагином для Go. Лучшее! Рекомендую. Если кто будет пользоваться – надо сразу начать и не мучиться.
Библиотеки – это был ещё один очень-очень приятный сюрприз, потому что буквально на любой чих мы что-нибудь находили сразу. Даже когда нам понадобился интерпретатор Javascript, мы подумали, что придётся писать самим – мы его просто нашли, он уже был.
На текущий момент в Git’е зарегистрировано 35 с лишним тысяч разных репозиториев, в которых поставлена хотя бы одна звёздочка. Могу повторить свою мысль: там есть и наши библиотеки, и чужие, и полно компаний, которые открывают какие-то свои внутренние библиотеки. В общем, я не могу припомнить случая, когда мне что-то понадобилось, и я тут же не нашёл бы это на GitHub (в случае Go).
Эксплуатация – мечта, особенно для тех, кто, например, работал с Java.
Сообщество – это тоже подкупило. Сообщество Go просто прекрасное, и оно летит восходящей звездой. К сожалению, на слайде указано мелко и не видно: слева – репозиторий на GitHub, справа – теги Stack Overflow:
Если посмотреть на Go, то он находится в компании языков, которые старше него раз так в пять!
Битва! Сравниваем с Node.js, например. Можно на самом деле сравнить с чем угодно. Но почему с Node?
Предположу, что Google планировал, что Go будет вытеснять Java, конкурировать с Java. На самом деле нет. Основным конкурентом Go оказался для Node.js, Python, для интерпретируемых языков. Почему? Потому что на Go за счёт выведения типов, за счёт множества мелких деталей (типа команды go run) возникает ощущение языка интерпретируемого, то есть лёгкого, на котором можно делать макеты, что-то быстро строить и прототипировать. Но при этом оно реально работает: реально компилируется, запускается и работает быстро.
Вот у нас два сервера простых – и там, и там http:
Разница.
Когда у вас есть такая модель, как в Erlang или Go, жизнь становится намного проще.
Да дофига!
Может, из-за быстрой сборки или из-за развёртывания одним бинарником? По причине конкурентности или эффективной утилизации железа? Может, из-за того, что он быстро развивается или благодаря крутому сообществу?
Я долго пытался ответить на этот вопрос сам себе. В конце концов, я понял: нет, ни одна из этих причин! Всё гораздо проще: Go работает.
Go – это предельно практичный язык для инженеров. Для инженеров, которые заняты разработкой веб-сервисов и распределённых систем – писать на нём интерфейсы, много чего…
Можно ли на нём написать «Битрикс»? Я не знаю. Скорее всего, нет, потому что слишком много интерфейсы. Но написать на нём платформу, на которой «Битрикс» будет работать быстрее (например, шину для передачи сообщений) – это то, что нужно, я уверен.
Кто уже успел прыгнуть в этот вагон?
Есть список компаний, которые так или иначе отметились, делают какие-то проекты на Go: https://github.com/golang/go/wiki/GoUsers [3]
Что мы написали за год?
Как я уже говорил, где-то в 2012 году мы поняли, что нас ждёт впереди стена. Это было довольно страшно. Мы не сильно ошиблись в своих прогнозах (что ещё два года и будет кранты), потому что в начале 2014 года у нас действительно было очень плохо…
И мы быстро смигрировали значительную часть генерирующей функциональности на свою новую платформу, в частности записи, всякие внешние транки – то, что генерирует много нагрузки на CPU, и с чем старая вендорская платформа уже категорически не справлялась.
Сейчас это всё уже успешно работает и практически вся запись, которая идёт на платформе, проходит через нашу систему на Go.
Если долго работаешь на репутацию, в какой-то момент репутация начинает работать на меня. И к нам уже продолжительное время приходят разные люди от операторов с предложениями делать что-нибудь.
Смогли бы мы это сделать на каком-то другом языке в такое короткое время? Напомню, с 2012 по 2015 – 3 года на продукт, который держит такую нагрузку и работает для миллионов абонентов Индонезии.
Я не знаю, но думаю, мы смогли бы сделать это на «Эрланге». Может быть, смогли бы сделать это на Java. Поскольку я, кроме основной работы, ещё и читаю лекции по системам реального времени и параллельному программированию в Тульском университете, для меня одним из конечных итогов, причин, по которым мы решили использовать Go, был очень просто эксперимент.
Я дал студентам лабораторные и убедился, что кривая обучения Go круче любого языка, с которым я когда-либо сталкивался (именно в этой сфере). Студенты начинали писать более-менее приличный код, потому что неприличный Go просто не даёт писать. Go даёт скучный код, и только скучный код! Но неприличный не получается – очень тяжело.
Могу похвастаться, что 31 декабря 2015, всего через месяц после развёртывания, на системе за один день было записано 160 тысяч сообщений, которые абоненты друг другу передают.
Вопрос из зала (далее – В): – Большое спасибо за доклад! Очень интересные кейсы. Скажите, пожалуйста, а как сейчас у Go выглядит обработка ошибок? Например, когда я пишу на Node и мне нужно сделать 5 подряд асинхронных операций, мой код выглядит в 5 строк: wait, wait, wait, wait, wait.
АН: – Как я уже сказал, там нет исключений. Во всяком случае в том смысле, в каких вы можете использовать их для контроля, управления.
В: – Как вы управляете ошибками?
АН: – if’ами! Я повторюсь, что Golang позволяет писать довольно скучный код и провоцирует cut’n’paste.
В: – И сколько этих if’ов будет на 5 асинхронных операций, каждая из которых может взорваться?
АН: – С моей точки зрения, они будут синхронными (с точки зрения этой горутины). 5 if’ов.
В: – Идёт практически удвоение кода.
АН: – Наверное, если бы я платил разработчикам кода, я бы расстраивался. Но поскольку я плачу за то, что они делают хороший, работающий код, я в принципе этому рад.
В: – А динамически какую-то Си-шную библиотеку прилинковать вообще возможно?
АН: – Да.
В: – То есть этот функционал остался?
АН: – То, что я показывал и рассказывал про CGO – там линкуется со статической библиотекой, если она есть, а если нет – подключается динамическая. Более того, в Go 1.5 появилась в принципе динамическая линковка, даже позволяет теперь делать динамические библиотеки. Но мы настолько привыкли, настолько прочувствовали такой механизм, что уже не чувствуем нужды. Динамические библиотеки Си подключать, конечно, можно, С++ – нет.
В: – А бинарник в итоге получается не слишком гигантским?
АН: – Нет. Бинарник всей нашей системы, которая обрабатывает все эти вызовы (вместе с интерпретатором JavaScript внутри) – это всего-навсего 6 мегабайт. Это бинарник, который в принципе влезает во второй кэш.
В: – Сам часто слышал сравнения: Go часто сравнивают именно с интерпретируемыми языками, и мало у кого есть задача написать полноценную коммуникационную платформу. Какие более простые практические кейсы есть?
АН: – Более простой кейс – отлично. Для компании «Мегафон» мы написали предбиллинг – что-то вроде шины, которая собирает внутри себя платформы от разных компонентов (биллинг, «Мультифон» – у большого оператора их всегда очень много), всё это дело внутри себя интегрирует, складывает в базу, высчитывает то, что нужно и посылает события в разные места.
В той же самой Индонезии простой шлюз (хоть и простой, но распределённый), который принимает в себя события от нашей системы и передаёт дальше в систему, которая отсылает её SSD… Вот такого рода задачи – конечно, всё это пишется очень-очень быстро, что и привлекает.
Спасибо, что остаётесь с нами. Вам нравятся наши статьи? Хотите видеть больше интересных материалов? Поддержите нас, оформив заказ или порекомендовав знакомым, облачные VPS для разработчиков от $4.99 [4], уникальный аналог entry-level серверов, который был придуман нами для Вас: Вся правда о VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps от $19 или как правильно делить сервер? [5] (доступны варианты с RAID1 и RAID10, до 24 ядер и до 40GB DDR4).
Dell R730xd в 2 раза дешевле в дата-центре Equinix Tier IV в Амстердаме? Только у нас 2 х Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 ТВ от $199 [6] в Нидерландах! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — от $99! Читайте о том Как построить инфраструктуру корп. класса c применением серверов Dell R730xd Е5-2650 v4 стоимостью 9000 евро за копейки? [7]
Автор: ua-hosting
Источник [8]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/349177
Ссылки в тексте:
[1] ITooLabs: http://itoolabs.com/
[2] Алексей Найдёнов. ITooLabs. Кейс разработки на Go (Golang) телефонной платформы. Часть 1: https://habr.com/ru/company/ua-hosting/blog/491652/
[3] https://github.com/golang/go/wiki/GoUsers: https://github.com/golang/go/wiki/GoUsers
[4] облачные VPS для разработчиков от $4.99: https://ua-hosting.company/cloudvps/nl
[5] Вся правда о VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps от $19 или как правильно делить сервер?: https://habr.com/company/ua-hosting/blog/347386/
[6] 2 х Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 ТВ от $199: https://ua-hosting.company/serversnl
[7] Как построить инфраструктуру корп. класса c применением серверов Dell R730xd Е5-2650 v4 стоимостью 9000 евро за копейки?: https://habr.com/company/ua-hosting/blog/329618/
[8] Источник: https://habr.com/ru/post/491656/?utm_campaign=491656&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.