IO v6. Структура
Проекты последней версии 6 фреймворка оборачиваются в среду Docker и запускаются на сервере.
Разработка ведется там же, так как поднять подобную среду на локальном компьютере будет затруднительно, не развернув на нем всю архитектуру платформы.
Структура проекта
project
├── app
│ ├── bin
│ ├── class
│ ├── controller
│ ├── cron
│ ├── dictionary
│ ├── io
│ ├── lib
│ ├── model
│ ├── view
│ └── i.php
├── cache
├── ckfinder
├── css
├── elFinder
├── files
├── icon
├── img
├── js
├── systpls
├── template
├── .htaccess
├── checkserver.php
├── cron.php
├── conf.php
├── index.php
├── robots.php
├── error.html
└── mksymlink.sh
project/app: главная папка, где хранятся функциональные файлы проекта. Папка, которая содержит всю логику проекта.project/app/bin: папка, содержащая bin скрипты.project/app/class: папка, содержащая классы для работы с базой данных.project/app/controller: папка, содержащая файлы по управлению страницами.project/app/cron: папка, содержащая cron скрипты.project/app/dictionary: папка, содержащая тексты переводов (файлы-словари фраз) на различные языки.project/app/io: папка фреймворка.project/app/lib: папка кастомных PHP библиотек проекта, которые по каким либо причинам нельзя установить через composer.project/app/model: папка, содержащая файлы логики проекта / api.project/app/view: папка, содержащая файлы интерфейсов UI. Папка, содержащая html шаблоны на основе шаблонизатора Twig.project/app/i.php: файл персональных функций и констант проекта. Подробнееproject/cache: symlink на папку/var/cache/php, папка с кешем (шаблонизатора twig, mpdf и многих других).project/ckfinder: symlink на библиотеку ckfinder во фреймворке (project/app/io/lib/ckfinder), папка файлового менеджера редактора текста CMS.project/css: папка, содержащая CSS файлы проекта и фреймворка.project/elFinder: symlink на библиотеку elFinder во фреймворке (project/app/io/lib/elFinder), папка файлового менеджера проекта.project/elFinder2: symlink на библиотеку elFinder v2.1.55 во фреймворке (project/app/io/lib/elFinder2.1.55), папка файлового менеджера проекта (не совсем поняно зачем...).project/files: папка, содержащая файлы, которые загружает пользователь.project/icon: (не совсем понятно зачем...).project/img: папка, содержащая изображения проекта и фреймворка.project/js: папка, содержащая javascript файлы проекта и фреймворка.project/systpls: symlink на папку фреймворка (project/app/io/systpls), папка, содержащая системные шаблоны CMS (независимо от подключения CMS).project/template: symlink на папку CDN, папка, содержащая все шаблоны сайтов на CMS (если CMS подключена).project/.htaccess: файл настроек для apache (неактуально).project/checkserver.php: файл, отображающий название проекта (ранее использовался для проверки на наличие на сервере установленных библиотек, необходимых для работы проекта).project/cron.php: файл, который запускает cron скрипты. Файл, обслуживающий автоматически выполняемые скрипты, которые выполняются через определенные промежутки времени. Данный файл запускается каждую минуту и в зависимости от настроек таблицы cron запускает скрипт.project/conf.php: файл, содержащий конфигурационные данные. Является уникальным для каждого проекта. Содержит основные настройки проекта, пароли от баз данных и др.project/index.php: центральный файл, который отвечает за запуск проекта. Он является вратами. Через него проходят все запросы, которые отправляются на сайт.project/robots.php: файл, генерирующий содержимое для файла robots.txt (для поисковиков).project/error.html: файл шаблона страницы непредвиденной ошибки.project/mksymlink.sh: файл создания необходимых symlink для работы проекта.
Содержимое файла conf.php
Пример:
if(!defined('BASE_PATH')) define('BASE_PATH', dirname(__FILE__));
// Номер проекта
define ('IOSERVER', 21);
// Разрешить статистику
define('CMS_STAT_ENABLE', 0);
// Разрашить дебаг, на продакшене ставить 0 всегда
define('DEBUG', 1);
define('CRON_DEBUG', 1);
define('PRODUCTION', 0);
define('BMCSALES', 'http://www.bmcsales.kz/');
define('DNS_DOMAIN', 'fXXX.bmcsales.biz');
define('DNS_RECORD', 'fXXX');
define('MASTER_PASSWORD', '');
// настройки mysql
define('MYSQL_ENABLE', 1);
define('MYSQL_USER', 'admin');
define('MYSQL_PASSWORD', 'admin');
define('MYSQL_SERVER', 'localhost');
define('IO_MYSQL_DB', 'iodb');
define('MYSQL_DB', 'project');
// Настройки mongo
define('MONGO_ENABLE', 1);
define('MONGO_USER', 'admin');
define('MONGO_PASSWORD', 'admin');
define('MONGO_DATABASE', 'cms');
define('MONGO_SERVER_READ', 'mongodb://127.0.0.1:27017');
define('MONGO_SERVER_WRITE', 'mongodb://127.0.0.1:27017');
// Настройки solr
define('SOLR_ENABLE', 0);
define('SOLR_USER', 'admin');
define('SOLR_PASSWORD', 'admin');
define('SOLR_SERVER', 'localhost');
define('SOLR_PORT', '27025');
define('SOLR_URI', '/search-system');
//define('SOLR_CRM_CLIENT','cms_test');
define('SOLR_CMS_SEARCH', 'cms_search');
error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('error_reporting', E_ALL);
include_once(dirname(__FILE__).'/app/io/api.php');
global $iodb, $iosearch, $iomongo, $iosolr;
$iodb = null;
$iosearch = null;
$iomongo = null;
//Event::$echo = 1;
//Event::$loglevel = 5;
include_once(dirname(__FILE__).'/app/i.php');
global $ioProjects;
$ioProjects['com'] = "//cab.devkdt.info"; // Система кабинетов
$ioProjects['study'] = "//study.devkdt.info"; // Дистанционное обучение
$ioProjects['maps'] = "//maps.devkdt.info"; // Онлайн-карты
$ioProjects['mobile'] = "//mobi.devkdt.info"; // Мобильное приложение
$ioProjects['bmcsales'] = "//devkdt.info"; // Портал bmcsales
Структура фреймворка
project/app/io
├── app
│ ├── class
│ │ └── ...
│ ├── components
│ │ └── cms
│ │ ├── ajaxWidgetRender.php
│ │ ├── widgetModel.php
│ │ └── widgetModel4.php
│ ├── controller
│ │ └── cms20
│ │ │ ├── cmsController.php
│ │ │ └── optionsController.php
│ │ ├── cmsController.php
│ │ ├── cronController.php
│ │ ├── entityController.php
│ │ ├── gateController.php
│ │ ├── loginController.php
│ │ ├── logoutController.php
│ │ └── optionsController.php
│ ├── dictionary
│ │ ├── cms.json
│ │ └── io.json
│ ├── model
│ │ └── ...
│ ├── view
│ │ └── ...
│ ├── i.breadcrumbs.php
│ ├── i.cms.php
│ ├── i.social.php
│ └── i.sys.php
├── class
├── docs
├── examples
│ └── modules
├── lib
├── systpls
├── vendor
├── api.php
├── changelog
├── checkserver.php
├── cmd.php
├── composer
├── composer.json
├── cronTemplate.php
├── crypt.php
├── db.mongo.php
├── db.mysql.php
├── db.php
├── db.postgre.php
├── functions.php
├── gate.php.example
├── iodb.sql
├── ioform.php
├── iogrid.php
├── iomodel.php
├── log.php
├── main.php
├── mvc.core.php
├── mvc.model.php
├── mvc.model4.php
├── mvc.model4.remote.php
├── mysql.php
├── mysql_pdo.php
├── mysqli.php
├── niceTable.php
├── protocolv2.php
├── protocolv3.php
├── search.php
├── solr.php
├── twig.php
├── web_request.php
└── xml.php
io/app: главная папка, где хранятся функциональные файлы фреймворка. Папка, которая содержит всю логику фреймворка.io/app/class: папка, содержащая классы для работы с базой данных.io/app/components: файлы классов компонентов фреймворка.io/app/components/cms/ajaxWidgetRender.php: файл класса виджетов CMS.io/app/components/cms/widgetModel.php: файл класса виджетов CMS.io/app/components/cms/widgetModel4.php: более новый файл класса виджетов CMS.io/app/controller: папка, содержащая файлы по управлению страницами.io/app/controller/cms20/cmsController.php: controller внешней части CMS (генератор страниц на основе настроек сайта в CMS).io/app/controller/cms20/optionsController.php: controller панели управления сайтом в CMS.io/app/controller/cmsController.php: старый controller внешней части CMS (генератор страниц на основе настроек сайта в CMS) (для очень старых проектов).io/app/controller/cronController.php: controller для обращения к cron скриптам (для очень старых проектов).io/app/controller/entityController.php: controller "общалки" для обращения к model.io/app/controller/gateController.php: controller "общалки" для обращения к class.io/app/controller/loginController.php: controller авторизации.io/app/controller/logoutController.php: controller деавторизации.io/app/controller/optionsController.php: controller панели управления сайтом в CMS (для очень старых проектов).io/app/dictionary: папка, содержащая тексты переводов на различные языки.io/app/dictionary/cms.json: файл словаря фраз для элементов CMS.io/app/dictionary/io.json: файл словаря фраз для элементов фреймворка.io/app/model: папка, содержащая файлы логики проекта (API).io/app/view: папка, содержащая файлы интерфейсов (UI). Папка, содержащая html шаблоны на основе шаблонизатора Twig.io/app/i.breadcrumbs.php: файл настроек массивов$breadcrumbsи$lineMenu(для дизайнов кабинетаCABINET_VERSION=1и2).io/app/i.cms.php: файл настроек, PHP и Twig функций/фильтров для CMS (если CMS подключена).io/app/i.social.php: файл настроек, PHP и Twig функций/фильтров для социальных элементов (для сообществ, соцсетей, agartu, ЕОП и др. т.п.).io/app/i.sys.php: файл системных настроек фреймворка и проекта, PHP и Twig функций/фильтров, подключение к базам данных, подключение файловi.cms.php,i.social.php,i.breadcrumbs.php, объявление основных$ioEnumконстант фреймворка.io/class: папка с классами фреймворка (для очень старых проектов).io/docs: папка с различными инструкциями, касаемых фреймворка.io/examples/modules: файлы JS модулей и библиотек (перенесено в CDN, но хранится также здесь для резерва).io/lib: папка кастомных PHP библиотек фреймворка, которые по каким либо причинам нельзя установить через composer.io/systpls: папка, содержащая системные шаблоны CMS (независимо от подключения CMS).io/vendor: папка PHP библиотек, устанавливаемых через composer.io/api.php: файл системных настроек фреймворка и проекта. Файл хранит в себе значения различных констант. API для серверов и докеров. В нем происходит объявление большинства глобальных переменных, констант фреймворка, функций для инициализации различных библиотек, путей к проектам, IP адресов серверов, языков, настроек$purify, функций подключения к базам данных, а также подключение основных классов фреймворка.io/changelog: файл версий и описания изменений во фреймворке (change log).io/checkserver.php: файл проверки на наличие на сервере установленных библиотек, необходимых для работы проекта.io/cmd.php: файл функций "общалки" (для очень старых проектов).io/composer: исполнительный файл composer.io/composer.json: файл, содержащий список PHP библиотек composer, используемых во фреймворке.io/cronTemplate.php: файл базового класса cron скриптов.io/crypt.php: файл с функциейdsCrypt()(обратимое шифрование методом "двойного квадрата") (где используется, ныне неизвестно).io/db.mongo.php: файл базового класса class для работы с БД MongoDB.io/db.mysql.php: файл базового класса class для работы с БД MySQL.io/db.php: файл базового класса для файлов классовdb.mongo.php,db.mysql.php,db.postgre.php.io/db.postgre.php: файл базового класса class для работы с БД PostgreSQL.io/functions.php: файл списка PHP функций фреймворка.io/gate.php.example: (для очень старых проектов).io/iodb.sql: дамп таблиц базы данныхiodb(центральная база фреймворка) в MySQL.io/ioform.php: файл класса генератора HTML форм через model (для очень старых проектов).io/iogrid.php: файл класса генератора HTML таблиц через model (для очень старых проектов).io/iomodel.php: файл базового класса model (для очень старых проектов).io/log.php: файл класса логирования фреймворкаEvent.io/main.php: файл функций "общалки" (для очень старых проектов).io/mvc.core.php: ядро фреймворка, файл классовIOWorkTimer,IOController,IOCore,IOHash,IOUser,IOSession,IOCoreData,IOCorePage,IOResultи различных функций, связанных с ядром.io/mvc.model.php: файл базового класса modelIOModel3,IOModel2,IOModel2Old(для старых проектов).io/mvc.model4.php: файл базового класса modelIOModel4(для старых проектов).io/mvc.model4.remote.php: файл базового класса удаленных modelIOModelRemote4(где используется, ныне неизвестно).io/mysql.php: файл классаIO_MYSQLдля работы с базой данных через переменную $iodb (для драйвераphp_mysql) (устарело, использовалось дляmysqli).io/mysql_pdo.php: файл классаIO_MYSQL_PDOдля работы с базой данных через переменную $iodb (для драйвераphp_pdo).io/mysqli.php: файл классаIO_MYSQLIдля работы с базой данных через переменную $iodb (для драйвераphp_mysqli) (использовалось доPDO).io/niceTable.php: файл классовIONiceTableиIONiceTable2, дополняющих функционал model, для работы с NiceTable таблицами (для очень старых проектов).io/protocolv2.php: файл функций "общалки" (для очень старых проектов).io/protocolv3.php: файл функций "общалки" (для очень старых проектов).io/search.php: файл классаIOSearchSphinxдля работы с поиском через программу sphinx (для очень старых проектов).io/solr.php: файл классаIOSolrдля работы с поиском через программу solr (для очень старых проектов).io/twig.php: файл инифиализации twig, а также базовых кастомных функций и фильтров фреймворка для twig.io/web_request.php: файл классаWebRequestдля работы с http запросами (вспомогательный класс для фреймворка).io/xml.php: файл классаioXMLдля работы с XML содержимым.
Архитектура проекта
- Кластер – комплекс серверов, обслуживающий один проект. Кластер является целостной структурой, состоящий из нод, балансировшиков, серверов, баз данных…
- Нода – комлпекс серверов, находящийся в одном датацентре, для уменьшения задержки обработки запросов. Нода в кластере синхронизируются между собой файлами и данными. Считается что нода всегда доступна, и данные с файлами нод в класетере одинаковые.
- Шардинг – горизонтальное разбиение данных по нескольким серверам по определенному критерию;
- Репликация – процесс копирования базы данных и постоянного копирования и применения изменений на этих базах данных. В итоге получается одинаковая база на разных серверах;
- Программа прокси базы данных – программа, которая определяет, на какой шард и на какую реплику обратиться для получения данных;
- Кэширование – сохранение результатов обработки информации по часто совершаемым запросам;
- Балансировшик – программа, которая распределяет нагрузку от запросов пользователей между серверами приложениями, а также защишает сервера от ддос и прочих атак, на уровне сети.

