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
Привет, коллеги! Сегодня хочу поделиться с вами 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
Например, наше приложение работает с разной нагрузкой - днём она высокая, а ночью маленькая.
Или у нас есть очереди, которые обрабатывают разное кол-во задач. То густо, то пусто 😃
Пакет будет каждую минуту запускать функцию, в которой мы говорим сколько серверов нужно в текущий момент.
Это позволяет сильно экономить на серверах.
Получается такой мини-кубернетис с автоматическим горизонтальным масштабированием.
Серверы создаются из заранее подготовленного образа. Прикольная тема, если что будем иметь ввиду.
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
Бывает такое, что при запуске проекта говорят, что сразу нужно подготовить серверы к нагрузке и масштабированию без остановки приложения. В этом случае я обычно создаю несколько серверов:
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🔥8❤1
Серверы и масштабирование Часть 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
Вчера говорили про серверы, на которых работает наше приложение. Их может быть от 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🔥7❤1💩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
В крупных и важных приложениях нужен хороший мониторинг, чтобы мы могли легко оценить текущее состояние системы, определить узкие места и вовремя реагировать на возможные неприятности.
В базовом варианте мониторингом может служить панель сервер-провайдера, то есть сервиса, где вы покупаете серверы - там обычно есть графики потребления памяти, процессора и диска. Можно настроить уведомления о привышении нагрузки, например когда потребление памяти превышает 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🔥9❤1