55
Федеральное государственное автономное образовательное учреждение высшего образования КАЗАНСКИЙ (ПРИВОЛЖСКИЙ) ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ ВЫСШАЯ ШКОЛА ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ И ИНФОРМАЦИОННЫХ СИСТЕМ Направление подготовки: 09.03.03 Прикладная информатика ВЫПУСКНАЯ КВАЛИФИКАЦИОННАЯ РАБОТА МЕТОДЫ РАЗРАБОТКИ И ПРОЕКТИРОВАНИЯ ВЫСОКОНАГРУЖЕННЫХ ПРИЛОЖЕНИЙ С ИСПОЛЬЗОВАНИЕМ ЯЗЫКОВ ПРОГРАММИРОВАНИЯ ELIXIR / RUBY Работа завершена: «___»_____________2017 г. Студент группы 11-304 ___________________ К.С. Каюмов Работа допущена к защите: Научный руководитель Старший программист, ООО Flatstack «___»_____________2017 г.

kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

  • Upload
    others

  • View
    25

  • Download
    0

Embed Size (px)

Citation preview

Page 1: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

Федеральное государственное автономное образовательное учреждение

высшего образования

КАЗАНСКИЙ (ПРИВОЛЖСКИЙ) ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ

ВЫСШАЯ ШКОЛА ИНФОРМАЦИОННЫХ ТЕХНОЛОГИЙ И

ИНФОРМАЦИОННЫХ СИСТЕМ

Направление подготовки: 09.03.03 Прикладная информатика

ВЫПУСКНАЯ КВАЛИФИКАЦИОННАЯ РАБОТА

МЕТОДЫ РАЗРАБОТКИ И ПРОЕКТИРОВАНИЯ

ВЫСОКОНАГРУЖЕННЫХ ПРИЛОЖЕНИЙ С ИСПОЛЬЗОВАНИЕМ

ЯЗЫКОВ ПРОГРАММИРОВАНИЯ ELIXIR / RUBY

Работа завершена:

«___»_____________2017 г.

Студент группы 11-304 ___________________ К.С. Каюмов

Работа допущена к защите:

Научный руководитель

Старший программист, ООО Flatstack

«___»_____________2017 г. ___________________ В.А. Бажанов

Директор Высшей школы ИТИС

«___»_____________2017 г. ___________________ А.Ф. Хасьянов

Казань – 2017 г.

Page 2: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

СОДЕРЖАНИЕВВЕДЕНИЕ..................................................................................................................31. БАЗОВЫЙ ПРОЕКТ...............................................................................................5

1.1. Elixir...................................................................................................................51.2. Phoenix...............................................................................................................71.2.1. Mix.................................................................................................................111.2.2. Plug................................................................................................................111.2.3. Ecto................................................................................................................121.2.4. Views.............................................................................................................13

2. ОПТИМИЗАЦИЯ КОМПОНЕНТОВ СИСТЕМЫ.............................................142.1. База данных.....................................................................................................142.2. Веб-сервер........................................................................................................172.3. Front-end...........................................................................................................202.4. Взаимодействие с Ruby..................................................................................23

3. DOCKER.................................................................................................................26ЗАКЛЮЧЕНИЕ.........................................................................................................30СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ................................................31ПРИЛОЖЕНИЕ.........................................................................................................32

2

Page 3: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

ВВЕДЕНИЕВ эпоху информационных технологий, когда у большинства людей есть

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

обеспечения. Начиная с простых текстовых редакторов и заканчивая

масштабными платформами для ведения бизнеса. Менялись и способы

предоставления программ конечным пользователям.

В 90-х годах одно приложение могло уместиться на дискете. Но шло

время, функционал усложнялся, и размер программ увеличивался.

В начале 2000-х ПО в основном распространялось на CD-дисках. Для

пользователей это был довольно удобный способ получения и использования

программ, однако создателям и разработчикам приходилось тратить

внушительное количество средств на заказ и производство самих CD-дисков.

Также приходилось придумывать средства защиты от подделки лицензий.

В годы, когда сеть Интернет развивается семимильными шагами, очень

распространенным способом продажи программного обеспечения является

продажа через Интернет. Пользователь может скачать программу с сайта

производителя с урезанным функционалом, а для разблокировки главных

функций необходимо приобрести лицензию. Сделать это можно с помощью

электронных платежей, которые на сегодняшний день отлично защищены. Этот

способ упрощает распространение ПО, но не обеспечивает должной защиты от

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

миллионы человек получат продукт бесплатно.

Самым современным форматом программ является веб-приложение. Веб-

приложение – клиент-серверное приложение, где клиент – это браузер, а сервер

– веб-сервер.

У такого ПО есть ряд преимуществ:

не нужна установка программы непосредственно на компьютер.

Нужен лишь браузер;

нет необходимости в создании несколько версий одного продукта

для разных операционных систем;

3

Page 4: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

не занимает память на жестком диске компьютера;

пользователь всегда получает последнюю версию;

доступ с различных устройств (смартфоны, планшеты и т.д.).

Но также есть и минусы:

необходим доступ к сети Интернет;

персональные данные хранятся на удалённых серверах;

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

взаимодействовало с системой пользователя, например утилиту для

форматирования дисков или очистки системы от «мусора».

Сегодня достаточно просто создать своё веб-приложение. Для различных

языков программирования существует огромное количество фреймворков и

инструментов. Так для Java есть Spring. Для Python есть Django. Для Ruby есть

Ruby on Rails. Все эти ЯП относятся к классу императивных языков, имеющих

свои недостатки. Другое класс – функциональные ЯП, например Haskell, Lisp,

Clojure. Они редко используются для создания веб-приложений. В основном их

применяют для организации сложных математических вычислений и обработки

больших данных.

Актуальность данной дипломной работы обусловлена тем, что в

настоящее время разработчик тратит большое количество времени для запуска

всех компонентов системы, необходимых для работы веб-сервиса. Помимо

этого нужно уделить немало времени для первоначальной настройки этих

компонентов в режиме высоких нагрузок.

Целью дипломной работы является:

создание базового проекта на основе языка программирования

Elixir и фреймворка Phoenix;

исследовать наиболее уязвимые в плане производительности части

приложений;

анализ различных конфигураций системы и подбор наиболее

оптимальных;

создание Docker-контейнера для быстрого и удобного запуска.

4

Page 5: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

1. БАЗОВЫЙ ПРОЕКТ1.1. Elixir

Elixir – функциональный, распределённый, язык программирования

общего назначения, работающий на виртуальной машине Erlang (BEAM). Elixir

