惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Cisco Blogs
Cyberwarzone
Cyberwarzone
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
SecWiki News
SecWiki News
Martin Fowler
Martin Fowler
T
Tor Project blog
N
Netflix TechBlog - Medium
C
Cybersecurity and Infrastructure Security Agency CISA
V
Vulnerabilities – Threatpost
V
Visual Studio Blog
GbyAI
GbyAI
PCI Perspectives
PCI Perspectives
D
DataBreaches.Net
Jina AI
Jina AI
H
Heimdal Security Blog
云风的 BLOG
云风的 BLOG
P
Privacy International News Feed
A
About on SuperTechFans
J
Java Code Geeks
美团技术团队
H
Hackread – Cybersecurity News, Data Breaches, AI and More
N
News | PayPal Newsroom
有赞技术团队
有赞技术团队
MyScale Blog
MyScale Blog
博客园 - 司徒正美
C
Check Point Blog
T
Threat Research - Cisco Blogs
Attack and Defense Labs
Attack and Defense Labs
宝玉的分享
宝玉的分享
AI
AI
Simon Willison's Weblog
Simon Willison's Weblog
C
Cyber Attacks, Cyber Crime and Cyber Security
I
Intezer
P
Proofpoint News Feed
Blog — PlanetScale
Blog — PlanetScale
Apple Machine Learning Research
Apple Machine Learning Research
Hugging Face - Blog
Hugging Face - Blog
The Last Watchdog
The Last Watchdog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Vercel News
Vercel News
I
InfoQ
阮一峰的网络日志
阮一峰的网络日志
Cisco Talos Blog
Cisco Talos Blog
W
WeLiveSecurity
Hacker News: Ask HN
Hacker News: Ask HN
Recent Commits to openclaw:main
Recent Commits to openclaw:main
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
D
Docker
博客园 - Franky
Security Archives - TechRepublic
Security Archives - TechRepublic

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Axelix. Cпецназ для Вашей Spring Boot экосистемы
Михаил Поливаха · 2026-06-01 · via Все публикации подряд на Хабре

Простой

9 мин

13K

Привет, Хабр!

Меня зовут Михаил Поливаха. Я думаю, что в Хабе Spring АйО меня уже относительно знают. В рамках Spring АйО мы довольно часто занимаемся подбором технического материала и его ревью. Сам же я довольно регулярно выступаю на конференциях, контрибьючу в Open Source и т.д.

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

На днях произошло довольно знаковое событие. Мы с небольшой командой примерно год писали инструмент, который призван существенно упростить весь процесс отладки, тестирования и мониторинга Spring Boot приложений в production. И вот этот проект наконец-то получил первый Milestone Релиз.

Проект называется Axelix.

Думаю, что важно сразу отметить: ядро проекта Axelix является Open Source продуктом и доступно на GitHub. Проект будет следовать модели Open Core. Поэтому Вы можете спокойно ставить его себе в контур так же, как ставите, например, Grafana.

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

Надеюсь, что Вам будет интересно. Ну что же, начнём :)

Сотояние Индустрии Enterprise Софта

Типичный enterprise имеет много внутреннего софта. Этот софт решает разные задачи и обычно написан на нескольких языках программирования — Java, Go, C# и т.д. Один из самых популярных ЯП для server-side/backend-приложений в крупных компаниях — это Java. На это есть много исторических причин, но факт остаётся фактом.

Кроме того, самый популярный фреймворк для написания backend-приложений на Java — бесспорно Spring Boot. Очень упрощённо: это дополнительный слой поверх Spring Framework, который упрощает его конфигурацию (хотя, сейчас Spring Boot уже гораздо больше, чем просто автоконфигурация). По ряду причин это безоговорочно самый популярный выбор в enterprise. Например, Netflix мигрировал свою экосистему (более 3000 приложений) на Spring Boot 3 и планирует оставаться на Spring Boot.

Итого: Spring Boot победил. Это очень популярный выбор на backend при разработке на Java. Это то, что у нас есть сегодня и с этим странно спорить.

Мотивация и Pain Point

Что интересно: Spring Framework изначально начинался как IoC-контейнер с dependency injection в качестве главной фичи, а сейчас это совсем другое — намного, намного больше. Сегодня Spring Framework / Spring Boot — целая экосистема, которая поддерживает весь технологический стек нашего приложения:

  • Обработка HTTP-запросов

  • Работа с RDBMS — от управления транзакциями до ORM

  • Отправка сообщений в message broker-ы и многое другое

