Golang Portal
8.01K subscribers
414 photos
27 videos
7 files
446 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для Golang-разработчика

Связь: @devmangx
Download Telegram
Стриминг больших файлов между микросервисами: Реализация на Go

Этот проект демонстрирует практическую реализацию на Go для эффективной передачи больших файлов или объёмных payload'ов между микросервисами. Он напрямую отвечает на задачу, озвученную Сумитом Мукхиджей в этом твите:

"Вашему микросервису нужно передавать большие объёмы данных (например, файлы, изображения) между сервисами. Как вы спроектируете коммуникацию, чтобы избежать узких мест в производительности и эффективно обрабатывать большие payload'ы?"


Реализация предлагает решение на основе стандартного HTTP-протокола, с акцентом на следующие аспекты:

🔹Эффективное использование памяти: исключается загрузка целого файла в память как на клиенте, так и на сервере.

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

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

🔹Производительность: используется буферизация ввода/вывода и возможности стандартной библиотеки Go для оптимизации операций.

Полный исходный код реализации доступен здесь

👉 Читать

👉 @juniorGolang | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍5😁2
⚙️ Альтернатива демонa auditd, поставляемому со многими дистрибутивами Linux

https://github.com/slackhq/go-audit

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21🤔1
Объяснение CPU requests и limits в контейнерах с настройкой GOMAXPROCS

Одна из самых интересных статей, которые я читал в последнее время

В ней объясняется:

🔹Как на самом деле работают CPU requests и limits, включая внутренние механизмы

🔹Почему установка GOMAXPROCS важна для Go-приложений, работающих в контейнеризованных средах

🔹Как на самом деле работает uber-go/automaxprocs

🔹Какие метрики можно использовать, чтобы определить, подвергается ли контейнер throttling'у

И многое другое

👉 Читать

👉 @juniorGolang | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM
👍75🔥2
Писать неудобный код — сложно, но приходится

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

Например, чтобы обновить документ в базе данных — почему бы просто не передать клиенту map[string]any, чтобы он сам обновил, что ему нужно?
Лично я такое не приемлю, особенно в командной работе.

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

Я не хочу давать клиенту лишние шансы ошибиться.

Использование any, map[string]interface{}, возврат пустых error, глобальные переменные, сваливание всех хелперов в shared/utils, создание монолитных общих интерфейсов, игнорирование ошибок (или возвращаемых значений) без комментариев, написание огромных функций без разбиения, использование context.Background() ради скорости, возврат 3–4 значений, хардкод вместо констант, наплевательское отношение к дизайну и зависимостям между пакетами, сваливание всех моделей в models/model.go

Я не утверждаю, что всё это всегда плохо — как обычно, всё зависит от контекста.

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

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

👉 @juniorGolang | #tip
Please open Telegram to view this post
VIEW IN TELEGRAM
👍147🔥3
⚙️ Функционально насыщенный, быстрый и гибкий контроллер входящего трафика, нативный для Kubernetes, и шлюз API следующего поколения, построенный на базе Envoy, реализованный на Go.

https://github.com/solo-io/gloo

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍54
Mutex — это концепт, который часто вызывает путаницу, хотя на самом деле он довольно прост для понимания. Mutex — это примитив синхронизации, который помогает избежать гонки данных (race conditions).

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

Mutex (сокращение от mutual exclusion) предоставляет две основные функции — Lock и Unlock, а также внутренний счётчик.

🔹counter = 0 означает, что mutex разблокирован

🔹counter = 1 означает, что mutex заблокирован

Когда первая горутина вызывает Lock, она блокирует доступ к срезу, установив счётчик в 1. Следующая горутина, попытавшаяся войти, будет заблокирована (впадёт в ожидание), пока счётчик не станет равным 0 — то есть пока первая горутина не вызовет Unlock.

По сути, mutex обеспечивает, чтобы только один поток выполнения (в данном случае — горутина) имел доступ к общему ресурсу в определённый момент времени. Это особенно полезно, когда, например, нужно избежать ситуации, при которой две горутины одновременно записывают данные в одну и ту же позицию среза.

