【问题标题】:Azure storage 'Lease' - correct exception approachAzure 存储“租约” - 正确的异常方法
【发布时间】:2021-06-19 23:24:04
【问题描述】:

我正在开发 NET Core Web 应用程序,我正在使用 blob 存储一些可以在请求期间修改的对象。我必须防止对一个对象的多个并行访问,所以我将“租用”添加到我的存储集成中。 实际上,当我收到请求时,会从带有租约的 blob 中获取一个对象一段时间。在请求结束时,此对象在存储中更新并删除租约 - 非常简单。 但是什么是正确的异常处理? 当请求中间发生一些异常时,我正面临这个问题,租约没有被释放。我试图实现释放到 dispose (在我控制从 blob 获取和租赁的某个类中)。但是当抛出未处理的异常时,这不会执行。 添加 try/catch/finally 对我来说似乎并不干净。我的问题是你知道一些最好的常见方法如何在最终请求中释放租约吗?谢谢

【问题讨论】:

  • 几个问题:1)您认为您的代码需要多长时间来处理请求,即您需要多长时间才能获得租约? 2) 您目前的租约期限是多少?
  • 您好,感谢您的回复。请求以毫秒为单位完成。在边缘情况下,它达到 2 秒。所以,我将租约设置为 15 秒(据我所知可能是最小值)
  • 如果您设置的租约为 15 秒,并且由于某种原因未能打破租约,它将在 15 秒后自动释放。您应该在工作完成后立即尝试解除租约,但如果失败,您知道租约最终会被破坏。
  • 问题是我等不及 15 秒。当客户致电原因 exc。在请求的中间,他自然会立即一次又一次地尝试。他不是在等待15秒。但是每个下一个请求都会停止,因为自第一个失败请求以来就存在租约。这就是为什么我需要在第一次请求期间删除租约。
  • 明白。其他可能的解决方案是将租约 ID 发送回客户端(以防在破坏租约时出错)并让客户端将此租约 ID 与请求一起发回。如果请求中存在租约 id,您应该首先尝试使用该租约 id 打破租约,获取新租约,然后尝试执行操作。不是最理想的解决方案,但我认为应该可以解决问题。

标签: c# .net-core azure-storage azure-blob-storage


【解决方案1】:

根据您的描述,我为您编写了一个关于租约和中断租约的简单演示,只需尝试以下代码:

using System;
using Azure.Storage.Blobs;
using Microsoft.AspNetCore.Mvc;
using Azure.Storage.Blobs.Specialized;
using System.Threading;

namespace getSasTest.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class editBlob : ControllerBase
    {
        [HttpGet]
        public string get()
        {
            var connstr = "";
            var container = "";
            var blob = "";
            
            var blobClient = new BlobContainerClient(connstr,container).GetBlobClient(blob);

            var leaseClient = new BlobLeaseClient(blobClient);
            try
            {
                //auto break lease after 15s
                var duration = new TimeSpan(0, 0, 15);
                leaseClient.Acquire(duration, null);

            }
            //if some error occurs, request ends here
            catch (Azure.RequestFailedException e)
            {
               
                if (e.ErrorCode.Equals("LeaseAlreadyPresent"))
                {
                    return "Blob is under process,it will take some time,please try again later";
                }
                else
                {
                    return "some other Azure request errors:"+ e.Message;
                }

            }
            catch (Exception e) { 
                    return "some other errors:" + e.Message;
            }

            //mock time consumption to process blob
            Thread.Sleep(10000);

            //break relase first if process finishs in 15s.
            leaseClient.Break();

            return "Done";
        }
    }
}

【讨论】:

  • 谢谢你的例子。不幸的是,我看不到我的问题的解决方案。我不能将责任转移到使用我正在处理的 API 的客户身上。我的要求很简单:1)一次拒绝对同一个 blob 的多次访问。 2) 如果出现任何错误,释放 blob 可立即用于下一个 incommig 请求。应用程序在请求开始时获取租约并将 blob 提取到内存中。然后对象被一些 BL 修改,然后在最后一步更新 blob 并删除租约。
【解决方案2】:

所以,根据您的要求,当检测到一些怪异(无论这对您意味着什么)时,您是否不能授权一方/cron/event(注册事件/ttl 处理程序?)来中断租约。看起来您真的很担心“模式”是否正确?

这应该补充正确性。

在实践中,异常处理策略应提供足够的可操作信息。

对于某些人来说,这意味着:

  • E -> E - 1(摘要或无摘要)-> E - 2(摘要或无摘要)..

这样:

  • E - n:异常,在一定的嵌套级别
  • digest:你会传播这个还是消化并继续前进?

打破租约(本质上是程序的正确性)并不意味着你会妨碍你的优雅版本。

每个服务通常是一对服务:

  • 服务本身
  • 服务清理处理程序 1 到 n
  • 服务边缘案例处理程序 1 到 n
  • 服务入门
  • 等等……

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 2011-12-24
    • 1970-01-01
    相关资源
    最近更新 更多