В результате экосистема Spring Framework существенно выросла в сложности. В современных Spring Boot microservice-ах у нас очень много движущихся частей. Например:

  • В приложениях много bean-ов. Часть приходит из Spring Boot и auto-configuration, часть — из внутренних платформенных библиотек, которые мы используем в компании, а часть мы создаём сами.

  • У нас довольно много properties, которые могут приходить из разных источников: из файла application.yaml, из Spring Cloud Config, из environment переменных внутри Pod-ов в K8S, из аргументов командной строки и так далее.

  • Конечно же, у нас много proxy! И все они работают друг с другом: transactional proxy, proxy для OpenFeign client-ов, proxy для Kafka Listener-ов и т.д.

Идея в том, что Spring Framework стал довольно большим и породил много взаимосвязанных частей, где каждая влияет на другую (например, properties влияют на создание bean-ов, созданные bean-ы могут подтянуть ещё properties и т.д.). Есть даже такое мнение, что из-за всего этого Spring Framework превратился в большого неукротимого монстра.

Подумайте сами: почти на любой Java-конференции — и внутри России, и даже за рубежом (говорю как спикер на международных конференциях, в том числе) — добрая половина докладов посвящена Spring Framework, тому как он устроен, или похожим темам.

Почему? Потому что Spring а) везде, и б) он сложен!

И, следуя из этого, за годы написания Spring Boot-приложений я с почти 100%-ной уверенностью могу сказать: когда мы, Java-разработчики на Spring Boot, деплоим приложения в любое окружение, мы снова и снова сталкиваемся с одними и теми же проблемами. Например:

  1. Мы делаем HTTP-запросы внутри транзакций и исчерпываем пул db-connection-ов.

  2. Мы создаем N + 1 и сталкиваемся с проблемами lazy loading в Spring Data JPA.

  3. Мы дебажим ситуации, когда в @Value / @ConfigurationProperties подтянулось не то property.

  4. Мы дебажим случаи, когда наш @Bean был “подавлен” из-за какого-то bean-а из @AutoConfiguration или платформенной либы и так далее…

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

А теперь: что, если я скажу, что боль от разработки Spring Boot backend-ов можно облегчить?

Вдумайтесь: сегодня по всему миру сотни и сотни команд пишут Spring Boot backend-ы и снова и снова борются с одними и теми же проблемами.

Можно ли это как-то решить? Давайте попробуем разобраться на примере.

Типичный День Spring Boot-разработчика

Чтобы глубже понять, что именно Axelix пытается решить, пройдёмся по паре примеров Java-кода. Представьте, что в приложении есть следующий код ниже. У нас есть Spring бин, который мы используем, чтобы получить набор permissions, которыми обладает гипотетический клиент:

@Slf4j
@Service
public class PermissionsResolver {

    @Value("${permission.caching.enabled:true}")
    private boolean cacheLookupsEnabled;

    @Autowired
    private ExternalPermissionsResolver delegate;

    @Autowired
    private PermissionsCache cache;
    
    @Autowired
    private DetailsResolver detailsResolver;

    @PostConstruct
    void init() {
        log.debug("Permissions cache lookup enabled: {}", cacheLookupsEnabled);
    }

    @Transactional
    public Set<PermissionDto> resolveClientPermissions(Client client) {
        try {
            Set<PermissionDto> permissions = delegate.resolve(client);
            
            for (Permission permission : permissions) {
                PermissionDetails details = detailsResolver.resolvePermissionDetails(permission);
                permission.setDetails(details);
            }
            
            return permissions;
        } catch (SomeExpectedException e) {
            if (cacheLookupsEnabled && client.getStatus() == ClientStatus.EXISTING) {
                log.debug("For the client '{}' taking permissions from the cache", client.getId());
                return cache.get(client.getId());
            } else {
                throw e;
            }
        }
    }
}

Это классический Java-код на стеке Spring Boot. Давайте честно: мы же все такое видели. Все такой код отлаживали, все много-много раз дорабатывали такой код.

И во время регрессионного тестирования QA-инженер приходит и говорит:

Привет! На dev/qa/sandbox/pre-prod окружении я не могу создать XYZ — пишет, что у моего client-а нет нужных permissions

Вы открываете IDE (или AI Agent, что уж там 😈) и пытаетесь разобраться в кодовой базе. Ищете, что может пойти не так.