построен поверх Erlang, что обеспечивает распределённость,

отказоустойчивость, исполнение в режиме мягкого реального времени,

метапрограммирование с макросами и полиморфизмом, реализованным через

протоколы. Elixir использует Erlang/OTP для работы с деревьями процессов[1].

Elixir был создан Жозе Валимом (José Valim), одним из основных

разработчиков Ruby on Rails о со-основателем компании Plataformatec. Его

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

Erlang VM, сохраняя совместимость с инструментами и экосистемой Erlang.

Erlang – функциональный язык программирования, позволяющий писать

программы для разного рода распределённых систем. Разработан и

поддерживается компанией Ericsson. Язык включает в себя средства

порождения параллельных процессов и их коммуникации с помощью посылки

асинхронных сообщений. Программа транслируется в байт-код, исполняемый

виртуальной машиной, что обеспечивает переносимость.

Как уже было сказано, Erlang относится к классу языков

функционального программирования. В этих языках основными

конструктивными элементами являются функции. Основное отличие от

императивных языков программирования заключается в декларативности

описаний функций. Тексты программ на функциональных языках

программирования описывают «как решить задачу», но не предписывают

последовательность действий для решения[2].

Ключевыми особенностями Erlang (соответственно и Elixir) являются:

Высокоуровневые конструкции языка. Erlang — это

декларативный язык программирования, позволяющий описывать,

что должно быть вычислено, вместо описания того, как это должно

5

Page 6: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

быть вычислено. Erlang так же использует динамическую

типизацию, что может ускорить разработку приложений.

Параллельная обработка и передача сообщений. Вместо

использования распространенной в настоящее время модели

параллельного программирования, в которой используются потоки

с разделяемой памятью, Erlang поддерживает параллельную

модель, основанную на легковесных процессах с асинхронной

передачей сообщений. Процессы в Erlang не имеют ничего общего

с процессами операционной системы и называются процессами

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

от других процессов. При этом процессы Erlang за счет своей

легковесности (время создания процесса составляет несколько

микросекунд и не зависит от количества уже работающих

процессов) работают даже эффективнее, чем потоки операционной

системы, что позволяет работать с несколькими десятками тысяч

процессов в одном приложении. Процессы общаются между собой

посредством передачи сообщений (время передачи сообщения

составляет несколько микросекунд так, как данные просто

копируются из пространства одного процесса в пространство

другого в рамках виртуальной машины), где сообщением может

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

передаются асинхронно, таким образом, сразу после посылки

сообщения отправитель может продолжить работу. Входящие

сообщения извлекаются из «почтового ящика» процесса выборочно

и, таким образом, нет необходимости извлекать сообщения по

очереди.

Распределенная обработка. Так как процессы в Erlang не

используют разделяемой памяти, а общаются только посредством

передачи сообщений, язык позволяет достаточно легко превратить

6

Page 7: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

параллельное приложение в распределенное, где различные

процессы выполняются на различных узлах сети.

Надежность. Erlang поддерживает различные подходы для

построения высоконадежных систем. На низком уровне процессы

могут быть связаны между собой и оповещаться посредством

сообщений при завершении связанного процесса. На более высоком

уровне, при использовании OTP (см. врезку), появляется

возможность устанавливать различные политики мониторинга

отдельных процессов и групп процессов. В распределенной системе

резервные узлы могут автоматически заменять узлы вышедшие из

строя.

Работа в режиме мягкого реального времени (soft real-

time). Хотя Erlang — это высокоуровневый язык, его можно

использовать для систем работающих в режиме мягкого реального

времени (когда нарушение временных ограничений приводит

только к снижению качества работы системы). Язык использует

автоматическое управление памятью, при котором «сборка мусора»

происходит отдельно для каждого процесса в системе. Это

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

микросекунд даже при наличии «сборки мусора», что, в свою

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

практически без потери пропускной способности.

Работа приложений в течение долгого времени. Язык

поддерживает «горячую» замену кода модулей в работающем

приложении, при котором в один момент времени могут работать

старая и новая версии кода. Это необходимо для систем, которые

просто не должны останавливаться для обновления кода.

Основные возможности Elixir:

компилируется в байт-код для выполнения на виртуальной машине

Erlang (BEAM);

7

Page 8: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

каждый элемент является выражением;

любые функции и модули языка Erlang могут быть использованы

без влияния на время исполнения из-за компиляции байт-кода в

Erlang и наоборот;

мета-программирование дает возможность манипулирования

абстрактным синтаксическим деревом (АБС);

полиморфизм, реализованный через механизм протоколов. Как и в

Clojure, протоколы обеспечивают механизм диспетчеризации (не

стоит путать с множественной диспетчеризацией);

возможность добавления документации прямо в коде в стиле строк-

документации из языка Python (Markdown);

параллельное выполнение команд без разделения ресурсов, через

передачу сообщений (модель акторов);

повсеместное использование рекурсии и функций высшего порядка

вместо циклов, основанного на побочных эффектах;

простой параллелизм с использованием механизмов Erlang с

упрощенным синтаксисом (например, Task);

ленивые и асинхронные коллекции, основанные на потоках;

pattern matching (сопоставление с образцом);

поддержка Unicode и UTF-8 строк.

Elixir был задуман как улучшение Erlang, в частности, значительного

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

повторного присваивания значений переменных. В Elixir разработчику не

нужно завершать каждую команду точкой, так как выражения разделяются

переводом строки и символом точки с запятой (;). Также не нужно

экспортировать функции модуля, в то время как в Erlang по умолчанию все

функции недоступны из других модулей, если не упомянуты в директиве -

export. Таким образом, синтаксис Elixir больше похож на синтаксис Ruby.

8

Page 9: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

1.2. Phoenix

Phoenix – MVC-фреймворк для веб-разработки, написанный на языке

Elixir. Большинство его компонентов и концептов выглядят похожими для тех,

кто имеет опыт в создании веб-приложений с использованием Ruby on Rails или

Django.

Phoenix предоставляет лучшее из двух миров – высокую продуктивность

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

имеет несколько интересных особенностей, например каналы для реализации

функционала, который будет работать в реальном времени, а также

прекомпилированные шаблоны для высочайшей скорости ответа на запросы.

Фреймворк Phoenix является верхним уровнем многоуровневой системы,

разработанной быть модульной и гибкой. Другие уровни включают такие

модули как Plug и Ecto, который будут описаны ниже. Также в этой системе

