Статьи

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

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

TL; DR : я создаю пользовательскую панель управления WordPress для корпоративного клиента, которая работает на основе React.js поверх Node.js, с MongoDB Atlas в качестве базы данных.

На этой панели инструментов используется несколько служб Microsoft Azure, например, Cognitive Services, службы приложений Azure и особенно функции без сервера Azure. В этой статье вы узнаете, как создать из него небольшой модуль, а также о причинах моего выбора стека, приложений и продуктов.


Один из моих корпоративных клиентов, которому принадлежит огромная сетевая и медиа-компания, настроил крупный сайт на WordPress. Недавно он проконсультировался со мной о возможности создания настраиваемой панели управления WordPress (на основе WordPress REST API ) — чтобы помочь ему принимать интеллектуальные бизнес-решения с помощью машинного обучения и искусственного интеллекта.

С JavaScript, пожирающим мир, и WordPress, адаптирующимся к движению путем создания проекта Гутенберга , я подумал о архитектуре / стеке, где WordPress будет нашим слоем контента, знакомой проверенной в бою средой, которая хорошо справляется со своей собственной встроенной панелью мониторинга. с помощью JavaScript.

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

Поэтому, после небольшого изучения моих вариантов, я решил использовать React.js поверх Node.js, чтобы начать создавать собственную панель управления WordPress. Пока проект находится в стадии разработки, я думаю, что важно поделиться некоторыми нашими целями, чтобы определить контекст, стоящий за моим выбором стека.

Пользовательские цели WordPress Dashboard

Представьте, что вы владеете крупной сетевой компанией, в которой более 500 отелей (в трех разных странах) используют ваши услуги для питания своих конференц-залов, ИТ-собраний и онлайн-управления недвижимостью, таких как сайты и блоги. Это то, что делает мой клиент.

Большая часть этого работает на огромном многосайтовом экземпляре WordPress, который управляет всем для отелей, веб-сайтов, онлайн-бронирования, регистрации, событий, билетов, отзывов и комментариев. Существуют также другие системы, использующие другое программное обеспечение, которое может создавать контент через REST API.

Мы решили создать собственную панель управления WordPress с учетом многих целей, но я перечисляю некоторые из них, связанные с этой конкретной статьей. Взгляните на то, что я построил до сих пор, все это основано на функциях Azure без сервера — которые довольно круты.

Настраиваемая панель управления WordPress с MongoDB Atlas, Microsoft Azure и доступны без сервера!

? Отчетность о данных высокого уровня

Настраиваемая панель инструментов будет отображать все данные высокого уровня, например, такие как продажи в реальном времени по всему портфелю моего клиента (более 500 отелей), разбивки по сущностям / по времени и по дате.

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

⚡ Бессерверная автоматизация

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

Первоначальная приблизительная оценка делает это решение на 34% более экономичным, чем серверная виртуальная машина, работающая постоянно. Мы используем функции Azure для этой безсерверной автоматизации.

? Центр Интернета вещей (Интернет вещей)

На моем клиенте работают около 200 ИТ-менеджеров, у которых есть устройства с поддержкой IoT, которые передают данные в несколько онлайн-проектов. Эта настраиваемая панель также включает эти данные для принятия лучших решений и объединения всего центра регистрации, управления и обслуживания в одном месте.

Как вы уже могли догадаться, этот проект использует IoT Hub из Microsoft Azure для подключения, мониторинга и управления всеми активами IoT.

? Машинное обучение и искусственный интеллект

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

Существует огромный набор данных, который подается в ML Studio, который позже помогает нам прогнозировать различные решения, такие как управление пространством, низкие тенденции регистрации для ИТ-событий и такие вопросы, как, почему и когда это происходит.

Хотя часть «Машинное обучение» выходит за рамки этой статьи, я все же планирую коснуться базового уровня с помощью потрясающего искусственного интеллекта, который я смог приготовить с помощью когнитивных служб Azure.

? в реальном времени и в режиме реального времени

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

Но в то же время, это для целей управления и не должно иметь никакого влияния на сайты WordPress. Это решающее решение при проектировании системы для этой панели.

Под этим я подразумеваю, что мы можем проводить всевозможные эксперименты с этой настраиваемой панелью мониторинга, но это не должно иметь никакого влияния на базу данных / серверы, на которых работает многосайтовый экземпляр WordPress.

MongoDB и MongoDB Atlas

Для этой пользовательской панели инструментов WordPress я использую MongoDB Atlas в качестве DBaaS (База данных как Сервис). И я не мог быть счастливее. Когда я впервые поделился, что буду использовать MongoDB, у многих разработчиков были проблемы.

MongoDB

В большинстве вопросов задавался вопрос, почему я бы добавил еще один уровень сложности, добавив в базу еще одну базу данных. Почему бы не использовать базу данных WordPress как есть? Чтобы ответить на эти и другие вопросы, я подготовил список причин, по которым я использую MongoDB Atlas .

♨ нелюбовь к РСУБД

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

? HDD дешево — CPU / RAM нет

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

В настоящее время дисковое пространство очень дешево. С другой стороны, ЦП / ОЗУ нет, и затраты вашего системного администратора могут взлететь очень быстро, если у вас в итоге будет неправильный выбор.

