Многопоточность в Azure

#multithreading #azure #azure-functions #parallel.foreach #azure-function-app

#многопоточность #azure #azure-функции #параллельный.для каждого #azure-функция-приложение

Вопрос:

Я хотел перенести службу Windows в azure, запустив ее через функцию Azure.

Служба Windows выполняет многопоточность с помощью Parallel.ForEach цикла, и просто чтобы проверить, работает ли многопоточность в Azure идеально или нет, я написал приведенный ниже код:

Функция Azure :

 [FunctionName("Function1")]
public static void Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer, TraceWriter log)
{
    try
    {
        Process process = new Process();

        process.StartInfo.FileName = @"D:homesitewwwrootDependencyMasterVBMasterVB.exe";
        process.StartInfo.Arguments = "";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;

        log.Info("Before Calling Start ");
        process.Start();
        log.Info("After Calling Start ");

        string output = process.StandardOutput.ReadToEnd();
        string err = process.StandardError.ReadToEnd();
        process.WaitForExit();
    }
    catch
    {
      //left out for brevity
    }
}
  

MasterVB.exe:

 Imports System.Collections.Concurrent
Imports Microsoft.WindowsAzure.Storage
Imports Microsoft.WindowsAzure.Storage.Blob
    
Module Module1
    
    Public connectionString As String = "DefaultEndpointsProtocol=https;AccountName=r53eripcjroswtest;AccountKey=cktlWe/byeSOis94OOA0YFlHPRrAfmORuy9xRGScTrxwuliY4KmZfAif8aF4cgng2mnDLvJWIvxl0xEPMU6DKw==;"
    Public storageAccount As CloudStorageAccount = CloudStorageAccount.Parse(connectionString)
    Public serviceClient As CloudBlobClient = storageAccount.CreateCloudBlobClient()
    Public container As CloudBlobContainer = serviceClient.GetContainerReference("igb-test")
    Public blob As CloudAppendBlob = container.GetAppendBlobReference("DocumentMaster.txt")
    
    Sub Main()
    
        If Not blob.Exists Then
            blob.CreateOrReplace()
        End If
    
        Dim dealist As New List(Of String)
    
        dealist.Add("First")
        dealist.Add("Second")
        dealist.Add("Third")
        dealist.Add("Fourth")
        dealist.Add("Fifth")
        dealist.Add("Sixth")
        dealist.Add("Seventh")
        dealist.Add("Eighth")
        dealist.Add("Nine")
        dealist.Add("Tenth")
        Dim exceptions As New ConcurrentQueue(Of Exception)
        Dim opts As New ParallelOptions
        opts.MaxDegreeOfParallelism = -1
        Parallel.ForEach(dealist, opts, Sub(deal)
                                            If Len(deal) > 0 Then
                                                Try
                                                    Dim p As New Process()
                                                    p.StartInfo.FileName = "D:homesitewwwrootDependencyMasterVBChildVBChildVB.exe"
                                                    p.StartInfo.Arguments = deal
                                                    p.StartInfo.UseShellExecute = False
                                                    p.StartInfo.CreateNoWindow = True
                                                    p.Start()
                                                    p.WaitForExit()
                                                Catch ex As Exception
                                                    exceptions.Enqueue(ex)
                                                End Try
                                            End If
                                        End Sub)
    
        If exceptions.Count > 0 Then
            For Each ex In exceptions
                'Console.WriteLine(ex.Message)
                blob.AppendText(ex.Message   Environment.NewLine)
            Next
        End If
    
    End Sub
    
End Module
  

ChildVB.exe

 Imports Microsoft.WindowsAzure.Storage
