Статьи

Мониторинг производительности многоуровневых приложений Windows Azure

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

Облачные приложения в Windows Azure обычно являются многоуровневыми приложениями.

Windows Azure позволяет легко создавать приложения, размещенные в облаке. По своей конструкции эти приложения имеют тенденцию быть высоко распределенными с несколькими уровнями. Устранение неполадок с низкой производительностью означает, что необходимо точно знать, какой узел или уровень дает сбой Распределенные приложения не имеют единой точки отказа. Здесь есть все, что угодно, и каждый отдельный узел на каждом уровне — от операционной системы до промежуточного программного обеспечения, от сторонних продуктов, аппаратного обеспечения, конфигурации сети и вашей собственной логики программного обеспечения. Каждый узел обычно выполняет свой собственный ввод-вывод, имеет свои собственные карты Ethernet и содержит различные запущенные процессы и потоки.

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

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

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

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

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

Предвидеть проблемы

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

Пример — 3 уровня (веб-интерфейс, служебная шина, фоновый процесс / рабочая роль)

Поэтому для начала я прошел через одну из лабораторий Azure. Вот лаборатория, которую я хотел проверить:

Лаборатория демонстрирует очереди, паб / саб

Цель лабораторной работы — настроить многоуровневое приложение, которое использует очереди служебной шины Windows Azure. Как известно большинству архитекторов, очереди позволяют создавать разрозненные приложения. Очереди являются мощными, поскольку они позволяют клиентским приложениям отправлять сообщения с высокой скоростью, которая может превышать способность внутреннего сервера обрабатывать. По мере того, как размер очереди начинает расти, можно добавить больше рабочих ролей Windows Azure, чтобы увеличить масштаб и, следовательно, своевременно обрабатывать сообщения. Это также основной строительный блок для публикации шаблонов подписки.

3-х уровневая диаграмма

Принцип работы рисунка 1 прост. Клиентские приложения подключаются к веб-роли и отправляют сообщения. Веб-роль принимает эти сообщения, а затем помещает их в очередь, которая запускается как приложение Windows Azure Service Bus. Рабочая роль может рассматриваться как фоновый процесс. Он проверяет очередь в служебной шине и читает сообщения из очереди. Если очередь начинает становиться слишком большой, нам нужно масштабировать рабочие роли, чтобы иметь возможность обрабатывать объем сообщений, помещаемых в очередь служебной шины.

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

фигура 1

Рисунок 1 — Концептуальная схема многоуровневого приложения

Где узкое место?

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

Идеальный мир

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

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

Обратите внимание, что представление, предоставляемое AppDynamics (рисунок 2), практически идентично концептуальной диаграмме. Прелесть всего этого в том, что это делается автоматически AppDynamics при публикации вашего приложения. Поскольку ее приложение растет или масштабируется, AppDynamics будет поддерживать диаграмму для вас. AppDynamics также позволит вам автоматически записывать тесты, которые будут использоваться для будущей диагностики.

Представление на рисунке 2 — это то, что можно увидеть на портале AppDynamics. Это не диаграмма, которую построил разработчик или архитектор. Это диаграмма, построенная автоматически AppDynamics с использованием агентов и элементов инфраструктуры, которые являются частью AppDynamics. При развертывании проекта Azure этот MSI выполняет: dotNetAgentSetup64.msi .

фигура 2

Рисунок 2 — представление AppDynamics — автоматически сгенерированный

Глядя на некоторый код

Вот решение в Visual Studio 2013. Обратите внимание, что решение тесно отражает рисунки 1 и 2. Это идеальный сценарий — разработчик может концептуально мыслить от концепции до мониторинга производительности и макета проекта Visual Studio.

Рисунок 3

Рисунок 3 — Проект Visual Studio

Понимание кода

В общем решении три проекта. Msftazuretut является основным проектом в решении и используется для развертывания и общей конфигурации. Как объяснялось ранее, веб-роль используется двумя способами. Первый способ заключается в том, что он действует как клиентское приложение, отправляя сообщения в очередь. Второй способ заключается в том, что он может выступать в качестве внешнего интерфейса для других клиентских приложений. В конце концов, это приложение в стиле MVC Web API. Третья часть — это рабочая роль, которая, по сути, является фоновым процессом, читающим из очереди, асинхронно обрабатывающим сообщения, ожидающие в очереди, размещенной там веб-ролью.

figure4

Рисунок 4 — Решение Visual Studio 2013

Более подробная логика

Логика здесь довольно проста.

Код Роли Сети — Контроллер

HomeController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using FrontendWebRole.Models;
using Microsoft.ServiceBus.Messaging;
using Microsoft.ServiceBus;

