Alex Code
142 subscribers
9 photos
19 links
Разработка, технологии, продукт, стартапы, управление и так далее
Download Telegram
Channel created
Всем привет 🤟

Давайте знакомиться - меня зовут Александр Русаков.
Вкратце перечислю, почему в принципе мои мысли относительно IT (и не только) могут быть интересны:

- занимаюсь программированием за деньги с 2010 года
- прошел путь от Junior Developer до CTO
- обучаю разработке, провожу вебинары с 2017 года
- поработал и в стартапах, и корпорациях, и в заказной разработке
- мне все еще интересен широкий перечень направлений (от фронтенда и верстки до devops и unit-экономики)
- и это еще не все 😊

До следующих апдейтов 😁
Продукт vs Технологии

Обсуждали с коллегой вопрос, к чему склоняться при выборе проекта. Что лучше - скучный продукт с крутыми технологиями или интересный продукт, но технологии так себе? 🤔

Давайте попробуем провести небольшую декомпозицию технической части. С одной стороны под технологиями можно понимать низкоуровневый набор языков программирования, библиотек, фреймворков, тулзов и сервисов, с помощью которых продукт функционирует в данный момент. С другой стороны можно иметь в виду более глобальные вопросы, которые придется решать: работа под высокими нагрузками, приложения реального времени, какая-то big data в конце концов. При должном упорстве один фреймворк можно поменять на другой (более хайповый), а вот глобальные задачи вряд ли удастся изменить.

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

Такие получились размышления относительно противостояния продукта и технологий в вакууме.
До связи 👋
Скорость софта и божественный ускоряющий upgrade

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

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

Во-вторых, профессия программист изменилась, изменились кадры. Если в 70ые-80ые это были люди с высшим образованием и степенями PhD 👨‍🦳, то в наше время можно закончить интенсив на пару месяцев и ты уже "пограмист" 👶. Человечеству нужно как можно больше софта, поэтому чем-то приходится жертвовать. Новоиспеченные разработчики больше обеспокоены тем, как бы задачу сдать в срок, а не все эти ваши рюшечки и бантики.

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

Но о чем это мы? Мы начинали про скорость софта, поэтому давайте на нем и завершим. Что же делать, если от скорости страдаем здесь и сейчас, а чудесное время работы над тех. долгом не настало. Единственная надежда, на которую мы надеемся - это божественный ускоряющий upgrade. Случайно посмотрели на changelog вашего супер-пупер фреймворка, а он в новой версии стал в 2 раза быстрее 🚀 да еще и сохранил обратную совместимость 🫶 Тогда бежим, скорее обновляемся и наша жизнь становится капельку лучше.

P.S. Например, этой весной вышел TypeScript v5, который стал и меньше весить, и реально быстрее работать.
https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/ Сказка.
Про Headless CMS в общем и Strapi в частности

Вряд ли кого-то можно удивить аббревиатурой CMS. Они известны с уже далеких 2000ых: всякие Wordpress, Joomla, или не дай бог Bitrix. Но что за зверь Headless CMS? Давайте разберемся.

Где-то к середине 2010ых годов на рынок разработки вышло приличное количество frontend-разработчиков, потому что всем нужны были Web 2.0 сайты, диджитал и вот это все. Это породило большую тройку фронтенд фреймворков (react, angular, vue) и соответственно создавать страницы внутри убогих интерфейсов CMS и потом прикурчивать jQuery к этим страницам уже никто не хотел. Так появились сначала изоморфные приложение, а потом и Server Side Rendering или SSR, под которым сейчас все понимают запуск js-кода на сервере и рендеренг HTML с помощью вашего любимого браузерного фреймворка.

Что же получается? Для таких ребят не нужна CMS в привычном смысле, где в конструкторе или псевдокоде собираются странички из блоков. Конструктор нужен, но уже не страниц, а бекенда целиком и результирующего API, чтобы затем отобразить полученные данные так, как хочется. Ведь типичный бекенд очень часто похож на копи-паст роутеров, валидаторов, запросов в БД и сериализиторов на выходе. Так почему бы не сделать один раз и на все случаи жизни 😅