есть HTTP-сервер (англ. HyperText Transfer Protocol – протокол передачи

гипертекста) Cowboy, написанный на Erlang, который работает как основа для

Plug и Phoenix[3].

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

свою цель и роль в построении веб-приложения:

The Endpoint (конечная точка):

o отвечает за все аспекты запросов до тех пор, пока роутер не

начинает работать;

o предоставляет основной набор так называемых “plugs” для

применения ко всем запросам;

o отправляет запросы в назначенный роутер.

The Router (маршрутизатор):

o обрабатывает поступающие запросы и отправляет их в

конкретный Controller (Контроллер) и Action (Действие).

Также передает параметры, если таковые имеются;

o предоставляет Helpers (методы-помощники) для генерации

путей и URLs (англ. Uniform Resource Locator –

9

Page 10: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

единообразный определитель местонахождения ресурса) к

ресурсам;

o определяет именованные пути, через которые разработчик

может передавать запросы;

Pipelines:

o позволяет просто применять группы ”plugs” к набору путей.

Controllers (контроллеры):

o предоставляют функции, называемые действиями, для

обработки запросов.

Actions (действия):

o подготавливают данные и передают их в Views

(представления);

o вызывают рендеринг через представления;

o выполняют переадрессацию.

Views (представления):

o отрисовывают шаблоны;

o выполняют роль презентативного уровня;

o определяют функции-помощники, доступные позже в

шаблонах для декорирования данных и отображения

пользователям.

Templates (шаблоны):

o наборы HTML-кода;

o прекомпилированные и быстрые.

Channels (каналы):

o управляют сокетами для простой и удобной связи в реальном

времени;

10

Page 11: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

o аналогичны контроллерам за исключением того, что каналы

поддерживают двунаправленное взаимодействие с

постоянными соединениями.

PubSub (сокр. публикация/подписка):

o распологается под уровнем каналов и позволяет клиентам

подписываться к topics (темам);

o абстрагирует нижележащий PubSub-адаптер для интеграции

со сторонними реализациями.

1.2.1. Mix

Elixir поставляется с прекрасным набором инструментов для лёгкой

разработки. Mix является утилитой, которая позволяет разработчикам с

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

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

интегрируется с пакетным менеджером Hex, который разрешает зависимости в

проектах и даёт возможность удалённо управлять пакетами.

1.2.2. Plug

Plug представляет из себя спецификацию для конструирования

компонуемых модулей для создания веб-приложений. Plugs являются

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

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

запросов или логирование. Из-за того, что Plug API достаточно маленький и

консистентный, plugs могут быть определены и выполнены в определенном

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

так и между различными проектами.

11

Page 12: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

Рисунок 1. Сравнение скорости ответа на запрос

Plugs могут быть написаны для обработки практически всего, начиная с

аутентификации и заканчивая обработкой параметров, и даже отрисовки

шаблонов.

Phoenix обладает в целом большим преимуществом Plug и в особенности

маршрутизатором и контроллерами.

Одной из самых важных вещей касательно Plug является то, что Plug

предоставляет адаптеры для HTTP-серверов, которые будут в конечном счёте

доставлять данные к пользователям. На сегодняшний день Plug имеет адаптер

только для веб-сервера Cowboy, написанном на Erlang в 1999-м году.

1.2.3. Ecto

Ecto – язык и инструмент композиции запросов, а также обертка базы

данных для Elixir. С Ecto мы можем запрашивать и добавлять информацию в

различные базы данных, моделировать нашу предметную область, писать

сложные запросы, иметь защиту от различных атак, включая SQL-инъекции и

многие другие.

Ecto построен вокруг четырёх абстракций:

Repo (репозиторий) – представляет соединение к конкретной базе

данных. Каждая операция в базе данных выполняется через

репозиторий:

Model (модель) – определение наших данных. Она определяет имя

12

Page 13: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

соответствующей таблицы в базе данных, названия и типы полей.

Также модель определяет ассоциации – отношения между

моделями;

Query (запрос) – связывает модели и репозитории вместе, позволяя

нам элегантно запрашивать данные из репозитория и транслировать

их в модель;

Changeset (изменения) – описывает изменения, которые мы должны

совершить с нашими данными в модели перед тем, как приложение

сможет их использовать. Сюда входят анализ типов, валидации и

др.

1.2.4. Views

Представления в Phoenix выполняют две главные задачи. Первая и

главная – они отрисовывают шаблоны (HTML-страницы). Главная функция для

отрисовки render находится в модуле Phoenix.View. Вторая задача –

предоставление функций-помощников, которые принимают данные и

преобразуют их для более простого использования в шаблонах. Это очень

напоминает такие шаблоны проектирования как Декоратор или Фасад.

Phoenix предоставляет строгое соглашение по именованию

представлений для конкретных контроллеров. Так для контроллера

PageController модель представления должен называться PageView, а шаблоны

должны лежать в директории web/templates/page.

13

Page 14: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

2. ОПТИМИЗАЦИЯ КОМПОНЕНТОВ СИСТЕМЫ2.1. База данных

В настоящее время ни один серьёзный web-проект не обходится без баз

данных. Базой данных мы считаем совокупность данных, хранимых в

соответствии со схемой данных. База данных позволяет упорядоченно хранить

данные о большом количестве однотипных объектов, обладающих одинаковым

набором свойств.

Для того, чтобы управлять данными в базе, необходимо выбрать систему

управления базами данных (СУБД). Системы управления базами данных

различаются по моделям данных, по степени распределённости, по способу

доступа и так далее. Самыми распростанёнными СУБД являются MySQL и

PostgreSQL. Для высоконагруженных систем более предпочтительной СУБД

является PostgreSQL, т.к. имеет ряд преимуществ:

наличие курсоров (для выборки большого количества данных);

функциональные индексы (можно построить индекс по функции

или скалярному выражению, что позволяет быстро находить

данные в таблице по результатам вычислений);

частичные индексы (индекс строится по определённому условию,

что позволяет уменьшить размер индекса и, следовательно,

ускорить запросы);

огромное количество встроенных типов данных;

высокопроизводительные и надёжные механизмы транзакций и

репликации;

расширяемая система встроенных языков программирования:

например, можно использовать язык PL/Ruby;

лёгкая расширяемость.

PostgreSQL поставляется со стандартными настройками, которые должны

подойти для любого проекта с «нуля». Однако, для высоконагруженной

системы, некоторые настройки необходимо изменить, чтобы обеспечить

прирост в скорости работы и отказоустойчивость.

14

Page 15: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

В PostgreSQL конфигурационные параметры принадлежат к различным

