我是 Azure 的新手。我想創建一個回傳序列號的函式。我創建了一個使用執行緒互斥鎖來鎖定序列號的函式。我用大約 10k 個并行請求測驗了下面的代碼。問題是我在做測驗時得到了重復的序列號,互斥鎖不起作用。我不知道該怎么做才能避免重復,而是為每個請求生成運行編號
Public class MySharedMutexCounter {
public static long count = 0;
public static Mutex ObjMutex = new Mutex(false,"SeqGenerator");
}
public long GetSequnceNo(){
long seqId = -1;
try{
MySharedMutexCounter.ObjMutex.waitOne();
seqId = MySharedMutexCounter.count;
if(seqId > 100){
MySharedMutexCounter.count = 0;
seqId = MySharedMutexCounter.count;
}
return seqId;
}finally{
MySharedMutexCounter.ObjMutex.RelaseMutex();
}
return -1;
}
uj5u.com熱心網友回復:
問題是,azure 函式可以擴展到在不同機器上運行的多個實體,因此您需要某種或其他方式的分布式鎖來保證不會對狀態進行并發訪問。
使用Durable Entity怎么樣?它基本上是一個可以被Durable Function訪問的狀態,并且對狀態的操作以安全的方式執行:
為了防止沖突,單個物體上的所有操作都保證串行執行,即一個接一個。
(來源)
持久物體就像分布式物件,因此函式的其他實體將使用相同的物體。
該開發者指南演示了如何使用計數器的很好的例子。有點適合你的場景。
uj5u.com熱心網友回復:
嗨@Peter Bons 我嘗試了下面的代碼,但花了很多時間。我的代碼可能有問題。是否有可能在幾分之一秒內獲得值 bcos 我回傳不到一秒的值。
[FunctionName("FunctionOrchestrator")]
public static async Task<int> RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
int currentValue = -1;
var input = context.GetInput<CounterParameter>();
if (input != null && !string.IsNullOrWhiteSpace(input.OperationName))
{
var entityId = new EntityId("Counter", "myCounter");
// Perform the requested operation on the entity
currentValue = await context.CallEntityAsync<int>(entityId, input.OperationName);
}
return currentValue;
}
[FunctionName("Counter")]
public static int Counter([EntityTrigger] IDurableEntityContext ctx, ILogger log)
{
log.LogInformation($"Request for operation {ctx.OperationName} on entity.");
switch (ctx.OperationName.Trim().ToLowerInvariant())
{
case "increment":
ctx.SetState(ctx.GetState<int>() 1);
break;
}
// Return the latest value
return ctx.GetState<int>();
}
[FunctionName("AutoIncrement")]
public static async Task<HttpResponseMessage> HttpAutoIncrement(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
[DurableClient] IDurableOrchestrationClient starter,
[DurableClient] IDurableEntityClient client,
ILogger log)
{
// Function input comes from the request content.
var input = new CounterParameter { OperationName = "Increment" };
string instanceId = await starter.StartNewAsync("FunctionOrchestrator", input);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
await starter.WaitForCompletionOrCreateCheckStatusResponseAsync(req, instanceId);
var entityId = new EntityId("Counter", "myCounter");
try
{
// An error will be thrown if the counter is not initialised.
var stateResponse = await client.ReadEntityStateAsync<int>(entityId);
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(stateResponse.EntityState.ToString())
};
}
catch (System.NullReferenceException)
{
return new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent("Counter is not yet initialised. "
"Initialise it by calling increment or decrement HTTP Function.")
};
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/359448.html
