Esercizio: Gestire e distribuire le applicazioni in nodi di calcolo
L'API client di Azure Batch consente di controllare a livello di codice tutti i componenti di un account Azure Batch.
Per continuare a migliorare l'app console aziendale, si aggiungeranno ora tutti i componenti necessari per convertire i video che sono stati caricati nell'ultimo esercizio.
Importante
Per eseguire questo esercizio è necessario disporre di una propria sottoscrizione di Azure e questo potrebbe comportare dei costi. Se non hai ancora una sottoscrizione di Azure, crea un account gratuito prima di iniziare.
Al termine di questo esercizio, il processo Batch sarà funzionante e potrà convertire i video MP4 in GIF animate. L'app aggiungerà un processo al pool esistente e aggiungerà e avvierà le attività di conversione dei video.
Migliorare il codice che usa il client di Batch
In Cloud Shell modificare il file
Program.cs
nell'editor:code Program.cs
Aggiungere una costante a Program.cs per JobId che servirà nel processo di Batch:
private const string JobId = "WinFFmpegJob";
Sostituire le righe nel metodo Main:
var batchClient = BatchClient.Open(sharedKeyCredentials); // Create the Batch pool, which contains the compute nodes that execute tasks. await CreateBatchPoolAsync(batchClient, PoolId);
Usando un blocco using per
batchClient
:using (BatchClient batchClient = BatchClient.Open(sharedKeyCredentials)) { // Create the Batch pool, which contains the compute nodes that execute the tasks. await CreateBatchPoolAsync(batchClient, PoolId); // Create the job that runs the tasks. await CreateJobAsync(batchClient, JobId, PoolId); // Create a collection of tasks and add them to the Batch job. await AddTasksAsync(batchClient, JobId, inputFiles, outputContainerSasUrl); }
Creare un processo
Aggiungere questo nuovo metodo
CreateJobAsync()
a Program.cs per creare e aggiungere un processo al pool:private static async Task CreateJobAsync(BatchClient batchClient, string jobId, string poolId) { Console.WriteLine("Creating job [{0}]...", jobId); CloudJob job = batchClient.JobOperations.CreateJob(); job.Id = jobId; job.PoolInformation = new PoolInformation { PoolId = poolId }; await job.CommitAsync(); }
Il codice precedente usa il client Batch per creare un processo. Il metodo assegna l'ID processo specificato e le informazioni relative al pool.
Aggiungere un'attività
Quando il processo è creato, l'ultimo passaggio consiste nell'aggiungere un'attività al processo. Aggiungere il metodo
AddTaskAsync()
seguente a Program.cs:private static async Task<List<CloudTask>> AddTasksAsync(BatchClient batchClient, string jobId, List<ResourceFile> inputFiles, string outputContainerSasUrl) { Console.WriteLine("Adding {0} tasks to job [{1}]...", inputFiles.Count, jobId); // Create a collection to hold the tasks added to the job List<CloudTask> tasks = new List<CloudTask>(); for (int i = 0; i < inputFiles.Count; i++) { // Assign a task ID for each iteration string taskId = String.Format("Task{0}", i); // Define task command line to convert the video format from MP4 to animated GIF using ffmpeg. // Note that ffmpeg syntax specifies the format as the file extension of the input file // and the output file respectively. In this case inputs are MP4. string appPath = String.Format("%AZ_BATCH_APP_PACKAGE_{0}#{1}%", appPackageId, appPackageVersion); string inputMediaFile = inputFiles[i].FilePath; string outputMediaFile = String.Format("{0}{1}", System.IO.Path.GetFileNameWithoutExtension(inputMediaFile), ".gif"); // This is the dos command built by using the ffmpeg application package, the paths from the input container string taskCommandLine = String.Format("cmd /c {0}\\ffmpeg-3.4-win64-static\\bin\\ffmpeg.exe -i {1} {2}", appPath, inputMediaFile, outputMediaFile); // Create a cloud task (with the task ID and command line) and add it to the task list CloudTask task = new CloudTask(taskId, taskCommandLine); task.ResourceFiles = new List<ResourceFile> { inputFiles[i] }; // Task output file will be uploaded to the output container in Storage. List<OutputFile> outputFileList = new List<OutputFile>(); OutputFileBlobContainerDestination outputContainer = new OutputFileBlobContainerDestination(outputContainerSasUrl); OutputFile outputFile = new OutputFile(outputMediaFile, new OutputFileDestination(outputContainer), new OutputFileUploadOptions(OutputFileUploadCondition.TaskSuccess)); outputFileList.Add(outputFile); task.OutputFiles = outputFileList; tasks.Add(task); } // Call BatchClient.JobOperations.AddTask() to add the tasks as a collection rather than making a // separate call for each. Bulk task submission helps to ensure efficient underlying API // calls to the Batch service. await batchClient.JobOperations.AddTaskAsync(jobId, tasks); return tasks; }
Questo metodo finale esegue tutte le azioni complesse dell'app. Per ogni file caricato, viene aggiunta un'attività al processo. L'attività assume la forma di un comando della shell. L'app (
ffmpeg
) è stata installata in ogni nodo in una posizione specifica, perché è stato usato un pacchetto dell'applicazione. Il servizio Batch archivia tale percorso in una variabile di ambiente nel nodo in modo che sia accessibile tramite il codice seguente:%AZ_BATCH_APP_PACKAGE_ffmpeg#3.4%
In questo modo si semplificano il caricamento e l'incremento a versioni più recenti dell'app
ffmpeg
. Il comando esamina la cartella ZIP ed esegue il comando seguente:ffmpeg.exe -i input-filename output-filename
Per ottenere prestazioni ottimali, le attività vengono aggiunte sotto forma di elenco a
batchClient.JobOperations.AddTaskAsync
. Questo approccio risulta più efficiente rispetto a eseguire una chiamata separata per ogni file.
Testare l'app console
Nell'editor di codice fare clic con il pulsante destro del mouse e scegliere Salva, quindi fare clic con il pulsante destro del mouse e scegliere Esci.
In Cloud Shell compilare ed eseguire l'app:
dotnet run
I messaggi seguenti saranno scritti nel terminale:
Creating container [input]. Creating container [output]. Uploading file ~\cutifypets\InputFiles\3.mp4 to container [input]... Uploading file ~\cutifypets\InputFiles\2.mp4 to container [input]... Uploading file ~\cutifypets\InputFiles\4.mp4 to container [input]... Uploading file ~\cutifypets\InputFiles\1.mp4 to container [input]... Uploading file ~\cutifypets\InputFiles\5.mp4 to container [input]... Uploading file ~\cutifypets\InputFiles\6.mp4 to container [input]... Creating pool [WinFFmpegPool]... Creating job [WinFFmpegJob]... Adding 6 tasks to job [WinFFmpegJob]...
L'app console si chiude non appena vengono aggiunte le attività. Il pool, i nodi, il processo e le attività sono state create in Azure. Quando l'app viene chiusa, non esistono processi da monitorare all'interno dell'app. Per visualizzare lo stato corrente della conversione e controllare i risultati, tornare al portale di Azure.
Nel portale di Azure selezionare l'account Batch che inizia con
cutify
nel Dashboard.Il dashboard di integrità viene visualizzato nella pagina Panoramica. Da qui è possibile controllare lo stato del processo in esecuzione corrente e del pool di nodi.
Nel menu a sinistra selezionare Processi in Funzionalità, quindi selezionare WinFFmpegJob. In questa pagina verrà visualizzato lo stato corrente delle attività.
Al termine delle attività, tornare all'account di archiviazione creato nel primo esercizio.
Nel menu a sinistra selezionare Contenitori in Archiviazione dati e quindi selezionare la cartella output.
La cartella contiene i file di GIF animate convertiti. Scaricare un file per verificare il più bel video degli animali.