уровням:

Postmaster – требует перезапуска сервера (большинство параметров

принадлежит именно этому уровню);

Sighup – требует только сигнала HUP (работающий сервер

перезагрузит конфигурационный файл без прекращения работы);

User – значение может быть установлено в рамках сессии и будет

актуально только внутри этой сессии;

Backend – значение должно быть установлено до начала сессии[4];

Superuser – может быть изменено во время работы сервера, но

только из под пользователя с правами superuser.

Список конфигураций, на которые стоит обратить внимание при

настройке PostgreSQL:

listen_addresses – по умолчанию PostgreSQL принимает соединения

только с локальных служб. Если сервер баз данных будет находится

на отдельном сервере, то потребуется поменять этот параметр,

чтобы PostgreSQL смог принимать соединения от удаленных служб

по протоколу TCP;

max_connections – этот параметр устанавливает максимальное

количество клиентов, которые могут подключиться к PostgreSQL.

Как правило, PostgreSQL может поддерживать несколько сотен

подключений, но создание нового является дорогостоящей

операцией. Для начала необходимо установить это значение

неболшим (16..32), постепенно увеличивая этот параметр. Важно

знать, что на поддержку каждого активного клиента, PostgreSQL

тратит большое количество ресурсов, и если необходимо добиться

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

необходимо использовать менеджеры соединений.

shared_buffers – PostgreSQL не читает данные напрямую с диска и

не пишет их сразу на диск. Данные загружаются в общий буфер,

15

Page 16: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

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

пишут блоки в этом буфере, а затем уже изменения сбрасываются

на диск. Этот параметр определяет, сколько памяти будет

выделяться PostgreSQL для кеширования данных. По-умолчанию

значение этого параметра совсем небольшое (для обеспечения

совместимости), но в практических условиях это значение следует

установить в 15..25% от всей доступной оперативной памяти.

work_mem – важный параметр для запросов, использующих

всевозможные сложные выборки и сортировки. Увеличение этого

параметра позволяет выполнять эти операции в оперативной

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

подобную операцию и, следовательно, если имеется 10 активных

клиентов и каждый выполняет 1 сложный запрос, то значение в

10Мб для этого параметра затребует 100Мб оперативной памяти.

Этот параметр стоит увеличивать, если имеется большое

количество памяти в распоряжении и для старта следует выставить

его в 1Мб.

effective_cache_size – этот параметр помогает планировщику

определить количество доступной памяти для дискового

кеширования. На основе того, доступна память или нет,

планировщик будет делать выбор между использованием индексов

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

устанавливать в 50%...75% всей доступной оперативной памяти, в

зависимости от того, сколько памяти доступно для системного

кеша. Этот параметр не влияет на выделяемые ресурсы, это лишь

оценочная информация для планировщика.

checkpoint_segments – на эту настройку стоит обратить внимание,

если имеется большое количество записей в БД (для

высоконагруженных систем это нормальная ситуация). PostgreSQL

записывает данные в базу данных порциями (WALL сегменты) –

16

Page 17: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

каждая размером в 16Mb. После записи определенного количества

таких порций (определяется параметром checkpoint_segments)

происходит чекпойнт. Чекпойнт – это набор операций, которые

выполняет PostgreSQL для гарантии того, что все изменения были

записаны в файлы данных (следовательно при сбое, восстановление

происходит по последнему чекпойнту). Выполнение чекпоинтов

каждые 16Мб может быть весьма ресурсоемким, поэтому это

значение следует увеличить хотя бы до 10.

Прочие настройки, на которые стоит обратить внимание:

maintainance_work_mem;

synchronous_commit;

temp_buffers;

vacuum_cost_delay;

max_stack_depth;

max_files_per_process.

2.2. Веб-сервер

Apache и Nginx – 2 самых широко распространенных веб-сервера с

открытым исходным кодом в мире. Вместе они обслуживают более 50%

трафика во всем интернете. Оба решения способны работать с разнообразными

рабочими нагрузками и взаимодействовать с другими приложениями для

реализации полного веб-стека.

Первый релиз Nginx состоялся в 2004 году, гораздо позже появления

Apache, именно поэтому Nginx был спроектирован так, чтобы решить

проблемы Apache. Nginx начал набирать популярность благодаря своей

легковесности, возможности легко масштабироваться на минимальном железе

и простой конфигурацией. Nginx превосходен при отдаче статического

контента и спроектирован так, чтобы передавать динамические запросы

другому ПО предназначенному для их обработки. Именно поэтому для

современных web-приложений чаще всего выбирают Nginx[8].

17

Page 18: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

В стандартной конфигурации Nginx может работать при очень больших

нагрузках. Тем не менее, эффективность его работы можно значительно

повысить, настроив его параметры.

Список конфигураций, на которые стоит обратить внимание при

настройке Nginx:

1. Обработка соединений. Максимальное количество соединений,

которые Nginx может обслуживать одновременно определяются

произведением двух параметров:

Всего соединений = worker_processes x worker_connections

worker_processes – определяет количество рабочих процессов. Его

лучше устанавливать в auto;

worker_connections – устанавливает максимальное количество

соединений одного рабочего процесса (выставить от 1024 до 4096).

2. Обработка запросов.

multi_accept – будет принимать максимально возможное

количество соединений (выставить в on);

sendfile – метод отправки данных sendfile более эффективен, чем

стандартный метод read+write (выставить в on);

tcp_nodelay / tcp_nopush – отправлять заголовки и начало файла в

одном пакете (выставить в on).

3. Информация о файлах. Nginx умеет кешировать информацию о

файлах, с которыми ему приходится работать (css стили или

картинки). Если к таким файлам происходит много обращений,

кеширование может значительно ускорить этот процесс.

open_file_cache – определяет максимальное количество файлов,

информация о которых будет содержаться в кеше (выставить в

max=200000 inactive=20s);

open_file_cache_valid – определяет через какое время информация

будет удалена из кеша (выставить в 30s);

open_file_cache_min_uses – будет кешировать информацию о тех

18

Page 19: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

файлах, которые были использованы хотя бы N раз (выставить в 2);

open_file_cache_errors – будет кешировать информацию об

отсутствующих файлах (выставить в on).

4. Логирование.

access_log – основной лог лучше отключить для экономии

дисковых операций (выставить в off);

error_log – лог ошибок лучше перевести в режим логирования

только критических ситуаций (выставить в [путь к файлу] crit).

5. Сжатие Gzip. Обязательно нужно использовать сжатие, это

