云计算设计模式(二十四)——仆人键模式

云计算设计模式(二十四)——仆人模式


使用一个令牌或密钥,向客户提供受限制的直接访问特定的资源或服务,以便由应用程序代码卸载数据传输操作。这个模式是在使用云托管的存储系统或队列的应用中特别有用,并且可以最大限度地降低成本,最大限度地提高可扩展性和性能。

背景和问题


客户端程序和网络浏览器经常需要读取和写入文件或数据流,并从一个应用程序的存储空间。通常,应用程序将处理的运动数据,或者通过从存储读取它,并将其传输到客户端,或通过从客户机读取该载流并将其存储在数据存储中。然而,这种方法吸收了宝贵的资源,如计算,存储和带宽。

数据存储要处理的上载和直接数据的下载,而不需要对应用程序执行任何处理移动至该数据的能力,但是这通常需要在客户端能够访问该存储区中的安全凭证。虽然这可能是一种有用的技术来减少数据传送费用的要求进行扩展的应用,并以最大化性能,这意味着应用程序不再能够管理的数据的安全性。一旦客户端已到数据存储器进行直接访问的连接,应用程序不能充当看门人。它不再是在该方法的控制,并且不能防止随后上载或下载的数据存储中。

这不是,可能需要使用不受信任的客户的现代分布式系统实事求是的态度。相反,应用程序必须能安全地控制对数据的访问是粒状的方法,但仍然通过设置此连接,然后使客户端能够直接与数据存储来执行所需的读或写操作的通信降低服务器上的负载。

 

解决方案


要解决控制访问的数据存储在那里的商店本身无法管理身份验证和客户授权的问题,一个典型的解决方案是限制访问的数据存储的公共连接,并提供客户端用钥匙或令牌数据存储本身可以验证。

这个密钥或令牌通常被称为仆人键。它提供了对特定资源的时间限制的访问中,仅允许预定的操作,例如读取和写入到存储或队列,或上载和下载的Web浏览器。应用程序可以创建和发行代客键客户快速,方便地设备和网络浏览器,允许客户端,而无需应用程序直接处理数据传送执行所需的操作。这消除了处理开销,并且在性能和可扩展性所造成的影响,从该应用程序和该服务器。

客户端使用该令牌来访问特定资源中的数据存储为只有特定的时期,并与访问权限的特定的限制,如示于图1中指定的时间后,将键变为无效并且不会允许后续访问该资源。

图1  - 模式概述


另外,也可以配置具有其他依赖关系,如该数据的位置的范围的一个关键。例如,根据不同的数据存储能力,所述键可在数据存储区指定一个完整的表格,或在表中仅特定的行。在云存储系统中的密钥可以指定一个容器,或只是一个特定项目的容器内。

键,也可以由应用程序无效。这是一种有用的方法,如果客户端通知该数据传送操作完成的服务器。然后,服务器可以是无效键,以防止将其用于任何后续访问的数据存储中。

使用这种模式可以简化管理对资源的访问,因为没有要求创建和验证用户,授予权限,然后再删除用户。它也可以很容易地限制的位置,允许,和有效期,所有通过简单地产生一个合适的键在运行时。的重要因素是限制的有效期,以及资源的特别的位置,尽可能紧,以使接收方可以将其用于仅在预定的目的。

问题和注意事项


在决定如何实现这个模式时,请考虑以下几点:
•管理密钥的有效性状态和时期。最关键的是不记名票据,如果泄露或泄露,有效地解除锁定目标项目,并使其可用于在有效期内恶意使用。一键通常可撤销或无效,这取决于它是如何发出的。服务器端的策略可以被改变,或者在最终的情况下,服务器键入其用可被无效签名。指定一个短有效期,尽量减少使后续的无端操作来发生对数据存储的风险。然而,如果在有效期太短时,客户端可能无法在密钥过期之前完成该操作。允许授权用户如果多次访问所需的受保护资源的有效期间过期之前更新的关键。
•访问控制的关键将提供的水平。典型地,该键应允许用户执行仅需要完成操作的行动,诸如只读访问,如果客户端不应该能够将数据上传到数据存储器。文件上传时,通常指定一个键,它提供只写权限,以及位置和有效期。至关重要的是要精确地指定资源或资源集到的关键应用。
•考虑如何控制用户的行为。实施这种模式是指控制一定的损失转移到哪些用户有权访问的资源。控制的可施加的电平是由可用于该服务或目标数据存储区中的策略和许可的能力的限制。例如,它通常是不可能创建密钥,限制数据的大小将被写入到存储,或者次数的密钥可用于访问文件的数目。这可导致由预期客户所使用,即使和可能是由在可能会导致重复上载或下载的代码的错误将导致数据传输巨大意想不到的成本。限制次数的文件可以被上载或下载的,可能有必要在可能情况下的数量,能够强制客户端,当一个操作完成后,通知该应用程序。例如,某些数据存储引发事件的应用程序代码,可用于监视操作和控制的用户行为。然而,它可能是很难执行对个人用户的配额在多租户场景,其中相同的密钥从一个租户使用的所有用户。
•验证和可选消毒,所有上传的数据。该收益的关键访问一个恶意用户可以上传,旨在进一步降低了系统的数据。可替换地,授权用户可上载的数据是无效的,并在处理时,可能会导致错误或系统故障。为了防止这一点,确保所有上传的数据进行验证,并检查使用前恶意内容。
•审核所有操作。许多基于密钥的机制可以登录的操作,如上传,下载,和失败。这些日志通常可以并入一个审核过程,并且还用于计费,如果基于文件大小或数据量的用户被收取费用。使用日志来检测可能是由与键提供的一个存储的访问策略,或者意外移开问题导致验证失败。
•提供关键安全。它可以被嵌入在用户激活在web页面的URL,或者可以在一个服务器重定向操作中使用,以便自动进行下载。始终使用HTTPS传送的关键在一个安全通道。
•保护敏感数据在传输过程中。通过应用程序发送的敏感数据通常会发生使用SSL或TLS,这应该被强制执行的客户端直接访问数据存储。

