#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 строк для обработки таким же образом, т. е. главный вызывающий дочерний элемент с использованием многопоточности.
Мои вопросы:
- Почему многопоточность в этом случае не согласована и каждый раз печатает все десять строк? Меня беспокоит то, что если она несовместима всего с 10 строками, сможет ли она обработать 4000 строк с
большим количеством операций, чем просто печать в текстовый файл в модуле ChildVB? - Есть ли какая-либо хорошая альтернатива для переноса этой службы Windows, которая включает в себя многопоточность, в azure.
- Есть ли вероятность, что это может быть связано с планом развертывания.
Примечание:
1. Я использую план потребления для развертывания, но не сталкиваюсь с какими-либо проблемами, такими как тайм-аут, который присутствует в этом плане в качестве стандарта (10 минут)
- Я запускал это несколько раз, но несоответствие сохраняется при каждом запуске функции azure.
- Нет никаких сложностей или ошибок во время выполнения.
Комментарии:
1. Я надеюсь, что эта строка подключения не является допустимой
2. Во-первых, вы реализуете функцию Azure, которая является «бессерверной службой», но вы жестко кодируете пути к ресурсам на диске. Вы выполняете файлы. В этой архитектуре много чего не так. На самом деле вам не следует делать ничего из этого. Во-вторых, это не «многопоточность» — это просто запуск множества процессов.
3. Нет проблем со строкой подключения, и жестко запрограммированные пути приведены здесь только с целью тестирования. Есть ли какая-либо альтернатива этому для выполнения в Azure?
4. Существует множество вариантов. Было бы лучше настроить план обслуживания приложений и загрузить проект WebAPI, у которого есть конечная точка, к которой вы можете подключиться. Используйте относительные пути к вашим EXE-файлам (честно говоря, я не знаю, почему вы используете здесь отдельные программы… просто напишите это в своем сервисе.) Вы также можете просмотреть веб-задания, которые выполняются одновременно с вашим AppService, если они должны оставаться в виде отдельных EXE-файлов.
Ответ №1:
Хотя может оказаться невозможным определить, почему не все запуски завершились без подробных журналов, я могу предложить решение для вашего сценария (и многих подобных сценариев, подобных этому).
Во-первых, вместо списка строк вы могли бы вставить сообщение в очередь (служебную шину или очередь хранения) для каждой строки, которую вам нужно обработать. У вас даже может быть функция HTTP-триггера, которая вставляет сообщения в очередь, используя соответствующую привязку вывода (служебная шина или очередь хранения).
Затем, в зависимости от выбранных вами служб очередей, у вас будет функция, запускаемая соответствующим триггером (служебной шиной или очередью хранения). Эта функция масштабирования в зависимости от количества сообщений, если вы используете ее на потребление или премиум — план.
Если вам требуется, чтобы подмножество сообщений обрабатывалось по порядку, тогда вам придется использовать служебную шину, использующую ее сеансы сообщений. Для триггера служебной шины существует параметр конфигурации, который вам нужно будет установить, чтобы он принимал сеансы обмена сообщениями.