значительно уменьшит трафик. Nginx будет сжимать все файлы с

перечисленными типами. Не все браузеры поддерживают сжатие,

поэтому, для браузеров типа «msie6» (соответствующие

регулярному выражению «MSIE [4-6]\.») сжатие будет отключено.

6. Обработка клиентов. Keepalive соединения позволяют избежать

необходимости повторного создания соединения между клиентом и

сервером.

keepalive_timeout – будет ждать N секунд перед закрытием

keepalive соединения (выставить в 30);

keepalive_requests – максимальное количество keepalive запросов

от одного клиента (выставить в 100).

Много проблем могут создать медленные клиенты. Медленная

передача тела запроса от клиента к серверу и неожиданное

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

лишних соединений на сервере[9].

reset_timedout_connection – если клиент перестал читать отвечать,

Nginx будет сбрасывать соединение с ним (выставить в on);

client_body_timeout – будет ждать N секунд тело запроса от

клиента, после чего сбросит соединение (выставить в 10);

send_timeout – если клиент прекратит чтение ответа, Nginx

подождет N секунд и сбросит соединение (выставить в 2).

19

Page 20: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

Необходимо ограничивать отправку больших запросов на сервер

(например, загрузку больших файлов), если это не предусмотрено

сайтом (конфигурация client_max_body_size).

2.3. Front-end

Ни один web-проект нельзя представить без пользовательского

интерфейса. То, что пользователь видит на сайте, с помощью чего он

взаимодействует с сайтом – это пользовательский интерфейс. И интерфейс

имеет очень больше значение для сайта, т.к. это то, что пользователь видит в

первую очередь. Важны такие параметры, как скорость работы интерфейса,

доступность, отзывчивость, привлекательность и т.д.

Для высоконагруженного проекта важны все параметры, но в первую

очередь – скорость работы интерфейса. Для того, чтобы обеспечить

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

программиста, необходимо выбрать инструмент для разработки front-end. В

настоящее время лидирующие позиции занимает библиотека React,

разработанная компанией Facebook в 2013 году.

Важно понимать, что React – это не полноценный фреймворк, а

библиотека для создания пользовательских интерфейсов. React является буквой

V в схеме MVC (Model-View-Controller). Отличительной особенностью React

является возможность использовать JSX, язык программирования с близким к

HTML синтаксисом, который компилируется в JavaScript[5].

Как React может ускорить работу сайта? Всё благодаря Virtual DOM.

Для начала разберёмся, что такое DOM.

DOM (аббревиатура от Document Object Model) – способ представления

структурного документа с помощью объектов. Это кроссплатформенное и

языко-независимое соглашение для представления и взаимодействия с данными

в HTML, XML и т.д.

Главная проблема DOM – он никогда не был рассчитан для создания

динамического пользовательского интерфейса. Мы можем работать с ним,

используя JavaScript и библиотеки наподобие jQuery, но их использование не

20

Page 21: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

решает проблем с производительностью. Но вместо того, чтобы

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

(Virtual DOM). Мы можем вносить изменения в копию, исходя из наших

потребностей, а после этого применять изменения к реальному DOM.

При этом происходит сравнение DOM-дерева с его виртуальной копией,

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

Такой подход работает быстрее, потому как не включает в себя все

тяжеловесные части реального DOM.

Но остаётся два вопроса: когда именно делать повторную перерисовку

DOM и как это сделать эффективно.

React создает легковесное дерево из JavaScript-объектов для имитации

DOM-дерева. Затем он создает из них HTML, который вставляется или

добавляется к нужному DOM-элементу, что вызывает перерисовку страницы в

браузере. React использует “наблюдаемый” режим проверки изменения данных.

Он следит за изменением состояния своих компонентов и если ничего не

изменилось, то и перерисовки DOM не будет[11].

Рисунок 2. Сравнение работы Virtual DOM и Browser DOMReact предоставляет эффективные алгоритмы для сравнения состояния,

группирует операции чтения/записи при работе с DOM, что значительно

ускоряет работу интерфейса.

21

Page 22: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

React рекомендует использовать подход создания компонентов,

пригодных для повторного использования. Это означает, что создав какой-

нибудь компонент (например, для вывода формы), можно будет использовать

его в других частях приложения, что позволяет ускорить работу не только

интерфейса, но и скорость разработки приложения.

Что необходимо установить и настроить в системе, чтобы удобно

работать с React:

Webpack – инструмент для сборки front-end файлов. Официальное

определение звучит так: webpack берет модули с зависимостями и

генерирует статические ресурсы, которые представляют эти

модули. Webpack позволит разработчикам быстро собрать JS/CSS

модули воедино по определённым правилам; добавит возможность

«горячей перезагрузки» файлов для быстрой разработки;

Babel – транспилятор, который позволит писать код на более

удобном стандарте – ES6. ES6 стандарт принят совсем недавно и,

следовательно, поддерживается не всеми браузерами, но для того,

чтобы им можно было пользоваться уже сейчас, можно

воспользоваться Babel. Babel автоматически переписывает код,

написанный на ES6, в код на ES5, который поддерживают

практически все браузеры.

Какие пакеты необходимо включить дополнительно:

css-loader – загрузка стилей в компонентах React. css-loader

позволяет реализовать css-модули, что решает проблему

накладывания разных стилей друг на друга. Теперь css стили будут

определны внутри компонента (локально), при загрузке каждый

стиль получит уникальный класс (в зависимости от настроек) и это

поможет избегать конфликтов стилей;

jest – тестирование React компонентов.

22

Page 23: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

2.4. Взаимодействие с Ruby

Elixir сочетает в себе удобство и скорость разработки Ruby

с конкурентной моделью и отказоустойчивостью Erlang. В то время как Elixir

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

случаи, когда он проявляет себя не лучшим образом. Например, парсинг

большого объема структурированных данных таких как XML. Поскольку

файлы, содержащие данные в этом формате, разделить достаточно сложно, не

получится просто взять и распределить нагрузку между несколькими потоками

или нодами Elixir. В таких случаях было бы отлично использовать

преимущества других языков, которые могут справиться с этими задачами

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

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

возвращаемым результатом.

Язык программирования Ruby за годы своего существования как

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

количеством различных библиотек, способных решить практически любую

задачу, с которой може столкнуться разработчик. Так как синтаксис Elixir очень

напоминает синтаксис Ruby, разработчик, пишущий на Elixir без особых

затруднений сможет написать код на Ruby, чтобы использовать существующие

библиотеки. Были исследованы три варианта, чтобы выполнять Ruby-код из