Как будто вы хотели создать собственную панель мониторинга, но ваш архитектор проектирования системы стоил вам двух системных администраторов того, как они решили проектировать вашу систему. Точно так же мой клиент хотел получить управляемое решение без необходимости нанимать команду IT / DevOps — по крайней мере для экспериментальной пользовательской панели.

? Плюсы MongoDB

  • Схема-меньше . Гибкая схема на победу. Мне не нужно ничего менять, мой обычный рабочий процесс разработки приложений, создание приложения на основе Node.js, которым я манипулирую данными типа JSON, я могу просто передать это в MongoDB, и это просто работает.
  • Рабочий процесс-согласованность . Создает документы так, как представлена ​​моя пользовательская панель инструментов. Продажи, видео, разговоры, комментарии, обзоры, регистрации и т. Д. — все это имеет одинаковое представление данных на веб-интерфейсе и бэкэнде — и даже в базе данных. Я управляю сторонними данными через промежуточное ПО. Эта последовательность переводит в чистый код.
  • Легкость масштабирования . Он масштабирует чтения с использованием наборов реплик. Весы записывает с помощью шардинга (автоматическая балансировка). Просто запусти другую машину и уходи. Самое главное, что вместо вертикального масштабирования с помощью RDBMS MongoDB позволяет выполнять горизонтальное масштабирование с различными уровнями согласованности. Это большой плюс. ➕
  • Стоимость Зависит от того, какая СУБД, конечно, но MongoDB бесплатна и может работать на Linux, идеально подходит для запуска на более дешевых комплектах товаров.

? Почему MongoDB Atlas ?

Что ж, теперь, когда я знаю, что MongoDB — это правильный выбор базы данных, существует так много разных вариантов размещения вашей базы данных. Я могу самостоятельно размещаться на своем компьютере с Linux через DigitalOcean, использовать облачного провайдера, такого как AWS / Azure, или выбрать службу DBaaS, специфичную для MongoDB.

Монгодб Атлас

Но я хочу быстрое, безопасное и управляемое решение MongoDB, которое можно легко масштабировать по мере роста количества модулей, которые мы подключаем к этой пользовательской панели инструментов WordPress. Это MongoDB Atlas .

MongoDB Atlas — это облачная служба MongoDB, разработанная и управляемая той же командой, которая создает базу данных. И угадайте, что, я верю, что они следуют лучшим операционным практикам, так как именно они создают MongoDB в первую очередь.

Я хочу, чтобы эта пользовательская панель управления была самоуправляемой, без сервера, а использование MongoDB Atlas избавило меня от беспокойства по поводу исправлений программного обеспечения, резервного копирования и надежной настройки конфигурации для новых обновлений БД. Опять большой плюс. ➕

Кроме того, тот факт, что MongoDB Atlas поддерживается кроссплатформенным, а также межрегиональным и различными облачными провайдерами, делает его гораздо лучшим выбором. Я думаю, что каждый кластер поставляется с двумя наборами реплик, готовых к масштабированию.

? MongoDB Compass

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

Mongodb Compass

Я предлагаю вам пойти дальше и скачать MongoDB Compass . Это буквально лучший инструмент для визуализации вашей базы данных MongoDB. Вот набор функций:

  • Визуализируйте и исследуйте: посмотрите на свою базу данных, узнайте, как все выглядит, и даже визуализируйте такие вещи, как карты / координаты.
  • Вставка, изменение и удаление: вы также можете выполнять операции CRUD для вашей БД прямо с компаса MongoDB. Делает тестирование проще.
  • Отладка и оптимизация: наконец, проанализируйте ваши данные, отладьте их и даже узнайте о проблемах производительности прямо в отличном графическом интерфейсе для вашей базы данных. Этот инструмент просто необходим, если вы работаете с MongoDB.
  • Расширяемость: и самое главное, вы можете создавать свои собственные плагины для расширения MongoDB Compass. Вот документация по созданию ваших собственных плагинов Compass .
  • Версия Enterprise : MongoDB Compass поставляется в нескольких вариантах: Community (бесплатная) и Enterprise (лицензионная) — версия Enterprise — это та, которая позволяет визуализировать схему БД.

✅ Начало работы с MongoDB Atlas

Давайте начнем и создадим простой модуль, который является частью пользовательской панели инструментов WordPress, которую я создаю. Для этого модуля мы собираем все данные о продажах. Для этого нам нужен экземпляр MongoDB, и, конечно, мы используем MongoDB Atlas здесь.

Шаг № 1: Перейти в MongoDB Atlas →

Перейдите на сайт MongoDB Atlas и зарегистрируйте совершенно бесплатный экземпляр MongoDB, размещенный на AWS, с общей оперативной памятью и 512 МБ хранилища. Нажмите кнопку « Начать бесплатно» .

Монгодб Атлас

Шаг № 2: Зарегистрируйтесь в MongoDB Atlas →

Теперь идите вперед и зарегистрируйтесь с вашим адресом электронной почты и заполните детали. Удивительно, что вы можете зарегистрироваться и использовать бесплатный экземпляр размещенной базы данных MongoDB Atlas, и вам даже не нужно добавлять для этого кредитную карту.

Mongodb Atlas Зарегистрироваться

Шаг № 3: Создать кластер

Теперь вы будете перенаправлены на страницу с кучей информации о новом кластере MongoDB, который вы собираетесь создать. Я предлагаю вам просмотреть эту информацию и двигаться дальше, нажав кнопку « Создать кластер» внизу, как на скриншоте ниже.