Итак, на сцену выходит Headless CMS Strapi (https://strapi.io/):
- начиналась как Open Source проект на Javascript + Node.js
- привлекла первый seed раунд инвестиций $4 миллиона в 2019 году
- суммарный объем инвестиций на текущий момент - $45 миллионов
- более 54k звезд на Github ⭐️
- более 70k установок ежемесячно по данным npmjs.com

Опенсорс версия остается бесплатной и по сей день. На чем же заработок? Для тех, кто не хочет заниматься настройкой и деплоем, Strapi предлагают готовую к использованию облачную версию за $99 в месяц на тарифе Pro и за $499 в месяц на тарифе Team. На тарифе Team прям жирненько 🤑

Какое у меня сформировалось ко всей этой истории отношение:
Во-первых, в 2019 году мы пытались внедрить Strapi на одном проекте, но отказались из-за отсутствия встроенного Rich Text Editor и поддержки иерархичности данных. В тот момент Strapi действительно была очень простой CMS.
Во-вторых, мне очень нравится такая модель, когда на базе опенсорса ребята смогли выстроить коммерчески успешную историю. Единственное, чего мне здесь не хватает, так это какой-то действительно прорывной технологии. Ну запрогали красивую админку, ну поля и формочки разные, есть коннекты к популярным бд (MySQL, PostgreSQL, MongoDB), наружу все это отдается через REST API или новомодный GraphQL. Можно ли это легко повторить? Не вижу препятствий 🙂
Я вроде бы и не впечатлен, но удалось ли этим ребятам захватить действительно полезную и востребованную нишу? Безусловно да. Если кто-то говорит Headless CMS, то Strapi всегда на слуху.

В сухом остатке собирать на конструкторе бекенд критической части приложения я бы не стал, но вот заменить все кастомные админки для лендингов, сайтов-визиток и корпоративных блогов - рекомендую. До связи 🤟
Про git и Сonventional Commits

Вспомнил забавную цитату про читаемость кода. "Пишите код так, как будто поддерживать его будет склонный к насилию психопат, который знает, где вы живёте!". Аж кровь стынет в жилах 😅 Шутки-шутками, но мысль о том, что профессиональные программисты пишут код, который потом будут читать и пытаться понять другие люди, так или иначе закрепляется в светлых умах. А что же насчет маленьких строчек текста, которые мы оставляем в git commit?

Ситуация с commit-ами немного иная: все понимают, что лучше бы написать туда что-то понятное, но все не так радужно. Сама система контроля версий никаких ограничений не накладывает, и в итоге коммиты пишутся на скорую руку и без какого-то смысла, а главное структуры: "bugfix something", "add new property", "close issue #42" и т.д. Понять характер измнений и наличие обратной совместимости обычно не представляется возможным.

Если вам так же кажется, что все тлен, то предлагаю познакомится с системой Conventional Commits. В общем виде заголовок коммита выглядит так:

type(scope): short description

Как это читать?
- Тип изменений - слово из фиксированного списка (fix, feat, perf, test, ci, build и тд)
- Опциональный скоуп - изолированная часть кодовой базы, к которой относятся изменения. Вы их выбираете сами под проект и нужды.
- Короткое описание в настоящем времени. Обычно включает глагол add, remove, setup, change и тд
- Если тип заменен на BREAKING CHANGE или после типа добавляется ! - значит изменения нарушают обратную совместимость

Несколько примеров заголовков коммитов из проектов на github, которые уже следуют этой системе:

test: fix editor SDK test
perf(core): setup workspaces in parallel
feat!: make all settings mergeable

Чуть больше подробностей читайте в официальной доке https://www.conventionalcommits.org/. А в следующий раз мы поговорим причем здесь версионирование.
До связи 🤟
Программирование и структуры данных

Я думаю многие знают замечательного парня Линуса Торвальдса, который подарил миру Linux, Git, а также массу мемов и цитат типа "Nvidia, fuck you!". Ещё Линус человек прямолинейный, за словом в корман не лезет и не стесняется поучать других в переписке разработчиков Linux. В одной из таких переписок и находится интересная цитата про код и данные (перевод на русский): "Плохие программисты заботятся о коде, хорошие - о структурах данных и их взаимосвязях".

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

- Данные первичны. От постановки задачи до конечного результата "заказчика" интересуют данные, а не чудесный способ их получения/хранения/обработки.

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

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

- Если начинать Code Review со способа хранения, то обычно все остальное становится более понятным.

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

Думайте о данных и хорошего коддинга 🤟
Must have технологии - S3

С годами активного проектирования и разработки сервисов логично накапливать строительные блоки 🧱, которые, может быть, не идеальны, но вы умеете их готовить правильно. Начну постепенно описывать свой набор. Первый кирпичик - хранилище объектов S3. В рамках S3 вы можете создать сколько угодно контейнеров, а уже в самих контейнерах лежат папочки и файлы. Изначально был запущен в качестве компонента AWS, но S3 настолько удобен, что доступен сейчас у всех крупных и не очень облачных провайдеров, есть опенсорсные реализации и в принципе является почти стандартом хранения файлов.

Для чего использую:
- Cохраняю статические файлы после сборки веб-сайтов (js, css, картинки, шрифты) в публично доступный контейнер S3, подключаю сеть для раздачи контента (CDN), а дальше статика оказываются в браузере ваших клиентов 👨‍👩‍👧‍👦
- Кладу в S3 файлики, загружаемые пользователями. Обычно это бинарные данные типа картинок, документов и тд. S3 для этого должен быть приватным. Доступ к нужным файлам для нужных пользователей реализовывается на уровне вашего приложения.
- Храню бекапы БД . Здесь несколько моментов. Для разных окружений/контуров использую разные контейнеры, чтобы разграничить доступ. Для этой темы идеально подходят "холодные" контейнеры, они дешевле для редко запрашиваемых данных. И, наконец, бекапы обычно не хранят вечно, поэтому настраиваю для таких контейнеров автоматическое удаление через 1-2-3 месяца 📆

P.S. При разработке и в CI использую Minio - с задачей справляется. Есть Docker 👍

До связи 🤟
Бизнес на Open Source

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

- Платная версия. У опенсорс продукта появляется вторая версия, которая продается за деньги. Есть все тоже, что и в бесплатной версии плюс вагон и/или маленькая тележка ништяков. Часто эти ништяки не относятся к основной функциональности приложения. Модель хорошо работает с технически сложными решениями (для них сложно/дорого искать замену). Для меня каноническим примером является Nginx. Есть Open Source версия, а есть NGINX Plus - коммерческий вариант, в котором есть дополнительные модули, а у общепринятых модулей больше различных опций.

- Облачная версия. На базе опенсорс продукта создается сервис, который помогает развернуть решение в облаке ☁️. Оформили подписку и всю головную боль по развертыванию, обновлению, мониторингу и так далее отдали на откуп. Вспоминается MongoDB и их облочное решение MongoDB Atlas: выбрали тариф, облако развертывания (AWS, Azure или GCP) и вперед - документо-ориентированная БД готова.

- Продажа модулей. Если опенсорс продукт предоставляет механизм расширений 🛠, то вокруг этого строится marketplace, где можно публиковать и продавать дополнительные модули. В этой модели и маркетплейс может зарабатывать на комиссии, и совершенно сторонние разработчики могут какую-то денежку на своем коде получать. Яркий пример CMS Wordpress, для которой существуют сотни платных плагинов.

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

- Дополнительный продукт. Нередко вокруг основного опенсорс продукта можно создать связанные продукты, которая будут решать узкоспециализированные проблемы пользователей основного решения. Например, Postgres.ai решает проблему создания быстрых "клонов" для баз данных PostgreSQL, что очень полезно, если проверить работу на большом количестве данных необходимо, но создавать/хранить постоянно бекапы долго и дорого, а давать доступ к продакшену для тестирования никто не будет.

- Обучение. Пожалуй, это скорее отдельная сфера - EdTech 📚. Но в любом случае очень большая часть обучения построена вокруг Open Source: языки программирования, фреймворки, базы данных, devops инструменты и так далее. Примеров приводить не буду, сейчас любой может привести минимум 5 примеров компании, которая гарантирует обучить с нуля до Middle Developer за 3-6-9-12 месяцев 😄

- Донаты. Вы создаете популярный опенсорс инструмент и его поддержка стала занимать слишком много времени? Открывайте прием донатов и занимайтесь вашим github-детищем в режиме фул тайм 😍 Например, один из самых популярных сборщиков для фронтенд-приложений - Webpack - собрал за все время более $1 миллиона!!! 💸

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

Люблю заходить в тему с цитаты, итак: "Есть только две сложные штуки в Computer Science: инвалидация кеша и придумывание названий" (автор Фил Карлтон). Будем считать, что с названиями для нас всё понятно 😂

А что же с кешом, в чем проблема? Для осознания масштаба проще всего перечислить кеши, которые могут участвовать в обработке одного запроса типичного веб-приложения:

- кеш в браузере (всякие заголовки Cache-Control, Expires, ETag принимают в этом непосредственное участие)
- кеш CDN, в котором хранятся копии статических файлов поближе к пользователям по всему миру
- кеш на прокси-сервере, например, Nginx и директивы с префиксом proxy_cache
- кеш уровня приложения, например, в in-memory бд типа Redis
- кеш основной бд, например, PostgreSQL пытается держать индексы и часть данных в памяти для ускорения доступа к ним
- кеш для жёсткого диска (в Linux для этого есть Disk Cache - сохраняет данные с диска в памяти)
- так SSD может выступать в качестве кеша для HDD в некоторых гибридных дисковых системах
- кеш внутри процессора (обычно их называют L1, L2 и тд; скорость доступ к данным в них на порядки превосходит RAM)

Теперь чувствуется масштабность вопроса с кешом? 😉
До связи 🤟
Pooling и зачем это нужно?

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

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

Наиболее распространенные виды пулов:
- Пул объектов или памяти (Object Pool / Memory Pool) - позволяет сократить время на выделение/освобождение оперативной памяти. Распространено во встроенных системах и видео играх.
- Пул тредов (Thread Pool) - экономим на создании/удалении потоков силами ОС. Часто используется в контекте Worker Pool для обработки задач из очередей.
- Пул TCP-соединений (Connection Pool) позволяет с сократить время на установку соединения. Обычно используется для работы с БД или между прокси-сервером и нашим приложением. В случае PostgreSQL каждое новое соединение пораждает новый процесс, так что с этой стороны пул соединений ещё и эту проблему сглаживает 👌

Используйте пул чего-нибудь с умом 🧠
До связи 🤟
Стартап DragonflyDB (убийца Redis)

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

Dragonfly - свеженькая open source in-memory база данных, написанная на C++ и совместимая с Redis (но НЕ является форком).
Какие основные моменты отмечаем:
- многопоточная архитектура призвана легче масштабироваться вертикально и лучше утилизировать современный CPU
- первый публичный релиз состоялся в 2022 году (v0.1.0)
- в марте текущего года выпущена v1.0 (стабильная и Production Ready)
- поддерживает порядка 200 команд Redis (это еще не полная совместимость, но достаточно близко)
- по бенчмаркам обгоняют Redis в 25 раз по QPS (бенчмарк от автором Dragonfly, очевидно)
- более 20 тысяч звезд на Github

Из интересного, так это тот факт, что пока нет никакого коммерческого продукта, не заявлена какая-либо бизнес модель.
Но уже состоялся А-раунд инвестиций на шикарные $21 миллион. Видимо вся надежда, что в скором времени все Redis во всех облаках будет заменен на Dragonfly...
Хочется напомнить, что в 2019 году уже появляся многопоточный "убийца" Redis. Называется KeyDB. На дворе 2023 год, но Redis все еще на коне - повод задуматься 🤔

Так же предлагаю ознакомится с моим переводом для Хабра
https://habr.com/ru/articles/745406/, где рассказано, чем плох LRU-кеш и что используется в Dragonfly вместо него.

До связи 🤟
Продуктовые команды

На смену классического разделения команд по функциональным областям (frontend, backend, mobile, design, qa, product…) в IT-компаниях, все чаще создают команды, объединенные работой над конкретным продуктом или какой-то его большой независимой частью. Данное разделение объединяет специалистов разного профиля для работы совместно, значит и задачи такая команд может решать не узкие, а полный цикл - от идеи до продакшена.

Какие достоинства я выделяю в первую очередь:

- Коммуникация 🗣️. В таких командах взаимодействия быстрые и конкретные, потому что людей не много, не нужно искать коллег в других отделах и, что самое главное, все погружены в общий продуктовый контекст.
- Ответственность 💪. Теперь конечный результат в явном виде зависит только от стараний тебя и твоих непосредственных коллег по команде. Вклад каждого заметно увеличивается, хотя бы на уровне ощущений.
- Скорость принятия решений 🚀. Из-за улучшенной коммуникации и сконцентрированной ответственности заметно возрастает скорость. Решения в таких условиях можно принимать быстро и доводить до результата своими силами.

В таком подходе все основные члены команды должны быть крепкими ребятами с опытом. Такой найм сам по себе челендж. Также в подобную структуру чуть сложнее набирать джунов. Морально проще взять одного Junior Backend в отдел бекенда из 5 человек, чем в продуктовую команду, где 1-2 бекендера 🥸

Последний момент заключается в том, в каком объеме данный подход по разделению команд реализован в той или иной компании. Тут все как в Agile, каждый его трактует по своему. У кого-то в рамках команды представлены вообще все компетенции, у кого-то разработка, qa и дизайн вместе, а продукт, аналитика где-то отдельно. Так что если вас зовут в продуктовую команду, нужно уточнять, что же это конкретно у них 😅

До связи 🤟
Кеширование для записи

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

Алгоритм простой:
- Сначала новые данные собираются в оперативной памяти;
- Затем накопленные данные периодически записываются на диск или в базу данных как единое событие. В англоязычном варианте может встречаться термины batching и/или bulk insert.

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

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

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

До связи 🤘
А зачем нам Graceful Shutdown?

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

‼️ Обработка сигналов. Первым шагом в Graceful Shutdown является обработка сигналов, таких как SIGINT и SIGTERM. Таким образом операционная система или система оркестрации контейнеров уведомляет приложение о том, что скоро оно будет завершено.

⛔️ Остановка обработки новых HTTP-запросов. Затем нужно перестать принимать новые HTTP-запросы от клиентов. Это гарантирует, что не будет создано новых активных соединений.

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

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

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

До связи 🤟