Семафор — это расширение концепции mutex. Если mutex допускает только одного "оператора", то семафор может иметь произвольное количество слотов. Например, sync.WaitGroup в Go использует семафорную модель под капотом.

На картинке приведён пример кастомной реализации mutex

👉 @juniorGolang | #tip
Please open Telegram to view this post
VIEW IN TELEGRAM
👍97
Анализатор сообщает о возможностях упростить и сделать существующий код более понятным с помощью более современных возможностей Go

https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍3
До сих пор самым впечатляющим аспектом Go для меня остаются его примитивы конкурентности.

В традиционных языках программирования конкурентность достигается за счёт потоков операционной системы. Например, если у вас CPU с 6 ядрами и поддержкой 2 логических потоков на ядро, вы можете распараллелить выполнение максимум на 12 потоков.

В Go есть собственный планировщик задач, встроенный в рантайм. Он не зависит от потоков ОС для запуска задач.

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

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

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

Синхронизировать горутины можно через sync.WaitGroup или использовать каналы (chan) для обмена данными и координации между ними.

Именно такая лёгкая модель выделения памяти и позволяет Go эффективно управлять тысячами и миллионами конкурентных задач.

👉 @juniorGolang | #tip
Please open Telegram to view this post
VIEW IN TELEGRAM
10🔥2👍1
Использование сигналов в Go

Статья рассказывает, как обрабатывать системные сигналы в Go с помощью пакета os/signal: как подписываться на сигналы (например, SIGINT при Ctrl+C), зачем это нужно (например, для graceful shutdown), и как отключить обработку сигналов с помощью signal.Stop

👉 Читать

👉 @juniorGolang | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍2
Каналы в Go — это интересная и поначалу достаточно сложная для понимания концепция.

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

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

Канал в Go — это просто очередь, через которую можно передавать данные.

Если вы записываете в канал — это эквивалентно добавлению элемента в очередь.
Если вы читаете из канала — вы извлекаете первый элемент из очереди.
Очередь работает по принципу FIFO (первым пришёл — первым вышел).

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

В коде вы просто записываете значение в канал, например struct{user userID; data interface{}}, и это может послужить триггером для запуска другой вычислительной задачи.

Каналы безопасны для конкурентного чтения и записи — для записи в канал не нужен мьютекс.

Вы можете контролировать, сколько сигналов канал может буферизовать, указывая размер буфера при создании через make (например, userChan := make(chan interface{}, capacity)).

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

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

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

По сути, каналы — это отличный способ организации взаимодействия между последовательными процессами, что и составляет суть модели конкурентности CSP (Communicating Sequential Processes) в Go.

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

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

👉 @juniorGolang | #tip
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍4
⚙️ Утилита для парсинга лог-файлов в форматах Common и Combined Log Format (CLF) и сохранения их в SQLite для последующего анализа. Разработана с учетом конкурентности.

https://github.com/thevxn/xilt

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2
This media is not supported in your browser
VIEW IN TELEGRAM
Большая актуальная базу бесплатных API, которая обновляется ежедневно

Тут собрано аж 363 бесплатных API на все случаи жизни: от игр и погоды до финансов и здоровья.

Алгоритмы присваивают рейтинг каждому API на основе надежности, частоты ошибок и времени отклика

Если API перестает работать или становится платным, он теряет рейтинг и удаляется с сайта

Переходите и смотрите сами: https://www.freepublicapis.com/

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍83
Самостоятельно размещаемая альтернатива Google Analytics, реализованная на Go

https://github.com/vinceanalytics/vince

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
Принёс шпаргалку с 12 командами Git, которые «должен знать каждый разраб»

1. git init – инициализация нового Git-репозитория в текущем каталоге.

2. git add – добавление изменений в индекс (staging area).

3. git commit – фиксация проиндексированных изменений с комментарием.

4. git push – отправка локальных изменений в удалённый репозиторий.

5. git pull – получение изменений из удалённого репозитория и их слияние с локальной веткой.