Imports Microsoft.WindowsAzure.Storage.Blob
Module Module1
    Public keycode As String = ""
    Public dealPass As String = ""
    Public runType As String = ""
    
    Public connectionString As String = "DefaultEndpointsProtocol=https;AccountName=r53eripcjroswtest;AccountKey=cktlWe/byeSOis94OOA0YFlHPRrAfmORuy9xRGScTrxwuliY4KmZfAif8aF4cgng2mnDLvJWIvxl0xEPMU6DKw==;"
    Public storageAccount As CloudStorageAccount = CloudStorageAccount.Parse(connectionString)
    Public serviceClient As CloudBlobClient = storageAccount.CreateCloudBlobClient()
    Public container As CloudBlobContainer = serviceClient.GetContainerReference("igb-test")
    Public blob As CloudAppendBlob = container.GetAppendBlobReference("DocumentChild.txt")
    
    Sub Main()
        Dim clArgs() As String = Environment.GetCommandLineArgs()
    
        If Not blob.Exists Then
            blob.CreateOrReplace()
        End If
            
        If clArgs.Count = 2 Then
    
            Dim args As String = clArgs(1)
            blob.AppendText(args   "----"   DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss")   Environment.NewLine)                
    
        End If
    End Sub
    
End Module
  

In the DocumentChild.txt , i am getting the following output:

 First----08/12/2020 15:15:03
Sixth----08/12/2020 15:15:04
Third----08/12/2020 15:15:05
Seventh----08/12/2020 15:15:06
Fourth----08/12/2020 15:15:07
Nine----08/12/2020 15:15:09
Tenth----08/12/2020 15:15:10
Fifth----08/12/2020 15:15:10

First----08/12/2020 15:20:17
Sixth----08/12/2020 15:20:17
Second----08/12/2020 15:20:18
Seventh----08/12/2020 15:20:19
Fifth----08/12/2020 15:20:21
Eighth----08/12/2020 15:20:21
Nine----08/12/2020 15:20:23
Tenth----08/12/2020 15:20:23
Fourth----08/12/2020 15:20:24

First----08/12/2020 15:25:02
Sixth----08/12/2020 15:25:03
Second----08/12/2020 15:25:04
Seventh----08/12/2020 15:25:04
Third----08/12/2020 15:25:05
Fifth----08/12/2020 15:25:06
Eighth----08/12/2020 15:25:07
Fourth----08/12/2020 15:25:07
Nine----08/12/2020 15:25:09
Tenth----08/12/2020 15:25:09

First----08/12/2020 15:30:01
Sixth----08/12/2020 15:30:01
Second----08/12/2020 15:30:03
Third----08/12/2020 15:30:03
Seventh----08/12/2020 15:30:04
Fifth----08/12/2020 15:30:05
Nine----08/12/2020 15:30:06
Fourth----08/12/2020 15:30:06
Eighth----08/12/2020 15:30:07
Tenth----08/12/2020 15:30:08

First----08/12/2020 15:35:02
Second----08/12/2020 15:35:04
Third----08/12/2020 15:35:04
Fifth----08/12/2020 15:35:06
Seventh----08/12/2020 15:35:06
Fourth----08/12/2020 15:35:07
Nine----08/12/2020 15:35:08
Eighth----08/12/2020 15:35:08
Tenth----08/12/2020 15:35:09
  

Приведенные выше строки показывают выходные данные при каждом запуске другой функции Azure через 5 минут в течение пяти разных периодов времени.
Выходные данные в первом и втором экземплярах, в 15:15 и 15:20, не печатают все десять строк, но делают это в третьем и четвертом экземплярах, но не печатают все строки в пятом экземпляре.
В реальном коде список освобождения, упомянутый в MasterVB, будет содержать более 4000 строк для обработки таким же образом, т. е. главный вызывающий дочерний элемент с использованием многопоточности.

Мои вопросы:

  1. Почему многопоточность в этом случае не согласована и каждый раз печатает все десять строк? Меня беспокоит то, что если она несовместима всего с 10 строками, сможет ли она обработать 4000 строк с
    большим количеством операций, чем просто печать в текстовый файл в модуле ChildVB?
  2. Есть ли какая-либо хорошая альтернатива для переноса этой службы Windows, которая включает в себя многопоточность, в azure.
  3. Есть ли вероятность, что это может быть связано с планом развертывания.

Примечание:

1. Я использую план потребления для развертывания, но не сталкиваюсь с какими-либо проблемами, такими как тайм-аут, который присутствует в этом плане в качестве стандарта (10 минут)

  1. Я запускал это несколько раз, но несоответствие сохраняется при каждом запуске функции azure.
  2. Нет никаких сложностей или ошибок во время выполнения.

Комментарии:

1. Я надеюсь, что эта строка подключения не является допустимой

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

3. Нет проблем со строкой подключения, и жестко запрограммированные пути приведены здесь только с целью тестирования. Есть ли какая-либо альтернатива этому для выполнения в Azure?

4. Существует множество вариантов. Было бы лучше настроить план обслуживания приложений и загрузить проект WebAPI, у которого есть конечная точка, к которой вы можете подключиться. Используйте относительные пути к вашим EXE-файлам (честно говоря, я не знаю, почему вы используете здесь отдельные программы… просто напишите это в своем сервисе.) Вы также можете просмотреть веб-задания, которые выполняются одновременно с вашим AppService, если они должны оставаться в виде отдельных EXE-файлов.

Ответ №1:

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

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

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

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