Создание веб-приложения на Go в 2017 году. Часть 4

https://grisha.org/blog/2017/04/27/go-web-app-part-4/
  • Перевод
  • Tutorial
Содержание

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


Обертки обработчиков HTTP


Немного поворчу: мне не нравится слово “middleware”. Концепция обертки существует с начала вычислений, поэтому не вижу необходимости изобретать для нее новые слова.


Но отбросим это в сторону, допустим, нам потребовалась аутентификация для определенного URL. Сейчас наш обработчик главной страницы выглядит так:


func indexHandler(m *model.Model) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, indexHTML)
    })
}

Мы можем написать функцию, которая принимает http.Handler в качестве аргумента и возвращает (другой) http.Handler. Возвращенный обработчик проверяет, аутентифицирован ли пользователь, с помощью m.IsAuthenticated() (неважно, что конкретно там происходит) и перенаправляет пользователя на страницу входа или выполняет оригинальный обработчик, вызывая его метод ServeHTTP().


func requireLogin(h http.Handler, m *model.Model) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if !m.IsAuthenticated(r) {
            http.Redirect(w, r, loginURL, http.StatusFound)
            return
        }
        h.ServeHTTP(w, r)
    })
}

С учетом этого, регистрация обработчика теперь будет выглядеть так:


   http.Handle("/", requireLogin(indexHandler(m), m))

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


Параметры в URL


В какой-то момент нам могут понадобиться параметры в URL, например, /Person/3, где 3 — это идентификатор человека. Стандартная библиотека Go ничего для этого не предоставляет, оставляя эту задачу в качестве упражнения для разработчика. Программный компонент, ответственный за такую штуку, называется Mux, т.е. «мультиплексор», или «маршрутизатор», и его можно заменить нестандартной реализацией. Маршрутизатор также реализует метод ServeHTTP(), что означает, что он удовлетворяет интерфейсу http.Handler, то есть он является обработчиком.


Очень популярным вариантом маршрутизатора является Gorilla Mux. Ему можно делегировать целые пути в тех местах, где требуется больше гибкости. Например, мы можем решить, что все, от /person и ниже, обрабатывается маршрутизатором Gorilla, и мы хотим, чтобы все это еще было аутентифицировано, тогда это может выглядеть так:


    // import "github.com/gorilla/mux"
    pr := mux.NewRouter().PathPrefix("/person").Subrouter()
    pr.Handle("/{id}", personGetHandler(m)).Methods("GET")
    pr.Handle("/", personPostHandler(m)).Methods("POST")
    pr.Handle("/{id}", personPutHandler(m)).Methods("PUT")
    http.Handle("/person/", requireLogin(pr))

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


Есть еще много других реализаций маршрутизатора/мультиплексора. Прелесть в том, что не привязываясь ни к какому фреймворку, мы можем выбрать тот маршрутизатор, который лучше всего нам подходит, или написать свой собственный (их нетрудно реализовать).


Обработка статики


Одна из самых изящных вещей в Go — это то, что скомпилированная программа представляет собой единственный двоичный файл, а не большую кучу файлов, как это часто бывает с большинством скриптовых языков и даже с некоторыми компилируемыми. Но если наша программа зависит от статических файлов (JS, CSS, изображений и других файлов), нам нужно будет скопировать и их на сервер во время развертывания.


Мы можем сохранить эту характерную особенность — «один бинарник» — нашей программы, включив статику как часть самого двоичного файла. Для этого существует проект go-bindata и его племянник go-bindata-assetsfs.


Поскольку упаковка статики в двоичный файл несколько выходит за пределы того, что может сделать go build, нам понадобится какой-то скрипт, который об этом позаботится. Лично я предпочитаю использовать проверенный и "трушный" make, и не так уж редко можно встретиться с «Makefile» в проекте Go.


Вот пример подходящего правила Makefile:


ASSETS_DIR = "assets"
build:
    @export GOPATH=$${GOPATH-~/go} && \
    go get github.com/jteeuwen/go-bindata/... github.com/elazarl/go-bindata-assetfs/... && \
    $$GOPATH/bin/go-bindata -o bindata.go -tags builtinassets ${ASSETS_DIR}/... && \
    go build -tags builtinassets -ldflags "-X main.builtinAssets=${ASSETS_DIR}"

Это правило создает файл bindata.go, который помещается в тот же каталог, где находится main.go, соответственно, он становится частью пакета main. main.go как-то узнает, что статические файлы встроены, — это получается с помощью трюка -ldflags "-X main.builtinAssets=${ASSETS_DIR}", так мы можем присваивать значения переменным на этапе компиляции. Это значит, что теперь наш код может проверять значение builtinAssets, чтобы решить, что делать дальше, например:


    if builtinAssets != "" {
        log.Printf("Running with builtin assets.")
        cfg.UI.Assets = &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, AssetInfo: AssetInfo, Prefix: builtinAssets}
    } else {
        log.Printf("Assets served from %q.", assetsPath)
        cfg.UI.Assets = http.Dir(assetsPath)
    }

Вторая важная вещь заключается в том, что мы определяем build tag с именем builtinassets. Мы также сообщаем go-bindata о нем, что означает «скомпилируй меня, только когда установлен builtinassets», а это позволяет контролировать, при каких условиях необходимо компилировать bindata.go (который содержит нашу статику в виде кода Go).


Предварительная транспиляция JavaScript


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


  • В принципе, вы можете пойти на уступки — установить npm и настроить файл package.json.


  • Как только npm установлен, банально устанавливается компилятор командной строки Babel — babel-cli, который является одним из способов транспиляции JavaScript.


  • Более сложный, в чем-то разочаровывающий, но в конечном счете более гибкий способ — использовать webpack. Webpack будет не только претранспиливать JS-код, но и объединит все JS-файлы в один, а также минимизирует его.


  • Я был удивлен тому, насколько сложно было обеспечить функциональность импорта модулей в JavaScript. Проблема в том, что есть стандарт ES6 для ключевых слов import и export, но нет реализации, и даже Babel предполагает, что реализовывать их для вас будет кто-нибудь другой. В конце концов, я остановился на SystemJS. Некоторое осложнение с SystemJS заключается в том, что внутрибраузерная транспиляция Babel должна быть чем-то, понятным для SystemJS, поэтому мне пришлось использовать его плагин для Babel. Webpack, в свою очередь (если я правильно понял), предоставляет свою собственную реализацию поддержки модулей, поэтому при упаковке SystemJS не нужен. В любом случае, это было довольно неприятно.

Заключение


Я бы сказал, что в примере, который я описываю в этой серии из четырех частей, Go безусловно блистает, а вот JavaScript — не особо. Но как только я преодолел начальные трудности с тем, чтобы заставить все это заработать, React/JSX оказался простым и, возможно, даже приятным для работы.


На этом я, пожалуй, закончу. Надеюсь, статьи оказались вам полезными.