namespace FrontendWebRole.Controllers
{
    // The controller for the web role.
    // It has 2 capabilities. First, it presents an entry
    // form for an order (Customer and Product Numbers)
    // Once the form is submitted, the second capability
    // comes into play - to place the submitted order as
    // a message into a service bus queue.
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            // Simply redirect to Submit, since Submit will serve as the
            // front page of this application
            return RedirectToAction("Submit");
        }

        public ActionResult About()
        {
            return View();
        }

        // GET: /Home/Submit
        public ActionResult Submit()
        {
            // Connect to the service bus queue
            var namespaceManager = QueueConnector.CreateNamespaceManager();


            // Get the queue, and obtain the message count.
            var queue = namespaceManager.GetQueue(QueueConnector.QueueName);
            ViewBag.MessageCount = queue.MessageCount;

            return View();
        }

        // POST: /Home/Submit
        // Controler method for handling submissions from the submission
        // form.
        [HttpPost]
        // Attribute to help prevent cross-site scripting attacks and
        // cross-site request forgery.
        [ValidateAntiForgeryToken]
        public ActionResult Submit(OnlineOrder order)
        {
            if (ModelState.IsValid)
            {
                // Create a message based on the order submitted by the form.
                // This will include a customer number and a product number.
                var message = new BrokeredMessage(order);


                // Submit the order. This adds the order to the
                // service bus queue.
                QueueConnector.OrdersQueueClient.Send(message);
                return RedirectToAction("Submit");
            }
            else
            {
                return View(order);
            }
        }
    }
} 

Рисунок 5 — веб-роль

Код рабочей роли

WorkerRole.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
using FrontendWebRole.Models;

namespace OrderProcessingRole
{
    // Worker role is responsible for reading message
    // put into the service bus queue by the web role.
    public class WorkerRole : RoleEntryPoint
    {
        // The name of the queue. It is the same queue used
        // by the web role.
        const string QueueName = "OrdersQueue";
        bool onStopCalled = false;

        // The Client is an object used to read from the
        // service bus queue.
        QueueClient Client;

        // The Run() method can be thought of as a never ending background
        // process that reads messages from the service bus queue.
        public override void Run()
        {
            Trace.WriteLine("Starting processing of messages");

            // Loop forever until onStopCalled is set.
            while (true)
            {
                try
                {
                    // If OnStop has been called, return to do a graceful shutdown.
                    if (onStopCalled == true)
                    {
                        System.Diagnostics.Debug.WriteLine("onStopCalled WorkerRole");
                        return;
                    }

                    // Read the messsage (if exists) from the service bus queue.
                    BrokeredMessage receivedMessage = Client.Receive();

                    // Process the message
                    System.Diagnostics.Debug.WriteLine("Processing Service Bus message: " +
                                     receivedMessage.SequenceNumber.ToString());

                    // Load the message into the OnlineOrder object.
                    OnlineOrder order = receivedMessage.GetBody<OnlineOrder>();

                    // For debugging purposes, display the order sent in by the web role.
                    Debug.WriteLine(order.Customer + ": " + order.Product, "ProcessingMessage");
                    receivedMessage.Complete();
                }
                catch
                {
                    // Handle any message processing specific exceptions here
                }
            }

            //CompletedEvent.WaitOne();
        }

        public override bool OnStart()
        {
            // Set the maximum number of concurrent connections
            ServicePointManager.DefaultConnectionLimit = 12;

            // Get the connection string to setup the connection.
            string connectionString =
                    CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
            var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);

            // Create queue, if doesn't exist.
            if (!namespaceManager.QueueExists(QueueName))
            {
                namespaceManager.CreateQueue(QueueName);
            }

            // Create a client object to be used by Run() method to
            // read messges.
            Client = QueueClient.CreateFromConnectionString(connectionString, QueueName);
            return base.OnStart();
        }

        public override void OnStop()
        {
            // Cleanup and close.
            Client.Close();
            onStopCalled = true;
            base.OnStop();
        }
    }
} 

Рисунок 6 — Рабочая роль

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

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

Всего 6 простых шагов. Они полностью задокументированы здесь:

Шаг 1 Зарегистрируйте учетную запись AppDynamics.
Шаг 2 Загрузите .NET Agent для AppDynamics.
Шаг 3 Добавьте агента в веб-роль или рабочую роль. Вы должны добавить агента к каждой веб-роли и рабочей роли.
Шаг 4 Добавьте некоторые команды запуска в виде текстового файла startup.cmd. Это означает копирование некоторого стандартного кода в startup.cmd. Это также означает, что нужно зайти в файл ServiceDefinition.csdef и указать, что только что добавленный файл startup.cmd будет запущен при запуске.
Шаг 5 Опубликуйте свою заявку.
Шаг 6 Мониторинг производительности. Используйте свой браузер, чтобы посетить контроллер AppDynamics по URL-адресу, указанному в приветственном письме, и на домашней странице учетной записи AppDynamics.

Вывод

Общеизвестно, что многоуровневые приложения трудно устранять, особенно если они размещены в облачной инфраструктуре. В случае сбоя или снижения производительности сложно определить основную причину или место возникновения проблемы. Еще сложнее предвидеть проблемы, прежде чем они окажут существенное влияние на конечных пользователей. Настройка оповещений и агентов мониторинга должна быть простой и быстрой. Кроме того, по мере роста сложности приложений для системы важно динамически обнаруживать уровни приложений и отображать поток транзакций, уделяя особое внимание задержке запросов в реальном времени, проверке полезной нагрузки, времени отклика, частоте появления ошибок и группировке транзакций. Короче говоря, AppDynamics обеспечивает целостное, многомерное представление на уровне бизнес-транзакций, а также производительность компонентов инфраструктуры более низкого уровня.Это позволяет быстро и легко находить медленные транзакции, утечки памяти, медленные запросы к базе данных, конфликты потоков и многое другое.