Нарушение правил: использование SQLite для демонстрации веб-приложений
Опубликовано: 2022-03-10Большинство потенциальных пользователей захотят опробовать программное обеспечение или услугу, прежде чем тратить время и деньги. Некоторые продукты отлично работают, просто предоставляя пользователям бесплатную пробную версию, в то время как другие приложения лучше всего работают с уже имеющимися образцами данных. Часто именно здесь в игру вступает старый демо-счет.
Однако любой, кто когда-либо использовал демо-счет, может подтвердить связанные с этим проблемы. Вы знаете, как обстоят дела в Интернете: любой может вводить данные (независимо от того, имеют ли они смысл для продукта или нет), и есть большая вероятность, что контент, добавленный анонимными пользователями или ботами, может быть оскорбительным для других. Конечно, вы всегда можете сбросить базу данных, но как часто и когда? И, в конце концов, действительно ли это решает проблему? Мое решение использовать SQLite .
Почему бы не использовать SQLite для производственной версии?
Общеизвестно, что SQLite не обрабатывает несколько потоков, поскольку вся база данных блокируется во время команды записи, что является одной из причин, по которой вам не следует использовать его в обычной производственной среде. Однако в моем решении для каждого пользователя , демонстрирующего программное обеспечение, используется отдельный файл SQLite. Это означает, что ограничение на запись ограничено только этим одним пользователем, но несколько одновременных пользователей (каждый со своим собственным файлом базы данных) не будут испытывать это ограничение. Это обеспечивает контролируемый опыт для пользователей, тестирующих программное обеспечение, и позволяет им видеть именно то, что вы хотите, чтобы они видели.
Этот учебник основан на реальном решении, которое я успешно использую для демонстрационного веб-приложения SaaS с 2015 года. Учебник написан для Ruby on Rails (мой любимый фреймворк) версии 3 и выше, но основные концепции должны быть возможность адаптации к любому другому языку или фреймворку. На самом деле, поскольку Ruby on Rails следует парадигме программного обеспечения «соглашение важнее конфигурации», его может быть даже проще реализовать в других фреймворках, особенно на «голых» языках (таких как обычный PHP) или фреймворках, которые мало что делают с точки зрения управления соединениями с базой данных. .
При этом этот метод особенно хорошо подходит для Ruby on Rails. Почему? Потому что, по большей части, это «независимо от базы данных». Это означает, что вы должны иметь возможность писать свой код Ruby и переключаться между базами данных без каких-либо проблем.
Образец готовой версии этого процесса можно загрузить с GitHub.
Первый шаг: среда развертывания
Мы вернемся к развертыванию позже, но Ruby on Rails по умолчанию разделен на среды разработки, тестирования и производства. Мы собираемся добавить в этот список новую демонстрационную среду для нашего приложения, которая будет почти идентична рабочей среде, но позволит нам использовать другие настройки базы данных.
В Rails создайте новую среду, скопировав файл config/environments/production.rb
и переименовав его demo.rb
Поскольку демонстрационная среда будет использоваться в производственных условиях, вам может не понадобиться изменять многие параметры конфигурации для этой новой среды, хотя я бы предложил изменить config.assets.compile
с false
на true
, что облегчит локальное тестирование без необходимость предварительной компиляции.
Если вы используете Rails 4 или более позднюю версию, вам также потребуется обновить config/secrets.yml
, чтобы добавить secret_key_base
для демонстрационной среды. Убедитесь, что этот секретный ключ отличается от производственного, чтобы обеспечить уникальность сеансов в каждой среде и дополнительно защитить ваше приложение.
Далее вам нужно определить конфигурацию базы данных в config/database.yml
. Хотя демонстрационная среда будет в основном использовать дублированную базу данных, которую мы рассмотрим в следующем разделе, мы должны определить файл базы данных по умолчанию и параметры, которые будут использоваться для нашей демонстрации. Добавьте в config/database.yml
следующее:
demo: adapter: sqlite3 pool: 5 timeout: 5000 database: db/demo.sqlite3
В Rails вы также можете проверить свой Gemfile
, чтобы убедиться, что SQLite3 доступен в новой демо-среде. Вы можете установить это любым количеством способов, но это может выглядеть так:
group :development, :test, :demo do gem 'sqlite3' end
После того, как база данных настроена, вам нужно выполнить rake db:migrate RAILS_ENV=demo
а затем заполнить данные в базе данных, как вы пожелаете (будь то из исходного файла, ручного ввода новых данных или даже дублирования файла development.sqlite3
). На этом этапе вы должны убедиться, что все работает, запустив rails server -e demo
из командной строки. Пока вы запускаете сервер в новой демонстрационной среде, вы можете убедиться, что ваши тестовые данные соответствуют вашим требованиям, но вы всегда можете вернуться и отредактировать это содержимое позже. При добавлении вашего контента в демонстрационную базу данных я бы рекомендовал создать чистый набор данных, чтобы файл был как можно меньше. Однако, если вам нужно перенести данные из другой базы данных, я рекомендую YamlDb, который создает независимый от базы данных формат для дампа и восстановления данных.
Если ваше приложение Rails работает должным образом, вы можете перейти к следующему шагу.
Второй шаг: использование демонстрационной базы данных
Важной частью этого руководства является возможность разрешить каждому сеансу использовать другой файл базы данных SQLite. Обычно ваше приложение будет подключаться к одной и той же базе данных для каждого пользователя, поэтому для этой задачи потребуется дополнительный код.
Чтобы начать работу, позволяющую Ruby on Rails переключать базы данных, нам сначала нужно добавить следующие четыре закрытых метода в application_controller.rb
. Вам также потребуется определить предварительный фильтр для метода set_demo_database
, чтобы логика, ссылающаяся на правильную демонстрационную базу данных, вызывалась при каждой загрузке страницы.
# app/controllers/application_controller.rb # use `before_filter` for Rails 3 before_action :set_demo_database, if: -> { Rails.env == 'demo' } private # sets the database for the demo environment def set_demo_database if session[:demo_db] # Use database set by demos_controller db_name = session[:demo_db] else # Use default 'demo' database db_name = default_demo_database end ActiveRecord::Base.establish_connection(demo_connection(db_name)) end # Returns the current database configuration hash def default_connection_config @default_config ||= ActiveRecord::Base.connection.instance_variable_get("@config").dup end # Returns the connection hash but with database name changed # The argument should be a path def demo_connection(db_path) default_connection_config.dup.update(database: db_path) end # Returns the default demo database path defined in config/database.yml def default_demo_database return YAML.load_file("#{Rails.root.to_s}/config/database.yml")['demo']['database'] end
Поскольку у каждого сеанса сервера будет своя база данных, вы сохраните имя файла базы данных в переменной сеанса. Как видите, мы используем session[:demo_db]
для отслеживания конкретной базы данных для пользователя. Метод set_demo_database
контролирует, какую базу данных использовать, устанавливая соединение с базой данных, заданной в переменной сеанса. Метод default_demo_database
просто загружает путь к базе данных, как указано в файле конфигурации database.yml
.
Если вы используете пустой язык, на этом этапе вы, вероятно, можете просто обновить сценарий подключения к базе данных, чтобы он указывал на новую базу данных, а затем перейти к следующему разделу. В Rails требуется еще несколько шагов, потому что он следует программной парадигме «соглашение важнее конфигурации».
Третий шаг: дублирование файла SQLite
Теперь, когда приложение настроено на использование новой базы данных, нам нужен триггер для нового демонстрационного сеанса. Для простоты начните с простой кнопки «Начать демонстрацию». Вы также можете сделать это формой, в которой вы собираете имя и адрес электронной почты (для последующей связи с отделом продаж и т. д.) или что-то еще.

