精华内容
下载资源
问答
  • 安全上下文

    千次阅读 2015-04-21 21:05:23
    (一)、类型强制策略的安全上下文 所有的操作系统访问控制都是基于与主体和客体相关的访问控制属性的。在SELinux中,访问控制属性杯称作安全上下文。所有的客体(文件,进程间通信,通信管道,套接字,网络主机等...

    (一)、类型强制策略的安全上下文
    所有的操作系统访问控制都是基于与主体和客体相关的访问控制属性的。在SELinux中,访问控制属性杯称作安全上下文。所有的客体(文件,进程间通信,通信管道,套接字,网络主机等)和主体(进程)有一个和他们相关的单一安全上下文。一个安全上下文有三个元素:用户,角色和类型标识符。指定和显示一个安全上下文常用的格式如下:

    用户(user):角色(role):类型标识符(type)

    每一个元素的字符串标识符杯定义在SELinux的策略语言中,策略语言的细节后面慢慢讨论。就现在来说,仅仅理解一个有效的安全上下文一定要有一个有效的用户,角色和类型标识符,并且标识符被策略书写者定义。每一个标识符的命名空间都是正交的。(所以,举个例子,用户,角色和类型有相同的字符串标识符是可以的,但是不推荐使用。)

    检查安全上下文:
    SELinux通过添加-Z选项修改了系统命令来展示主体和客体的安全上下文。例如,ls -Z 显示了文件系统对象的安全上下文,ps -Z展示了进程的安全上下文。另外一个有用的命令是 id,他展示你的shell的安全上下文(也就是说,你的当前的用户,角色和类型)。下面的例子展示了一个运行在SELinux中的shell的安全上下文。

    $ id -Z
    joe:user_r:user_t

    你可以在你自己的SELinux中使用这些命令,正如我们在这一章节中使用的一样。

    (二)、SELinux和标准Linux比较

    此时此刻,比较在标准Linux和SELinux中的访问控制属性是非常有用的。为了简单起见,我们坚持使用常用的文件系统对象,例如文件和目录。在标准Linux中,主体的进程访问属性是通过进程结构体提供的在linux内核中所有进程的真实有效的用户ID和组ID。这些属性被内核所保护着,并且经过一些列的控制方式来设置。包括登录进程和setuid程序。对于客体来说,文件的索引节点包含着一系列的访问模式位和文件的用户ID和组ID,前者是基于三个读/写/可执行位的集合来实现控制访问,这三个分别代表文件拥有者,文件组和其他任何人。后者决定了文件的所有者和组来决定对于一个给定的访问尝试应该使用哪一个位集合。

    正如前面所述,在SELinux中,访问控制属性他基本上就是安全上下文。所有的客体和主体有一个相关的安全上下文。标准Linux使用进程的用户/组ID,文件访问模式位和文件用户/组ID来同意或者是拒绝访问,SELinux使用进程和客体的安全上下文来进行访问控制。更具体的说,由于SELinux的主要访问控制特征是TE,即类型强制策略,安全上下文中的类型标识符被用来决定访问。

    注意:
    SELinux是在标准Linux之上添加的类型强制机制。也就是说标准Linux和SELinux访问控制都必须满足才能访问客体。所以,例如,我们有SELinux对于文件的一个写权限,但是没有标准linux的写权限,我们依然不能想文件中写入数据。

    下面的表列出了标准Linux和SELinux的一些区别:

    这里写图片描述

    (三)、关于安全上下文更多的信息

    安全上下文是一个简单的,一致的访问控制属性。在SELinux中,类型标识符是安全上下文中决定访问的主要的部分。由于历史原因,进程的类型经常被称作域(domain)。使用域和域类型来代表进程的类型是比较普遍的,所以我们不可避免的要是用术语“域”。大体上,认为域,域类型,主体类型和进程类型是同义的。

    在安全上下文中的用户标识符和角色标识符在访问控制策略中起很小的作用,因为是类型强制策略而不是约束条件强制策略,约束条件强制策略我们将在第七章中讨论。对于进程来说,用户标识符和角色标识符是非常有趣的。

    因为他们被用来控制用户标识符和Linux用户账户的类型相关联的。对于客体来说,用户标识符和角色标识符几乎没用。作为一个公约,一个客体的角色通常是 object_r ,一个客体的用户通常是创建该客体的进程的用户标识符。他们在访问控制中没有作用。

    最后,要知道标准Linux中的用户ID和SELinux在安全上下文中的用户标识符的不同。技术上,他们是完全正交的标识符,被标准的访问控制机制和安全增强型的访问控制机制分别使用。他们之间的任何联系都是通过登录进程按照公约严格提供的,而不是被SELinux策略直接实施的。

    展开全文
  • DDD—上下文映射图

    千次阅读 2019-11-17 16:34:22
    一个项目的上下文映射图(Context Map)可以用两种方式表示, (1)比较容易的一种是画一个...1、上下文映射图为什么重要 在开始采用DDD时,首先应该为你当前的项目绘制一个上下文映射图,其中应该包含你项目中当...

    一个项目的上下文映射图(Context Map)可以用两种方式表示,
    (1)比较容易的一种是画一个简单的框图来表示两个或多个限界上下文之间的映射关系。该框图表示了不同的限界上下文在解决方案空间中是如何通过集成相互关联的。

    (2)另一种更详细的方式通过限界上下文集成的源代码实现来表示。

    1、上下文映射图为什么重要

    在开始采用DDD时,首先应该为你当前的项目绘制一个上下文映射图,其中应该包含你项目中当前的限界上下文和它们之间的集成关系。下图表示一个抽象的上下文映射图,后文将不断地向里面添加细节内容。

    在这里插入图片描述

    比如,当你为一个大型企业进行限界上下文之间的集成时,你可能需要与大泥球进行交互。大泥球的维护团队才不关心你的项目呢,因为你依赖于他们的API、因此,他们并不会深入到你的上下文映射图中,然而你的映射图依然需要反映出和他们的集成关系,因为这样可以使你了解到映射图的内部,并且可以指明在哪些地方需要与其他团队进行交流。这样对你团队的成功是有帮助的。

    假定你期望大泥球维护团队提供一套新的API。然而,他们并不打算这样做。此时你的团队和大泥球的维护团队的关系便成了客户方-供应方的关系。由于大泥球团队决定维持现状,你的团队不得不陷入一种遵奉者关系中。尽早绘制上下文映射图,这样可以迫使呢仔细思考你的项目和你所依赖项目之间的关系。

    CollabOvation团队应该在建模之初就使用上下文映射图,然而当时他们对于战略建模一无所知。后来,通过经验积累,在之后的ProjectOvation中,尝到了建模的甜头。

    上下文映射图表现的是项目当前的状态,如果项目发生变化,你可以更新上下文映射图。注意上下文映射图不需要画得太正式了,手绘即可。

    2、产品和组织关系

    这一节主要重复下,整个专栏的案例说明,详情见:DDD案例说明。

    SaaSOvation公司正在开发的3个产品:

    1、CollabOvation——一款社交协作软件。该产品允许注册用户发布对业务有价值的内容,发布方式是一些流行的基于Web的工具,比如论坛、共享日历、博客和wiki等。这是SaaSOvation公司的旗舰产品,也是该公司的第一个核心域。开发团队后来从CollabOvation中提取了IdOvation模型。对于CollabOvation来说,IdOvation是一个通用子域,而CollabOvation本身又作为ProjectOvation的支撑子域。

    2、IdOvation——一款可重用的身份和访问管理产品。IdOvation为注册用户提供安全的、基于角色的访问管理。这些功能一开始和CollabOvation混合在一起,这样导致的问题是:实现受到了限制,功能不可重用。SaaSOvation对CollabOvation进行了重构,引入了一个新的、结构清晰的限界上下文。SaaSOvation公司决定支持多个租户,这种功能对于SaaS产品来说是至关重要的。对于消费方来说,IdOvation扮演着通用子域的角色。

    3、ProjectOvation——一个敏捷项目管理产品。这是SaaSOvation公司的核心域。ProjectOvation采用基于Scrum的项目运行框架,用户可以创建项目管理资产,同时对项目资产进行分析和设计,还能跟踪项目进度。和CollabOvation一样,ProjectOvation将IdOvation作为一个通用子域来使用。该产品的一大创新是将CollabOvation引入了敏捷项目管理,这样用户可以围绕Scrum的产品、发布、冲刺和待定项展开讨论。

    这些限界上下文之间的关系如何,不同开发团队之间的关系又如何?让我们看下各种关系之间的定义:

    • 合作关系(partnership):如果两个限界上下文的团队要么一起成功,要么一起失败,此时他们需要建立起一种合作关系。他们需要协调开发计划和集成管理。

    • 共享内核(share kernel):对模型和代码的共享将产生一种紧密的依赖性,对于设计来说,这种依赖性可好可坏。我们需要为共享的部分模型指定一个显式的边界,并保持共享内核的小型化。共享内核具有特殊的状态,在没有与另一个团队协商的情况下,这种状态是不能改变的。我们应该引入一种持续集成过程来保证共享内核与通用语言的一致性。

    • 客户方——供应方开发(Customer-Supplier Development):当两个团队处于一种上游-下游关系时,上游团队可能独立于下游团队完成开发,此时下游团队开发可能会受到影响。因此,在上游团队的计划中,我们应该顾及到下游团队的需求。

    • 遵奉者(conformist):在存在上游-下游关系时,如果上游团队已经没有动力提供下游团队之所需,下游团队便孤军无助了。只能盲目地使用上游团队的模型。

    • 防腐层(Anticorruption layer):在集成两个良好的限界上下文时,翻译层可能很简单,甚至可以很优雅地实现。但是,当共享内核、合作关系或客户方-供应方关系无法顺利实现时,此时的翻译将变得复杂。对于下游客户来说,你需要根据自己的领域模型创建一个单独的层,该层作为上游系统的委派向你的系统提供功能。防腐层通过已有的接口与其他系统交互,而其他系统只需要做很小的修改,甚至无须修改。在防腐层内部,它在你自己的模型和他方模型之间进行翻译转化。

    • 开放主机服务(open host service):定义一种协议,让你的子系统通过该协议来访问你的服务。你需要将该协议公开,这样任何与你集成的人都可以使用该协议。在有新的集成需求时,你应该对协议进行改进或者扩展。对于一些特殊的需求,你可以采用一次性的翻译予以处理,这样可以保持协议的简单性和连贯性。

    • 发布语言(published language):在两个限界上下文之间翻译模型需要一种公用的语言。此时你应该使用一种发布出来的共享语言来完成集成交流。发布语言通常与开放主机一起使用。

    • 另谋他路(separateWay):在确定需求时,我们应该做到坚持到底。如果两套功能没有显著的关系,那么它们也可以被完全解耦的。声明两个限界上下文之间不存在任何关系,这样使得开发者去寻找简单的、专门的方法来解决问题。

    • 大泥球(Big Ball of mud):当我们检查已有系统时,经常会发现系统中存在混杂在一起的模型,它们之间的边界是非常模糊的。此时,你应该为整个系统绘制一个边界,然后将其归纳在大泥球范围之列。在这个边界之内,不要试图使用复杂的建模手段来化解问题。同时,这样的系统有可能会向其他系统蔓延,你应该对此保持警觉。

    在与身份与访问上下文集成时,协作上下文和敏捷项目管理上下文均没有采用另谋他路的手法。诚然,在上下文范围之内,另谋他路的手法可以应用在特殊的系统上,同时它也可以用于一些个例。比如,一个团队可能拒绝使用集中式的安全管理系统,但他们依然会与另外类型的安全管理系统集成。

    在集成时,他们将会用到开放主机服务和发布语言,有可能还会用到防腐层。虽然这两者都会在限界上下文之间创建开放的标准,但是它们并不矛盾。通过使用下游上下文中的基本原则,他们依然可以得到由独立翻译所带来的好处,并且不会像与大泥球集成那样复杂。翻译层将变得简单、优雅。

    在上下文映射图中,我们使用以下缩写来表示各种关系:

    • ACL 表示防腐层
    • OHS 表示开放主机服务
    • PL 表示发布语言

    3、映射3个示例限界上下文

    当CollabOvation团队意识到自己已经陷入僵局时,他们研究发现“上下文映射图”的工具非常实用。

    从团队设计的第一张映射图可以看出,他们已经知道应该创建一个名为“协作上下文”的限界上下文。从图中怪异的边界又可以看出,他们可能希望创建第二个限界上下文,但是却不知道如何将这个上下文从核心域中分离出来。
    在这里插入图片描述

    团队成员意识到安全、用户和权限并不属于协作上下文,需要将这些概念从核心域中分离出来,是这些概念只有在得到同意的时候才能进入核心域。

    在对子域进行了分析,或对问题空间进行了评估之后,团队所绘制的上下文映射图如图所示,从一个限界上下文中分离出了两个子域。由于子域和限界上下文最好保持一对一的关系,我们应该将原来的协作上下文分离成两个限界上下文。

    在这里插入图片描述

    对子域和边界的分析要求我们做出决定。当人们需要使用CollabOvation的功能时,他们扮演者时参与者、作者和主持者的身份。有了这样的角色分离,我们便可以绘制一个更高层次的上下文映射图,如图所示。团队使用了分离内核对系统进行重构。

    在这里插入图片描述

    当下一个ProjectOvation项目启动时,团队将使用这个新的核心域——敏捷项目管理上下文来增强已有的上下文映射图,如图所示。

    在这里插入图片描述

    SaaSOvation的开发团队已经对核心的模型分离有了很好的理解。与CollabOvation相似,当ProjectOvation的用户扮演的是产品负责人或团队成员的角色。身份与访问上下文已经从核心域中分离出去了。协作上下文对于ProjectOvation来说只是一个支撑子域。任何时候,这个新的模型都受到了上下文边界的保护,外部概念需要通过翻译才能进入核心域中。

    身份与访问上下文位于最上游,它对协作上下文和敏捷项目管理上下文均会产生影响。同时,协作上下文又是敏捷项目管理上下文的上游,因为后者的模型依赖于前者的模型和服务。

    在限界上下文中我们提到,ProjectOvation将自治地运行,而不会依赖于周边的环境。这并不是说自治服务就可以完全独立于上游模型,而是我们的设计应该尽可能地限制实时依赖性。虽然ProjectOvation是自治的,但是它依然属于其他系统的下游。

    上图中,上游系统的连接框,都标以OHS/PL,分别表示开放主机服务和发布语言。所有下游的连接框都标以ACL,即防腐层。简单地来说,这些集成模式采用以下技术:

    • 开放主机服务:该模式可以通过REST实现。通常来讲,我们可以将开放主机服务看成是远程过程调用(RPC)的API。同时,他也可以通过消息机制实现。

    • 发布语言:发布语言可以通过多种形式实现,但最常见的是使用XML Schema。在使用REST服务时,发布语言用来表示领域概念,此时可以使用XML和JSON。发布语言既可以使用标准的媒体类型进行发布,也可以使用自定义类型。同时,发布语言还可以用于事件驱动架构(Event-Driven Architecture),其中领域事件以消息的形式发送给订阅方。

    • 防腐层:在下游上下文中,我们可以为每个防腐层定义相应的领域服务(Domain Service)。同时,你也可以将防腐层用于资源接口。在使用REST时,客户端的领域服务将访问远程的开放主机服务,远程服务以发布语言的形式返回,下游的防腐层将返回内容翻译成本地上下文的领域对象。比如,协作上下文向身份与访问上下文请求“具有Moderator角色的用户”。所返回的数据可能是XML格式或JSON格式,然后防腐层将这些数据翻译成协作上下文中的Moderator对象,该对象是一个值对象。这个Moderator实例反映的是下游模型中的概念,而不是上游模型。

    由于协作上下文是第一个核心域,让我们把它放大来看看。首先我们将接触到一些简单的集成方式,然后再是更高级的。

    4、协作上下文

    协作上下文作为SaaSOvation公司的第一个核心域。开发团队已经对其有很好的理解了。这里他们使用的集成方式比较简单,但是在可靠性和自治性上还稍逊一筹。要将此上下文映射图进行放大还是相对容易的。

    身份与访问上下文通过REST的方式向外发布服务。作为该上下文的客户,协作上下文通过传统类似于RPC的方式来获取外部资源。协作上下文并不会永久性地记录下从身份与访问上下文中获取来的数据,而是在每次需要数据时重新向系统发出请求。显然,协作上下文高度依赖于远程服务,它不具有自治性。但目前SaaSOvation公司愿意采取这种方式集成,以满足交付计划。由于之后的ProjectOvation项目将使用自治性服务,CollabOvation到时可以借鉴ProjectOvation的做法。

    在这里插入图片描述

    上图是放大后的上下文映射图,下游系统的边界对象采用同步的方式向上游系统获取到资源。当获取到远程数据模型数据之后,边界对象取出所需数据,再将其翻译成适当的值对象实例。

    在这里插入图片描述

    在上图中,翻译图(Translation Map)将所获取数据转化成一个值对象。这里,身份与访问上下文中一个具有Moderator角色的User被翻译成了协作上下文中的Moderator值对象。

    不幸的是,如果由于远程系统不可用而导致同步请求失败,那么本地系统也将跟着失败。虽然REST并不是真正意义上的RPC,但它却具有与RPC相似的特征。彻底的系统失败并不多见,但它却是一个潜在的问题。CollabOvation团队急切地希望解决这个问题。

    5、敏捷项目管理上下文

    为了达到比RPC更高的自治性,敏捷项目管理上下文团队将尽量限制对RPC的使用,此时他们可以选择异步请求,或者事件处理等方式。

    如果系统所依赖的状态已经存在于本地,那么我们将获得更大自治性。有人可能认为这只是对所有依赖对象进行缓存,但这不是DDD的做法。DDD的做法是:在本地创建一些由外部模型翻译而成的领域对象,这些对象保留着本地模型所需的最小的状态集。为了初始化这些对象,我们要有限的RPC调用或REST请求。然而,要与远程模型保持同步,最好的方式是在远程系统中采用面向消息的通知机制。消息通知可以通过服务总线进行发布,也可以采用消息队列或者REST。

    被同步的状态应该是本地模型所需远程模型的最小属性集。这里并不只是限制我们的对数据的需求,还应该对概念进行恰当的建模。

    6、和身份与访问上下文集成

    在这里插入图片描述

    在图中我们看到,对于身份与访问上下文的领域事件,系统将以URI的方式向外发布事件通知。这种功能是通过NotificationResource提供的,它向外发布REST资源。这里的通知资源是一组被发布的领域事件。对于消费方来说,每个事件总是可用的。消费方应该避免对事件的重复消费。

    一个自定义的媒体类型表明客户可以请求两种资源:
    在这里插入图片描述

    通过第一个资源URI,客户可以(使用HTTPGET请求)获取当前的通知日志(一个固定大小的通知集合)。对于自定义的媒体类型:
    在这里插入图片描述

    可以看出,这里的URI是全新的,并且是稳定的,因此它不会改变。无论当前的通知日志中包含了什么样的内容,该URI都会将其发布。

    事实上,ProjectOvation团队并不打算全盘使用REST。比如,他们目前正与CollabOvation团队协商是否可以使用消息机制,例如rabbitMQ。但就目前而言,它们和身份与访问上下文的集成依然是基于REST的。

    现在,让我们忽略技术细节,看看映射图中各个交互对象所扮演的角色。如图表示集成过程的序列图:

    在这里插入图片描述

    • MemberService是一个领域服务,它向本地模型提供ProductOwner和TeamOwner对象,同时作为基本防腐层的接口。maintainService方法用于周期性地检查身份与访问上下文所发出的通知。该方法不由模型的正常用户调用,而是由通知组件周期性地调用,在上图中,MemberSynchronizer表示这样的同步组件,它会把请求委派给MemberService。
    • MemberService进一步把请求委派给IdentityAccessNotificationAdapter,该类在领域服务和远程开放主机服务之间扮演着适配器的角色。该适配器作为远程系统的客户端而存在。与远程系统NotificationResource交互并没有显示在图中。
    • 一旦适配器从远程的开放主机服务获取到了数据,它将调用Member
      Translator的toMember()方法将发布语言中的媒体数据翻译成本地系统中的领域对象Member。如果该对象在本地系统中已经存在,则更新该对象。MemberService的updateMember()方法用于更新一个Member
      对象,此时它把委托操作委派给了自己。Member的子类有ProductOwner和TeamMember,它们反映了本地系统中的上下文概念。

    我们不应该将重点放在技术实现和集成产品上,而应该放在限界上下文之间的分离上,这样我们可以保持每个上下文的纯洁性,同时将一个上下文中的数据用于另一个上下文的概念中。

    让我们看看敏捷管理上下文是如何与协作上下文集成的。同样,我们关注的是系统的自治性,但这给集成带来了更多的困难与挑战。

    ProjectOvation将使用CollabOvation所提供的附加功能,比如论坛和共享日历等。ProjectOvation用户并不直接与CollabOvation交互。对于某租户来说,ProjectOvation必须决定出哪些CollabOvation的功能时该租户可用的。然后,ProjectOvation将协调对CollabOvation资源的创建。

    比如,Forum和Discussion必须在协作上下文进行创建的。在身份与访问上下文中,对象是先前存在的。而对于敏捷项目管理上下文来说,对象是不会预先存在的,直到被请求为止。这对于实现系统自治性来说是一个潜在的障碍,因为我们依赖于协作上下文来远程地创建资源。

    在使用领域事件和事件驱动架构时,我们应该仔细思考最终一致性。本地系统产生的事件通知并不是只能由远程系统消费。在ProjectOvation中,当ProjectInitiated事件产生时,该事件将由本地系统进行处理。本地系统要求Forum和Discussion在远程完成创建。这可以通过RPC或消息机制完成。

    如果项目负责人是图使用一个不存在的Discussion会发生什么问题吗?有时是由于调用失败,有时是由于没有预先付款导致协作功能不可用,这不一定是一个技术原因。对于最终一致性的处理我们应该将其考虑在建模访问之内。

    处理资源不可用的一个好办法便是将其显现出来。考虑以下由标准类型实现的状态和模式。此时的状态是一个值对象。
    在这里插入图片描述
    在该设计中,由DiscussionAvailability定义的状态将对象Discussion其保护作用。当有人是图参加关于一个Product的讨论时,该设计将正确地处理Discussion的状态。如果状态不为READY,参与者将得到以下消息之一:
    (1)要使用团队协作功能,你需要购买附加功能。
    (2)产品负责人还没请求创建产品讨论。
    (3)讨论启动失败,请稍后再试。

    此时,ProjectOvation团队还不清楚采用哪种方式与CollabOvation进行集成。在讨论了客户方-供应方关系后,它们得到了下图:
    在这里插入图片描述

    敏捷项目管理上下文可以使用第二个防腐层来处理与协作上下文之间的集成。事实上CollaborationAdapter并不是单个,此处只是一个占位符,表示有多个适配器。

    敏捷项目上下文在本地有DiscussionService和SchedulingService,它们是领域服务,用于管理协作系统中的讨论和日历条目。

    以上的例子已经展示了上下文映射图的某些细节。

    对于一个非常详细的上下文映射图,我们很有可能无法对其进行实时更新。保持简单性和敏捷性,拒绝繁文缛节,这样我们创建的上下文映射图将对项目起推动作用,而不是阻碍作用。

    展开全文
  • Flask——请求上下文和应用上下文

    千次阅读 2019-08-09 10:06:14
    在flask框架中,引入了上下文的概念,为了能够让大家真实的感受到上下文在flask框架中所到的作用,所以下面我就用一个具体的需求实例来给大家进行说明,首先在我不使用上下文思路的情况下来解决这一需求,然后再...

    在flask框架中,引入了上下文的概念,为了能够让大家真实的感受到上下文在flask框架中所起到的作用,所以下面我就用一个具体的需求实例来给大家进行说明,首先在我不使用上下文思路的情况下来解决这一需求,然后再改造成使用了上下文的方式,那么我们就可以更好的来对比前后的不同,从而感受到上下文的作用、原理、以及给我们带来的好处。
    在实际的开发中,当用户登录之后,就会把用户登录时候的时间,IP地址这些数据记录到数据库里面此用户的名下,那么下面我们就来实际的模拟一下这过程。当然具体写入数据库的操作就不实际的写了,只是打印出来模拟写入数据库的操作即可,因为我们的现在要说的重点上下文的相关概念。以下就是不使用上下文的解决方案。
    在这里插入图片描述当然我们首先需要通过地址 http://127.0.0.1:8111/login?username=xiaoming&passwd=111111 来验证我们的代码。
    在以上代码中,当我们验证了用户名和密码以后就调用了记录用户登录时间和用户登录IP的方法。将记录写入到了数据库里面的该用户的记录下面。我们看到,由于我们需要记录某一用户的登录时间和登录IP,所以我们不得不传递当前用户的信息(用户名)给login_time和login_ip函数中。如果我们有许多类似的函数调用,是不是每个都要传递参数呢?有没有更简化的操作呢?

    这里就要提到我们的应用上下文中的g变量。g是一个全局临时变量。全局指的是同一次request请求,临时指的时,此次request请求一旦消失,g变量也随之消失,再一次request请求又会新生成一个g变量。
    在这里插入图片描述对比上下,大家看到有什么不同呢?我们这次在调用两个函数的时候没有传递username进去,而是直接将变量username赋值给了g下面我们自定义的一个属性g.username。而在两个函数login_time和login_ip内部,我们就直接通过g.username的形式就可以拿到上面传递过来的值。神不神奇?意不意外?这是怎么做到的呢?让我们来解释以下其中的原理。
    首先我们在浏览器中通过地址发起了对login视图函数的请求。而在此视图函数内部,我们又调用了login_time和login_ip这两个函数,那么就意味着我们同在一次request请求当中,而我们上面说了再同一次request请求当中是可以共享全局临时变量g的。

    所以flask框架就给我们提供了这一变量,由于g变量是供我们实例化的app应用(指的是app=Flask(name)存储变量、数据来用的,所以被叫做应用上下文。应用上下文一般是用来保存配置信息,数据库链接,应用信息等的。
    那么再来说以下request,我们同样看到,我们浏览器当中实际请求的时login视图函数,但是我们却从login_ip当中去获取客户端ip地址,request.dict[‘environ’][‘REMOTE_ADDR’])),也就是我们从request对象中包含的字典当中,来取其中的各个属性。那么我们为什么可以这样做呢?这就是我们的请求上下文的概念,虽然login和login_ip是两个函数,但是由于我们在login视图函数当中调用了login_ip,所以他们都归属于同一个请求。在同一个请求的上下文当中,他们是拥有相同的request属性,所以我们可以从login_ip函数中取到此次请求的客户端IP地址。

    所以request属于请求上下文,保存着客户端和服务器交互的数据。而我们上面提到的应用上下文g,主要是帮助request获取当前的应用,伴随着request而生,随request的消失而消失的。
    关于请求上下文,还有session也属于请求上下文,根据我们之前所讲,session是用来保持不同请求之间的状态的,要在不同的请求之间传递用户信息,所以明显能够感觉到session就是为多请求而生的。我们可以在登录请求中写入用户信息到session中,然后我们就可以在用户中心的请求中使用session中的用户信息了。可以看出session就是用来保证多请求在同一会话管道中共享数据的,所以session也是请求上下文。
    另外current_app也是flask提供的应用上下文,里面保存了当前app应用的相关信息,这里我们只来看一下怎么通过current_app获取我们的配置项。我们可以在配置文件setting.py中加入新的配置项:设置分页每页显示数据的个数PER_PAGE=10,我们就可以以下方式拿到这个配置项了。

    在这里插入图片描述这就是我们讲的四个上下文:
    请求上下文:request(记录http请求的相关内容)、session(记录请求会话中的信息)。
    应用上下文:g(在同一次请求上下文中设置临时变量属性,供请求上下文使用)、curent_app(保存当前app相关信息)。

    展开全文
  • 线程上下文切换

    千次阅读 2018-08-29 10:05:04
    一、为什么要减少线程上下文切换  当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行。这种切换称为...

                一、为什么要减少线程上下文切换
                    当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行。这种切换称为“上下文切换”(“context switch”)。CPU会在一个上下文中执行一个线程,然后切换到另外一个上下文中执行另外一个线程。上下文切换并不廉价,是比较耗时的
                二、线程上下文切换发生的条件
                    1.中断处理:中断分为硬件中断和软件中断,软件中断包括因为IO阻塞、未抢到资源或者用户代码等原因,线程被挂起
                    2.多任务处理:每个程序都有相应的时间处理片,当前任务的时间片用完之后,系统CPU正常调度下一个任务
                    3.用户状态切换:这种情况下,上下文切换并非一定发生,只在特定操作系统才会发生上下文切换
                三、上下文切换的步骤
                    1.为了理解为什么上下文切换的时候会损耗性能,我们应该先看看上下文切换的过程中究竟发生了什么。在切换过程中,正在执行的进程的状态必须以某种方式存储起来,这样在未来才能被恢复。这里说的进程状态包括该进程正在使用的所有寄存器(尤其是程序计数器),和一些必要的操作系统数据。保存进程状态的数据结构叫做“进程控制块”(PCB,process control block);
                    2.PCB通常是系统内存占用区中的一个连续存区,它存放着操作系统用于描述进程情况及控制进程运行所需的全部信息,它使一个在多道程序环境下不能独立运行的程序成为一个能独立运行的基本单位或一个能与其他进程并发执行的进程。
                    上下文切换的具体步骤是(假设当前进程是进程A,要切换到的下一个进程是进程B):
                        1.保存进程A的状态(寄存器和操作系统数据);
                        2.更新PCB中的信息,对进程A的“运行态”做出相应更改;
                        3.将进程A的PCB放入相关状态的队列;
                        4.将进程B的PCB信息改为“运行态”,并执行进程B;
                        5.B执行完后,从队列中取出进程A的PCB,恢复进程A被切换时的上下文,继续执行A。
                        6.线程分为用户级线程和内核级线程。同一进程中的用户级线程切换的时候,只需要保存用户寄存器的内容,程序计数器,栈指针,不需要模式切换。但是这样会导致线程阻塞和无法利用多处理器。而同一进程中的内核级线程切换的时候,就克服了这两个缺点,但是除了保存上下文,还要进行模式切换。
                    线程切换和进程切换的步骤不同。进程的上下文切换分为两步:1.切换页目录以使用新的地址空间;2.切换内核栈和硬件上下文。对于linux来说,线程和进程的最大区别就在于地址空间。对于线程切换,第1步是不需要做的,第2是进程和线程切换都要做的。所以明显是进程切换代价大。线程上下文切换和进程上下文切换一个最主要的区别是线程的切换虚拟内存空间依然是相同的,但是进程切换是不同的。这两种上下文切换的处理都是通过操作系统内核来完成的。内核的这种切换过程伴随的最显著的性能损耗是将寄存器中的内容切换出。
                四、如何减少线程上下文切换
                        1.无锁并发编程:多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据。 
                        2.CAS算法:Java的Atomic包使用CAS(compare and swap)算法来更新数据,而不需要加锁。 
                        3.使用最少线程:避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态。 
                        4.协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。

    一、上下文切换
        1.即使是单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停的切换线程执行,让我们感觉多个线程是同时执行的,时间片一般是几十毫秒。
        2.CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是在切换之前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的状态。所以任务从保存到再加载的过程就是一次上下文切换。
    二、多线程并不一定快
    三、测试上下文切换的次数和时长
        1.通过Lmbench3测量上下文切换的次数
        2.通过vmstat测量上下文切换的次数
    五、避免死锁的常见方法
        1.避免一个线程同时获取多个锁
        2.避免一个线程在锁内同时占用多个资源
        3.尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制
        4.对于数据库锁,加锁和解锁必须在一个数据库连接中,否则会出现解锁失败的情况
    六、资源限制的挑战
        1.什么是资源限制:资源限制是指在进行并发编程的时候,程序的执行速度受限于计算机硬件资源或软件资源。例如:硬件资源限制有带宽的上传和下载速度、硬盘读写速度和CPU的处理速度,软件资源限制有数据库的连接数和socket连接数等
        2.资源限制引起的问题:在并发编程中,将代码执行速度加快的原则是将代码中串行执行的部分变为并发执行,但是如果将某段串行的代码并发执行,因为受限于资源,仍然在串行执行,这个时候系统性能反而会变慢,因为增加了上下文切换和资源调度的时间。
        3.如何解决资源限制的问题:对于硬件资源限制,可以考虑使用资源池将资源服用。
        4.在资源限制下进行并发编程:如何在资源限制的情况下,让程序执行的更快呢?根据不同的资源限制调整程序的并发度。

    展开全文
  • 上下文切换技术

    千次阅读 2016-10-10 18:50:46
    简述 在进一步之前,让我们先回顾一下各种上下文切换技术。...当我们说“上下文切换”的时候,表达的是一种从一个上下文切换到另一个上下文执行的技术。而“调度”指的是决定哪个上下文可以获得接下去的CPU时
  • Android之所以不同于java,源于java工程简单,随便一个main方法便可运行起来,而android工程需要依赖一些特定的android环境,在此环境中需要衔接好各组件的正常运作,context起着至关重要的作用。 获取上下文有三种...
  • windbg中所谓的上下文

    千次阅读 2017-06-17 23:34:30
    为了深入了解背后的含义,我翻开windbg帮助文档,发现其进程/寄存器上下文的解释最为晦涩。只能通过实际的练习,趟石子过河,最后记录下自己的总结。  windbg中与进程上下文相关的命令是.process,与寄存器...
  • CSS基础:CSS的上下文之BFC

    万次阅读 2021-02-24 14:34:36
    看到这个名词,可能会有些陌生,但其实 上下文 = 区域,如果这么理解的话就会有行级上下文、块级上下文、flex上下文等等有一定排列规则的区域,我们今天只聊一聊 块级格式化上下文(BFC) 一、什么是BFC? BFC全称...
  • 每一个OpenGL上下文都关联有一个绘图表面,GPU命令就是作用在绘图表面上的。不同用途的OpenGL上下文关联的绘图表面不一样,例如用于离屏渲染的OpenGL上下文关联的绘图表面可以用Pbuffer描述,而用于屏幕渲染的OpenGL...
  • 上下文无关文法、上下文有关文法

    千次阅读 2014-01-17 02:24:59
    一直被这两个绕,现在...(任何产生规则的左手端和右手端都可以被终结符和非终结符的上下文所围绕,乔姆斯基描述自然语言的一种方式介入的,在自然语言中一个单词是否可以出现在特定的位置要依赖于上下文。)  
  • 什么是设备上下文

    千次阅读 2008-10-21 16:31:00
    关于设备场景,叫法颇多,有些书说为设备环境、显示场景,更常见的叫做设备描述表或设备描述体...而实质,widnows下的所有绘图都是通过设备场景进行的,而不是直接窗口和设备本身进行。为了说明设备场景,很多书
  • 对于服务器的优化,很多人都有自己的经验和见解,但就我观察,有两点常常会被人忽视 – 上下文切换 和 Cache Line同步 问题,人们往往都会习惯性地把视线集中在尽力减少内存拷贝,减少IO次数这样的问题上,不可否认...
  • Qt学习—qt上下文菜单显示

    千次阅读 2015-12-30 10:17:04
    Qt学习—qt上下文菜单显示   Qwidget类及其子类都具有右键菜单响应功能,QWidget类提供了以下两个与右键菜单有关的函数: 1、 Qt::ContextMenuPolicy contextMenuPolicy()const 该函数用来获取控件上下文菜单项的...
  • java context上下文

    万次阅读 热门讨论 2012-12-31 13:20:41
    Context在Java中的出现是如此频繁,但其中文翻译“上下文”又是如此诡异拗口,因此导致很多人不是很了解Context的具体含义是指什么,所以很有必要来深究一下这词的含义。先来举几个JAVA中用到Context的例子(1)JNDI...
  • 在分布式链路跟踪系统中,同一条请求处理链路要用...利用 Mtrace(公司内部统一的分布式会话跟踪系统)的服务间传递上下文特性,在原有传输上下文的基础上,添加了测试标识的属性,以保证传输中始终带测试标识。
  • 进程控制块、进程上下文

    千次阅读 2016-11-07 23:06:29
    一. 进程控制块   为了描述和控制进程的运行,系统为每... 操作系统就是根据进程的PCB来感知进程的存在,并依此进程进行管理和控制。 PCB是进程存在的唯一标识。    PCB主要包括如下4方面的信息  
  • java上下文Context类

    千次阅读 2014-05-05 19:48:24
    Context在Java中的出现是如此频繁,但其中文翻译“上下文”又是如此诡异拗口,因此导致很多人不是很了解Context的具体含义是指什么,所以很有必要来深究一下这词的含义。 先来举几个JAVA中用到Context的例子 ...
  • java 中的context上下文

    千次阅读 2018-09-06 09:43:28
    Context在Java中的出现是如此频繁,但其中文翻译“上下文”又是如此诡异拗口,因此导致很多人不是很了解Context的具体含义是指什么,所以很有必要来深究一下这词的含义。先来举几个JAVA中用到Context的例子(1)JNDI...
  • 基本功:线程上下文切换

    万次阅读 多人点赞 2019-05-31 22:06:42
    更多的线程意味线程创建销毁开销加大、上下文非常频繁,你的程序反而不能支持更高的TPS。可以看另一篇《Java从线程安全到synchronized和Lock探索》 时间片 多任务系统往往需要同时执行多道作业。作业数往往大于...
  • 介绍了多线程的概念、优点,以及线程上下文切换时的性能损耗问题
  • linux 上下文和自旋锁

    千次阅读 2014-02-20 14:40:01
    而自旋锁则防止在不同CPU上的执行单元共享资源的同时访问,以及不同进程上下文互相抢占导致的共享资源的非同步访问。 在对称多处理器,仅仅禁止某个CPU的中断是不够的,当然我们也可以将所有CPU的中断都禁止,...
  • Menu详解(三):使用上下文菜单

    千次阅读 2014-08-21 17:36:12
    因为最近学的东西比较多,感想也比较多,单一的写一个方面比较乏味,所以我就穿插写了,下面我会把相关的链接给大家,供大家系统的学习。 不积跬步无以至千里,不积小流无以成江河。 (千里之行,始于足下,...
  • 一文让你明白CPU上下文切换

    千次阅读 2018-12-20 13:07:37
    我们都知道,Linux 是一个多任务操作系统,它支持远大于 CPU 数量的任务同时运行。当然,这些任务实际上并不是真的在同时运行,而是因为系统在很短的时间内,将 CPU...什么是 CPU 上下文 CPU 寄存器和程序计数器就是...
  • 一、中断上下文 当执行一个中断处理程序时,内核处于中断上下文(interrput context) 中 让我们先回忆一下进程上下文。进程上下文是一种内核所处的操作模式,此时内核代表进程执行——例如, 执行系统调用或运行...
  • PDP 上下文的激活(转)

    千次阅读 2008-10-29 20:07:00
    激活一个PDP 上下文意味发起一个分组数据业务呼叫MS 请求发起PDP 上下文激活MO无论PDP 地址为静态或动态都可由MS 请求发起PDP 上下文1 MS 向SGSN 发出激活PDP 上下文请求NSAPI,TI,PDP 类型,APN ,要求的QoS,PDP ...
  • windows设备上下文的概念

    千次阅读 2016-08-06 22:57:03
    关于设备场景,叫法颇多,有些书说为设备环境、显示场景,更常见的叫做设备描述表或设备...而实质,widnows下的所有绘图都是 通过设备场景进行的,而不是直接窗口和设备本身进行。为了说明设备场景,很多书都拿
  • 深入理解Linux的CPU上下文切换

    千次阅读 2018-12-14 11:10:11
    如何理解Linux的上下文切换 Linux 是一个多任务操作系统,它支持同时运行的任务数量远大于 CPU 个数。其实这些任务没有真正的同时运行,是因为系统在很短的时间内,将 CPU 轮流分配给它们,造成多任务同时运行的错觉...
  • java Context(上下文)释义

    千次阅读 2014-01-06 09:45:06
    Context在Java中的出现是如此频繁,但其中文翻译“上下文”又是如此诡异拗口,因此导致很多人不是很了解Context的具体含义是指什么,所以很有必要来深究一下这词的含义。先来举几个JAVA中用到Context的例子 (1)...
  • 形状上下文(shape context)算法完全解读

    千次阅读 多人点赞 2020-04-11 00:12:08
    形状上下文(Shape Context)算法完全解读前言一. 轮廓提取(Canny Edge Detection)和轮廓点采样(Jitendra's Sampling) 前言 一般来说,在计算机视觉任务中,形状匹配可以分为 基于特征(Feature-based): 基于傅里叶...
  • 在GDI中,DC(Device ...也有的书将DC翻译为设备上下文。 到底什么是DC? 用现实中的例子来理解可能更容易些。 如果你喜欢画画,你得先准备了画布,画笔,颜料…… 画画的环境搭建好了,你就可以画画了。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 138,059
精华内容 55,223
关键字:

对上下文起着什么作用