Часть 1. Смена Уровня Логирования

А вариантов того, что может пойти не так в Spring Boot приложении — просто вагон.

Например, может оказаться, что мы берём client-ов из кэша. Ну, по крайней мере, кэш должен быть включён, верно? Или нет… И, как всегда, нужный нам log — в DEBUG, а не в INFO. И, конечно, logback — дефолтная система логирования под Spring Boot — его отфильтровывает и не пропускает.

Разве не было бы круто временно поднять уровень логирования для этого класса до DEBUG? Без редеплоя, буквально на 10 минут? Axelix позволяет временно изменить уровень логирования — только для отладки, — а потом откатить его назад. Кстати, очень скоро Axelix сможет откатить уровень логгирования сам, без необходимости разработчику вручную возвращать всё как было.

Часть 2. Загадочное Значение Property

Вы копаете дальше и понимаете: поведение некорректно, потому что на pre-prod мы вообще не должны брать client-ов из кэша. Мы должны упасть и вернуть соответствующий status code.

Теперь вопрос: почему, чёрт возьми, кэш вообще включён? Мы же явно отключили его через переменную окружения… Может, где-то есть другой property (например, из Spring Cloud Config), который переопределяет наш? А что, если Spring вообще не увидел нашу переменную окружения, отключающую кэш?

Это открытые вопросы, и поверьте, Вы не один такой. С этим сталкивается очень много людей.

Axelix может не только показать, какие properties знает Spring, но и сказать, какое property в итоге победило и подавило остальные — и откуда оно пришло.

Часть 3. Зоопарк Bean-ов

Ладно, Вы выяснили, что property на самом деле пришло из VCS через Spring Cloud Config, и какой-то инженер просто его поменял и забыл сказать (упс, как неловко-то вышло). Вы, скаля зубы, выключили кэширование и попросили QA перезапустить сценарий. Client, очевидно, по-прежнему без permissions, но хотя бы теперь мы отдаём ошибку, а не ответ из fallback-кэша.

Теперь нужно понять, почему permissions нет. QA мамой клянётся, что добавил их в базу данных или попросил кого-то это сделать. Вы ему доверяете, но (не на все 100%, конечно) и снова открываете IDE. И вот что находите:

public interface ExternalPermissionsResolver {

    Set<PermissionDto> resolve(Client client);
}

@Component
@ConditionalOnProperty(prefix = "permissions.resolver", value = "source", havingValue = "legacy", matchIfMissing = true)
@ConditionalOnMissingBean(ExternalPermissionsResolver.class)
public class LegacySystemPermissionsResolver implements ExternalPermissionsResolver {

    @Override
    public Set<PermissionDto> get(Client client) {
        // implementation
    }
}

@Component
@ConditionalOnProperty(prefix = "permissions.resolver", value = "source", havingValue = "database")
@ConditionalOnDatabaseAvailable
@ConditionalOnMissingBean(ExternalPermissionsResolver.class)
public class DatabaseSystemPermissionsResolver implements ExternalPermissionsResolver {

    @Override
    public Set<PermissionDto> get(Client client) {
        // implementation
    }
}

Итак, на pre-prod мы не хотим использовать старый LegacySystemPermissionsResolver — мы от него избавляемся. Есть ли шанс, что он всё ещё используется? По крайней мере, мы можем посмотреть properties и их фактические значения — Axelix уже помогает с этим. Однако это ещё не отвечает на главный вопрос: а мы на 100% уверены, что используем DatabaseSystemPermissionsResolver? А что, если нет?

Здесь Axelix может не только сказать, какие bean-ы реально активны, но и объяснить, откуда они взялись. Более того, Axelix может объяснить, почему bean-ы, которые мы ожидали увидеть созданными, на самом деле не были созданы.

Например, наш DatabaseSystemPermissionsResolver мог не создаться, потому что кастомная conditional-аннотация @ConditionalOnDatabaseAvailable не прошла, — и в итоге создался fallback LegacySystemPermissionsResolver.

Часть 4. Hibernate всегда рядом, чтобы всё испортить

Уже измотанный, измучанный, бедняга, Вы решили и эту проблему. Причина сломанных permissions — использование не того ExternalPermissionsResolver. Тестирование на pre-prod завершено, наконец. Столько времени ушло на отладку — это просто безумие!. Но разработчики для этого и существуют, чтобы страдать. Вы это принимаете и возвращаетесь к работе.