其他问题要注意实现这个模式的时候是:
•如果客户端没有,或者无法通知操作完成的服务器,唯一的限制是关键的到期期限,该应用程序将无法执行审计业务,如计算上载或下载的数量,或防止多个上传或下载。
•可以生成可能是有限的关键策略的灵活性。例如,一些机制可以允许只使用一种定时期满期。其他人可能无法以指定读/写权限的足够的粒度。
•如果指定的开始时间的键或令牌有效期限,确保它是比当前的服务器时间,以允许客户端时钟,可能会稍微超出同步早一点。如果没有指定,则默认通常是当前服务器时间。
•包含密钥的URL将被记录在服务器日志文件中。而键通常已过期的日志文件进行分析之前,请确保您限制对它们的访问。如果日志数据发送到监控系统或存储在另一位置中,需要考虑的延迟,以防止密钥的泄漏,直至经过其有效期限已经过期。
•如果客户端代码,在Web浏览器中运行,浏览器可能需要支持跨域资源共享(CORS),使Web浏览器中执行访问的数据从该服务的网页源域不同的域代码。一些旧的浏览器和一些数据存储不支持CORS,和代码运行在这些浏览器可能无法使用仆人键,提供对数据的访问在不同的领域,比如云存储帐户。

 

 

 

何时使用这个模式


这种模式非常适合于以下几种情况:
•为了最大限度地减少资源负荷,最大限度地提高性能和可扩展性。使用仆人键不要求资源被锁定,没有远程服务器呼叫是必需的,有对可发出仆人键的数目没有限制,并且其避免了单点,将出现从执行数据失败的传送通过应用程序代码。创建仆人键通常是签订一个字符串键的简单加密操作。
•为了最大限度地降低运营成本。支持直接访问存储和队列是资源与成本效率,可以导致更少的网络往返,并且可以允许在所需的计算资源的数量的减少。
•当客户定期上载或下载数据,特别是在有一个大的体积,或当每个操作涉及大量的文件。
•当应用程序具有有限的计算资源可用,或者是由于托管限制或成本的考虑。在这种情况下,该模式是更有利的,如果有很多并发的数据上传或下载,因为它会减轻,从处理数据传输的应用。
•当数据被存储在远程数据存储装置或不同的数据中心。如果该应用程序被要求作为一个看门者,有可能是因为数据中心之间传送数据的额外的带宽,或通过客户端和应用程序之间的公共或专用网络的电荷,然后将应用程序和数据存储之间。

这种模式可能不适合于下列情况:
•如果应用程序必须对数据执行一些任务之前将其存储或将其发送到客户端之前。例如,应用程序可能需要执行验证,登录访问成功,或者对数据进行变换。然而,一些数据存储和客户端都能够进行谈判,并进行简单的变换,如压缩和解压(例如,Web浏览器通常可以处理gzip等格式)。
•如果现有的应用程序的设计和实施,使得它难以和昂贵的工具。使用这种模式通常需要用于传送和接收数据的一个不同的体系结构方法。
•如果有必要保持审核跟踪或控制的执行数据传送操作的次数,并在使用代客关键机制不支持该服务器可用于管理这些操作的通知。
•如果有必要,以限制该数据的大小,特别是在上载操作。唯一的解决方法是为应用程序来检查数据的尺寸后,在操作完成后,或在指定时间或按计划检查上传的大小。

例子

微软Azure支持共享访问签名(SAS)对Azure存储的细粒度的访问控制,数据的blob,表和队列,并为服务总线队列和主题。一个SAS令牌可配置为提供特定的访问权限,如读,写,更新和删除特定表;一个键范围的表内;队列;一个blob;或BLOB容器。有效期可以是一个指定的时间段,或没有时间限制。