Придерживаясь соглашений Rails, создайте новый демо-контроллер:
rails generate controller demos new
Затем вы должны обновить маршруты, чтобы они указывали на ваши новые действия контроллера, заключив их в условное условие, чтобы предотвратить его вызов в производственной среде. Вы можете назвать маршруты, как хотите, или назвать их, используя стандартные соглашения Rails:
if Rails.env == 'demo' get 'demos/new', as: 'new_demo' post 'demos' => 'demos#create', as: 'demos' end
Далее давайте добавим очень простую форму в views/demos/new.html.erb
. Вы можете добавить дополнительные поля формы для захвата:
<h1>Start a Demo</h1> <%= form_tag demos_path, method: :post do %> <%= submit_tag 'Start Demo' %> <% end %>
Волшебство происходит в действии create
. Когда пользователь отправляет этот маршрут, действие копирует файл demo.sqlite3
с новым уникальным именем файла, устанавливает переменные сеанса, выполняет вход пользователя (если применимо), а затем перенаправляет пользователя на соответствующую страницу (мы будем называть это 'панель приборов').
class DemosController < ApplicationController def new # Optional: setting session[:demo_db] to nil will reset the demo session[:demo_db] = nil end def create # make db/demos dir if doesn't exist unless File.directory?('db/demos/') FileUtils.mkdir('db/demos/') end # copy master 'demo' database master_db = default_demo_database demo_db = "db/demos/demo-#{Time.now.to_i}.sqlite3" FileUtils::cp master_db, demo_db # set session for new db session[:demo_db] = demo_db # Optional: login code (if applicable) # add your own login code or method here login(User.first) # Redirect to wherever you want to send the user next redirect_to dashboard_path end end
Теперь вы сможете опробовать демонстрационный код локально, еще раз запустив сервер с помощью команды rails server -e demo
.
Если у вас уже был запущен сервер, вам нужно будет перезапустить его для внесения любых изменений, поскольку он настроен на кэширование кода, как на рабочем сервере.
Как только весь код заработает, как и ожидалось, зафиксируйте изменения в системе управления версиями и убедитесь, что вы зафиксировали файл demo.sqlite3
, а не файлы в каталоге db/demos
. Если вы используете git, вы можете просто добавить в свой файл .gitignore
:
Если вы хотите получить дополнительную информацию от демонстрационного пользователя (например, имя и/или адрес электронной почты), вы, вероятно, захотите отправить эту информацию через API либо в ваше основное приложение, либо в какой-либо другой конвейер продаж, поскольку ваша демонстрационная база данных не будет надежной. (он сбрасывается каждый раз при повторном развертывании).
!/db/demo.sqlite3 db/demos/*
Последний шаг: развертывание демонстрационного сервера
Теперь, когда у вас есть демонстрационная установка, работающая локально, вы, очевидно, захотите развернуть ее, чтобы каждый мог ее использовать. Хотя каждое приложение отличается, я бы порекомендовал, чтобы демонстрационное приложение располагалось на отдельном сервере и, следовательно, в домене рабочего приложения (например, demo.myapp.com). Это обеспечит изоляцию двух сред. Кроме того, поскольку файл SQLite хранится на сервере, такие службы, как Heroku, не будут работать, поскольку они не предоставляют доступ к файловой системе. Однако вы по-прежнему можете использовать практически любого провайдера VPS (например, AWS EC2, Microsoft Azure и т. д.). Если вам нравится автоматизированное удобство, есть другие варианты «Платформы как услуга», которые позволяют вам работать с VPS.
Независимо от вашего процесса развертывания вам также может потребоваться убедиться, что у приложения есть соответствующие разрешения на чтение и запись для вашего каталога, в котором вы храните демонстрационные файлы SQLite. Это можно сделать вручную или с помощью хука развертывания.
SQLite не будет работать для меня. А как насчет других систем баз данных?
Нет двух одинаковых приложений, как и их требования к базе данных. Используя SQLite, вы можете быстро дублировать базу данных, а также хранить файл в системе контроля версий. Хотя я считаю, что SQLite будет работать в большинстве ситуаций (особенно с Rails), бывают ситуации, когда SQLite может не подходить для нужд вашего приложения. К счастью, те же принципы, что и выше, все еще можно использовать с другими системами баз данных. Процесс дублирования базы данных будет немного отличаться для каждой системы, но я опишу решение для MySQL, и аналогичный процесс существует для PostgreSQL и других.
Большинство описанных выше методов работают без каких-либо дополнительных модификаций. Однако вместо того, чтобы хранить файл SQLite в системе управления версиями, вы должны использовать mysqldump
(или pg_dump
для PostgreSQL) для экспорта файла SQL любой базы данных с содержимым, которое вы хотели бы использовать для демонстрации. Этот файл также должен храниться в вашем контроле версий.
Единственные изменения в предыдущем коде будут найдены в действии demos#create
. Вместо копирования файла SQLite3 действие контроллера создаст новую базу данных, загрузит файл sql в эту базу данных и при необходимости предоставит разрешения пользователю базы данных. Третий шаг предоставления доступа необходим только в том случае, если ваш пользователь администратора базы данных отличается от пользователя, который приложение использует для подключения. Следующий код использует стандартные команды MySQL для обработки этих шагов:
def create # database names template_demo_db = default_demo_database new_demo_db = "demo_database_#{Time.now.to_i}" # Create database using admin credentials # In this example the database is on the same server so passing a host argument is not require `mysqladmin -u#{ ENV['DB_ADMIN'] } -p#{ ENV['DB_ADMIN_PASSWORD'] } create #{new_demo_db}` # Load template sql into new database # Update the path if it differs from where you saved the demo_template.sql file `mysql -u#{ ENV['DB_ADMIN'] } -p#{ ENV['DB_ADMIN_PASSWORD'] } #{new_demo_db} < db/demo_template.sql` # Grant access to App user (if applicable) `mysql -u#{ ENV['DB_ADMIN'] } -p#{ ENV['DB_ADMIN_PASSWORD'] } -e "GRANT ALL on #{new_demo_db}.* TO '#{ ENV['DB_USERNAME'] }'@'%';"` # set session for new db session[:demo_db] = new_demo_db # Optional: login code (if applicable) # add your own login code or method here login(User.first) redirect_to dashboard_path end
Ruby, как и многие другие языки, включая PHP, позволяет вам использовать обратные кавычки для выполнения команды оболочки (например, `ls -a`
) из вашего кода. Однако вы должны использовать это с осторожностью и убедиться, что никакие пользовательские параметры или переменные не могут быть вставлены в команду, чтобы защитить ваш сервер от вредоносного кода. В этом примере мы явно взаимодействуем с инструментами командной строки MySQL, что является единственным способом создания новой базы данных. Таким же образом среда Ruby on Rails создает новую базу данных. Обязательно замените ENV['DB_ADMIN']
и ENV['DB_ADMIN_PASSWORD']
либо собственной переменной среды, либо любым другим способом установки имени пользователя базы данных. Вам нужно будет сделать то же самое для ENV['DB_USERNAME']
, если ваш пользователь-администратор отличается от пользователя для вашего приложения.
Это все, что нужно для перехода на MySQL! Наиболее очевидным преимуществом этого решения является то, что вам не нужно беспокоиться о потенциальных проблемах, которые могут возникнуть из-за различного синтаксиса между системами баз данных.
В конце концов, окончательное решение принимается на основе ожидаемого качества и обслуживания, а не удобства и скорости, и оно не обязательно зависит только от цены.
Последние мысли
Это всего лишь отправная точка того, что вы можете делать с вашим новым демонстрационным сервером. Например, на вашем маркетинговом веб-сайте может быть ссылка «Попробуйте функцию XYZ». Если вам не требуется имя или адрес электронной почты, вы можете связать метод demos#create
с такой ссылкой, как /demos/?feature=xyz
, и действие будет просто перенаправлять на нужную функцию и/или страницу, а не на панель инструментов в приведенный выше пример.
Кроме того, если вы используете SQLite для разработки и демонстрационных сред, постоянное наличие этой пробной базы данных в системе контроля версий даст всем вашим разработчикам доступ к чистой базе данных для использования в локальной среде разработки, тестовых средах или тестировании обеспечения качества. Возможности безграничны.
Вы можете загрузить готовую демонстрацию с GitHub.