1375
Пишу про Go, Vim, и про то, как я медленно ползу в сторону FAANG. Веду @digest_golang С предложениями: @junsenpub
Некоторое время назад я написал большой гайд о том, как настроить neovim с нуля и привести его к виду, пригодному для разработки: с подсветкой синтаксиса, пониманием кода, автокомплитом, и десятком других возможностей, к которым мы привыкли в IDE.
Мотивация у меня простая. Когда я только начинал разбираться в теме, я не видел ни одного гайда, следуя которому я не столкнулся бы с ошибками или в котором все сразу бы заработало. Большинство авторов или упускают множество моментов, или не раскрывают весь контекст, из-за чего новичку тяжело понять, в чем проблема и как ее решить.
Чтобы это исправить, в своей статье я настраивал neovim на чистой тачке, начиная с установки и конфигурирования консоли и заканчивая тем, что редактор стал похож на IDE.
Затем я перевел статью на английский и опубликовал ссылку на нее на различные тематические ресурсы.
И как показывает статистика, в 2024-ом году писать код в консоли все еще кому-то интересно 🙂
Поэтому я дописал вторую часть, где показал как настроить вторую пачку плагинов, которые вместе с первой составляют мой базовый набор: с ним можно без проблем писать код, иметь интеграцию с гитом и большинство привычных возможностей из IDE.
Го читать - https://poltora.dev/neovim-for-developers-2-ru/
Релиз Go 1.23
Самое большое обновление - появились итераторы. В пакеты slices и maps добавлены новые методы для работы с итераторами, например метод Chunk из пакета slices позволяет перебирать слайс пачками из заданного числа элементов:
people := People{
{"Gopher", 13},
{"Alice", 20},
{"Bob", 5},
{"Vera", 24},
{"Zac", 15},
}
for c := range slices.Chunk(people, 2) {
fmt.Println(c)
}
Вчера я писал о первом совете из книги Go with Domains: стоит определять бизнес логику так, как она звучит.
Продолжаем знакомиться с этой книгой, и сегодня хочу написать про второе правило внедрения DDD в приложение: всегда держите валидное состояние в памяти в одном месте.
Это значит, что вся логика работы с доменом должна быть определена в отдельном пакете и скрыта от других пакетов. Менять состояние домена должно только публичное API. Автор также не советует создавать геттеры и сеттеры.
Возвращаясь к нашему примеру с тренажерным залом из вчерашнего поста, инкапсулируем домен Hour:
type Hour struct {
hour time.Time
availability Availability
}
// ...
func NewAvailableHour(hour time.Time) (*Hour, error) {
if err := validateTime(hour); err != nil {
return nil, err
}
return &Hour{
hour: hour,
availability: Available,
}, nil
}
h := hour.NewAvailableHour("13:00")
if h.HasTrainingScheduled() {
h.SetState(hour.Available)
} else {
return some error
}
func (h *Hour) CancelTraining() error {
if !h.HasTrainingScheduled() {
return some error
}
h.availability. Available
return nil
}
h := hour.NewAvailableHour("13:00")
if err := h.CancelTraining(); err != nil {
return err
}
Большинство компаний, особенно относительно больших, сейчас имеют в своей инфраструктуре кубер или его аналоги, внутри которого множество подов обмениваются друг с другом запросами.
Часто под не светит свои порты во внешний мир и сервис в целом не имеет внешнего домена, доступного снаружи.
С опозданием, но теперь и я узнал о команде, которая позволяет бить в закрытые от внешнего мира поды с локальной машины (единственное условие - находиться в той же vpn сети и иметь права на выполнение команды port-forward в кубере), спешу поделиться.
Сначала находим нужный под в нужном окружении:
➜ ~ kubectl get pods -n prod | grep pod_name_prefix
➜ ~ kubectl port-forward pod_full_name -n=prod 5050:5050
➜ ~ Forwarding from 127.0.0.1:5050 -> 5050
➜ ~ Forwarding from [::1]:5050 -> 5050
➜ ~ Handling connection for 5050
➜ ~ curl -s http://localhost:5050/mypage
Скорее всего у тебя в проекте, на каком бы языке он не был написан, в корне лежит большой Makefile. На команды, определенные там, часто завязывается ci/cd, через make удобно настраивать локальный запуск проекта.
Например, у меня в компании Makefile с определенными командами - обязательное требование, без которого невозможно поднять новый сервис.
Тема и правда удобная, но есть один большой минус - эти файлы очень плохо читаются и еще сложнее что-то туда добавить. В поисках альтернативы для go-проектов нашел mage - тулза, задача которой убрать сложность чтения и записи make-команд. Решается это с помощью определения тех же команд внутри go-файла, что выглядит, пишется и читается сильно удобней:
//go:build mage
package main
import (
"github.com/magefile/mage/sh"
)
// Runs go mod download and then installs the binary.
func Build() error {
if err := sh.Run("go", "mod", "download"); err != nil {
return err
}
return sh.Run("go", "install", "./...")
}
mage -h build
PGO-оптимизации или как бесплатно ускорить приложение
Узнал про интересную возможность бесплатно и очень быстро ускорить go-приложение на ~10%.
В Go 1.20, релиз которого был чуть больше года назад, добавили PGO - новые возможности компилятора оптимизировать приложение на основе его поведения.
В чем идея: с помощью профилировщика снимаем профиль процессора, затем запускаем go build с флагом -pgo и нужным профилем: go build -pgo ./pgo/profile.pprof
Компилятор на основе данных профилировщика понимает, где можно заинлайнить какие-либо данные, где можно предсказать ветвление по входным данным или где можно реорганизовать данные так, чтобы тратить меньше времени на переключение контекста. На выходе мы получаем тот же билд нашего приложения, но на 2-7% быстрее, чем его аналог скомпилированный без этого флага. В определенных случаях для специфических паттернов можно ускорить приложение на 10 и более процентов.
Так, например, ребята из cloudflare сумели такой бесплатной оптимизацией сэкономили 97 ядер из 3000, на которых было запущено приложение. Если перевести 97 ядер в стоимость облачной инфры, получается очень приятная цифра, которую получилось сэкономить за пару минут.
Последний год я активно пользуюсь ChatGPT, и хочу поделиться кейсами, как он помогает мне в работе.
Во-первых, SQL. Каждый раз, когда мне нужно написать запрос, будь то запрос на создание таблицы, запрос на select/insert/update, или мне нужно создать индекс - я копирую запрос, копирую структуру таблиц и кидаю в ChatGPT с вопросом "what can be improved in this query". Например, недавно я закинул запрос на создание таблицы в PostgreSQL, где была стандартная история с расширением для UUID:
create extension if not exists "uuid-ossp";
create table if not exists table (
id uuid primary key default uuid_generate_v4(),
...
if !(!(price <= discount) && !((!(!(quantity >= maxLimit)) || !!(minOrderValue > 100)) && !(price*quantity-discount <= 200))) {
...
}
Таким образом, условие !(!(price <= discount) && !((!(!(quantity >= maxLimit)) || !!(minOrderValue > 100)) && !(price*quantity-discount <= 200))) можно переформулировать так:
Условие выполнено, если цена товара больше скидки, и либо количество товара меньше максимального лимита, либо минимальная стоимость заказа больше 100, и при этом общая стоимость товара (цена умноженная на количество) минус скидка больше 200.
в очень темное время живем
светлая память Алексею Навальному
https://www.youtube.com/watch?v=wp66e-JRlj0
на фоне ужасных событий последних недель, и ужасных событий последних двух лет в целом, я хочу заняться социально-полезной работой и, вероятно, смогу кому-то помочь
если ты, или твои знакомые переехали из России и у тебя проблемы с работой разрабом - я готов бесплатно посмотреть твое резюме, дать советы и провести мок-собес, если твой стек находится в пределах go/php
я часто вижу подобные вопросы и жалобы от людей в твиттере, так что думаю, что проблема актуальна
пока не знаю, осталась ли тут какая-то активность за время моего отсутствия, так что если интересно - лайкай, если лайки будут - оставлю контакты куда можно написать
Вообще, посты у меня и так были не часто, а на фоне всего происходящего очень сложно вести канал и поддерживать какую-либо работу.
С одной стороны - это кажется неуместным, и, вероятно, так и есть.
С другой, я попробую продолжить это делать, и надеюсь, кому-то это будет сейчас полезно: любая такая информация это возможность что-то изучить и что-то в последующем поменять.
Немного скажу про то, что я тут пилил пару недель назад в режиме лайвкодинга.
Зрителей было немного, но основная идея - приложение, которое будет отслеживать реальный уровень инфляции. Источников, которые показывали бы всё кристально чисто - я не нашёл.
Смысл такой: каждый день через определённые интервалы времени я набираю одну и ту же продуктовую корзину, и смотрю, насколько изменилась цена за предыдущий день.
Раз в неделю смотрю, как изменилась за неделю.
И раз в месяц финалим стату за 30 дней.
Собственно, софтина готова, кроме ротации проксей, небольшого количества асинхронщины и интеграции с парой крутых либ - особо интересного там ничего нет, поэтому код пока открывать смысла не вижу.
Изначально идея была настроить автопостинг этого в твиттер, но переписка с dev-саппортом твиттера затягивается, поэтому на днях сделаю автопостинг этого в отдельный канал в telegram. Вероятно, кому-то будет интересно посмотреть, что происходит с ценами, и насколько больше/меньше сегодня нужно будет заплатить, чем вчера.
Затем, если будут заинтересованные, может провести несколько сессий по рефакторингу в режиме лайв-кодинга: есть идея прикрутить дженерики, добавить больше асинхронщины и в целом привести всё к божескому виду.
Кому нужна международная Visa карта для оплаты сервисов - @Bankoff_Bo_Bot работает. Карта выдается в телеграм боте, чтоооо вообще происходит:) Пополнение через крипту USDT (её TRX или BEP20 вариант, не ETH) — видос о том, как купить крипту, был на канале. На бинансе было бы дешевле, но я брал на kassa.cc.
Пополнение этой карты с крипты долгое, до 72 часов. Много людей к ним повалило и они зашиваются, там похоже команда вся 4 офигевших от своего счастья человека:).
Но я вчера пополнил, сегодня дошли. Оплатил снова Ютуб премиум, чтобы видосы слушать можно было на телефоне, свернув программу. Работает.
Только ребят, дисклеймер — я ответственности никакой не несу за этот банкофф и никого не призываю туда слать крипту. Просто рассказал о своём опыте, он положительный.
хочу протестировать трансляции в телеге, и сделать немного лайвкодинга
серверная часть будет на go, со стороны сервера на первой итерации будут веб-парсеры и веб-сервер с парой ручек
со стороны морды будет vue, задача которого - отобразить эти самые пару ручек
ничего сложного, проект на пару-тройку вечеров, писаться всё будет без подготовки, просто кодим в реал-тайме
если интересно - плюсуй
⚡️ Вышел Go 1.18
Что нового: https://go.dev/doc/go1.18
выше я делился мануалом по настройке wireguard от канала "Диджитализируй", по которому и сам настроил себе vpn
у меня и всех, кому я его расшарил - отлично работает
всем, кто пользуется сторонними решениями - рекомендую
во-первых, это дешевле
во-вторых, вероятность его блокировки гораздо ниже, чем у какого-либо стороннего сервиса
ну и в-третьих, аргументы, которые описывает автор мануала:
Наверное, все уже слышали, что в ближайшие дни может начать шататься интернет, в связи с либо проверкой аппаратуры, которая умеет его ограничивать, либо уже с непосредственно ограничением.
Поэтому, всем, кто ещё не подготовился, вероятно, стоит это сделать:
https://telegra.ph/CHto-delat-pri-otklyuchenii-interneta-02-27?utm_source=tg&utm_medium=novaya&utm_campaign=chto-delat-v-sluchae-polnogo-otklyucheniya
Настроим в этом видео WireGuard VPN. Это легко конфигурируемый, быстро работающий и нетребовательный к ресурсам VPN, работающий — внезапно — лучше тех платных VPN сервисов, которые я за прошедшие дни пробовал. Помимо доступа к ресурсам, которые перестали работать — а сейчас могут не открываться даже сайты заказа лекарств, WireGuard это безопасный интернет за счёт шифрования трафика, а также возможность объединять несколько компьютеров в одну сеть с доступом откуда угодно. И самый сок — всё настраивается куда проще, чем в случае с OpenVPN, конфиги в несколько понятных строк. Будем поднимать!
https://www.youtube.com/watch?v=5Aql0V-ta8A
Domain need to be a database agnostic
Продолжаю читать книгу "Go with domains" и учиться строить DDD-приложения.
Ранее я уже писал о двух правилах построения DDD: вся логика должна быть упрощена до типов, которые имеют поведение и всегда держите валидное состояние домена в одном месте.
Дальше автор пишет про третье правило - домен не должен работать с базой данных (будь то реляционная, in-memory или любая другая БД) напрямую.
У нас есть как минимум три причины чтобы следовать этому:
• Домены по определению описывают сущности, связанные с бизнес-логикой, а не с DB-слоем, и их нужно различать.
• Вероятно, мы захотим хранить данные в базе в более оптимальном виде. Например, если в домене у нас есть тип []string, то в DB-слое мы, вероятно, захотим использовать pq.StringArray
• В Go нет ORM-решений и магии в виде аннотаций из коробки, что сильно усложняет интеграцию домена с DB-слоем
И пример хорошего кода на основе всех трех правил:
func (g Server) MakeHourAvailable(ctx context.Context, request *trainer.UpdateHourRequest) (*trainer.EmptyResponse, error) {
trainingTime, err := protoTimestampToTime(request.Time)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "unable to parse time")
}
if err := g.hourRepository.UpdateHour(ctx, trainingTime, func(h *hour.Hour) (*hour.Hour, error) {
if err := h.MakeAvailable(); err != nil {
return nil, err
}
return h, nil
}); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &trainer.EmptyResponse{}, nil
}
Hour, есть поведение - MakeAvailable(), которое мы используем. И вся логика работы со слоем базы данных скрыта и так же инкапсулирована с помощью паттерна репозиторий - о котором я расскажу в следующем посте.
Читать полностью…
Сейчас читаю книгу "Go with domains" про то, правильно приготовить DDD в Go.
Автор пишет:
While implementing your domain, you should stop thinking about structs like dummy data structures or “ORM like” entities with a list of setters and getters. You should instead think about them like types with behavior.
training schedule на 13:00", вместо этого человек ответит: "я запланировал тренировку на 13:00".
func (s TrainerService) ScheduleTraining(ctx context.Context, request Request) error {
hour, found := s.FindHour(request.Hour)
if request.HasTrainingScheduled && !hour.Available {
//
}
if request.Available && request.HasTrainingScheduled {
//
}
if !request.Available && !request.HasTrainingScheduled {
//
}
}
Hour, для которого описать поведение ScheduleTraining, где мы или получим ошибку что время уже занято, или займем его, если оно доступно:
func (h *Hour) ScheduleTraining() error {
if !h.IsAvailable() {
return ErrHourNotAvailable
}
h.availability = TrainingScheduled
return nil
}
Я активно уже несколько месяцев веду канал с дайджестом статей по Go: @digest_golang, пробил там первую тысячу и просмотрел за это время огромное количество статей и материалов.
Хочу продублировать сюда несколько интересных статей за последнее время, думаю что кто-то найдет это полезным:
* Generic Concurrency в Go - автор затрагивает тему дженериков и приводит паттерны, по которым их можно использовать в асинхронной работе вместе с горутинами. Дженерики добавили в Go больше года назад, но многие разработчики, исходя из моих наблюдений, все еще не используются или боятся использовать, хотя по-моему, инструмент очень крутой. У меня было несколько кейсов, когда получилось действительно убрать очень много дублирующего кода.
* No sleep until we build the ideal pub/sub library in Go - очень крутой материал, где автор, кстати с использованием дженериков и горутин, что отлично продолжит первую статью, пишет библиотеку для pub/sub. Отличный материал для понимания работы подобных библиотек и для практики работы с многопоточным программированием.
* Hash-Based Bisect Debugging in Compilers and Runtimes - сильно технический, но очень полезный ман о том, как искать и править баги в коде с помощью поиска по бинарному дереву через инструмент Bisect.
Открыл для себя google apps script - инструмент, позволяющий работать с инфрой гугла с помощью js-подобного кода и ставить задачи по времени like крон.
Например, задача: вам на почту приходят письма, и некоторые из них - супер важные. Предположим, что как только супер-важное письмо пришло - вам нужно сгенерировать отчет и отправить его заказчику.
И еще предположим, что супер-важное письмо содержит в заголовке строку "weekly report". При этом тот, кто отправляет письма не хочет и не может заинтегрироваться с вашим api. Тут на помощь приходит apps script.
Задача решается в несколько шагов:
* Сначала подготавливаем http-ручку на нашем бэкенде, вызов которой делает нужную нам работу.
* В моем случае я завел ещё одну почту, куда с помощью фильтров отправил только нужные мне письма, добавив к каждому из них определенный лейбл и пометив его звёздочкой.
* Затем идём на script.google.com и под нужным аккаунтом, почту которого нужно проверять, пишем обработку наших писем:
function checkEmails() {
const threads = GmailApp.search('is:starred label:"my_label"');
for (const thread of threads) {
const messages = thread.getMessages()
for (const message of messages) {
if (!message.isStarred()) {
continue;
}
...
let response = UrlFetchApp.fetch('https://myapi.com/api/test', options);
...
message.unstar()
}
}
}
написал большой и подробный ман о том, как с нуля настроить neovim и зачем в 2024 году это нужно
постарался описать все то, чего не хватало мне, когда я погружался в эту тему
https://poltora.dev/neovim-for-developers/
го читать
реакции есть, так что кто считает, что ему нужна помощь, пишите: @junsenpub
чтобы пост не был из одной строчки, поделюсь еще своими наблюдениями о собеседованиях
я уже давно собеседовал php-разработчиков на разные грейды, и около года как начал собеседовать go-разработчиков на senior и middle позиции
сейчас популярна такая тема, как хак-собеседований: когда ты не готовишься и разбираешься, а учишься умело наебать интервьюера, ответить на его вопросы с помощью чата таких же хакеров, как и ты, и задорно зателеть на работу, на которой потом работать ты, конечно же, не планируешь - только получать деньги
особенно громко таких ребят слышно в твиттере
да, на рынке есть разные неповоротливые конторы, где (если ты конечно как-то к ним пройдешь) в каком-нибудь отделе тебя просто могут не замечать полгода и платить тебе зарплату
но везде, где я работал (а я много где работал) - такая история не прокатила бы и человека уволили бы на испыте одним днем
в минусе от такого увольнения оказывается не компания - у компании постоянный поток кандидатов, и компания вместо него возьмет следующего, а мамких хакер - абсолютное большинство потратит в итоге на поиски компании столько времени, что можно было бы несколько раз подготовиться, получить знания и пройти собес
я разделяю мнение, что типичный собес плохо оценивает тебя как разраба, и скорее всего ты сможешь перекладывать json как бы ты его не прошел
но
мой опыт, как и опыт большого числа компаний показывает, что есть огромная корреляция между тем, насколько хорошо человек проходит собес (если на этом собесе была не только теория, но и задачи, дающие кандидату возможность показать, как он умеет думать), и тем, насколько хорошо он потом будет работать и делать задачи
сейчас риторика апологетов хака собесов стала меняться на "я просто хочу, чтобы на собесе проверяли знания; сейчас все собесы не работают, и мы это доказываем тем, что мы их хакаем"
как я уже сказал выше, если ты и найдешь собес, который можно наебать, то испытательный срок обойти будет сильно сложнее
ну и вседа держи в голове, что основное, что эти апологеты хотят - это бабки, так как все такие чаты платные
какой тут можно сделать вывод: если у тебя совсем нет знаний, и ты решил таким путем быстро получить работу - волшебной кнопки не бывает, и будь готов, что помимо денег за доступ к чату таких же "хакеров", ты еще потратишь очень много нервов, времени и сил на поиск компании, с которой этот номер пройдет
если у тебя уже есть какие-то знания - вероятно, полезней будет посмотреть примеры прохождения собесов на твоем стеке на youtube - это бесплатно, и очень часто совпадает с реальными собесами
в очередной раз все пошло не по плану :)
план, собственно, был описан выше
предприму еще одну попытку оживить тут активность, и в этот раз у меня есть, что писать
несколько недель назад я сменил работу - полностью перешел на golang и теперь пишу только на нем
сейчас вкатываюсь в процессы, смотрю как тут решаются разные задачи и радуюсь красоте этого языка :)
параллельно решил добить все-таки курс от бывшего mail.ru group на coursera, последний раз я остановился на том, что решил легендарную вторую домашку и дальше забил
курс оплачен, отображается (кстати, надолго ли? или coursera решила все-таки оставить уже начатые курсы?), и надеюсь его получится завершить
пока в планах описывать разное полезное с работы касательно go, архитектуры и процессов
собственно, далеко ходить не буду и отвечу на вопросы, которым я задавался когда менял стек: насколько сильно обычная backend-разработка на go отличается от разработки на php, как отличается реальная структура проекта от описанной в golang-layout, как отличаются паттерны описания сервисов и репозиториев от тех, что можно найти в разных статьях на medium и видосах на youtube?
ответ: почти не отличаются
те примеры, что видел я и базовую структуру которых повторял в своих проектах оказались очень похожими на правду, за исключением некоторых субъективных моментов
так что всем страждущим и желающим перейти на go могу однозначно посоветовать следующие ресурсы:
https://www.youtube.com/c/TheArtofDevelopment - хорошие построения базовой структуры rest-приложения, примеры построения ddd-архитектуры и в целом большое количество видосов и автор, умеющий объяснить
https://www.youtube.com/c/MaksimZhashkevych - примеры построения приложений, выделения структуры сервисов, репозиториев и интеграции всего этого вместе
https://github.com/golang-standards/project-layout - пример структуры приложения, де-факто стандарт
на практике многое отсюда заимствуется, что-то пропускается
кто-то считает этот пример плохим и пилит свой
но ознакомится и попробовать точно стоит
проверил бота выше, есть контакт
единственное, судя по всему из-за нагрузки, крипта конвертится чуть дольше, чем за 72 часа, у меня пришло почти через 4 дня
всем аллоха :)
сегодня будет лайвкодинг, без подготовки, в режиме реальной разработки: с гуглом и туплением, в общем всё, как обычно :)
цели на сегодня:
- написать несколько парсеров с интеграцией с какой-нибудь субд, скорее всего это будет что-то документоориентированное, и скорее всего - монга, но может и её аналоги
- поднять веб-сервер, написать несколько ручек, которые будут выводить данные, собранные парсерами
- если всё пройдёт относительно быстро (1.5-2 часа), то порефачить всё написанное и прикрутить к парсерам многопоточную работу; если всё пройдёт не быстро, то сделаю это либо на 2-ом стриме, либо за кадром
вчера протестировал трансляции в телеге, и, как оказалось, до трансляций в хорошем качестве тут ещё очень далеко, поэтому стримить буду на твиче
кому интересно включить что-то фоном - ссылка будет в канале в 18-19 по мск
постоянно обновляемый список пакетов/бандлов/софта, в котором обнаружена малварь или иные, связанные с последними событиями, вещи:
https://docs.google.com/spreadsheets/d/1H3xPB4PgWeFcHjZ7NOPtrcya_Ua4jUolWm-7z9-jSpQ/htmlview?usp=sharing&pru=AAABf7rAbC0*P8SbG5KHN5WLt2JJJhoK-Q
проверьте свои зависимости
возможно, имеет смысл сейчас жёстко из зафиксировать
Многие спрашивают в комментах — это вы всё выпендриваетесь, я вот поставил бесплатный VPN и всё работает у меня. Или плагин в браузер. Или платный VPN купил.
Тем временем РКН заблокировал уже 20 VPN сервисов:) Что произойдёт, когда ваш бесплатный или платный — чужой — сервис просто перестанет работать? Или будет работать, но без нужных вам сайтов? Ну, можно будет искать очередной и ждать, пока заблокируют его.
Думаю, что сейчас самое время научиться устанавливать свои VPN и подобные им решения. Это то, что вы контролируете в отличие от чужих сервисов. Ваши решения тоже могут быть заблокированы, но знания останутся с вами и вам будет проще найти другой рабочий вариант. Их сейчас огромное количество. Действительную ценность имеют ваш опыт и ваши навыки. Всегда полезно их развивать.
И да. Стоит сказать, что понимание ценности Open Source решений у меня сейчас поднимается на новый уровень.
отличный и как никогда актуальный тред о том, как привязать себя к валюте и найти работу за бугром: https://twitter.com/M0rtyMerr/status/1502230397245087747?s=20&t=Spg7Jh3hZUJZlTlG_Qnv_w
Читать полностью…
Текстовая инструкция по настройке Wireguard к видео.
Обновляем сервер:
apt update && apt upgrade -y
apt install -y wireguard
wg genkey | tee /etc/wireguard/privatekey | wg pubkey | tee /etc/wireguard/publickey
chmod 600 /etc/wireguard/privatekey
vim /etc/wireguard/wg0.conf
[Interface]
PrivateKey = <privatekey>
Address = 10.0.0.1/24
ListenPort = 51830
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
<privatekey> содержимое файла /etc/wireguard/privatekeyecho "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
systemctl enable wg-quick@wg0.service
systemctl start wg-quick@wg0.service
systemctl status wg-quick@wg0.service
wg genkey | tee /etc/wireguard/goloburdin_privatekey | wg pubkey | tee /etc/wireguard/goloburdin_publickey
vim /etc/wireguard/wg0.conf
[Peer]
PublicKey = <goloburdin_publickey>
AllowedIPs = 10.0.0.2/32
<goloburdin_publickey> — заменяем на содержимое файла /etc/wireguard/goloburdin_publickeysystemctl restart wg-quick@wg0
systemctl status wg-quick@wg0
vim goloburdin_wb.conf
[Interface]
PrivateKey = <CLIENT-PRIVATE-KEY>
Address = 10.0.0.2/32
DNS = 8.8.8.8
[Peer]
PublicKey = <SERVER-PUBKEY>
Endpoint = <SERVER-IP>:51830
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 20
<CLIENT-PRIVATE-KEY> заменяем на приватный ключ клиента, то есть содержимое файла /etc/wireguard/goloburdin_privatekey на сервере. <SERVER-PUBKEY> заменяем на публичный ключ сервера, то есть на содержимое файла /etc/wireguard/publickey на сервере. <SERVER-IP> заменяем на IP сервера.
Нашёл огненную статью по профилированию и отладке go-программ: https://habr.com/ru/company/badoo/blog/301990/
Огромный массив информации про инструменты и методы, позволяющие найти в программе места, где плохо памяти, процессору, или где не стоит пересобирать регулярку в цикле :)
После прочтения понимаешь, что авторы языка сумели сделать не просто много инструментов для профилирования кода, они сумели ещё и сделать их крайне удобными.
А автор статьи сумел показать на примерах, как эти инструменты использовать.