виртуальной машины Erlang:

1. Библиотека Export. Этот метод запускает интерпретатор Ruby и

предоставляет API для конвертации типов между языками;

2. Библиотека Erlix. Этот метод заставляет Ruby процесс вести себя

как узел Erlang, который имеет связь с виртуальной машиной Erlang

через сеть. Для его конфигурации необходимо указать имя

процесса, который будет принимать сообщения из Ruby. А также

указать имя процесса , который будет хранить PID процесса,

который Ruby отправляет сразу после соединения с узлом. Для

корректной работы при старте приложения мы должны создавать

23

Page 24: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

новый процесс, который который будет принимать сообщения из

Ruby, и зарегистрировать его под определенным именем, чтобы

Ruby смог его найти в дальнейшем. Также мы должны запустить

цикл, который будет слушать команды и отправлять их в Ruby;

3. Библиотека Erlectricity. Этот метод подразумевает запуск

разработчиком Erlang порта, а также обработку типов данных на

стороне Elixir. Для работы разработчику необходимо запустить

Erlang порт и создать процесс с определенными параметрами. Из-за

того, что используется порт-протокол, данные должны быть

закодированы. Наконец мы можем отправить сообщение в наш

Ruby процесс и ожидать ответа. Стоит отметить, что все действия

происходят асинхронно. Далее мы получаем ответ из Ruby

процесса, декодируем его и продолжаем работу[7].

Для приведенных методов были проведены нагрузочные тесты для того,

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

ходе тестов ни один из методов ни разу не дал сбой в виртуальной машине

Erlang. В то время как забота о корректной работе ложится на плечи

разработчика, можно быть уверенным, что если Ruby-код и завершится с

ошибкой, это не повлияет на работоспособность всего Elixir приложения.

Во время разработки было замечено, что библиотека Erlix достаточно

нестабильна. Она переставала корректно работать после примерно 1500

сообщений. В коде этой библиотеки были обнаружены большое количество

TODO комментариев касательно потребления памяти. Поэтому было принято

решение не проводить тесты для этого метода.

В тестах сравнивались два метода:

1. Вызов функции из Ruby процесса с использованием Export;

2. Вызов функции из Ruby процесса с использованием Erlectricity.

24

Page 25: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

Рисунок 3. Сравнение количества итераций в секунду

В результате было установлено, что библиотека Export примерно в 1,21

раза медленнее, чем Erlectricity. Связано это с тем, что последняя написана как

расширение на языке C для Ruby. Она и будет использоваться для запуска

Ruby-кода.

25

Page 26: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

3. DOCKERНа пути продвижения приложения через цикл разработки и, в конечном

итоге, в эксплуатацию зачастую встречается множество препятствий. Помимо

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

вероятность столкнуться с проблемами отслеживания зависимостей,

масштабирования приложения и обновлений отдельных компонентов, не

затрагивающих непосредственно само приложение.

Docker-контейнеризация и сервис-ориентированное проектирование

пытаются решить многие из этих проблем. Приложения могут быть разбиты на

управляемые функциональные компоненты, индивидуально упакованные

вместе со всеми своими зависимостями, а затем легко развернуты на

нестандартной архитектуре. Это также упрощает масштабирование и

обновление компонентов.

Контейнеризация и изолирование компонентов не новые концепции в

мире вычислений. Некоторые Unix-подобные операционные системы

используют "зрелые" контейнерные технологии уже более 10 лет.

Система LXC (Linux Containers) - основа последующих технологий

контейнеризации - была добавлена в ядро Linux в 2008 году. LXC использует

комбинацию таких функция ядра, как cgroups (позволяет изолировать и

отслеживать использование ресурсов) и пространства имен (позволяют

разделять группы так, чтобы они не могли "видеть" друг друга), для реализации

легковесной изоляции процессов[6].

Docker, появившийся несколько позже, позиционировался, как

инструмент для упрощения работы по созданию и управлению контейнерами.

Изначально Docker использовал LXC в качестве драйвера исполнения по

умолчанию (с тех пор для этих целей была разработана библиотека под

названием libcontainer). Docker, не привнося большого количества новых идей,

сделал контейнеры доступными для обычного разработчика и системного

администратора путем упрощения процесса и стандартизации интерфейса. Это

26

Page 27: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

стимулировало возрождение интереса к контейнеризации среди разработчиков

в Linux-мире.

Контейнеры несут в себе много привлекательных преимуществ как для

разработчиков, так и для системных администраторов. Некоторые из наиболее

заманчивых преимуществ перечислены ниже:

Абстрагирование хост-системы от контейнеризованных

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

стандартизованными. Это означает, что контейнер соединяется с

хостом или чем-либо внешним по отношению к нему при помощи

определенных интерфейсов. Контейнеризованное приложение не

должно полагаться или каким-то образом зависеть от ресурсов или

архитектуры хоста, на котором оно работает. Это упрощает

предположения об среде выполнения приложения в процессе

разработки. Аналогично, со точки зрения хоста, каждый контейнер

представляет собой "черный ящик". Хосту нет дела то того, что за

приложение внутри.

Простота масштабирования. Одним из преимуществ

абстрагирования между операционной системой хоста и

контейнерами является то, что при правильном проектировании

приложения, масштабирование может быть простым и

прямолинейным. Сервис-ориентированная архитектура (будет

рассмотрена далее) в комбинации с контейнеризованными

приложениями обеспечивает основу для лёгкого масштабирования.

Разработчик может запустить несколько контейнеров на своей

рабочей машине, при этом та же система может быть

горизонтально масштабирована, например, на тестовой площадке.

Когда контейнеры запускаются в эксплуатацию (продакшн), они

снова могут быть масштабированы.

Простота управления зависимостями и версиями приложения.

Контейнеры позволяют разработчику связать приложение или

27

Page 28: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

компонент приложения со всеми его зависимостями и дальше

работать с ними как с единым целым. Хосту не надо беспокоиться о

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

Если хост может запустить Docker, он может запустить любой

Docker-контейнер. Это делает лёгким управление зависимостями и

также упрощает управление версиями приложения. Хост-системы

больше не должны отвечать за управление зависимостями

приложения, потому что, за исключением случаев зависимости

одних контейнеров от других контейнеров, все зависимости

должны содержаться в самом контейнере.

Чрезвычайно легкие, изолированные среды выполнения. Не

смотря на то, что контейнеры не предоставляют такого же уровня

изоляции и управления ресурсами, как технологии виртуализации,

они обладают чрезвычайно лёгкой средой исполнения. Контейнеры

