cgroups 实现了对资源的配额和度量。 cgroups 的使用非常简单,提供类似文件的接口,在/cgroup目录下新建一个文件夹即可新建一个group,在此文件夹中新建task文件,并将pid写入该文件,即可实现对该进程的资源控制。具体的资源配置选项可以在该文件夹中新建子subsystem ,{子系统前缀}.{资源项} 是典型的配置方法
如memory.usage_in_bytes 就定义了该group 在subsystem memory中的一个内存限制选项。
另外,cgroups中的 subsystem可以随意组合,一个subsystem可以在不同的group中,也可以一个group包含多个subsystem - 也就是说一个 subsystem。
1. 关于术语定义
A * cgroup * associates a set of tasks with a set of parameters for one
or more subsystems.
A * subsystem * is a module that makes use of the task grouping
facilities provided by cgroups to treat groups of tasks in
particular ways. A subsystem is typically a "resource controller"that
schedules a resource or applies per-cgroup limits, but it may be
anything that wants to act on a group of processes, e.g. a
virtualization subsystem.
主要关心cgroups可以限制哪些资源,即有哪些subsystem会受到影响。
2. 子系统
子系统是一种模型元素,它具有包(其中可包含其他模型元素)和类(其具有行为)的语义。子系统的行为由它所包含的类或其他子系统提供。子系统实现一个或多个接口,这些接口定义子系统可以执行的行为。
2.1 确定方法
如果某个协作中的各个类只是在相互之间进行交互,并且可生成一组定义明确的结果,就应将该协作和它的类封装在一个子系统中。
这一规则同样适用于协作的子集。可以对协作的任何部分或全部进行封装和简化,这将会使设计更易于理解。
提示 |
详细说明 |
注意可选性 |
如果特定的协作(或子协作)代表可选行为,则应将其封装在一个子系统中。如果可以将某些功能删除、升级或替换为其他功能,就应该认为这些功能是独立的。 |
注意系统的用户界面。 |
如果用户界面相对独立于系统中的实体类(即二者都可以且将要独立地变更),则应创建横向集成的子系统:将相关的用户界面边界类归入一个子系统,而将相关的实体类归入另一个子系统。 |
如果用户界面和它所显示的实体类紧密耦合(即一方的变更会触发另一方的变更),则应创建纵向集成的子系统:将相关的边界类和实体类装入共同的子系统中。 |
|
注意主角 |
将两个不同主角使用的功能分开,因为每个主角可能会独立变更自己对系统的需求。 |
查找类与类之间的耦合和内聚 |
耦合度或内聚度较高的类彼此协作,以提供某一组服务。将耦合度较高的类组织成子系统,沿着弱耦合的界线将类分开。在某些情况下,可以将类分成更小的类,使其具有内聚度更高的职责,从而完全消除弱耦合。 |
注意替换 |
如果为某项特定功能指定了几个服务级别(例如,高、中、低可用性),则要将每个服务级别表示成一个独立的子系统,每个子系统都将实现同一组接口。这样,子系统就可互相替换。 |
注意分布 |
虽然一个特定子系统可能有多个实例,每个实例都在不同的节点上执行,但不可能在各节点间拆分子系统的单个实例。如果必须在各节点间拆分子系统行为,则需要将子系统分成更小的子系统,使其具有限制更严格的功能。确定必须存在于每个节点上的功能,并创建一个新的子系统,使其“拥有”该功能,然后相应地在该子系统内分布职责和相关元素。 |
一旦将类组织成子系统,就要相应地更新用例实现。
1.记录子系统:
一旦创建了子系统:供一个名称和一段简短说明。 如果工具支持包但不支持子系统,可以用包来记录子系统;在此环境中应使用包构造型表示子系统。 应将原始分析类的职责转移给新建的子系统,并使用该子系统的说明来记录职责。
2.子系统和构件:
构件属于实施范畴;为了在设计中表示构件,可以将子系统用作构件的代理。
系统的每个部分都应尽可能独立于系统的其他部分。 从理论上说,应该可以用新的部分替换系统的任何部分,但前提是新部分必须支持相同的接口。 应该可以使系统的不同部分独立地演进,而不受系统其他部分的影响。 为此,设计子系统提供了一种在设计模型中表示构件的理想方法:它们是用来封装许多类的行为的设计元素(就象构件封装许多类实例的行为一样),并且只能通过它们所实现的接口访问它们的行为(构件就是这样)。
代表现有产品的子系统
如果现有产品是用来导出接口(即操作,也许会导出接收)的产品,但却隐藏了实施的所有细节,就可以在逻辑视图中将该产品建模为子系统。您可以用子系统表示系统所使用的产品,例如:
通信软件(中间件)。 数据库访问支持(RDBMS 映射支持)。 应用程序专用产品。 某些现有的产品,如类型集合和数据结构(例如,栈、列表、队列)最好用包来表示,因为它们所展示的不仅仅是行为。既重要又有用的是包中的特定内容,而不是包本身,包不过是一个容器而已。
对于常用的实用程序(如数学库),如果它们只导出接口,就可以将其表示成子系统,但这是否有必要或有意义,还要取决于设计人员对建模对象性质的判断。子系统是面向对象的构造,它们不仅是分类器,还是包:子系统可以具有实例(如果设计人员作出这样的指定)。通过 UML,也可以在作为构造型类的实用程序(该实用程序没有实例)中建立多组全局变量和过程的模型。
当定义子系统来代表产品时,还要定义一个或多个接口来表示产品接口。
3.子系统依赖关系限制:
子系统与包在语义上具有差异:子系统是一种通过一个或多个它所实现的接口来提供行为的包。包并不提供行为;它们只不过是用来容纳提供行为的对象的容器。
之所以要使用子系统而不使用包,是因为子系统完全封装自己的内容,只通过自己的接口提供行为。其好处在于,与包不同,只要子系统的接口保持不变,就可以完全自由地更改子系统的内容和内部行为。另外,子系统还提供了一种“可替换的设计”元素:任何两个实现相同接口的子系统(或类,就此而论)都可以互换。
2.2 使用
可以通过多种互补的方法来使用子系统,将系统分为若干个单元,这些单元:
可以独立预定、配置或交付 可以独立开发(只要接口保持不变) 可以在一组分布式计算节点上独立部署 可以在不破坏系统其他部分的情况下独立地进行更改 此外,子系统还可以:
将系统分为若干单元,以提供对关键资源的有限安全保护 在设计中代表现有产品或外部系统。
2.3 规则
为确保子系统在模型中是可互换的元素,需要执行以下几条规则:
子系统不应暴露自己的任何内容(即,子系统所包含的元素都不应有“公有”的可见性);子系统外部的元素都不应依赖于子系统内部特定元素的存在。 子系统只应依赖于其他模型元素的接口,因此它不直接依赖于子系统外部的任何特定模型元素。例外情况是,许多子系统共享一组类定义。在这种情况下,这些子系统将“导入”包含公共类的包中的内容。这一操作只应对位于构架低层的包执行,并且只能是为了确保必须在子系统之间传递的公共类定义保持一致。
以下显示了子系统和包的依赖关系的示例:
设计模型中子系统和包的依赖关系。
2.4 子系统与其相关名词的界定
功能是使用角度下的定义,主要指特定场景下的输入及其输出,通常来说,一个系统会有多个功能。
系统是一个可以独立存在的完整实体,由一组完成特定任务的功能组成。
子系统顾名思义,它也是一个系统,也就是说仍然是完整的实体。系统和子系统的概念是相对的,当作为另一个系统的一部分时,系统就成为一个子系统。
模块和系统、子系统一般情况下没有本质区别,但是如果模块不能必须配合系统的其它部分才能工作时则不称为系统。
3. cpu
cpu : 在cgroup中,并不能像硬件虚拟化方案一样能够定义CPU能力,但是能够定义CPU轮转的优先级,因此具有较高CPU优先级的进程会更可能得到CPU运算。
通过将参数写入cpu.shares,即可定义改cgroup的CPU优先级 - 这里是一个相对权重,而非绝对值。当然在cpu这个subsystem中还有其他可配置项,手册中有详细说明。
4. cpusets
cpusets : cpusets 定义了有几个CPU可以被这个group使用,或者哪几个CPU可以供这个group使用。在某些场景下,单CPU绑定可以防止多核间缓存切换,从而提高效率
5. memory
memory : 内存相关的限制
6. blkio
blkio : block IO相关的统计和限制,byte/operation统计和限制(IOPS等),读写速度限制等,但是这里主要统计的都是同步IO
net_cls, cpuacct , devices , freezer 等其他可管理项。
如果这份博客对大家有帮助,希望各位给恒川一个免费的点赞👍作为鼓励,并评论收藏一下⭐,谢谢大家!!!
制作不易,如果大家有什么疑问或给恒川的意见,欢迎评论区留言。