Поделиться публикацией
Похожие публикации
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама
Комментарии 77
  • +16

    Прочитал внимательно все четыре части, впечатление осталось странное.


    1. Из преимуществ Go заметил (видимо, основное) указание (раз пять) на то, что на выходе один бинарник, а не куча файликов. Ну… Ээээ… Это действительно актуально?


    2. Автор не может решить фронтовые задачи без установки npm и его пакетов. Но при этом у него "Go блистает, а JavaScript не очень".


    3. Автор преподносит практику написания прямых SQL запросов как некое позитивное новаторство и хорошую практику, которой больше нигде нет… То же самое и насчёт фреймворков, но не так смешно.


    4. Автор рассказывает, что Go такой крутой, что вам больше не нужен ни redis ни nginx… Ну вот можно ещё только РСУБД оставить.

    Не в первый взгляд вижу подобные утверждения. Ещё было забавно как-то услышать, что для проекта на Go писали тесты на Node.js...


    В общем, переводчик молодец, спасибо за труд. Но пока что вижу, что ёжики продолжают плакать, колоться и писать на Go. До сих пор жду статью, которая покажет мне профит использования Go. Искренне верю в то, что он есть, но до сих пор подозреваю, что use cases довольно узкие.

    • 0

      Например — решения на Go (во множественном числе, что дает нам богатство выбора) сопоставимы со скоростным Tarantool, при этом развесистось экосистемы несравнима.

      • 0
        Профит Go:
        1. Это язык от гугла, в его разработке участвуют достаточно именитые авторы.
        2. На выходе получается довольно быстрый машинный код.
        3. Память управляется сборщиком мусора. Сборщик мусора оптимизирован на минимум пауз.
        4. Сам по себе язык очень простой, быстро изучить его по силам любому программисту.
        5. Язык предлагает довольно полное описание того, как на нём надо писать; в стандартной библиотеке довольно много всего нужного, в общем при разработке будет минимум душевных терзаний, а максимум продуктивности. То же про инструментарий.
        6. Насколько я знаю, потребление памяти у Go невелико. Т.е. можно писать достаточно неприхотливые к оперативной памяти микросервисы.
        7. Быстрый старт.

        На мой взгляд идеальной нишей для Go являются HTTP-микросервисы.
        • +1
          1. Мы тут недавно в одной Telegram-группе обсуждали (в основном новые) языки программирования. Так вот — за любым языком стоят 1-2 автора. И где язык создаётся — не так уж и важно.

          Остальное можно считать плюсом Go :-)

          • +3
            1. Google glass, Google lively, Google wave, Google answers… Не всё то хорошо, что Google.
            2. Может и получается, но я до сих пор видел только бенчмарки, которые сравнивают go и однопоточную ноду или php 5 на apache.
            3. Да это уже почти везде так...
            4. Когда я смотрел go, первым плевком в мою душу было отсутствие "while". У меня больше 10 лет опыта разработки, я пишу на c++, c#, php, java, Pascal, javascript — и везде, везде я мог написать "while". Не представляете, сколько ангста у меня вызвала эта мелочь. И go был единственным языком, с которым у меня за вечер hello world не стартовал. Уж не помню, что были за грабли, может слишком сложную задачку себе придумал. Но впечатление осталось именно "а давайте сделаем хипстерский язык не как у всех"… Но это, конечно, индивидуально.
            5. С этим пунктом согласен. Когда приходится изучать лучшие практики парсинга json на языке X — это вымораживает.
            6. Тоже хочется бенчмарков :)
            7. Вы имеете в виду старт приложения? Потому что о старте разработке написали в пункте 4. А время старта приложения сейчас значения не имеет — хорошие CI инструменты позволяют, например, раскатать обе версии приложения, а затем переключиться между ними — как мгновенно, так и постепенно.

            Было бы интересно посмотреть на наглядное сравнение node.js vs Go на микросервисах. Потому что сейчас лидирую разработку банковских микросервисов на Node.js — и больше года проблем не знаю…
            По-моему, для go должен оптимально подходить или какой-то лютый highload с экономией на каждом мегагерце процессора и байте памяти, либо математика.

            • 0
              Основной плюс Go в сравнении с нодой — он может без лишних телодвижений использовать все ядра сервера. На ноде, насколько я понимаю, для этого нужно уже писать полноценное масштабируемое приложение и пускать N экземпляров. Ну и статическая типизация, хотя тут при желании можно TypeScript/Flow использовать или жить с динамической, кому как. В остальном, наверное, каких-то других особых преимуществ не будет.
              • 0

                Вот мнение maintainer’а кучи популярных nodejs библиотек — https://medium.com/@tjholowaychuk/farewell-node-js-4ba9e7f3e52b Товарищ плюнул на нодкжс и перешёл на go, глупый наверное. Стоп… и Матц туда же, контрибьютит гошные поректы.


                Да что это с ними творится со всеми??


                Все эти упоротые неадекваты переходят с node.js на Go — https://medium.com/digg-data/the-way-of-the-gopher-6693db15ae1f.
                На node.js остаются только нормальные разработчики .


                Даже вконтакте перешел с node.js на go — https://twitter.com/M0sth8/status/638132331295952896 :


                Готов ли Go для продакшена? VK переписали push уведомления c nodejs на Go и вместо 60 упоротых стало 24 ненагруженных сервера

                вот ведь ламеры!

                • +1
                  1. Первому упомянутому скорее просто надоела нода. Такое бывает с разработчиками — когда долго на чём-то пишешь, то перейти на другое в кайф.
                  2. Извините, не знаю никакого Матца.
                  3. А вот про digg и вконтактик я охотно верю. Но это как раз те кейсы, о которых я говорил выше — большая экономия при хайлоаде. Плюс ещё надо учесть, что это хайлоад на довольно простых проектах. И есть ли ещё кейсы оправданного использования go — я по прежнему не знаю...
                  • 0

                    1) Абсолютно нет. Кайф — это перейти с плохого инструмента на хороший. Переход с хорошего инструмента на плохой — это кайф только для мазахистов и монадирующих неадекватов. Bower переводит инфраструктуру с node.js на go — https://twitter.com/bower/status/717426243730345986 Сначала переходят капитаны, а за ними побегут и все остальные, как крысы с тонущего корабля. Over9000 других переходов с node.js на go — http://lmgtfy.com/?q=switching+from+node+to+go


                    2) Автор Руби


                    3) "Плюс ещё надо учесть, что это хайлоад на довольно простых проектах. " — чтобы стать аргументом это утверждение нуждается в доказательствах. Но если вы имеете ввиду под сложными проектами типичный кровавый ынтырпрайз из гигабайтов бессмысленного кода, то будем надеяться, что go там не приживется. Пусть в этой нише остается java и c# :)


                    Остаётся выяснить в чём заключается простота ноды-жс в сравнении с Гоу. Видимо в отсутствии стат. гарантий, callback hell и идиотском module resolving

                    • 0
                      1. Отдых это смена деятельности. Так что инструменты вполне могут быть одинаковые по качеству. Меня вот радует переключаться между Node.JS, C# и Java. И иногда даже на PHP, если понимаю, что быстрее напишу на PHP без всяких актуальных недостатков.

                      Насчёт bower — вы опять приводите в пример лютый хайлоад. Такие вещи всегда писали на сях, но Go успешно занимает эту нишу — и я уже писал, что это круто. Но повторюсь — хайлоада не так много.

                      2. Это вроде говорит о том, что автор перешёл конкретно с руби на Go. Руби мне никогда не нравились, так что понимаю его…

                      3. Там я писал про конкретные кейсы. И для digg и для вконтактика миграция осуществлялась для довольно простых проектов. Можете прочитать статьи по своим ссылкам — там всё описано, не совсем понятно, что нужно доказывать.

                      По сложными проектами я ни в коем случае не имею в виду кровавый энтерпрайз. Понятно, что там так и будет Java и C#. Под сложными проектами я имею в виду не-хайлоад средней руки, который представляет собой 99% веба — это то, что сейчас пишут на Laravel, Symphony и Yii для PHP, и нодовые микросервисы — например, на express и socket.io. Которые не хайлоад, но работают со сложными структурами и взаимосвязями. Вот для них я не вижу смысла перехода. И смысл начинания проектов такого масштаба на Go для меня под вопросом.

                      Про простоту Node.JS по сравнению с Go я ни разу не писал. Хотя имхо сейчас Node.JS гораздо больше похожа на любой классический язык разработки, и мигрировать на неё легче, чем на Go. Но на этом я ни в коем случае не настаиваю.

                      Что у вас не так с module resolving — не знаю, что такое «стат. гарантии» сходу придумать не могу, а callback hell уже несколько лет как неактуален.
                • +1
                  Когда я смотрел go, первым плевком в мою душу было отсутствие «while»

                  Вот же он

                  for sum < 1000 {
                  	sum += sum
                  }
                  
              • 0

                Все про делу, кроме "один бинарник".


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


                Другое дело, что вроде все современные языки это умеют.

                • –1
                  Другое дело, что вроде все современные языки это умеют.

                  Даже интерпретируемые PHP, Python, Ruby?
                  • +1

                    Для PHP это phar для остальных, не знаю, но 100% есть.

                    • –2
                      По сути, это просто архив, а не бинарник. Для его выполнения всё-равно понадобится PHP.
                    • 0

                      для Ruby как минимум есть Ocra и Releasy.


                      Но я имел ввиду, конечно, современные языки, которые сейчас активно развиваются. Nim, Go, Crystal, Kotlin etc.

                      • 0
                        для Ruby как минимум есть Ocra и Releasy.

                        Благодарю за подсказку. Про releasy, по-моему, даже где-то слышал.
                        Но я имел ввиду, конечно, современные языки, которые сейчас активно развиваются. Nim, Go, Crystal, Kotlin etc.

                        Ну так это компилируемые языки. Хотя, для Kotlin всё же нужна виртуальная машина, в нативные приложения он ещё не компилируется. Но в статье то Go сравнивался именно с Ruby и Python. И, как правило, именно они (вместе с PHP) используются в веб-разработке.
                    • 0
                      Ну да, ну да. А потом вы решите статику чуть-чуть поменять, ну так, слегка допилить CSS, и будете собирать заново этот свой единственный бинарник? Вы извините, но это не является преимуществом, не для веб приложений однозначно.

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

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

                      Т.е. это такие решения, которые не следует (как правило) хардкодить в Go, а нужно откладывать и принимать в Runtime. Это верно и для классических уже решений типа Apache, и в мире Java оно так, и во многих других местах.

                      Я бы еще про работу с базой добавил… где автору тоже в общем нечем гордиться.
                      • +1
                        А потом вы решите статику чуть-чуть поменять, ну так, слегка допилить CSS, и будете собирать заново этот свой единственный бинарник?
                        Да, новый релиз. Как и на скриптовых языках.

                        А вы вместо подготовки релиза будете сразу на продакшене css править?

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

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

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

                          >Не вижу разницы между компилируемыми и некомпилируемыми языками.

                          Я не знаю, про что вы там говорите, но в описанной тут архитектуре (к которой опять же и претензии) вся логика обработки хардкодится, и не может быть изменена без компиляции. А то что почти в любом языке в принципе можно сделать в том числе и динамическую загрузку плагинов — это и ежу понятно.
                          • –1
                            Или вы поставляете софт клиентам, и что бы они не лазали куда не надо? ;)
                            • 0
                              Не совсем уверен, что понял эту фразу.

                              Но вообще говоря, веб — это не тот случай, когда вы «поставляете» софт клиенту. И самое главное — клиенты бывают разные. В том числе такие, которым по работе надо лазать туда, куда якобы «не надо». Т.е. скажем в случае заказного софта для одного конкретного заказчика я всегда предпочту, чтобы и разработчик, и поддержка заказчика именно что могли, если надо, залезть и поправить.

                              P.S. Я выше написал, что вполне допускаю существование «эмбеддед» веба, в виде веб-морды для роутера или там веб-камеры. Наверное в таком случае один бинарник имел бы право на жизнь, хотя и тут это не факт.
                              • 0
                                То есть веб приложение которое поставляется клиенту уже не веб? :)
                                Я про готовое решение — клиент покупает лицензию/суппорт и пользуется им.
                                Большие корпоративные приложения то же не должны позволять менять свои ресурсы.

                                • 0
                                  Условия поставки бывают разные, как и сами приложения. А также и способы запретить менять ресурсы. Кому не надо — тем не выдаются права на запись, и все дела. При чем тут один бинарник, особено если учесть, что все равно ни одно реальное приложение к одному бинарнику не сводится?

                                  Более того, в мире JavaEE скажем, явно различаются фазы разработки и деплоя, и деплоер, т.е. как правило админ или саппортер заказчика, может менять очень многое. А еще бывают плагины, которые опять же пишутся персоналом потребителя. И в вебе тоже.
                                  • 0
                                    Как вы запретите клиенту менять то, что стоит у него на серваке и он никогда не признается суппорту, что поковырялся, пока по логам/косвенным признакам не будет вычислен?

                                    Если разрешено менять. А плагины ставятся через веб морду и сервак сам раздает их, при этом проверяя еще и целостность/подпись.
                                    • +1
                                      Видите ли, я в этой ситуации был много раз, и с обех сторон — как разработчик, и как заказчик. Расскажу небольшую историю из жизни:

                                      — широко известная компания XYZ присылает новую версию своего софта.
                                      — в софте обнаруживается баг в десериализаторе JSON, JSON генерится веб приложением, там есть плагины, они самописные (т.е. наши, а не XYZ), и могут содержать ошибки, особенно при разработке
                                      — софт на этом баге и кривом JSON падает, пишет в лог одну строчку, которая не позволяет идентифицировать место ошибки, и продолжает дальше как ни в чем ни бывало
                                      — десериализованная модель данных приложения при этом частично пустая.

                                      Пара дней копания в логах позволяют найти зацепку, и конкретный класс. Благо это java, байткод не обсфуцированный, и нормально декомпилируется. Баг тривиальный, типично индусский код, без проверок на null там где они обязательны (как я говорил, это были внешние для бэкенда данные, на минутку). В классе порядка 500 строк, вполне обозримы, и понятно что делают. В итоге находится еще два таких же места, где оно может падать. Фиксим, компилируем, собираем, деплоимся. Ура, все работает!!!

                                      Репортим баг в багтрекере компании XYZ. Реверс инжиниринг запрещен лицензией, так что о нем молчок.

                                      Через месяц-два в очередном релизе нам сообщают, что баг исправлен. Ставим, проверяем — а вот фигвам. Одно место исправили, код вокруг переписали, еще два других места не нашли. Репортим еще один баг.

                                      Итог — через полгода и два или три релиза все наконец заработало. Угадайте, на какой версии мы работали все это время?

                                      Вот поэтому, когда разработчиком являюсь я, я был и буду против того, чтобы мешать заказчику что-либо менять в купленном софте. Можно его предупредить, что изменения на свой страх и риск, можно потребовать воспроизводить баги на оригинальной версии софта, без его изменений, можно даже гарантии лишить. Но нельзя мешать потребителю вносить изменения в купленный софт — во-первых, он заплатил, а во-вторых, если что-то гавкнется, то отвечать все равно будет он, потому что бизнес его, а не разработчика, и потому что других лицензий практически не встречается в природе.
                                      • 0
                                        Я смотрю с другой стороны — заказчик что-то сделал по себя, в обход СДК/лицензии. При обновлении все бабахнуло, получаем запрос в суппорт, тратим кучу времени, что бы разобраться с проблемой. Потом всплывает, что клиент лазал туда, куда не надо и начинается долгий процесс разборок кто будет платить за потраченное время поддержки/разработчиков, кто будет отвечать.

                                        Красиво звучит. Только это фантастика.
                                        Потребитель заплатил за право пользования софтом в соответствие лицензией.

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

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

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

                                        Все зависит от клиентов и категории систем.
                                        • 0
                                          Я вам давно сказал, что условия поставки и софт бывают разными. О чем мы спорим, непонятно?
                            • 0
                              Как вариант — веб-морда к сетевому сервису. Изменения в веб-интерфейсе чаще всего потребуется внести при изменениях в основной логике сервиса, т.е. новая сборка и деплой.
                              Мне кажется, у автора именно такой случай — поэтому и возник вопрос встраивания статики в бинарник. В случае, когда главная цель сервиса — API для веб-сайта, согласен с вами — отдельные файлы удобнее.
                              PS. А что вы подразумевали под «частный случай», говоря об «ембеддед»? Мне кажется, это такой же кейс, как и api для сайта или сетевой сервис.
                              • 0
                                Ну я тут нечетко выразился. Не частный, а просто другой. Все-таки, когда говорят про веб, чаще подразумевается интернет, а не веб морды к роутерам. Ну т.е. если мы говорим, что собрать статику в бинарник это хорошо и полезно — надо уточнять, для какого проекта. А то для других это вовсе и не хорошо и не полезно.
                                • 0
                                  У автора в этой части в примере речь про персоны — ну какой сетевой сервис в самом деле? )
                                  • 0
                                    Надо же было на чем-то пример показать, основной проект — закрытый )
                                    На статике просто показан пример «задела на будущее» — сначала обработка статики выполняется передачей файлов с диска (http.Dir(assetsPath)), а уже в текущей части приведен пример встраивания статики в бинарник (и вытаскивания).
                                    С тем же успехом можно было кэшировать статику в redis'е например. Т.е., на мой взгляд, смысл тут в том, чтобы показать гибкость. Nginx классно отдает статику — к нему обычно вопросов нет, но если зачем-то понадобится отдавать ее не с диска, то можно вот так.
                                • 0
                                  Кто вам сказал, что во всех случаях будет новый релиз?

                                  Вы:
                                  И релизится будет только то


                                  Фронтенд и бекенд сейчас — это 2+ разных приложения. Но вы будете релизить как раз какое-либо приложение целиком.

                                  но в описанной тут архитектуре (к которой опять же и претензии) вся логика обработки хардкодится

                                  У нас же все конфиги компилируются, в некомпилируемом языке при сборке. Поэтому это ничем не отличается от компилируемых по способу распространения и работы. Ведь в обоих случаях есть сборка.
                            • +2

                              Нода кстати тоже нынче умеет "один бинарник"
                              https://github.com/zeit/pkg

                              • 0

                                Насколько я вижу данные тестов, опять ноду на один процессор сравнивают с Go на четырёх… Ну то есть понятно, что процессор и память она будет есть в любом случае больше в разы, но время, делёное на 4, уже получается таким же как у Go.

                                • –1

                                  == я вижу данные тестов, опять ноду на один процессор сравнивают с Go на четырёх


                                  Не выдумывайте. Все тесты выполнялись в одинаковом окружении. Больно признать правду?


                                  == время, делёное на 4, уже получается таким же как у Go.


                                  тут вынужден вас огорчить. Не только с нодойжс, с Гоу тоже — внезапно! — можно такой фокус провернуть — запустить не один процесс, а 4. Вот только нодажс отсосёт у Го по производительности в этом случае не в 4 раза, а раз эдак в 50.

                                  • 0

                                    Окружение одинаковое — 4 ядра. А тест написан так, что года задействует только одно. А Go нынче по умолчанию задействует все.


                                    В частности из-за вот таких восторженных невежественных бенчмарков у меня и сложилась антипатия к Go.

                                    • –1

                                      Хм… а я то думал, что нодажс не умеет в многопоточность — это проблемы нодежс, а не Гоу.
                                      И почему всего лишь 4? Давайте уже сразу 100500 нод vs. одного процеса на Гоу.


                                      ещё раз. Имеем Go 1 процесс ос, Nodejs 1 процесс ос. Это — одинаковое окружение.
                                      То, что предложили вы, Go 1 процесс ос, Nodejs — 4 процесс ос — это ни разу не одинаковое окружение, поскольку 4 > 1


                                      Приложение Гоу тоже можно запустить 4-мя процесами ос. тогда уже давайте тестировать 4 ноды против 4 Гоу


                                      Что нодежс будут в такой конфигурации быстрее — это всего лишь ваше предположение, ни чем не подтверждённое пока что. А не аргумент. в отличие от результатов тестов. Хотите опровергнуть достоверность тестов — сделайте это на деле а не на словах.


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

                                      • 0
                                        Хм… а я то думал, что нодажс не умеет в многопоточность — это проблемы нодежс, а не Гоу.

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


                                        Приложение Гоу тоже можно запустить в 4-мя процесами ос. тогда уже давайте тестировать 4 ноды против 4 Гоу

                                        Ну таки да.


                                        Что нодежс будут в такой конфигурации быстрее — это всего лишь ваше предположение, ни чем не подтверждённое пока что. А не аргумент. в отличие от результатов тестов. Хотите опровергнуть достоверность тестов — сделайте это на деле а не на словах.

                                        Приведённый тест заведомо некорректен. Простая логика подсказывает, что при использовании cluster результаты будут заметно отличаться. Писать свой тест только ради спора с вами — откровенно лень.


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

                                        Гмм.


                                        Больно признать правду?
                                        Вот только нодажс отсосёт у Го по производительности в этом случае не в 4 раза, а раз эдак в 50.

                                        Вижу заметно эмоциональные голословные утверждения с предвзятостью. Понимаю, что понравилась новая классная игрушка (и она правда классная, я ни разу не спорил), но это же не повод вот так некрасиво её форсить.

                                        • 0

                                          == Простая логика подсказывает, что при использовании cluster результаты будут заметно отличаться.


                                          ага, вот только совершенно не факт, что в лучшeю для ноды сторону, поскольку в Гоу сверхнизкий оверхэд на межпотоковое взаимодействие. Ну и если уж на то пошло гошный код намного проще накачать стероидами, чем нодовский. Можно переписать узкие места на Go-ассемблер. Использовать sync.Pool (хранилище повторно используемых объектов, куда можно складывать неприменяемые объекты, чтобы кто-то другой смог их достать и повторно использовать), оптимизированyый под использование на многоядерных компьютерах. Плюс ещё пачка хаков. А вы тут мне про кластер-шмастер рассказываете, который всего-то потоки (или процесcы?) создаёт. тот ещё bubble effect.


                                          == Писать свой тест только ради спора с вами — откровенно лень.


                                          ну разумеется! ведь делать заявления намного проще, чем писать код.


                                          == Вижу заметно эмоциональные голословные утверждения с предвзятостью


                                          То есть говоря о "восторженных невежественных бенчмарках" вы имели ввиду мои личные высказывания? забавно.
                                          Ну поскольку они подкреплены результатами тестов, я могу позволить себе их эмоционально окрасить.


                                          == это же не повод вот так некрасиво её форсить.


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

                                          • 0
                                            Ещё раз повторяю. Приведённые тесты заведомо некорректны. И дело не в тюнинге (если упарываться, то можно хоть CUDA прицепить), а в фундаментальном непонимании принципов работы технологии. Попытайтесь просто это понять. Больше мне добавить нечего.
                                            • 0

                                              Из того, что разработчик кода тестов на нодежс не использовал Кластер, ни каким образом логически не следует, что он не умеет в Кластер. Более правдоподобное предположение — Кластер вызовет ещё бОльшую деградацию перформанса нравится вам это или нет.


                                              "хоть CUDA прицепить" — о, ну из Гоу вызывать сишный код тоже можно и примерно с тем же результатом, при чём без приседаний как там описано по ссылке. Вот только речь шла о языковых инструментах, а не интеграции со сторонними платформами.

                              • +2

                                Вот преимущества Гоу, которые вы или не поняли, или не упомянули, или автор их не достаточно раскрыл:


                                1) Горутины предоставляют основное преимущество программирования потоков перед событийно-асинхронным и асинхронным программированием — простой и понятный линейный синхронный код, который легко поддерживать, дебажить и расширять + два дополнительных преимущества, благодаря которым программа на Go может спокойно работать с миллионом одновременно запущенных горутин:


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


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

                                При программировании на Go не нужно помнить, где именно использовать генератор или поставить await / async / yield — за вас это делает компилятор, который ошибается намного реже среднестатистического программиста


                                2) — простой синтаксис и go fmt, благодаря которым код на go легко понимать


                                3) сборка программы в один самодостаточный бинарник без каких-либо внешних зависимостей автоматически решает типичные проблемы деплоя новых версий программы — dll hell, dependency hell и jvm hell и избавляет от костылей в виде docker-а


                                4) кросс-платформенная компиляция out of the box — программу можно скомпилировать под любую поддерживаемую платформу на любой платформе. под виндой собрать бинарник для линукс или наоборот;


                                5) поддержка всех необходимых средств для тестирования и замеров производительности out of the box. Благодаря этому тесты с бенчмарками на go пишутся и читаются очень просто


                                6) поддержка профилирования по cpu, memory allocation’ам и блокировкам out of the box. Причем профилирование можно включать/отключать удаленно в продакшн в любой момент времени, и это не снизит существенно скорость программы


                                7) отсутствие "убийц времени", существенно замедляющих разработку программ на практике — эксепшнов, наследования, перегрузки операторов и функций, конструкторов, неявных преобразований типов и generic-ов


                                8) высокая скоростью компиляции


                                9) стандартная библиотека, содержащая действительно полезную на практике функциональность, а не нафиг не нужную хрень


                                Так что "ёжики продолжают плакать, колоться и писать на Go" — это у вас стокгольмский синдром на нодежс или на чём вы там пишите программы

                                • +2

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


                                  Про ёжиков, которые продолжают плакать и колоться — я имел в виду использование Go исключительно по той причине что "он же крутой". Как тимлид, я прикидываю, на чём мне писать различные компоненты системы — и использование Go выходит очень дорогим во внедрении. Хотя бы потому что или надо брать дорогих разработчиков, или переходить имеющимися, что в любом случае подразумевает затраты времени. Вопрос — стоит ли игра свеч, и в какой перспективе. Оговариваюсь — рассматриваю случай, когда не хайлоад, а некий относительно стандартный веб сервис. Проблемы в производительности которого (если возникают) гораздо легче решить горизонтальным масштабированием, чём писать хоть что-то новое. Думаю, у большинства ситуация такая же, как у меня — время разработчиков стоит гораздо дороже железа.


                                  Подводя итог — меня просто огорчает, когда в очередной раз пишут на Go то, что с тем же успехом и с на порядок меньшими затратами работало бы на php или node.js.

                                  • –2
                                    я имел в виду использование Go исключительно по той причине что "он же крутой"

                                    Тут дело не в моде, а в прагматичности. Go для тех, кто хочет быстрый, простой в сопровождении и расширении код. Для модников, любителей смузи, callback и dependency hell’a есть nodejs.


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

                                    В node и похапэ затраты будут значительно больше на деплой, сопровождение, отладку, тестирование. В отличие от Go в них на каждый чих надо прикручивать интеграцию со сторонними инструментами на подобие redis или memcached, поскольку платформы на столько ущербные, что не позволяют сделать даже банальный твердотельный кэш БД без жима лёжа с груди


                                    В Go затраты будут значительно меньше, поскольку


                                    2) отлично масштабируются на все ядра процессора, в отличие от однопоточного nodejs. При этом не нужно извращаться с shared memory при взаимодействии между процессами nodejs, ведь в Go достаточно одного процесса, чтобы загрузить работой все ядра CPU. И для этого не нужно извращаться с асинхронностью, калбэками, промисами, async / await и т.п. костылями при обращении к файлам и внешним сервисам типа базы данных, key-value storage/cache или самописным микросервисам — достаточно обычного простого и понятного синхронного кода.


                                    1. работают быстрее программ на nodejs и php — меньше нагрев железа и требования к нему


                                    2. содержат меньше багов, т.к. простой синхронный код легче дебажить, поддерживать и расширять, чем закрученный асинхронный.
                                    • 0
                                      Тут дело не в моде, а в прагматичности. Go для тех, кто хочет быстрый, простой в сопровождении и расширении код. Для модников, любителей смузи, callback и dependency hell’a есть nodejs.

                                      Повторюсь в пятый раз. В Node.JS как минимум уже три года как нет callback hell. Dependency hell возникает крайне редко в случае использования огромного количества разношёрстных библиотек разной степени давности. Просто не надо так делать. Кстати, такие случаи возникают обычно в случае использования всякого клиентского Javascript. Учитывая то, что в примере данной статьи клиентский javascript собирается той же нодой, Go не даёт ровным счётом никакой выгоды.

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

                                      Может быть правдой только в том случае, если у вас исходно нет никакой инфраструктуры. Если есть, то затрат на развёртывание новых модулей никаких нет.

                                      на каждый чих надо прикручивать интеграцию со сторонними инструментами на подобие redis или memcached

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

                                      отлично масштабируются на все ядра процессора, в отличие от однопоточного nodejs.

                                      Опять повторюсь — если это нужно, то все ядра нагружаются кластером.

                                      извращаться с shared memory при взаимодействии между процессами nodejs

                                      Wut?

                                      В Go затраты будут значительно меньше, поскольку...

                                      У вас правда затраты измеряются исключительно затратами на железо? И снова повторюсь — большая часть затрат (опять же, если у вас не лютый хайлоад) — не на железо, а на время разработчиков. Время PHP разработчиков в 3-4 раза дешевле, чем Go разработчиков. Время Node.JS разработчиков в 1.5-2 раза дешевле, чем время Go разработчиков. В 99% случаев время окупаемости затрат на более дорогую разработку стремится к бесконечности. Аргумент про «содержат меньше багов» я просто опущу, поскольку это полнейший холивар.
                                      • –2
                                        В Node.JS как минимум уже три года как нет callback hell.

                                        Да, чатично ему на смену, частично в дополнение, пришёл promises hell и мучительные попытки понять в каких местах нужно ставить async await. Ещё через лет 10 они придут к пониманию, что надо сделать легковесные потоки как в Гоу, потом ешё через 5 их реализуют.


                                        вы видимо просто не знаете, зачем используется redis.

                                        Из чего вы сделали такой вывод? Рассказать вам как Гоу делается в 10 строчек кода на базе стандартного map-а и стандартных примитивов синхронизации то, для чего в ноде нужно костылить с помощью сторонних глючных и неудобных в использовании говномодулей?


                                        извращаться с shared memory при взаимодействии между процессами nodejs
                                        Wut?

                                        А вы почитайте про проблемы конкурентного программирования (очень полезные знания для тимлида), прежде чем гневно топить за ноду


                                        Время PHP разработчиков в 3-4 раза дешевле, чем Go разработчиков. Время Node.JS разработчиков в 1.5-2 раза дешевле, чем время Go разработчиков.

                                        Пруф в студию.


                                        Аргумент про «содержат меньше багов» я просто опущу, поскольку это полнейший холивар.

                                        так это статистика гитхаба — из проектов с овер 10000 звёзд наиболее надёжные — Гоу, Erlang и Clojure.

                                        • –2
                                          клиентский javascript собирается той же нодой, Go не даёт ровным счётом никакой выгоды

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


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

                                          Может быть правдой только в том случае, если у вас исходно нет никакой инфраструктуры. Если есть, то затрат на развёртывание новых модулей никаких нет.

                                          с каких это пор создание, сопровождение и интеграция инфраструктуры стали бесплатными?

                                  • 0

                                    Вот еще один бенчмарк, где node.js со swift’ом проиграли Go почти в 20 раз — https://github.com/valyala/swift-response

                                    • 0
                                      Имейте совесть и смотрите бенчмарки, которые приводить в пример.
                                      Там сравнивается производительность Go с кодом из пяти строк и использованием нативных библиотек с производительностью ноды с экспрессом. Если вы не в курсе, экспресс — один из самых универсальных и тяжёлых серверов для ноды. Всё то же самое можно было бы написать в такое же количество строк кода на нативных библиотеках, и работало бы это минимум раз в пять быстрее. Минимум.

                                      Вот так вот и выглядит вся популяризация Go. Сделать любой подлог, только чтобы получить зрелищные бенчмарки. Стыдно должно быть.
                                      • –1
                                        Всё то же самое можно было бы написать в такое же количество строк кода на нативных библиотеках, и работало бы это минимум раз в пять быстрее.

                                        к сожалению это не более чем ещё одно голословное утверждение.
                                        почему именно в 5, а например не в 7.5? Может быть всё же реальный коэффициент — 1.1...1.2?
                                        и на фига тогда нужен Express, если нативные библиотеки быстрее?

                                    • 0
                                      Не только переводчик — автор тоже молодец. Возможно он склонен к преждевременным оценкам, но статью он сделал полезную. Как тьюториал — просто превосходно для новичков.

                                      Что касается востребованности Go — она становится более отчетлива, когда вы определите нишу и станете подбирать язык под нее. Например, у меня есть три важных вещи: мне нужен язык без GIL, с возможностью передавать аргумент по ссылке, но так, чтобы быстро написать код. Что посоветуете, кроме Go?
                                      • 0
                                        Я понимаю, что навлеку гнев и ненависть, но… C#? Даже есть аналог channels и всякие ништяки с zero-copy buffers.
                                        • 0
                                          Код на C# не пишется быстро, на сколько мне известно. И он будет конкурентом только до тех пор, пока приложение надо писать под Windows. А это очень узкий круг из полного списка.
                                          • 0
                                            Вообще пишется очень быстро… Очень странное наблюдение. У меня как раз обратное впечатление. Особенно без дженериков. Может пример приведете? И на *nix прекрасно себя чувствует. .Net Core Linux.
                                            • 0
                                              Не знал, что C# кроссплатформенный. Ну ок, пусть так.
                                              Давайте опустим, что эта кроссплатформенность не полная (это я только что загуглил :-) ), и что кроссплатформенность оплачивается потерей производительности — как любая кроссплатформенность, а значит хайлоад особо не попишешь.

                                              Тогда получается, что Go и C# конкуренты. Но, видимо, это полный список. Всего два варианта. Что и является ответом на вопрос, зачем нужен Go.
                                              • 0
                                                Полная это на сколько? :) Есть Mono и CoreClr. Mono вообще на всякой экзотике работает.
                                                Но производительность Mono отстает от CoreClr весьма знатно. CoreClr как раз весьма шустрый и как раз прекрасно решает задачи high load.
                                                Вот тут еще можете глянуть что готовят ;)
                                                • 0

                                                  Да не суть важно полная или нет. Тем более, что я сказал "допустим" — потому что это все равно не влияет на список конкурирующих языков. По факту C# все равно в списке только до тех пор, пока не задали вопрос, зачем возиться с портированием, если есть нативный Go. То есть вопрос "зачем нужен Go?" отвечен.

                                                  • 0
                                                    Портированием чего? Если вы не собираете платформозависимый бинарник, то вообще проблем нет(Я про CoreClr, не про .Net или Mono).
                                                    У меня проект, который запускается на RHEL, WinServer Nano и Debian.

                                                    Что вы подразумеваете под нативный? :)
                                                    • 0
                                                      Портированием чего

                                                      Кода на C#, который не будет работать без виртуальной машины (а именно этим является CLR, про который вы говорите). Также, как не работает код Java без JVM и как не работает код ни одного интерпретируемого языка, потому что по сути все интерпретаторы — виртуальные машины (типа как Python Virtual Machine).

                                                      У меня проект, который запускается на RHEL, WinServer Nano и Debian.

                                                      Я очень рад, что вы на столько талантливый инженер, что можете запустить что угодно на чем угодно с десятью прослойками и костылями. Но тему диалога пожалуйста прочитайте.
                                                      Я дал в условиях «отсутствие GIL» — что должно вам намекнуть, что задача написать очень экономное по CPU приложение и передачу по аргументу, что в основном применяется для экономии памяти. Экономное, понимаете? Не подходит ваш C#, потому что ему нужен CLR. А без этого он не работает и свою исконную быстроту (что есть экономия ресурсов CPU/RAM и прочих) показать не может.
                                                      Вы сможете мне показать хоть один high-load проектов на C#? И если не найдете, сможете объяснить, почему его не существует?

                                                      Что вы подразумеваете под нативный?

                                                      Если вам нужна виртуальная машина, то ваш код не является нативным для данной платформы.
                                                      • 0
                                                        CoreClr уже кроссплатформенный вообще то…

                                                        Ох… C# не интерпретируемый. Он компилируемый, как и Go, как и Java. Только Go использует AOT компиляцию сразу в нативный бинарник, а JVM и CLR компилируются в промежуточный ассемблерный язык(IL, Bytecode) своей VM и при первом выполнении в нативный код(грубо говоря). Причем для C# уже есть CoreRT.
                                                        Уж если говорить про быстроту, то тут есть нюансы. Типа проверка выхода за границы массива. По умолчанию она работает в C#(грубо говоря), но вы можете использовать unsafe например.

                                                        StackOverflow? :D

                                                        Вы в курсе что у Go так же есть рантайм, который так же отвечает за GC, выделение памяти и тд? Этот тот же JVM или CLR, только без промежуточной компиляции.
                                                        • 0
                                                          Вы в курсе что у Go так же есть рантайм, который так же отвечает за GC, выделение памяти и тд? Этот тот же JVM или CLR, только без промежуточной компиляции.

                                                          Я даже в курсе, что это неправда. Правда тут: "Go's runtime is analogous to libc, the C library.
                                                          It is important to understand, however, that Go's runtime does not include a virtual machine, such as is provided by the Java runtime. Go programs are compiled ahead of time to native machine code
                                                          "
                                                          Полный текст.

                                                          C# не интерпретируемый

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

                                                          Я не готов продолжать этот бессмысленный спор, пока вы не объясните, зачем он нужен для той изначальной задачи, о которой говорилось.
                                                          Покажете, где C# используют для серьезного хайлоада — тогда продолжим про него говорить. Нет — тогда сами думайте почему его не используют.

                                                          Хорошего вам дня.
                                                          • 0
                                                            Вы понимаете, что код на Java и C# То же будет нативным после работы JIT? Рантайм может добавлять дополнительную логику и проверки. Но это уже нюансы, который могут быть как opt-in так и opt-out.

                                                            Тогда причем тут GIL?

                                                            Я вроде показал — StackOverflow.com. Может у вас какое-то свое определение этого термина? Тогда Azure Portal сойдет? Или AzureAD?

                                                            Ваши тезисы относительно C# некорректны и показывают, что вы говорите о том, чего не знаете. Ваш разговор о GIL уже показателен.
                                                            • 0
                                                              GIL тут при том, что вы выдергивае е слова из текста не заморачиваясь о их значении. Потом уже склеиваете из них предложения, какие вам нравятся. Я не говорил, что у С# есть GIL, а потому не хочу сидеть тут с виноватым видом, как будто я такое сказал.

                                                              И я не знаю на что вы мне отвечаете «стэковерфлоу», потому что вы не цитируете фразу перед ответом. Что stackoverflow?

                                                              Ну и я обращаю внимание на то, что вы так и не смогли показать ни одного серьезного хайлоад проекта на C#.
                                                              • 0
                                                                Вы приводите требование к отсутствию GIL при обсуждении C#. Вообще даже ЯП с GIL могут в хайлоад.

                                                                Он написан на .Net + C#. Как и то, что приведено дальше. AzureAD проводит 1 миллиард аутентификаций в день. Или это не достаточно high-load?

                                                                Вы считаете Go какой-то магией, хотя это просто GC+AOT и специально обрезанный функционал языка с настройкой GC под определенные кейсы. Java и C# — GC+JIT. Причем C# так же умеет в AOT(dotnet native) для некоторых задачек уже.

                                                                • 0
                                                                  Вы приводите требование к отсутствию GIL при обсуждении C#

                                                                  Это не правда. Хронология диалога такова:
                                                                  1. Мне нужен язык без GIL (+2 других правила)
                                                                  2. Вот тебе C#
                                                                  3. C# отвечает этим требованиям (отсутствие GIL + 2 других правила) и помещается в список конкурентов. Но не проходит по другим требованиям, которые изначально озвучены не были.

                                                                  Вы считаете Go какой-то магией

                                                                  Еще одно голословное утверждение, которого я не заявлял. Более того, ниже другому человеку я написал:
                                                                  Там, где бизнес логика, там никому, кроме Java и C# вообще делать нечего


                                                                  Сколько еще вы будете делать за меня заявления и сам же их опровергать? Я вам вообще нужен в споре? Мне кажется, вы вполне самодостаточны.
                                                                  • +1
                                                                    Тогда зачем обсуждать GIL и интерпретируемые языки вообще относительно C#? :D

                                                                    Проблема в том, что вы не в курсе как обстоят дела у C# сейчас, но беретесь его оценивать и сравнивать :)

                                                                    • –1
                                                                      Вы меня довести решили?
                                                                      GIL мы обсуждаем потому, что это было изначальным условием. Вне зависимости от того, приплели вы тут C# или не приплели. Задача крутится вокруг GIL, arg by reference и быстрой скорости написания. С какого перпуга с вашим появлением она начала крутиться вокруг C# я не понимаю. Прошел C# по критериям — отлично. Не пролешел — тоже отлично. Но GIL — изначальный критерий.

                                                                      Проблема в том, что вы не в курсе как обстоят дела у C# сейчас, но беретесь его оценивать и сравнивать :)

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

                                                  C# и net core ни чем не лучше java и jvm. На вскидку почему net core хуже рантайма Гоу для бэкенда:


                                                  • в net core нет зелёных потоков


                                                  • net core по тяжести аналогична jvm, но по уровню развития отстаёт лет на 10


                                                  • деплой преимущественно через докер


                                                  • net core ещё не допилили до уровня production ready. Тулинг постоянно меняется, большая часть старых либ не умеет в net core, например, FparsecCS


                                                  • зоопарк с зависимостями и конфигурацией проекта

                                                  Опять же на вскидку почему С# хуже Гоу:


                                                  • стандартная библиотека C# в сравнении с Гоу поражает своей бедностью


                                                  • в C# огромное количество убийц времени — дженерики, наследование, перегрузка методов, боксинг-анбоксинг, конструкторы и т.п.


                                                  • в целесообразности и правильности расстановки асинков и эвейтов легко запутаться и допустить ошибку, которую потом хрен поймаешь

                                                  -нет встроенных бенчмарков и средств тестирования — оно делается через убогие костыльные фреймворки на подобие nunit


                                                  -нет встроенных детекторов гонок данных

                                                  • 0
                                                    1. А они нужны? Мне модель native thread + tasks + async нравится.
                                                    2. Аргументируйте пожалуйста.
                                                    3. Спокойно без докера все делается. Возможно обилие статей вводит в заблуждение :)
                                                    4. Тулинг менялся один раз (project.json -> *.csproj). Сейчас уже не меняется. В 2.0 как раз будет механизм для поддержки старых либ.
                                                    5. Поподробнее пожалуйста. Если вы на релизных пакетах — проблем особо нет. У меня один из проектов на найтли билдах живет и не сильно страдаю от этого. Но это осмысленный выбор :D

                                                    1. Примеры? Стандартную либу уже расширяют пакетами. Надо каналы? Ставите нужны пакет и вперед.
                                                    2. Не используйте, если вам это не надо. А GC вас не смущает? Может просто на C писать? ;)
                                                    У меня вот наоборот проблема была с тем, что приходилось дублировать код для коллекций.
                                                    И за прошлый год добавили достаточно, что бы как раз дать возможность писать высокопроизводительный код, но при этом вы сами выбираете где и в какой части системы что использовать. Мне вот как-то не сильно понравилось на Go бизнес логику реализовывать(например работу с OpenId Connect). Но это все индивидуально.
                                                    3. Вообще там ничего сложного нет. Достаточно просто почитать и глянуть ildasm'ом разок.

                                                    Зачем встроенный бэнч? Есть BenchmarkDotNet.
                                                    Вы вспомнили трупик блин. Есть шикарный xUnit.
                                                    Плюс все тулы могут добавлять свои команды для dotnet.

                                                    Вот тут согласен. Но есть Concurrency Visualizer :)

                                                    Если хотите поподробнее обсудить — пишите в личку :)

                                                    • –1

                                                      Спасибо за интересный и подробный ответ! Позволю себе дать Вам совет — забейте на C# и asp net core с кучей бессмысленных мозгодробильных абстракций и магии. Переходите на Go. Там все просто и понятно. Основы Go изучаются за пару дней. Нормальный код сможете писать через неделю.


                                                      1) https://habrahabr.ru/post/329622/#comment_10240390 см. "1) горутины" Добавлю, что через пару лет поймут, что программисты тупые и не могут правильно расставить асинки с эвейтами в большинстве случаев. После этого "изобретут" dot-net-routine'ы с channel'ами. Но уже будет поздно, т.к. 99% программ будут писаться на go. :-) А в данный момент потоки операционной системы имеют следующие недостатки по сравнению с goroutines:


                                                      • Размер стэка нельзя изменять после старта потока. Поэтому на каждый поток выделяется слишком много памяти под стэк, чтобы хватило на все случаи (обычно несколько мегабайт и больше). В go размер стека динамически меняется. Поэтому при старте горутины выделяется 2КБ или 4КБ стек, который потом растет по мере необходимости. Выходит, что для ста тысяч потоков под С# нужно более 100 гигабайт памяти под стэк, а для go — от 200 мегабайт,.


                                                      • Переключение между потоками операционной системы занимает намного больше времени по сравнению с переключеним между goroutines в go. Для переключения между горутинами достаточно только сменить контекст горутины без перехода в режим ядра (в контекст горутины входит ограниченный набор регистров CPU).

                                                      2) я имею ввиду наличие большой виртуальной машины и задержки, с которой она стартует процесс. В Гоу ни того ни другого нет. Для сравнения бинарник Гоу — это 5..15 МБ, и в функцию main процесс попадает за примерно 15 мс. Размер бинарников go-программ со включенным в них кодом рантайма получается в несколько раз меньше размера net core-программ, которым для запуска нужна ещё и виртуальная машина внушительного размера.


                                                      3) на выделенный VPS думаю да, но для облачных приложений, например, heroku и amazon, докер всё таки потребуется. А для Гоу — нет :-)


                                                      5) возможно повезло вам, у меня более печальный опыт с релизными библиотеками в asp net core. Например, драйвер orientdb переодически отваливается в процессе развития net core. Можно конечно ругать разработчиков библиотек, но Гоу тулинг построен так, что подобных проблем никогда и не было. В большинстве случаев невозможно перевести программу с большим количеством внешних зависимостей на новую версию net core. Для этого нужно дождаться, пока авторы всех зависимостей соизволят портировать их на новую версию. А это на практике мало реально.




                                                      1) Например


                                                      • http сервер из коробки c http/2.0 и tls
                                                      • https без использования OpenSSL
                                                      • поддержка автоматического получения и обновления TLS-сертификатов — golang.org/x/crypto/acme/autocert
                                                      • сериализатор asn1. В С# даже для банальной сериализации json надо прикручивать костыльную стороннюю либу, написанную хипстером. Естественно сериализация json есть в стандартной библиотеке go
                                                      • data-driven шаблоны для генерации форматированного вывода text/template, html/template и т.д., плюс пакет синтаксического анализа, на котором они построены.
                                                      • высокоуровневая поддержка обработки растровых изображений, в сравнении с которой System.Drawing — слёзы.
                                                      • разбор флагов командной строки
                                                      • ещё много всего нужного и полезного
                                                        Поэтому в гоу для решения большинства задач достаточно стандартной библиотеки, а в С# обычно нужно подключать кучу сторонних библиотек, большинство из которых мягко говоря неудобны в использовании, как и стандартная библиотека.

                                                      2)


                                                      А GC вас не смущает?

                                                      Нет, не смущает, посколку в go1.8 STW паузы GC не превышают 100 микросекунд на любом размере хипа :-) С таким GC можно и нужно жить. В то время как STW паузы в net core сильно зависят от настроек GC и размера хипа, и в моём случае измерены в районе 100 миллисекунд, т.е. в 1000 раз больше, чем в Go.


                                                      Может просто на C писать? ;)

                                                      я с удовольствием. Имхо прекрасный язык. Практика подтверждает :-)


                                                      приходилось дублировать код для коллекций.

                                                      Какие контейнеры кроме array и hashmap вы используете каждый день? Эти два контейнера встроены в Go и позволяют работать с произвольными типами. Остальные контейнеры используются настолько редко, что не составляет никакого труда написать их кастомную реализацию под требуемый тип данных. Кроме того! Вы удивитесь насколько продвинутые возможности кодогенерации есть у сторонних инструментов/библиотек экоситемы Гоу


                                                      3) Совместно компилятор и рантайм Гоу БЕСПЛАТНО делают то, над чем бьются с переменным успехом джедаи dot net за деньги заказчика/инвесторов :-) Я в своей практике не встречал ни одного программиста включая себя, который умел бы правильно расставлять асинки-эвейты

                                                      • 0
                                                        Я даже спорить с вами не буду. Go мне нравится, но C#+AspNetCore разумный компромисс для меня между Java и Go :) С авинками проблем нет и 100 тыс. потоков не запускаю.
                                                        А вот 100 тыс. тасков запросто ;) TaskScheduler раскидывает таски по потокам, а тред пул регулирует необходимое количество в зависимости от загрузки.

                                                        При возникновении любой сложной логики объектная модель Go меня совершенно не устраивает. Тут я лучше Scala возьму. Но C# уже скоро не отличить от нее будет :D Работа с большими codebase для меня очень неудобна(больше 700kk loc).
                                                        Огромный dealbreaker — нет динамической линковки и рефлексии. Сложные системы расширений и плагинов никак.
                                                        Кастомные коллекции очень важны для инкапсуляции специфической логики работы с набором данных.

                                                        http/2, tls, port sharing: WebListener. Есть еще Kestrel(но они упираются по части http/2). И кастом народ активно пилит.
                                                        На никсах да не супер. Но в основном хостинг на Nano или Service Fabric. Там норм :D
                                                        Очень спорный функционал. Обычно я через PKI инфраструктуру такие штуки делаю.
                                                        Хотите могу дать исходники))) JavaScriptSerializer вообще со времен царя Гороха :)
                                                        Это вы про var myString = $«This is my {somevariable}»?
                                                        Лучше ImageSharp, SkiaSharp но и Drawing кстати портировали.
                                                        Ну например
                                                        System.CommandLine

                                                        GC в Go имеет определенный тюнинг под специфичные задачи. Я просто использую unsafe и никакого STW по 100 ms ))
                                                        Часто использую хешсеты, связанные списки, очереди. Более сложные вещи типа BlockingCollection и тд. Хотя последнее сейчас заменяю на каналы.
                                                        T4 шаблоны? ;)

                                                        Ну тут у каждого свой опыт. Иногда полезно ковыряться в MSIL. На самом деле не все так сложно :D

                                                        Причем про стандартную либу еще сразу подкину ссылочку. Ее легко пропустить, но когда делал прототипы на Go и на NetCore был удивлен, что все нашлось ))

                                                        Про остальное попозже расскажу. Пока времени нет :)
                                                        • 0
                                                          Green vs Native threads достаточно обширная тема для обсуждения. У обоих подходов есть право на жизнь. ThreadPool + Tasks очень хорошо справляются со своей задачей ИМХО.

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

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

                                                          Для деплоя как Go есть self-contained режим сборки ;)

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

                                                          В целом Go классный, но для больших приложений со сложной логикой — ну его нафиг :)

                                                          Кстати шаблонизатор на Go это типа Razor?
                                        • +3
                                          Автор оригинала решал очень простые проблемы, я бы даже сказал что тривиальные.

                                          Но когда появится необходимость писать уже чуть более сложную бизнесс логику, то полезет много неприятных моментов в виде в рефлексию и/или написание полотна однообразного кода. Go не самый удачный выбор для сложных веб-приложений.
                                          • 0
                                            Там, где бизнес логика, там никому, кроме Java и C# вообще делать нечего. IMHO.

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