天青SAS还支持可与特定资源相关联,如表或斑点服务器存储访问策略。这个特征提供了额外的控制和灵活性相比,应用程序生成的SAS令牌,并且应该尽可能使用。在服务器中存储策略中定义的设置可以在不发出新的令牌来改变,并反映在无需将发行新令牌的令牌,但在令牌本身定义的设置不能被改变。这种方法还使得有可能撤销有效的SAS令牌之前它已经过期。

注意:

欲了解更多信息,请参阅表介绍SAS(共享访问签名),队列SAS和更新的Blob SAS在Azure存储团队博客和共享访问签名,第1部分:了解SAS型号MSDN上。

下面的代码演示了如何创建一个SAS的有效期为5分钟。该GetSharedAccessReferenceForUpload方法返回一个SAS可用于将文件上传到Azure的Blob存储。

public class ValuesController : ApiController
{
  private readonly CloudStorageAccount account;
  private readonly string blobContainer;
  ...
  /// <summary>
  /// Return a limited access key that allows the caller to upload a file 
  /// to this specific destination for a defined period of time.
  /// </summary>
  private StorageEntitySas GetSharedAccessReferenceForUpload(string blobName)
  {
    var blobClient = this.account.CreateCloudBlobClient();
    var container = blobClient.GetContainerReference(this.blobContainer);

    var blob = container.GetBlockBlobReference(blobName);

    var policy = new SharedAccessBlobPolicy
    {
      Permissions = SharedAccessBlobPermissions.Write,

      // Specify a start time five minutes earlier to allow for client clock skew.
      SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-5),

      // Specify a validity period of five minutes starting from now. 
      SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(5)
    };

    // Create the signature. 
    var sas = blob.GetSharedAccessSignature(policy);

    return new StorageEntitySas
    {
      BlobUri = blob.Uri,
      Credentials = sas,
      Name = blobName
    };
  }

  public struct StorageEntitySas
  {
    public string Credentials;
    public Uri BlobUri;
    public string Name;
  }
}


 

注意:

在ValetKey解决方案提供下载本指导意见提供包含此代码的完整样本。在此溶液中ValetKey.Web项目包含一个Web应用程序,包括如上所示的ValuesController类。使用该Web应用程序检索SAS键,将文件上传到Blob存储的样本客户端应用程序是在ValetKey.Client项目中可用。

本文翻译自MSDN:http://msdn.microsoft.com/en-us/library/dn568102.aspx

 