Только собрались с мыслями, сели за тикет — прилетает отчёт от нагрузочного тестирования:

95-й перцентиль latency улетел в космос: 5–6 секунд! Такое нельзя в прод катить!

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

Вы снова внимательно смотрите на код и понимаете:

Чёрт! Снова N + 1! DatabaseSystemPermissionsResolver возвращает entity без JOIN FETCH-нутой коллекции permissions!

Дъявол! А ведь проблема с N + 1 коварна тем, что её не так просто поймать в тестах! Конечно, Hibernate даёт статистику для её детекта, но никто же не заморочился писать тесты с глубоким анализом Hibernate statistics!

И этот код успешно прошёл:

  1. Code Review

  2. Quality Gate

  3. Функциональное тестирование от QA

  4. Security проверки от Sonar Qube и т.д.

Все барьеры пройдены! А теперь… Теперь нужно менять код, мержить, перетестировать, заново гонять security scan. Это такая боль! В агонии начинаете чувствовать, что ненавидите работу, а Hibernate — ещё больше, потому что всё так неочевидно!

Но не переживайте — Axelix может помочь. Axelix может обнаружить N + 1 запросы на testing/qa/sandbox окружениях задолго до деплоя на pre-prod или стенд нагрузочного тестирования.

Вот и всё. Более того, Вы не только можете обнаружить N + 1 запросы, но и точно сказать, какие запросы Hibernate выполнил под капотом в рамках этой @Transactional и сколько она длилась.

Наконец, если не хотите использовать UI Axelix, в ближайшем будущем можно будет настроить экспорт этих данных в любое APM-решение на Ваш вкус — от простого экспорта дополнительных Prometheus Metrics, до современного Open Telemetry — и смотреть те же данные из Axelix в привычной Grafana, например.

Интеграция с AI. MCP Server.

Фичи выше — это примерно ~30% того, что Axelix умеет сейчас; там гораздо больше. Я не перечисляю всё, иначе статья станет очень длинной. Но есть ещё один слон в посудной лавке, которого нельзя игнорировать — AI.

Сегодня мы все пользуемся AI Agent-ами: Cursor, Codex, Claude и т.д. Давайте честно: они занимают значительную часть нашей жизни как Software Engineer-ов. В Axelix мы это прекрасно понимаем; у нас AI:

  • Помогает ревьюить код в monorepo

  • Помогает писать интернационализированную документацию и т.д.

Мы признаём влияние и ценность AI. Поэтому во всех дистрибутивах Axelix идёт встроенный MCP server, который отдаёт все описанные выше (и не только) возможности AI Agent-у через embedded MCP server. Хотите отлаживать проблемы через AI Agent — пожалуйста.

Правило, которому мы следуем: всё, что доступно человеку через UI, также доступно AI Agent-ам через MCP server.

Сравнение со Spring Boot Admin

Уверен, опытные разработчики слышали про Spring Boot Admin. Этот инструмент работает как proxy к существующим Spring Boot Actuator endpoint-ам и даёт часть возможностей, которые умеет Axelix.

Мы настолько часто объясняли, чем Axelix отличается от Spring Boot Admin, что даже сделали отдельную страницу в документации, где объясняем, какие проблемы со Spring Boot Admin мы видим и какую роль Axelix играет в общей картине. Прочитайте, если интересно.

Заключение. Что дальше

Повторю: мы только что выпустили первый milestone. GA-релиза пока нет, но мы планируем его во второй половине лета 2026 года. Чтобы быть в курсе, мы завели telegram-канал для новостей о фичах и релизах. Подписывайтесь, если хотите следить за проектом.

У нас уже есть pilot-команды, которые поставили Axelix в свои окружения — как Helm Chart, Docker image или даже просто JAR. Мы по-прежнему активно обрабатываем feedback от пилотных команд. Если хотите поставить Axelix — Вы уже можете это сделать, документация доступна на русском и английском. В этом случае Вы сможете дать feedback и существенно повлиять на развитие Axelix.

Мы активно полируем документацию; если понадобится помощь — пишите напрямую администраторам Telegram-канала проекта Axelix. Поможем с установкой.

Надеюсь, статья была интересной. Если любопытно, как это устроено — исходники Axelix Core на GitHub. Изучайте на здоровье!

P.S: Мы приветствуем контрибьюторов! Хотите помочь — загляните в contribution guidelines нашего проекта. Будем рады увидеть PR/Issue от Вас когда-нибудь!