OneCode
1.4K subscribers
628 photos
59 videos
3 files
524 links
Full Stack на PHP, Laravel и всё, что с этим связано.
YouTube: https://www.youtube.com/@onecode_blog
Download Telegram
Bash скрипт из Laravel Forge

Привет, коллеги! Сегодня хочу поделиться с вами bash-скриптом, который используется в официальном сервисе для управления серверами и деплоя приложений - Laravel Forge.

Для запуска скрипта необходима чистая установка Ubuntu 20.04 x64, куда мы загружаем файл скрипта, запускаем его и ждём завершения.

Что делает скрипт:
- Nginx;
- PHP;
- MySQL / Postgres (что выбрано);
- Logrotate;
- UFW Firewall;
- OPcache;
- Memcached;
- Redis;
- MeiliSearch;
- Автоматические обновления безопасности;
- И многое другое.


Скачать скрипт: https://cloud.mail.ru/public/2Z5j/FF1jCdBXy

Сайт Laravel Forge: https://forge.laravel.com

PS: этот скрипт для Application Server (сервер приложений), то есть максмальная конфигурация, где есть всё и сразу, однако в Forge можно выбрать другой тип сервера: сервер базы данных, сервер очередей, балансировщик нагрузки и тд, таким образом там устанавливается только то, что необходим для выбранного типа сервера.

#forge #servers
Пакет для автоматического создания и удаления дополнительных серверов

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

Или у нас есть очереди, которые обрабатывают разное кол-во задач. То густо, то пусто 😃

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

Это позволяет сильно экономить на серверах.

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

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

https://spatie.be/docs/laravel-dynamic-servers/v1/introduction

#laravel #server #servers
👍5
Серверы и масштабирование Часть 1 Серверы

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

1. Балансировщик нагрузки (LoadBalancer). Этот сервер стоит на передовой и принимает все HTTP-запросы к приложению. На сервере стоит веб-сервер Nginx, который проксирует (перенаправляет) запросы к одному из серверов приложений по локальной сети. То есть он скрывает за собой серверы с приложением и распределяет запросы (нагрузку) между ними. На балансировщике стоит SSL-сертификат, таким образом остальные серверы НЕ требуют его установки, тк их общение проходит в локальной (закрытой) сети.

2. Сереры приложения (Application1). Их может быть несколько, но в начале создаю один нужной конфигурации для обработки ожидаемого количества запросов. На этом сервере тоже установлен Nginx, который принимает запросы от балансировщика (первый сервер) и направляет их в приложение - PHP, PHP-FPM, Laravel.

3. Сервер очередей (Queue). Этот сервер НЕ принимает запросы, а занимается только обработкой задач в очереди. На нём так же работают задачи по расписанию, запускаемые ежеминутно через CRON. Тут стоит PHP и тоже самое приложение на Laravel. Очереди с помощь Laravel Horizon.

4. WebSocket-сервер (WS). Это опциональный вариант, если для приложения требуется обновление данных на клиенте в реальном времени. Вместо этого сервера можно использовать внешние сервисы, такие как Pusher и Ably (раньше использовал оба). Или развернуть на этом сервере свой вебсокет-сервер на JavaScript, например Soketi (использовал). Или развернуть тоже самое приложение на Laravel с новым пакетом Laravel Reverb (использую сейчас). На этом сервере подключен отдельный домен с SSL для обработки входящих подключений и Nginx, который перенаправляет запросы на сам вебсокет-сервер.

Что даёт это разделение? А то, что application серверы скрыты за балансировщиком, позволяет незаметно добавлять новые серверы по мере необходимости. Например нужно увеличить мощность application сервера (вертикальное масштабирование) - тогда просто создаём новый application сервер бОльшей мощности, разворачиваем на нём приложение и говорим балансировщику, чтобы он все запросы отправлял на него, а старый (маленький) application сервер удаляем.

Таким образом для увеличения мощности сервера НЕ пришлось останавливать работу сайта. Или другой вариант - просто добавить второй такой же application сервер (горизонтальное масштабирование), балансировщик будет разделять все запросы между двумя серверами и опять же без остановки приложения. Так можно добавлять еще сервера в будущем по мере роста нагрузки.

Что касается сервера очередей и вебсокет-сервера, то их в этой схеме не получится увеличить без простоя, то есть пока сервер выключен (увеличивается), задачи в очереди обрабатываться не будут, а когда включится - обработка продолжиться. Обычно это занимает 2 минуты, поэтому для очередей это не так критично, а сам сайт продолжает работу. С вебсокетами аналогично. Не вижу смысла здесь сильно запариваться.