6. git remote – добавление, просмотр или удаление удалённого репозитория.

7. git branch – вывод списка веток, создание новой ветки и переключение на неё.

8. git fetch – загрузка изменений из удалённого репозитория без их слияния.

9. git checkout – переключение на указанную ветку.

10. git merge – слияние указанной ветки с текущей.

11. git status – отображение текущего состояния репозитория и неподтверждённых изменений.

12. git reset – откат текущей ветки до указанного коммита.


Сохраняем и пользуемся

К слову, Git на днях отметил своё 20-летие — 7 апреля 2005 года Линус Торвальдс написал его всего за пару недель, чтобы заменить BitKeeper при разработке ядра Linux

С тех пор без Git не обходится почти ни один проект ✌️

👉 @juniorGolang
Please open Telegram to view this post
VIEW IN TELEGRAM
8👍5
Пакет Go, который декодирует url.Values в значения Go и кодирует значения Go в url.Values. Поддержка как массивов, так и полных отображений

https://github.com/go-playground/form

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
gRPC в Go: Потоковые RPC, перехватчики и метаданные

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

https://victoriametrics.com/blog/go-grpc-basic-streaming-interceptor/

👉 @juniorGolang | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM
👍62🔥2
⚙️ Порт свежего агента от OpenAI Codex CLI на Go — легковесный мультимодальный агент для написания кода на естественном языке, работающий прямо в терминале.

https://github.com/epuerta9/codex-go

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
4
Если вы хотите протестировать производительность своего Go-кода, вы можете написать несколько бенчмарк-тестов.

Они анализируют скорость выполнения и использование памяти различными функциями и блоками кода.

Здесь Педро показывает, как писать бенчмарк-тесты для ваших функций на Golang:

https://freecodecamp.org/news/how-to-write-benchmark-tests-for-your-golang-functions/

👉 @juniorGolang | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2
Начиная с Go 1.8, стандартная библиотека http.Server включает метод Shutdown, который критически важен для корректного завершения работы веб-сервисов.

Этот метод обеспечивает "плавное" завершение работы сервера, поскольку он:

🔹Немедленно прекращает приём новых подключений

🔹Сохраняет существующие подключения активными до завершения всех текущих запросов

🔹Предоставляет контекст для управления таймаутом на завершение "висящих" запросов

🔹Завершается только после обработки всех находящихся в процессе выполнения запросов

🔹Предотвращает утечки подключений при завершении работы приложения

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

Метод Shutdown элегантно решает эту проблему. Ниже приведена полноценная реализация, демонстрирующая обработку нескольких сигналов ОС для плавного завершения работы:

👉 @juniorGolang | #tip
Please open Telegram to view this post
VIEW IN TELEGRAM
14👍9
This media is not supported in your browser
VIEW IN TELEGRAM
Лёгкая очередь сообщений, реализованная на Go, с поддержкой SQLite, PostgreSQL и ORM в качестве постоянного хранилища

https://github.com/ixugo/nsqite/blob/master/README.md

👉 @juniorGolang | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍81
При разработке приложений, использующих LLM API, таких как OpenAI или Anthropic, вы быстро упрётесь в лимиты запросов при масштабной обработке. Пакет rate из https://golang.org — хорошее решение этой проблемы, так как он:

🔹Реализует лимитирование скорости на основе алгоритма token bucket с точной настройкой

🔹Поддерживает ожидание с учётом контекста и возможностью отмены

🔹Эффективно обрабатывает всплески нагрузки благодаря настраиваемому размеру «ведра»

🔹Органично интегрируется с моделью конкурентности Go

Алгоритм token bucket особенно хорошо подходит для LLM‑API. Каждый запрос потребляет один токен из «бакета», который пополняется с заданной скоростью. Если «бакет» пуст, запросы ожидают появления токенов вместо того, чтобы сразу завершаться с ошибкой.

Выше приведён пример кода с неофициальным клиентом OpenAI и использованием пакета rate

👉 @juniorGolang | #tip
Please open Telegram to view this post
VIEW IN TELEGRAM
👍71