Mongodb Atlas Создать кластер

Шаг № 4: Создать имя пользователя и пароль БД

Это займет минуту, и ваша БД будет создана. Как только это произойдет, зайдите в Security > MongoDB Users и нажмите кнопку + ADD NEW USER справа, чтобы создать нового пользователя для вашей базы данных. Давайте оставим все остальные настройки по умолчанию для этой вступительной статьи.

Я устанавливаю user / pass как usermongo но вы знаете лучше.

GIF для MongoDB Atlas, Microsoft Azure и функции без сервера

Шаг № 5: Добавить IP в белый список для доступа

Чтобы иметь доступ к базе данных MongoDB Atlas, вам нужно настроить белый список IP-адресов с IP-адресом вашего сервера, на котором размещено ваше приложение. Аутентификация выходит за рамки того, что я обсуждаю здесь, поэтому в целях этой демонстрации давайте просто позволим всем (очевидно, плохая практика в производстве).

Итак, снова перейдите в белый список Security > IP и нажмите кнопку + ADD IP ADDRESS справа, и, наконец, разрешить доступ с любого места , чтобы разрешить анонимный доступ.

GIF для MongoDB Atlas, Microsoft Azure и функции без сервера

Шаг № 6: Подключение через MongoDB Compass

Теперь, когда IP-доступ нашей БД и пользователь созданы, мы можем подобрать строку подключения и использовать ее для подключения к нашей базе данных с нашим приложением MongoDB Compass.

Перейдите в Connect, затем выберите Connect with MongoDB Compass и загрузите Compass, если у вас его нет. Скопируйте строку подключения URI. Наконец, откройте Compass, и он сможет обнаружить строку подключения в буфере обмена, разрешив ему подключиться к вашей базе данных.

И вы настроены на визуализацию базы данных, анализ ее производительности и даже на выполнение полных операций CRUD. Потрясающие! ?

GIF для MongoDB Atlas, Microsoft Azure и функции без сервера

Теперь, когда мы создали Atlas MongoDB и соединили его с MongoDB Compass, мы можем двигаться дальше и начать создавать приложение Node.js.

WordPress REST API — FTW!

Эта пользовательская панель инструментов Node.js на основе WordPress взаимодействует с экземпляром WordPress через API-интерфейс WordPress REST . Поскольку это приложение Node.js, я использую потрясающую библиотеку wpapi написанную K Adam White . Он также создал демо-приложение Express на основе WordPress. Это то, что меня вдохновило при создании этой пользовательской панели инструментов, так что вы многое увидите здесь.

Custom WordPress Custom Router на основе экспресс

Маршрутизатор настроен на экспресс . Вот основной обработчик ошибок и шаблон маршрутизатора для использования WordPress с экспрессом.

 'use strict'; var express = require('express'); var router = express.Router(); var siteInfoMiddleware = require('../middleware/site-info'); // Set global site info on all routes router.use(siteInfoMiddleware); // Public Routes // ============= router.get('/', require('./index')); router.get('/page/:page', require('./index')); router.get('/:slug', require('./single')); router.use('/tags/:tag', require('./tag')); router.use('/categories/:category', require('./category')); // Catch 404 and forward to error handler. router.use(function (req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); // Error Handling // ============== // Development error handler will print stacktrace. function developmentErrorRoute(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); } // Production error handler. No stacktraces leaked to user. function friendlyErrorRoute(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); } // Configure error-handling behavior if (router.get('env') === 'development') { router.use(developmentErrorRoute); } else { router.use(friendlyErrorRoute); } module.exports = router; 

Посмотреть код на Gist .

? Базовая экспресс-реализация