изолированы на уровне процессов, работая при этом поверх одного

и того же ядра хоста. Это значит, что контейнер не включает в себя

полную операционную систему, что приводит к практически

мгновенному его запуску. Разработчики могут легко запустить

сотни контейнеров со своей рабочей машины без каких-либо

проблем[11].

Совместно используемые слои. Контейнеры легки еще и в том

смысле, что они сохраняются "послойно". Если несколько

контейнеров основаны на одном и том же слое, они могут

совместно использовать этот базовый слой без дублирования, что

приводит к минимальной загрузке дискового пространства в

последующих образах.

Возможность компоновки и предсказуемость. Docker-файлы

позволяют пользователям задать конкретные действия,

необходимые для создания нового образа контейнера. Это

позволяет Вам задавать настройки среды исполнения так, как будто

28

Page 29: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

бы это код, при желании сохраняя эти настройки в системе

контроля версий. Одинаковый Docker-файл, собранный в одном и

том же окружении, всегда создаст идентичный образ контейнера.

Рисунок 4. Архитектура Docker

Для настройки Docker-контейнера в проект был добавлен

конфигурационный файл, в котором указано:

установка Phoenix;

использование конфигурационного файла для Nginx;

установка Node.js

установка и настройка PostgreSQL

Полный код данного конфигурационного файла находится в приложении.

29

Page 30: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

ЗАКЛЮЧЕНИЕЯзык программирования Elixir активно развивается и становится всё

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

виртуальной машины Erlang в совокупности с достаточно простым

синтаксисом, похожим на Ruby, что позволяет разрабатывать

высоконагруженные системы.

В ходе работы были проанализированы различные варианты

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

проекта. Данный базовый проект позволит любому программисту быстро и без

особых усилий начать разработку проекта, способного выдерживать высокие

нагрузки.

30

Page 31: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ1. Официальный сайт языка Elixir [Электронный ресурс]. URL: https://elixir-

lang.org (дата обращения: 03.02.2017).

2. Официальный сайт языка Erlang [Электронный ресурс]. URL:

https://www.erlang.org (дата обращения: 04.02.2017).

3. Официальный сайт фреймворка Phoenix [Электронный ресурс]. URL:

http://www.phoenixframework.org (дата обращения: 05.02.2017).

4. Оптимизация и масштабирование Web-приложений [Электронный ресурс].

URL: https://ruhighload.com (дата обращения: 10.03.2017).

5. Официальный сайт библиотеки React [Электронный ресурс]. URL:

https://facebook.github.io/react (дата обращения: 15.04.2017).

6. Официальный сайт Docker [Электронный ресурс]. URL:

https://www.docker.com (дата обращения: 20.04.2017).

7. Взаимодействие Elixir и Ruby [Электронный ресурс]. URL:

https://blog.fazibear.me/elixir-ruby-dont-fight-talk-d83d5abc8898 (дата

обращения: 01.05.2017).

8. Высоконагруженные системы [Электронный ресурс]. URL:

https://habrahabr.ru/company/plarium/blog/217151 (дата обращения:

10.02.2017).

9. Документация PostgreSQL [Электронный ресурс]. URL:

https://www.postgresql.org/docs (дата обращения: 11.03.2017).

10.The difference between Virtual DOM and DOM [Электронный ресурс]. URL:

http://reactkungfu.com/2015/10/the-difference-between-virtual-dom-and-dom

(дата обращения: 16.04.2017).

11.The Docker Ecosystem [Электронный ресурс]. URL:

https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-an-

introduction-to-common-components (дата обращения: 21.04.2017).

12.

31

Page 32: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

ПРИЛОЖЕНИЕ1. Сравнение скорости выполнения Ruby-кода из Elixir:

Erlang/OTP 19 [erts-8.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]Elixir 1.3.4Benchmark suite executing with the following configuration:warmup: 2.0stime: 5.0sparallel: 1inputs: none specifiedEstimated total run time: 14.0s

Benchmarking erlectricity_function...Benchmarking export_function...Generated bench/index.html

Name ips average deviation medianerlectricity_function 18.49 K 54.07 μs ±48.86% 47.00 μsexport_function 15.28 K 65.43 μs ±42.51% 57.00 μs

Comparison:erlectricity_function 18.49 Kexport_function 15.28 K - 1.21x slower

2. Конфигурационные файл для Docker:FROM elixir:latest

# Elixir requires UTF-8RUN apt-get update && apt-get upgrade -y && apt-get install locales && locale-gen en_US.UTF-8ENV LC_ALL en_US.UTF-8ENV LANG en_US.UTF-8ENV LANGUAGE en_US.UTF-8

# NodeENV NPM_CONFIG_LOGLEVEL infoENV NODE_VERSION 6.10.2

RUN apt-get update && \ apt-get install -qq -y \ git ssh curl wget make sudo \ build-essential \ libpq-dev \ libqt4-dev libqtwebkit-dev libmysqlclient-dev \ nginx \ --fix-missing --no-install-recommends && \ apt-get clean && \ apt-get purge && \

32

Page 33: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

ENV PHOENIX_VERSION 1.2.1

# install the Phoenix Mix archiveRUN mix archive.install --force https://github.com/phoenixframework/archives/raw/master/phoenix_new-$PHOENIX_VERSION.ezRUN mix local.hex --force \ && mix local.rebar --force

# Nginx# Remove the default Nginx configuration fileRUN rm -v /etc/nginx/nginx.conf

# Copy a configuration file from the current directoryCOPY nginx.conf /etc/nginx/

# Append "daemon off;" to the beginning of the configurationRUN echo "daemon off;" >> /etc/nginx/nginx.conf

# Expose portsEXPOSE 80

# Set the default command to execute# when creating a new containerCMD ["service", "nginx start"]

# Install Node.js# Copied from https://github.com/nodejs/docker-node/blob/f3c3821591765ad0727bdde2cb98f41dc1b9b4b9/6.8/DockerfileRUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" && \ tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/local --strip-components=1 && \ rm "node-v$NODE_VERSION-linux-x64.tar.xz" && \ ln -s /usr/local/bin/node /usr/local/bin/nodejs

# PostgreSQLENV PSQL_VERSION 9.6

# Add the PostgreSQL PGP key to verify their Debian packages.# It should be the same key as https://www.postgresql.org/media/keys/ACCC4CF8.ascRUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8

33

Page 34: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

# Add PostgreSQL's repository.RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ precise-pgdg main" > /etc/apt/sources.list.d/pgdg.list