Описание схемы
- Весь проект должен быть размещен минимум в трех географически удаленных датацентрах;
- Выбор датацентра, к которому будет адресован запрос, будет выбран на основе DNS round robin балансировки;
- В датацентрах размещены сервера, которые содержат следующие программы:
- балансировшик, выделенный в отдельный сервер, задача которого переадресовывать запросы, согласно нагрузке серверов веб приложения;
- приложение, которое содержит всю логику проекта и обрабатывает запросы пользователей, выделенное на отдельный сервер. На сервере, где расположено приложение, находятся файлы, которые загружаются пользователями, которые не предназначены для хранения в облачном хранилище (например, шаблон сайта). Синхронизация файлов происходит с помощью программы lsyncd;
- кэш часто запрашиваемых данных от пользователей, расположенный на отдельном сервере;
- кэш поиска необходимой информации по различным критериям, расположенный там же, где и кэш часто запрашиваемых данных (скорее всего это будет одна и та же программа);
- программа прокси к базе данных для перенаправления запросов к репликам, расположенная на том же сервере, что и приложение;
- конфиг сервер для mongodb, содержащий мета данные реплик, расположенный на отдельном сервере;
- база реплика для каждого шарда, на каждый шард минимум три реплики. Каждая реплика на отдельном сервере;
- Каждый веб сервер (приложение) должен обладать программой приложением, кэшем данных и программой прокси к БД;
- На серверах располагается только один проект, никаких других проектов на этих серверах быть не должно;
- Минимальное количество серверов для проекта - 3 сервера, размещенных в разных датацентрах, на которых размещены все необходимые программы;
- Для увеличения производительности при росте данных можно наращивать серверные мощности:
- Увеличивать количество шардов и реплик, работающих в режиме чтения;
- Увеличивать количество серверов, отвечающих за кэширование;
- Увеличивать количество серверов на котором размещено приложение для обработки запросов пользователя;
- Обработка запроса от пользователя не должна превыщать 10 мс. В идеале 1мс.
- Все сервера в проекте должны быть объединены в одну единую виртуальную сеть. Обмен трафиком должен происходить только через нее. Сеть должна быть децентрализованной. Пароли от сети должны меняться раз в день.
- Арихитектура должна обеспечить доступ к домену
test.<название сайта>для апробации новой версии приложения при его деплое;
Файлы проекта можно кэшировать с помощью программы lsyncd (статья).
Работа схемы
- Пользователь открывает браузер и вводит адрес проекта;
- С помощью DNS балансировшика должен выбираться ближайший незагруженный к пользователю сервер и отсылается запрос на него;
- Программа принимает запрос и начинает его обработку;
- Программа запрашивает кэш на наличие этих данных;
- Если данных нет, программа обращается к прокси БД для обработки запроса;
- Программа прокси на основе данных шардинга, которые находятся на конфигурационных серверах находит реплику, на которой размещены необходимые данные. Реплика должна находиться в этом же датацентре, что и сам прокси;
- После нахождения реплики, прокси отправляет запрос к БД;
- По возращении результата от прокси программе приложению, приложение должно сохранить в кэш вернувшийся ответ на запрос, чтобы в дальнейшем не обращаться лишний раз к базе;
- Если запрос был на изменение данных, то приложение, должно сообщить всем кэширующим серверам, что данные изменены, пусть перехешируют;
Ограничения
- Минимальное количество серверов на кластер – 3;
- Минимальное количество серверов в шарде базы данных – 3;
- Максимальное количество голосующих серверов в шарде при выборе первичного сервера – 7;
- Не должно быть четного количества серверов;
- Не должно быть сервера, где размещены несколько реплик одной и той же БД;
- Среднее количество серверов на один проект – 21 (в одном датацентре содержится 1 балансер, 2 приложения, 1 конфиг, 2 шарда, кэш);
- Рабочая нагрузка к базе данных – 3 000 запросов / сек;
- Среднее количество запросов к базе данных для генерации одной страницы: 8 запросов;
- Среднее количество активных пользователей – 300 пользователей / сек;
- Максимальное время обработки одного http запроса – 10мс;
- Коэффициент запаса прочности системы – 5;
Процесс обновления программного обеспечения
Обновление происходит по кластерно. Каждый сервер содержит следующие папки:
/srv/<название проекта>/www– симлинк на рабочую версию;/srv/<название проекта>/test– папка симлинк на новую версию;/srv/<название проекта>/v/<версия>- папка с версиями проекта, синхронизируется между нодами;/srv/<название проекта>/tmp– временная папка;/srv/<название проекта>/upload– сюда заливаются файлы из форм;/srv/<название проекта>/data– папка с данными проекта, синхронизируется между нодами;
Процесс обновления происходит следующим образом:
- Загрузить новую версию проекта в папку
/srv/<название проекта>/v/<версия>на один из серверов; - Подождать пока произойдет синхронизация файлов по серверам;
- Установить тестовый симлинк на новую версию. Теперь все сайты
test.<домен сайта>будут ссылаться на сайт с новой версией, аwww.<домен сайта>на текущую версию проекта; - Запустить скрипты, изменяющие данные базы данных;
- Проверить работоспособность каждого сайта
test.<домен сайта>и качество отображения; - Если все в порядке и ошибок не обнаружено, то изменить симлинк папки www на новую версию.
- Теперь на каждом сайте кластера новая версия проекта.