#azure
#azure
Вопрос:
Я пытаюсь запустить исполняемый файл на C в Azure. У меня много рабочих ролей, и они постоянно проверяют очередь заданий. Если в очереди есть задание, рабочая роль запускает экземпляр исполняемого файла C как процесс в соответствии с аргументами командной строки, хранящимися в классе заданий. Исполняемый файл C обычно создает некоторые файлы журнала. Я не знаю, как получить доступ к этим созданным файлам. Какова логика, стоящая за этим? Где хранятся созданные файлы? Кто-нибудь может мне объяснить? Я новичок в Azure и C #.
Еще одна проблема заключается в том, что всем рабочим экземплярам исполняемого файла C необходимо прочитать файл данных. Как я могу распространить этот требуемый файл?
Ответ №1:
Во-первых, поймите, что в Windows Azure ваша рабочая роль просто выполняется в среде Windows 2008 Server (либо SP2, либо R2). При развертывании вашего приложения вы также должны развернуть исполняемый файл на C (или извлечь его из хранилища больших двоичных объектов, но это немного сложнее). Чтобы узнать, где находится ваше приложение на диске, вызовите Environment.GetEnvironmentVariable("RoleRoot")
— это возвращает путь. Обычно ваше приложение находится в папке с именем AppRoot в корневом каталоге роли. Вы бы нашли там свой исполняемый файл на C.
Далее вы захотите, чтобы ваше приложение записывало свои файлы в выходной каталог, указанный вами в командной строке. Вы можете настроить хранилище на своей локальной виртуальной машине с помощью свойств вашей роли. Посмотрите на вкладку «Локальное хранилище» и настройте именованную область локального хранилища:
Теперь вы можете получить путь к этой области хранения в коде и передать его в качестве аргумента командной строки:
var outputStorage = RoleEnvironment.GetLocalResource("MyLocalStorage");
var outputFile = Path.Combine(outputStorage.RootPath, "myoutput.txt");
var cmdline = String.Format("--output {0}", outputFile);
Вот пример запуска вашего myapp.exe процесс с аргументами командной строки:
var appRoot = Path.Combine(Environment.GetEnvironmentVariable("RoleRoot")
@"", @"approot");
var myProcess = new Process()
{
StartInfo = new ProcessStartInfo(Path.Combine(appRoot, @"myapp.exe"), cmdline)
{
CreateNoWindow = false,
UseShellExecute = false,
WorkingDirectory = appRoot
}
};
myProcess.WaitForExit();
Обычно для CreateNoWindow устанавливается значение true, но его легче отлаживать, если вы можете видеть окно командной оболочки.
И последнее: как только ваше приложение завершит создание файла, вы захотите либо:
- Обработайте его и удалите (он не находится в надежном месте, поэтому в конечном итоге он исчезнет)
- Измените свое хранилище на использование облачного диска (долговременное хранилище)
- Скопируйте ваш файл в большой двоичный объект (долговременное хранилище)
В рабочей среде вам потребуется добавить обработку исключений, и вы можете перенаправить stdout и stderr для записи. Но этого примера кода должно быть достаточно, чтобы вы начали.
УПС — еще одна «еще одна вещь»: при добавлении вашего ‘myapp.exe ‘ для вашего проекта обязательно перейдите в его свойства и установите для параметра «Копировать в выходной каталог» значение «Копировать всегда» — в противном случае ваш myapp.exe файл не попадет в Windows Azure, и вы будете удивляться, почему что-то не работает.
РЕДАКТИРОВАТЬ: Передача результатов в большой двоичный объект — краткий пример
Сначала настройте учетную запись хранилища и добавьте в настройки своей роли. Допустим, вы назвали его «AzureStorage» — теперь настройте его в коде, получите ссылку на контейнер больших двоичных объектов, получите ссылку на большой двоичный объект внутри этого контейнера, а затем выполните загрузку файла в большой двоичный объект:
CloudStorageAccount storageAccount = CloudStorageAccount.FromConfigurationSetting("AzureStorage");
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer outputfiles = blobClient.GetContainerReference("outputfiles");
outputfiles.CreateIfNotExist();
var blobname = "myoutput.txt";
var blob = outputfiles.GetBlobReference(blobname);
blob.UploadFile(outputFile);
Комментарии:
1. Спасибо. Можете ли вы также объяснить мне, как собирать созданные файлы из локального хранилища? Каждый рабочий может скопировать созданный файл в большой двоичный объект. Затем какая-либо другая рабочая роль или клиентское приложение могут получить доступ к этому двоичному объекту, верно?
2. Смотрите обновленный ответ для краткого примера переноса выходного файла в большой двоичный объект. Опять же, вам понадобится обработка исключений и т.д. Я рекомендую загрузить учебный комплект для платформы Windows Azure, чтобы получить более подробную информацию — там есть отличные учебные пособия и практические лабораторные работы.
3. это отличный ответ, и я многому научился из этой темы; но единственная проблема, с которой я в настоящее время сталкиваюсь, заключается в создании выходного файла. в ответе Дэвида предполагается наличие флага «—output» для указания выходного файла. что, если флага нет? есть альтернатива использованию process.standardoutput также для получения выходных данных в виде потока, но я предпочитаю использовать операторы перенаправления командного вывода «>», «>>» и т.д., Если это возможно. итак, вопрос в следующем: возможно ли использование оператора cmd? спасибо за дополнительную информацию.
Ответ №2:
На территории Azure не следует выполнять запись в файловую систему. Вы должны написать в SQL Azure, хранилище таблиц или, скорее всего, в данном случае хранилище больших двоичных объектов (в принципе, я думаю, вы должны думать о хранилище больших двоичных объектов как о старой файловой системе)
Это потому, что:
-
У вас может быть запущено несколько экземпляров, и в конечном итоге у вас будут разные файлы на разных экземплярах (которые являются просто виртуальными машинами)
-
Ваш экземпляр потенциально может быть перемещен в любой момент, и вы потеряете информацию о файловой системе, поскольку она не является частью вашего пакета развертывания.
Использование одного из трех вариантов хранилища предоставит доступ ко всем вашим экземплярам к центральному хранилищу, которое будет сохраняться при повторном развертывании.
Комментарии:
1. На самом деле это не так. У вас есть как недолговечное, так и долговременное файловое хранилище для записи. Смотрите мой ответ (через мгновение) для получения более подробной информации.
2. надежное хранилище файлов — это хранилище больших двоичных объектов?
3. Да — примерно за 10 строк кода вы можете смонтировать том NTFS в качестве облачного диска. Выглядит точно так же, как буква диска вашего приложения.
4. Но полностью согласен с локальным файловым хранилищем — оно отлично подходит для временного хранения. В примере, который я показал выше, идея заключалась бы в том, чтобы позволить приложению генерировать выходные данные, а затем что-то делать с этим выводом (копировать его в большой двоичный объект, обрабатывать / анализировать его, что угодно) и не рассчитывать на то, что он навсегда останется в локальном хранилище. Я часто использую локальное хранилище для обработки / вывода — это очень удобно и позволяет многим сторонним приложениям работать без изменений.