<think>嗯,用户之前问过关于三个商人和三个随从过河问题的Python实现,现在他们想推广到四个商人和四个随从的情况。我需要先回顾一下原来的问题解决方案,然后看看哪些部分需要调整。 首先,原来的状态是(left_m, left_c, boat_position),其中商人、随从的数量和船的位置。现在问题规模变大了,从3变成4。所以状态表示应该还是类似的,但是数值范围扩大到了0-4。这点需要在代码中修改初始状态和目标状态,比如初始状态是(4,4,0),目标则是(0,0,1)。 接下来,合法移动的规则可能需要调整吗?原来的移动方式是[(1,0), (2,0), (0,1), (0,2), (1,1)],也就是每次过河的可能人数组合。这里可能需要确认,当人数增加到四个时,是否允许更多的移动方式,比如带3个人?不过根据经典问题,通常船只能载两人,所以移动方式应该不变。但用户的问题里可能假设船还是只能载两人,所以保持原来的移动方式,但需要确认是否正确。 然后安全条件的验证。原来的条件是两岸的商人数量必须大于等于随从,或者商人为零。这部分逻辑应该保持不变,只是数值范围扩大到了4。所以在is_valid函数中,需要调整右岸的计算方式,比如right_m = 4 - m,right_c =4 -c。 另外,在生成下一个状态的时候,原来的代码中检查dm + dc是否在{1,2}中,这是因为船最多载两人。这部分逻辑应该不需要改变,因为船容量不变。 然后需要测试当商人数量增加到4时,是否有解。根据经典问题,当商人和随从人数超过3且船容量为2时,可能没有解。比如四个商人和四个随从的情况下,可能无法找到安全过河的路径。这可能需要验证,或者用户可能希望代码能处理这种情况,即使没有解也能正确返回。 所以在代码修改后,可能会出现无解的情况。因此,在解决函数中需要处理这种情况,返回None或者提示无解。用户可能想知道是否存在解,或者如何处理这种情况。 另外,原来的代码中使用的是广度优先搜索,这仍然适用,因为需要找到最短路径。状态空间增大,可能会影响性能,但四个商人和四个随从的情况应该还是可以处理的,因为状态总数是5(商人)*5(随从)*2(船的位置)=50种状态,不会太多。 现在需要修改代码中的初始状态、目标状态,以及右岸人数的计算。同时,在安全验证时,检查是否商人数量>=随从数量或商人为0。这部分逻辑保持不变,但数值范围变化。 测试代码是否正确,可能需要手动验证几个中间步骤,比如当有四个商人和四个随从时,某些移动是否会导致不安全的状态。例如,如果带两个随从过河,左岸剩下四个商人和两个随从,这时候商人数量4大于随从数量2,是安全的。但右岸有0商人和2随从,也是安全的,因为商人数量为0。 不过当人数增加到四个时,可能存在中间状态导致无法继续的情况。例如,当船在右岸,需要带回商人或随从来继续运输,但可能无法满足安全条件。 因此,修改代码后,运行可能会发现没有解,或者找到一条可行的路径。根据已有的知识,四个商人和四个随从在船容量为2的情况下是没有解的,所以用户可能需要了解这一点,或者代码需要处理这种情况。 总结来说,用户的问题是如何将原来的三个商人和三个随从的问题推广到四个的情况,可能需要调整状态表示和数值,同时验证是否存在解。此外,需要说明在这种情况下是否存在可行解,或者问题是否有解的条件是什么。</think>以下是针对 **4商人4随从过河问题** 的Python实现及分析,重点说明与原问题的差异及解决方案: --- ### **1. 问题建模调整** - **状态表示**:`(left_m, left_c, boat_position)` - `left_m`:左岸商人数量(0-4) - `left_c`:左岸随从数量(0-4) - `boat_position`:船的位置(0=左岸,1=右岸) - **目标**:从初始状态 `(4, 4, 0)` 到目标状态 `(0, 0, 1)` --- ### **2. 关修改点** #### **2.1 安全条件验证** 两岸需满足: $$ \text{商人数量} \geq \text{随从数量} \quad \text{或} \quad \text{商人数量} = 0 $$ 代码调整: ```python def is_valid(state): m, c, _ = state right_m = 4 - m # 原3改为4 right_c = 4 - c return (m >= c or m == 0) and (right_m >= right_c or right_m == 0) ``` #### **2.2 初始状态与目标** ```python start = (4, 4, 0) # 原3改为4 target = (0, 0, 1) ``` --- ### **3. 完整代码实现** ```python from collections import deque def is_valid(state): m, c, _ = state right_m = 4 - m right_c = 4 - c return (m >= c or m == 0) and (right_m >= right_c or right_m == 0) def get_next_states(current): m, c, boat = current next_states = [] # 保持移动规则:船最多载2人 for dm, dc in [(1,0), (2,0), (0,1), (0,2), (1,1)]: if boat == 0: # 船在左岸,向→移动 new_m = m - dm new_c = c - dc else: # 船在右岸,向←移动 new_m = m + dm new_c = c + dc # 确保人数非负且符合移动规则 if 0 <= new_m <= 4 and 0 <= new_c <= 4 and (dm + dc) in {1, 2}: new_state = (new_m, new_c, 1 - boat) if is_valid(new_state): next_states.append(new_state) return next_states def solve(): start = (4, 4, 0) target = (0, 0, 1) queue = deque([(start, [])]) visited = set() visited.add(start) while queue: current, path = queue.popleft() if current == target: return path + [current] for next_state in get_next_states(current): if next_state not in visited: visited.add(next_state) queue.append((next_state, path + [current])) return None # 无解 solution = solve() if solution: for step in solution: print(step) else: print("无解") ``` --- ### **4. 结果分析** #### **4.1 运行结果** 代码将输出 **`无解`**,因为经典问题中: **当商人数量 $N \geq 4$ 且船容量为2时,无法找到安全路径** (数学可证明,随从数量超过船容量时必然存在不安全状态) #### **4.2 无解原因** - **关冲突**:每次最多带2人过河,无法平衡两岸的 **商人≥随从** 条件 - **示例矛盾点**: - 若尝试先送2随从到右岸,左岸剩4商2随,右岸0商2随(安全) - 但需带至少1人返回左岸时,右岸随从数量将超过商人(导致冲突) --- ### **5. 扩展讨论** #### **有解条件** - **船容量 ≥3**:若船可载3人,4商人4随从问题可能有解 - **减少人数**:$N=3$ 时问题有解(原问题已验证) #### **算法优化方向** - **启发式搜索**:使用A*算法加速路径搜索 - **剪枝策略**:预判无效移动(如反复横跳) --- ### **6. 核心结论** 1. **原问题推广到4人时无解**(船容量2限制) 2. **安全验证逻辑需严格满足** $m \geq c$ 或 $m=0$ 3. **代码可复用于其他规模问题**(修改初始状态即可) 如需进一步验证或调整参数(如船容量),可修改代码中的移动规则和安全条件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值