# Install PostgreSQL 9.6RUN apt-get update && \ apt-get install -qq -y \ postgresql-$PSQL_VERSION postgresql-client-$PSQL_VERSION postgresql-contrib-$PSQL_VERSION

# Run the rest of the commands as the ``postgres`` user created by the ``postgres-9.6`` package when it was ``apt-get installed``USER postgres

# Create a PostgreSQL role named ``docker`` with ``docker`` as the password and# then create a database `docker` owned by the ``docker`` role.RUN /etc/init.d/postgresql start && \ psql --command "CREATE USER docker WITH SUPERUSER PASSWORD 'docker';" && \ createdb -O docker docker

# Adjust PostgreSQL configuration so that remote connections to the# database are possible.RUN echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/$PSQL_VERSION/main/pg_hba.conf

# And add ``listen_addresses`` to ``/etc/postgresql/9.6/main/postgresql.conf``RUN echo "\n\listen_addresses='*'\n\max_connection = 16\n\work_mem = 1MB\n\checkpoint_segments=10\n\">> /etc/postgresql/$PSQL_VERSION/main/postgresql.conf

# Expose the PostgreSQL portEXPOSE 5432

# Add VOLUMEs to allow backup of config, logs and databasesVOLUME ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]

# Set the default command to run when starting the containerCMD ["/usr/lib/postgresql/$PSQL_VERSION/bin/postgres", "-D", "/var/lib/postgresql/$PSQL_VERSION/main", "-c", "config_file=/etc/postgresql/$PSQL_VERSION/main/postgresql.conf"]

# Make port 80 available to the world outside this containerEXPOSE 80

34

Page 35: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

# working directoryWORKDIR /app

# copy projectCOPY ./phoenix-base /app

# setup projectRUN bin/setup

# Run phoenix serverCMD ["bin/server"]

3. Конфигурационный файл для Nginx:worker_processes auto;

events { use epoll; worker_connections 1024; multi_accept on;}

http { include /etc/nginx/mime.types; default_type application/octet-stream;

access_log off; error_log /var/log/nginx/error.log crit;

keepalive_timeout 30; keepalive_requests 100;

client_max_body_size 1m; client_body_timeout 10; reset_timedout_connection on; send_timeout 2; sendfile on; tcp_nodelay on; tcp_nopush on;

gzip on; gzip_disable "msie6"; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;

open_file_cache max=200000 inactive=20s;

35

Page 36: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on;

server { listen 80; server_name $APP_NAME www.$APP_NAME;

location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://localhost:34567; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }}

4. Конфигурационный файл для базового проекта:defmodule PhoenixBase.Mixfile do use Mix.Project

def project do [app: :phoenix_base, version: "0.0.1", elixir: "~> 1.3", elixirc_paths: elixirc_paths(Mix.env), compilers: [:phoenix, :gettext] ++ Mix.compilers, build_embedded: Mix.env == :prod, start_permanent: Mix.env == :prod, aliases: aliases(), deps: deps()] end

# Configuration for the OTP application. # # Type `mix help compile.app` for more information. def application do [ mod: {PhoenixBase, []}, elixirc_paths: elixirc_paths(Mix.env), applications: ~w(phoenix phoenix_pubsub phoenix_html cowboy logger gettext phoenix_ecto postgrex erlexec effects guardsafe monadex

36

Page 37: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

timex comeonin faker bamboo)a ] end

# This makes sure your factory and any other modules in test/support are compiled # when in the test environment. defp elixirc_paths(:test), do: ~w(lib web test/support) defp elixirc_paths(_), do: ~w(lib web)

# Specifies your project dependencies. # # Type `mix help deps` for examples and options. defp deps do [ {:bamboo, "~> 0.7"}, {:bamboo_smtp, "~> 1.2.1"}, {:cowboy, "~> 1.0"}, {:comeonin, "~> 2.5"}, {:bodyguard, "~> 0.4.0"}, {:effects, "~> 0.1.0"}, {:erlexec, "~> 1.2.1"}, {:exrm, "~> 1.0.5"}, {:faker, "~> 0.7"}, {:gettext, "~> 0.11"}, {:guardian, "~> 0.13.0"}, {:guardsafe, "~> 0.5.0"}, {:logger_file_backend, "~> 0.0.9"}, {:monadex, "~> 1.0.2"}, {:ok, "~> 1.0.0"}, {:phoenix, "~> 1.2.1"}, {:phoenix_ecto, "~> 3.0"}, {:phoenix_html, "~> 2.6"}, {:phoenix_pubsub, "~> 1.0"}, {:postgrex, ">= 0.0.0"}, {:timex, "~> 3.0"}, {:credo, "~> 0.4", only: ~w(dev test)a}, {:dialyxir, "~> 0.3", only: :dev}, {:edeliver, ">= 1.2.9", only: :dev}, {:eper, "~> 0.94.0", only: :dev}, {:ex_doc, "~> 0.11", only: :dev}, {:ex_machina, "~> 1.0", only: ~w(dev test)a}, {:phoenix_live_reload, "~> 1.0", only: :dev}, {:hound, "~> 1.0", only: :test} ] end

37

Page 38: kpfu.ru€¦  · Web viewФедеральное государственное автономное образовательное учреждение высшего образования

# Aliases are shortcuts or tasks specific to the current project. # For example, to create, migrate and run the seeds file at once: # # $ mix ecto.setup # # See the documentation for `Mix` for more info on aliases. defp aliases do ["ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], "ecto.reset": ["ecto.drop", "ecto.setup"], "test": ["ecto.create --quiet", "ecto.migrate", "test"]] endend

5. Код инициализации приложения:defmodule PhoenixBase do use Application

# See http://elixir-lang.org/docs/stable/elixir/Application.html # for more information on OTP Applications def start(_type, _args) do import Supervisor.Spec

# Define workers and child supervisors to be supervised children = [ # Start the Ecto repository supervisor(PhoenixBase.Repo, []), # Start the endpoint when the application starts supervisor(PhoenixBase.Endpoint, []), # Start your own worker by calling: PhoenixBase.Worker.start_link(arg1, arg2, arg3) # worker(PhoenixBase.Worker, [arg1, arg2, arg3]), ]

# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html # for other strategies and supported options opts = [strategy: :one_for_one, name: PhoenixBase.Supervisor] Supervisor.start_link(children, opts) end

# Tell Phoenix to update the endpoint configuration # whenever the application is updated. def config_change(changed, _new, removed) do PhoenixBase.Endpoint.config_change(changed, removed) :ok endend

38