Нужно продолжение? С тебя лайк и репост! @onecode_blog 👈

#servers #devops
👍55🔥81
Серверы и масштабирование Часть 2 Базы данных

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

Сегодня говорим про базы данных. У нас может быть несколько баз данных. В моих проектах их две - реляционная (PgSQL) для основных данных приложения и NoSQL (Redis) для кеширования, сессий и задач в очереди.

Реляционная база данных

В нашем примере я выношу основную базу на отдельный сервер. Это нужно потому что все серверы, на которых работает наше приложение должны работать с одной базой данных. Соответственно наши application серверы и worker сервер подключаются к отдельному серверу БД по локальной сети.

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

NoSQL база данных

Для кеша использую БД Redis, который тоже ставлю на отдельный сервер, чтобы к нему могли иметь доступ остальные серверы с приложением. Сессии в идеале тоже нужно хранить на отдельном сервере, чтобы в случае очистки кэша (php artisan cache:clear) они не потерялись - в этом случае пользователям придется заново входить в кабинет (в случае с аутентификацией через сессию).

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

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

Подводим итог

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

Дополнительно

В последнее время вместо разворачивания серверов с базой (в продакшене) использую облачные базы данных, управляемые поставщиком услуги (Cloud Managed Databases). Там мы просто выбираем тип базы данных (MySQL, PostgreSQL, Redis), размер сервера (процессор, оперативка, размер диска) и всё. База автоматически разворачивается, а наши приложения подключаются к ней, как обычно. Там мы видим основную статистику по работе этой базы, можем увеличивать её мощность, имеем автоматическое резервное копирование (репликацию) и можем добавлять еще экземпляры для чтения в пару кликов. И всё это без остановки приложения!

Очень понравилось много репостов в прошлый раз. Ну вы поняли. @onecode_blog 👈

#servers #devops
Please open Telegram to view this post
VIEW IN TELEGRAM
👍40🔥71💩1🍌1
Серверы и масштабирование Часть 3 Мониторинг

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

В базовом варианте мониторингом может служить панель сервер-провайдера, то есть сервиса, где вы покупаете серверы - там обычно есть графики потребления памяти, процессора и диска. Можно настроить уведомления о привышении нагрузки, например когда потребление памяти превышает 80% мы получим письмо на email. Это удобно и всегда нужно сразу настраивать такие уведомления.

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

Например для Nginx полезно видеть количество запросов, время отклика, количество открытых соединений и тд. Для PHP-FPM тоже количесто запросов, время обработки запроса, потребление памяти и тд. Для PostgreSQL или MySQL тоже количество запросов, время работы запросов, потребление ресурсов и тд.

Для решения этой задачи есть разные способы, но оптимальный с точки зрения простоты настройки, надежности и полноты я считаю связку Prometheus + Graphana. Можно сказать, что это классический популярный вариант. Обычно они вместе ставятся на отдельный небольшой сервер.

Prometheus

Как я сказал, прометеус в идеале устанавливается на отдельный сервер и собирает необходимые данные с остальных серверов, сохраняя их в свою внутреннюю базу данных. Настройка прометеуса довольно проста - там есть файл конфигурации prometheus.yml, в котором мы указываем какие метрики, с каких серверов и с какой периодичностью необходимо получать.

Помимо этого на каждый сервер, с которого прометеус должен собирать метрики, необходимо установить экспортер - небольшая программа, которая получает данные от нужного процесса и передаёт их в прометеус. Например, если мы хотим собирать метрики Nginx, то нужно установить nginx-prometheus-exporter, для PHP-FPM устанавливаем php-fpm_exporter, для PostgreSQL ставим postgres_exporter и так далее.

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

Graphana

Графана нужна для отображения данных из прометеуса в графическом интерфейсе. В графане мы можем создавать различные информационные панели с графиками на основе данных из прометеуса, выдавать к ним доступ и настраивать уведомления (alerts). Например, можно создать панель, отображающую количество запросов в секунду (RPS) для Nginx, время отклика PHP-FPM, использование CPU и памяти сервером и т.д.

Таким образом анализируя метрики в Graphana, собранные Prometheus, можно выявлять узкие места в производительности и принимать решения о масштабировании или оптимизации инфраструктуры и своевременно получать уведомления, когда что-то идёт не так.

Спасибо за внимание и репосты, парни! @onecode_blog 👈

#servers #devops
👍12🔥91