Я не размещаю всю эту вещь на WordPress, но первоначальный план был сделать именно это. Если вы хотите сделать это, вам нужно построить индекс, запросив всю информацию с RSVP.hash утилиты RSVP.hash для удобства и параллелизма. Для этого вот что вы должны сделать.

 'use strict'; var wp = require( '../services/wp' ); var contentService = require( '../services/content-service' ); var pageNumbers = require( '../services/page-numbers' ); var pageTitle = require( '../services/page-title' ); var RSVP = require( 'rsvp' ); function getHomepage( req, res, next ) { var pages = pageNumbers( req.params.page ); RSVP.hash({ archiveBase: '', pages: pages, title: pageTitle(), // Primary page content posts: wp.posts().page( pages.current ), sidebar: contentService.getSidebarContent() }).then(function( context ) { if ( req.params.page && ! context.posts.length ) { // Invalid pagination: 404 return next(); } res.render( 'index', context ); }).catch( next ); } module.exports = getHomepage; 

Посмотреть код на Gist .

? Аутентификация, приготовленная в

Для этой настройки вам также потребуется аутентифицировать ваше приложение Node.js, предоставив ему данные аутентификации, которые вместе с wpapi могут обрабатываться следующим образом. Остерегайтесь, это не всегда лучший метод, если вы не используете правильные разрешения и настройки переменных среды.

 var WP = require( 'wordpress-rest-api' ); var _ = require( 'lodash' ); var config = _.pick( require( './config' ).wordpress, [ // Whitelist valid config keys 'username', 'password', 'endpoint' ]); var wp = new WP( config ); module.exports = wp; 

Посмотреть код на Gist .

? Накопление контента сайта

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

  • Все страницы постраничной коллекции.
  • Информация о вашем сайте WordPress.
  • Алфавитный список категорий.
  • Определенная категория (указанная slug) из кэша контента.
  • Алфавитный список тегов.
  • Определенный тег (указанный слагом) из кэша контента
  • Другой контент должен иметь некоторое соотношение функций с WP.

Код для этого выглядит примерно так.

 'use strict'; var wp = require( './wp' ); var cache = require( './content-cache' ); var _ = require( 'lodash' ); var RSVP = require( 'rsvp' ); /** * Recursively fetch all pages of a paged collection * * @param {Promise} request A promise to a WP API request's response * @returns {Array} A promise to an array of all matching records */ function all( request ) { return request.then(function( response ) { if ( ! response._paging || ! response._paging.next ) { return response; } // Request the next page and return both responses as one collection return RSVP.all([ response, all( response._paging.next ) ]).then(function( responses ) { return _.flatten( responses ); }); }); } function siteInfo( prop ) { var siteInfoPromise = cache.get( 'site-info' ); if ( ! siteInfoPromise ) { // Instantiate, request and cache the promise siteInfoPromise = wp.root( '/' ).then(function( info ) { return info; }); cache.set( 'site-info', siteInfoPromise ); } // Return the requested property return siteInfoPromise.then(function( info ) { return prop ? info[ prop ] : info; }); } /** * Get an alphabetized list of categories * * All archive routes display a sorted list of categories in their sidebar. * We generate that list here to ensure the sorting logic isn't duplicated * across routes. * * @method sortedCategories * @return {Array} An array of category objects */ function sortedCategories() { return all( wp.categories() ).then(function( categories ) { return _.chain( categories ) .sortBy( 'slug' ) .value(); }); } function sortedCategoriesCached() { var categoriesPromise = cache.get( 'sorted-categories' ); if ( ! categoriesPromise ) { categoriesPromise = sortedCategories(); cache.set( 'sorted-categories', categoriesPromise ); } return categoriesPromise; } /** * Get a specific category (specified by slug) from the content cache * * The WP API doesn't currently support filtering taxonomy term collections, * so we have to request all categories and filter them down if we want to get * an individual term. * * To make this request more efficient, it uses sortedCategoriesCached. * * @method categoryCached * @param {String} slug The slug of a category * @return {Promise} A promise to the category with the provided slug */ function categoryCached( slug ) { return sortedCategoriesCached().then(function( categories ) { return _.findWhere( categories, { slug: slug }); }); } /** * Get a specific tag (specified by slug) from the content cache * * The WP API doesn't currently support filtering taxonomy term collections, * so we have to request all tags and filter them down if we want to get an * individual term. * * To make this request more efficient, it uses the cached sortedTags promise. * * @method tagCached * @param {String} slug The slug of a tag * @return {Promise} A promise to the tag with the provided slug */ function tagCached( slug ) { return sortedTagsCached().then(function( tags ) { return _.findWhere( tags, { slug: slug }); }); } /** * Get an alphabetized list of tags * * @method sortedTags * @return {Array} An array of tag objects */ function sortedTags() { return all( wp.tags() ).then(function( tags ) { return _.chain( tags ) .sortBy( 'slug' ) .value(); }); } function sortedTagsCached() { var tagsPromise = cache.get( 'sorted-tags' ); if ( ! tagsPromise ) { tagsPromise = sortedTags(); cache.set( 'sorted-tags', tagsPromise ); } return tagsPromise; } function getSidebarContent() { return RSVP.hash({ categories: sortedCategoriesCached(), tags: sortedTagsCached() }); } module.exports = { // Recursively page through a collection to retrieve all matching items all: all, // Get (and cache) the top-level information about a site, returning the // value corresponding to the provided key siteInfo: siteInfo, sortedCategories: sortedCategories, sortedCategoriesCached: sortedCategoriesCached, categoryCached: categoryCached, tagCached: tagCached, sortedTags: sortedTags, sortedTagsCached: sortedTagsCached, getSidebarContent: getSidebarContent }; 

Посмотреть код на Gist .

? Пользовательские маршруты и данные о продажах

Наконец, я приготовил несколько пользовательских маршрутов, из которых я могу получить любые данные, связанные с продажами. Для конкретной архитектуры, которую я использую, я снова использую утилиту RSVP.hash для удобства и параллелизма. Отлично работает.

 var WPAPI = require( 'wpapi' ); var RSVP = require('rsvp'); // Using the RSVP.hash utility for convenience and parallelism RSVP.hash({ categories: wp.categories().slug( 'it-services' ), tags1: wp.tags().slug('hotel-name'), tags2: wp.tags().slug('march-events') }).then(function( results ) { // Combine & map .slug() results into arrays of IDs by taxonomy var tagIDs = results.tags1.concat( results.tags2 ) .map(function( tag ) { return tag.id; }); var categoryIDs = results.categories .map(function( cat ) { return cat.id; }); return wp.posts() .tags( tags ) .categories( categories ); }).then(function( posts ) { // These posts are all fiction, either magical realism or historical: console.log( posts ); }); 

Посмотреть код на Gist .

Получив эти данные, я отправляю их на Paddle.com для обработки вместе с заказанным заказом на покупку, чтобы их можно было добавить к нашему экземпляру MongoDB с помощью бессерверных функций Azure.

 // Registering custom routes. site.itSales = site.registerRoute( 'sales/v1', '/resource/(?P<some_part>\\d+)' ); site.itSales().somePart( 7 ); // => myplugin/v1/resource/7 // Query Parameters & Filtering Custom Routes. site.handler = site.registerRoute( 'sales/v1', 'receipts/(?P<id>)', { // Listing any of these parameters will assign the built-in // chaining method that handles the parameter: params: [ 'before', 'after', 'author', 'parent', 'post' ] }); // Yields from the custom data of buyers. site.handler().post( 8 ).author( 92 ).before( dateObj )... // Sent to paddle. 

Посмотреть код на Gist .

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

Эти данные отправляются Paddle, и они сильно кэшируются, поэтому наши экземпляры WordPress не получают никакой нагрузки, пока мы экспериментируем с пользовательской панелью мониторинга. Я также готовил в небольшом модуле data-refresh который выбирает данные по запросу из выбранного экземпляра WordPress.

Microsoft Azure и функции Azure

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

Options три варианта

Присутствуют три основных поставщика облачных услуг. Это Microsoft Azure , Google Cloud Platform и Amazon Web Services . Каждая из них имеет доступные функции без сервера, соответственно называемые функциями Azure, GCP Cloud Functions и AWS Lambdas.

Az Выбор Лазурного

Azure обладает одной из крупнейших облачных архитектур и глобальным присутствием. В 50 регионах Azure, больше, чем у любого облачного провайдера, и после тестирования каждого из этих трех я обнаружил, что функции Azure имеют лучшее время отклика в ОАЭ (поскольку бизнес моего клиента основан на ОАЭ).

Кроме того, тот факт, что мы используем Azure ML Studio, AI Cognitive Services и виртуальные машины для размещения частей этого проекта, означает, что имеет смысл использовать функции Azure для безсерверной архитектуры.

Начало работы с функциями Azure

Давайте начнем с функций Azure. Я собираюсь провести вас через процесс создания простой бессерверной функции Azure, которая будет запускаться через HTTP-запросы, и внутри нее мы будем обрабатывать информацию о продажах, отправленную нам с Paddle.com.

⚙ Что мы строим ?!

  1. Я создаю бессерверную функцию Azure, которая основана на JavaScript и, в частности, на коде Node.js.
  2. Эта функция Azure будет вызвана простым GET HTTP-запросом от нашего стороннего платежного решения, т.е. Paddle.com.
  3. Как только на Paddle.com появится продажа, он запустит веб-крючок, который содержит информацию, касающуюся нашей продажи, количества, товара, дохода и некоторых связанных с участниками данных, которые WordPress отправил в Paddle.
  4. Используя WordPress REST API, я добавил некоторые пользовательские данные, связанные с пользователем, который приобрел продукт, например, идентификатор пользователя в БД WordPress, сайт продажи WordPress и метаинформацию этого пользователя.
  5. Когда функция Azure получает этот GET запрос, она обрабатывает информацию, извлекает то, что мне нужно сохранить в MongoDB Atlas Cluster, и формирует объект JavaScript, готовый для сохранения в БД.
  6. Затем функция Azure подключается к экземпляру MongoDB Atlas через пакет npm под названием mongoose , где после подключения базы данных я создаю модель / схему БД, а затем эти данные сохраняются в кластере MongoDB Atlas.
  7. После чего функция Azure находится там, ожидая следующей продажи, когда мой клиент оплачивает только время выполнения и количество выполнений для функций Azure. ( 1 миллион из которых бесплатны каждый месяц ?).

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

Итак, давайте продолжим и создадим эту вещь.

Шаг № 1: Настройка Microsoft Azure и VSCode

Я ожидаю, что на вашем конце будет настроена учетная запись Azure . Вам нужно будет подписаться с помощью кредитной карты, поскольку нам нужно хранилище для размещения файлов Node.js, которые будут использоваться с функциями Azure, и вам придется заплатить за хранилище (вы, вероятно, получите бесплатный кредит в размере 200 долларов в первый месяц и даже после этого стоимость довольно низкая).

Итак, продолжайте и настройте следующее:

  1. ✅ Настройте учетную запись Microsoft Azure с помощью кредитной карты для выставления счетов.
  2. ✅ Установите код Visual Studio (Psst. Я делаю курс по VSCode ).
  3. Extension Установите расширение функций Azure на свой VSCode.
  4. ? Чтобы включить локальную отладку, установите основные инструменты функций Azure .
  5. ? Создайте новый каталог и откройте его в VSCode.

Если вам интересно, какую тему и шрифт я использую, это Shades of Purple for — для получения дополнительной информации посмотрите, какое программное и аппаратное обеспечение я использую .

7 оттенков фиолетового VSCode

Шаг № 2: Создайте новый проект приложения функции

Теперь давайте создадим новый проект приложения функции. Это действительно легко с VSCode. Все, что вам нужно сделать, это перейти в проводник расширений Azure, представленный в панели активности. Оттуда перейдите на вкладку FUNCTIONS и нажмите на первый значок Create New Project .

Это создаст демонстрационный проект с основными файлами, необходимыми для начала работы, и инициализирует Git-репо для вас. Я буду следить за небольшими демонстрациями на основе GIF, чтобы вам было проще.

GIF для MongoDB Atlas, Microsoft Azure и функции без сервера

Шаг № 3. Создание функции Azure, запускаемой по протоколу HTTP

Теперь, когда мы создали проект приложения функции, давайте создадим безсерверную функцию Azure, запускаемую по протоколу HTTP. Для этого перейдите в проводник расширений Azure, представленный в панели активности. Оттуда перейдите на вкладку FUNCTIONS и нажмите на второй значок Create Function .

Ради этой демонстрации я выберу простую часть аутентификации, поэтому я выберу анонимный доступ. Имя нашей функции Azure — HttpTriggerJS поэтому вы можете найти новый каталог, созданный с этим именем, внутри вашего проекта. Он должен содержать два файла, т.е. functions.json и index.js

Function Функция является основным понятием в функциях Azure. Вы пишете код для функции на выбранном вами языке и сохраняете код и файлы конфигурации в одной папке.

Configuration Конфигурация называется function.json , которая содержит данные конфигурации JSON. Он определяет привязки функций и другие параметры конфигурации. Среда выполнения использует этот файл для определения событий, которые нужно отслеживать, и того, как передавать данные и возвращать данные из выполнения функции. Подробнее об этом файле в официальной документации здесь .

Ниже приведен пример файла function.json который создается.

 { "disabled": false, "bindings": [ { "authLevel": "anonymous", "type": "httpTrigger", "direction": "in", "name": "req" }, { "type": "http", "direction": "out", "name": "res" } ] } 

Посмотреть код на Gist .

И еще, есть файл index.js который содержит базовый код, который вы можете использовать для тестирования вашей функции Azure. Он получает name параметра и печатает его обратно или показывает ошибку, запрашивая этот параметр.

 module.exports = function (context, req) { context.log('JavaScript HTTP trigger function processed a request.'); if (req.query.name || (req.body && req.body.name)) { context.res = { // status: 200, /* Defaults to 200 */ body: "Hello " + (req.query.name || req.body.name) }; } else { context.res = { status: 400, body: "Please pass a name on the query string or in the request body" }; } context.done(); }; 

Посмотреть код на Gist .

GIF для MongoDB Atlas, Microsoft Azure и функции без сервера

Шаг № 4. Разверните и протестируйте свою функцию Azure

Теперь, когда мы создали функцию Azure, которая может быть вызвана запросом GET HTTP, давайте развернем ее с помощью VSCode и протестируем с помощью Postman API Explorer.

Чтобы развернуть функцию, перейдите в проводник расширений Azure, представленный на панели действий. Оттуда перейдите на вкладку FUNCTIONS и нажмите на третий значок Deploy to Function App .

Это задаст вам кучу вопросов о названии вашего приложения, используйте что-нибудь уникальное. Я использовал demo-wp-mdb-azure — затем VSCode использует это для создания группы ресурсов, для группировки ресурсов, относящихся к вашему приложению-функции, его хранилищу (используемому для сохранения файлов) и созданной функции Azure — наконец, отвечая на нам с публичным URL.

Затем я пошел к этому URL, и он попросил name параметра в соответствии с кодом. Когда я отправил name параметра с приложением «Почтальон», оно ответило « ?

VSCode также попросил меня обновить версии приложения расширения функций до бета-версии, и я выбрал «да» — потому что это поможет мне использовать Node.js v8 для async / await.

Шаг № 5: Создайте package.json и установите mongoose

Теперь, когда наша функция Azure запущена, давайте создадим файл package.json в корне нашего проекта и установим mongoose . Нам понадобится это для подключения и сохранения данных в наш Atlas Cluster MongoDB.

Mongoose предоставляет простое решение на основе схем для моделирования данных вашего приложения. Он включает в себя встроенную типизацию, проверку, построение запросов, хуки бизнес-логики и многое другое. Это довольно круто. ?

GIF для MongoDB Atlas, Microsoft Azure и функции без сервера

Шаг № 6: Добавить настройки приложения для подключения MongoDB

Теперь мы почти готовы начать писать код для нашего приложения. Но прежде чем сделать это, нам понадобится строка подключения, чтобы иметь возможность подключиться к нашему Atlas Cluster MongoDB (как мы это делали с MongoDB Compass). Эта строка подключения является частной, и вы не должны фиксировать ее в git-репо.

String Эта строка подключения принадлежит файлу local.settings.json в корне проекта. Давайте сначала MongodbAtlas настройки, затем добавим настройку MongodbAtlas вместе с нашей строкой подключения (получим эту строку из панели мониторинга MongoDB Atlas) и MongodbAtlas настройки приложения.

Для этого перейдите в проводник расширений Azure, представленный на панели действий. Оттуда перейдите на вкладку FUNCTIONS и выберите свою подписку, затем свое функциональное приложение Azure, то есть demo-wp-mdb-azure . Щелкните правой кнопкой мыши Настройки приложения и выберите Загрузить удаленные настройки…, чтобы загрузить и Загрузить локальные настройки…, чтобы загрузить настройки после добавления MongodbAtlas подключения MongodbAtlas к настройкам.

Шаг № 7. Обновление версии узла функции Azure

В этом коде я намерен использовать async / await , который недоступен в Node.js v6.5.0, который поставляется с версией 1 функций Azure по умолчанию. На шаге 4 VSCode попросил меня обновить версию функции Azure во время выполнения до бета-версии, и я сделал это. Это включило поддержку последних версий Node.js в функциях Azure.

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

GIF для MongoDB Atlas, Microsoft Azure и функции без сервера

Шаг № 8: Создание модели / схемы MongoDB

Прежде чем сохранять какие-либо данные в нашем Atlas Cluster MongoDB, давайте создадим файл modelSale.js который будет содержать схему модели для того, что мы намереваемся сохранить в базе данных. Это чрезвычайно простая реализация схемы, и я предлагаю вам прочитать о том, что вы можете сделать здесь с помощью mongoose и MongoDB .

Этот файл говорит сам за себя.

 /** * Model: Sale */ const mongoose = require('mongoose'); mongoose.Promise = global.Promise; // Sale Schema. const saleSchema = new mongoose.Schema({ sale_gross: Number, earnings: Number, currency: String, memberSince: Date, customerEmail: String, event_time: { type: Date, default: Date.now }, }); // Export the model. module.exports = mongoose.model('Sale', saleSchema); 

Посмотреть код на Gist .

Шаг № 9: закодируйте функцию Azure с помощью Node.js

Теперь давайте закодируем нашу функцию Azure. Я добавляю весь основной код в файл index.js для демонстрации. Я также собираюсь использовать объект контекста в качестве первого параметра, поэтому обязательно прочитайте об этом . Все остальное объясняется в фрагменте кода ниже.

Итак, это всего лишь демонстрационный код для этой статьи. Это делает следующее:

  • ✅ Получает данные от Paddle.com
  • ⚡ Подключается к MongoDB Atlas через строку подключения, которую мы добавили в настройках приложения.
  • ? Использует определенную схему БД внутри test базы данных, где она создает коллекцию sales , включая документы для наших продаж.
  • ⚙ Проверяет данные и создает объект finalData который сохраняется в кластере MongoDB Atlas. Ура!
  • ? Наконец, отвечает на веб-крючок Paddle с кодом состояния 200 если все идет хорошо, и танцует context.done() .

Все в значительной степени объясняется с помощью встроенной документации.

 /** * Azure Function: Sale. * * Gets data from Paddle.com (which in turn gets data * from WordPress) and processes the data, creates a * finalData object and saves it in MongoDB Atlas. * * @param context To pass data between function to / from runtime. * @param req HTTP Request sent to the Azure function by Paddle. */ module.exports = async function (context, req) { // Let's call it log. const log = context.log; // Log the entire request just for the demo. log('[RAN] RequestUri=%s', req.originalUrl); /** * Azure function Response. * * Processes the `req` request from Paddle.com * and saves the data to MongoDB Atlas while * responding the `res` response. */ // Database interaction. const mongoose = require('mongoose'); const DATABASE = process.env.MongodbAtlas; // Connect to our Database and handle any bad connections mongoose.connect(DATABASE); mongoose.Promise = global.Promise; // Tell Mongoose to use ES6 promises mongoose.connection.on('error', (err) => { context.log(`ERROR→ ${err.message}`); }); // Sale Schema. require('./modelSale'); const Sale = mongoose.model('Sale'); // Create a Response. if (req.query.customFieldName) { // Simple authentication for the purpose of demo. // Build the data we need. const sale_gross = req.query.p_sale_gross || '0'; const earnings = JSON.parse(req.query.p_earnings)['16413'] || '0' const currency = req.query.p_currency || 'USD'; const memberSince = req.query.memberSince || new Date(); const customerEmail = req.query.customerEmail || ''; const event_time = new Date(); log('[OUTPUT]—— sale_gross: ' + sale_gross); log('[OUTPUT]—— earnings: ' + earnings); log('[OUTPUT]—— currency: ' + currency); const finalData = { sale_gross: sale_gross, earnings: earnings, currency: currency, memberSince: memberSince, customerEmail: customerEmail, event_time: event_time, } // Save to db. const sale = await (new Sale(finalData)).save(); log("[OUTPUT]—— SALE SAVED: ", sale); // Respond with 200. context.res = { status: 200, body: "Thank You for the payment! " + (req.query.customFieldName || req.body.customFieldName) }; } else { context.res = { status: 400, body: "Please pass a name on the query string or in the request body" }; } // Informs the runtime that your code has finished. You must call context.done, or else the runtime never knows that your function is complete, and the execution will time out. // @link: https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-node#contextdone-method context.done(); }; 

Посмотреть код на Gist .

Шаг № 10. Переустановите функцию Azure.

Теперь давайте повторно развернем функцию Azure. Для этого перейдите в проводник расширений Azure, представленный в панели активности. Оттуда перейдите на вкладку FUNCTIONS и нажмите на третий значок Deploy to Function App .

GIF для MongoDB Atlas, Microsoft Azure и функции без сервера

Шаг № 11: Проверка функции Azure с помощью Webhook от Paddle

Похоже, мы почти закончили. Осталось только протестировать нашу функцию Azure, запустив фиктивный веб-крючок через Paddle.com. Давайте сделаем это. Кроме того, когда все работает, давайте посмотрим, как наши данные выглядят в MongoDB Compass.

Вау, хм! Это было много. Рад, что это сработало. ?

? Итак, что только что произошло ?!

Приготовься к глотку. Я создал небольшую часть модуля Sales в пользовательском приложении WordPress Dashboard, которое я создаю. Я использовал MongoDB Atlas и Compass, затем создал функцию Microsoft Azure через приложение Function с VSCode, развернул приложение с секретом env в качестве строки приложения со строкой подключения MongoDB, обновил версию Node.js и вызвал функцию через фиктивный веб-крючок с Paddle.com (как это будет происходить при продаже) отправлять данные (из Paddle + WordPress) в нашу функцию Azure и оттуда в MongoDB Atlas. И это сработало, ха-ха!

Машинное обучение и искусственный интеллект

Машинное обучение и искусственный интеллект всегда являются завораживающей темой в мире программных технологий, но мы не много говорим об этом в контексте WordPress или в сообществе WP.

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

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

Я объяснил это в видео в другом посте, который вы можете найти здесь: Создание плагина WordPress для искусственного интеллекта → .

Я достиг аналогичных результатов на этой панели с пакетом wpapi . Сначала я загружаю изображение в когнитивные сервисы, а затем с уверенным ответом отправляю его в WordPress для загрузки через WordPress REST API с описанием изображения, которое создается с помощью Computer Vision AI.

 /** * Get Image Alt Recognition with Computer Vision * using Azure Cognitive Services. */ var WPAPI = require('wpapi'); var wp = new WPAPI({ endpoint: 'http://src.wordpress-develop.dev/wp-json' }); /** * Handle Image Alt Generation. */ function processImage() { // ********************************************** // *** Update or verify the following values. *** // ********************************************** // Replace <Subscription Key> with your valid subscription key. var subscriptionKey = "<Subscription Key>"; // You must use the same region in your REST call as you used to get your // subscription keys. For example, if you got your subscription keys from // westus, replace "westcentralus" in the URI below with "westus". // // Free trial subscription keys are generated in the westcentralus region. // If you use a free trial subscription key, you shouldn't need to change // this region. var uriBase = "https://westcentralus.api.cognitive.microsoft.com/vision/v2.0/analyze"; // Request parameters. var params = { "visualFeatures": "Categories,Description,Color", "details": "", "language": "en", }; // Display the image. var sourceImageUrl = document.getElementById("inputImage").value; document.querySelector("#sourceImage").src = sourceImageUrl; // Make the REST API call. $.ajax({ url: uriBase + "?" + $.param(params), // Request headers. beforeSend: function (xhrObj) { xhrObj.setRequestHeader("Content-Type", "application/json"); xhrObj.setRequestHeader( "Ocp-Apim-Subscription-Key", subscriptionKey); }, type: "POST", // Request body. data: '{"url": ' + '"' + sourceImageUrl + '"}', }) .done(function (data) { // Show formatted JSON on webpage. $("#responseTextArea").val(JSON.stringify(data, null, 2)); // Extract and display the caption and confidence from the first caption in the description object. if (data.description && data.description.captions) { var caption = data.description.captions[0]; if (caption.text && caption.confidence >= 0.5) { const imgDescription = caption.text; //  Upload to WordPress. wp.media() // Specify a path to the file you want to upload, or a Buffer .file(sourceImageUrl) .create({ title: imgDescription, alt_text: imgDescription, caption: imgDescription, description: imgDescription }) .then(function (response) { // Your media is now uploaded: let's associate it with a post var newImageId = response.id; return wp.media().id(newImageId).update({ post: associatedPostId }); }) .then(function (response) { console.log('Media ID #' + response.id); console.log('is now associated with Post ID #' + response.post); }); } } }) .fail(function (jqXHR, textStatus, errorThrown) { // Display error message. var errorString = (errorThrown === "") ? "Error. " : errorThrown + " (" + jqXHR.status + "): "; errorString += (jqXHR.responseText === "") ? "" : jQuery.parseJSON(jqXHR.responseText).message; alert(errorString); }); }; 

Посмотреть код на Gist .

? Автоматизация модерации контента

Одна из наших идей — использовать AI / ML из Azure для использования в качестве платформы для модерации контента , которая предлагает встроенное машинное обучение «человек в цикле», помогающее модерировать изображения, текст и видео. Это работа в процессе, но это что-то действительно интересное, на что вы обязательно должны взглянуть.

Блок-схема модератора контента

? WordPress Грамматика (нацистская) разведка

У вас есть привычка вводить одни и те же опечатки снова и снова. Я делаю это все время. Самая крутая вещь когда-либо — это когда поисковые системы, такие как Bing и Google, могут проверять орфографию и корректировать поисковый запрос для вас.

Представь, если бы это было у WordPress ?! Итак, я приступил к работе и закончил готовить ту же функциональность в админке WordPress, когда вы набираете опечатку в заголовке своего поста (или более одного опечатки, если мне все равно!).

WordPress AI: автоматическое исправление заголовка и проверка правописания

Я был так взволнован, что не мог сдержать себя, поэтому я в левом нижнем углу. Все счастливы и удивлены! ??????☝??

Теперь твоя очередь!

Я действительно надеюсь, что вам понравилась эта потенциальная интеграция между всеми этими современными платформами JavaScript, продуктами AI / ML и функциями без серверов.

Этот проект очень веселый.Я думаю, что если вы попробуете этот технический стек, вы тоже сможете получить сумасшедшее удовольствие. Итак, я оставляю на ваше усмотрение попробовать MongoDB Atlas в контексте WordPress — и, возможно, присоединить все это к куче бессерверных функций.