精华内容
下载资源
问答
  • 容器原理

    千次阅读 2018-07-01 09:04:58
    基于容器中元素的组织方式:顺序容器、关联容器按照与容器所关联的迭代器类型划分:可逆容器随机访问容器容器的基本功能与分类容器顺序容器array(数组)、vector(向量)、deque(双端队列)、forward_list...

    容器的基本功能与分类

    • 容器类是容纳、包含一组元素或元素集合的对象。
    • 基于容器中元素的组织方式:顺序容器、关联容器
    • 按照与容器所关联的迭代器类型划分:可逆容器随机访问容器

    容器的基本功能与分类

    • 容器
      • 顺序容器
        • array(数组)、vector(向量)、deque(双端队列)、forward_list(单链表)、list(列表)
      • (有序)关联容器
        • set(集合)、multiset(多重集合)、map(映射)、multimap(多重映射)
      • 无序关联容器
        • unorderedset (无序集合)、unorderedmultiset(无序多重集合)
        • unorderedmap(无序映射)、unordermultimap(无序多重映射)

    容器的分类

     

    容器的通用功能

    • 容器的通用功能
      • 用默认构造函数构造空容器
      • 支持关系运算符:==、!=、<、<=、>、>=
      • begin()、end():获得容器首、尾迭代器
      • clear():将容器清空
      • empty():判断容器是否为空
      • size():得到容器元素个数
      • s1.swap(s2):将s1和s2两容器内容交换
    • 相关数据类型(S表示容器类型)
      • S::iterator:指向容器元素的迭代器类型
      • S::const_iterator:常迭代器类型

    对可逆容器的访问

    • STL为每个可逆容器都提供了逆向迭代器,逆向迭代器可以通过下面的成员函数得到:
      • rbegin() :指向容器尾的逆向迭代器
      • rend():指向容器首的逆向迭代器
    • 逆向迭代器的类型名的表示方式如下:
      • S::reverse_iterator:逆向迭代器类型
      • S::constreverseiterator:逆向常迭代器类型

    随机访问容器

    • 随机访问容器支持对容器的元素进行随机访问
      • s[n]:获得容器s的第n个元素
    展开全文
  • Docker实现原理/容器原理Docker实现原理/容器原理什么是容器(Container)容器解决什么问题传统虚拟化架构 Docker实现原理/容器原理 容器是Linux内核提供得技术,Docker只是一个容器工具。Docker ≠ 容器 谈Docker必谈...


    本文主要让你了解什么是容器,Docker是什么,容器和Docker是什么关系,Docker实现原理

    Docker实现原理/容器原理

    容器是Linux内核提供得技术,Docker只是一个容器工具Docker ≠ 容器

    谈Docker必谈容器 先了解一下容器是什么

    什么是容器(Container)

    根据WIKI的定义,容器概念如下:

    1. 容器是一种基础工具;泛指任何可以用于容纳其他物品的工具,可以是部分或完全封闭,被用于容纳、存储、运输物品。物体可以放置在容器中,而容器则可以保护内容物。
    2. 人类使用容器的历史至少有十万年,甚至可能有数百万年的历史;

    计算机领域内的容器技术想要能明白的话,要先了解一下传统虚拟化面临的问题。先看下一节。

    容器

    容器Logo

    计算机容器技术本身也是一种虚拟化技术(轻量级虚拟化)。在容器技术诞生之前我们已经有了传统虚拟化:KVM、VMware、Xen等传统虚拟化实现。那我为什么还要使用容器呢?

    传统架构问题

    传统虚拟化架构图

    如上图所示传统虚拟化分为Type-I(裸机) 和Type-2(寄宿)两种类型,试想一下,如下场景:
    我想运行一个Nginx,在两种虚拟化类型下分别需要做那些事情:
    1.Type-I: 需要为Nginx程序创建一个操作系统,然后才能运行Nginx。Nginx运行在虚拟操作系统的用户空间。

    硬件资源虚拟化链路为 hypervisor->操作系统内核空间->操作系统用户空间->Nginx。

    2.Type-II: 需要为Nginx程序创建一个操作系统,然后才能运行Nginx。Nginx运行在虚拟操作系统的用户空间。

    硬件资源虚拟化链路为 寄宿的操作系统->hypervisor->操作系统内核空间->操作系统用户空间->Nginx

    综上所述,我就想运行一个Nginx,在传统虚拟化中需要为Nginx准备一个操作系统,才能运行Nginx。必须花费大量的时间来安装与设置虚拟机,接着才能开始评估或测试所需运作的软件,这些设置包含了操作系统的安装、安全性或兼容性软件的更新、网络、系统调校…等。
    注:横线部分不是容器技术本身能解决的,由Docker提供镜像(Image) 机制解决。

    回归一下这个问题的本质。应用程序运行依赖操作系统提供的库,依赖的软件和特定于系统的数据结构或文件系统。于是我们要为应用程序提供虚拟操作系统,虚拟的操作系统同时提供了一个虚拟的内核。虚拟的内核来管理虚拟的硬件设备。

    **总结一下:传统虚拟化在使用成本上较高,提供虚拟的硬件设备,虚拟的操作系统。当然还有为了提供这些所造成的CPU,内存压力。既然如此何不直接把虚拟的操作系统去掉?于是容器技术就诞生了。

    容器是什么

    去掉虚拟的操作系统层后,我们所追求的环境如下:

    容器内核

    创建多个隔离环境。应用程序应该跑在用户空间,内核提供的是内核空间,而现在需要进程运行在隔离环境,在一个内核中用户空间只有一个,那就表示所需要隔离的是用户空间。所以期望的是将用户空间隔离成多组,彼此之间互相不干扰,一个用户空间至运行一个或部分进程。(注意通常会有一个名称空间有特权,一般是第一个用户空间,类系Xen和KVM) 随后进程启动和运行在用户空间中,在众多用户空间能共享底层同一个内核,被同一个内核管理。但是进程自己运行时所能看到的边界是所属用户空间的边界。这样彼此间也就隔离了。(这样隔离并没有主机虚拟化隔离的那么彻底) 此时这个用户空间给进程提供运行环境,并且其能够保存内部进程不是其他进程干扰。这就是计算机的容器技术。

    容器如何实现

    容器实现

    一个用户空间的主要目标就是隔离环境,任何进程运行在用户空间当中,进程就认为自己是唯一运行在到当前内核之上的用户空间中的进程,而且它所能看到的所有进程也就是当前主机的所有进程了。 一个名称空间他应该有这些组件:UTS(主机名和域名)、Mount(根文件系统)、IPC(同名称空间进程间通信专用通道)、 PID(进程数)、User(用户)、Net(网卡,网络接口,全套接字)。如上这些资源都由内核通过名称空间机制,并且封装成为系统调用向外暴露。还有一个很重要的机制chroot,即 change root directory (更改 root 目录)。在 linux 系统中,系统默认的目录结构都是以 /,即以根 (root) 开始的。而在使用 chroot 之后,系统的目录结构将以指定的位置作为 / 位置。 在现代计算机中容器就是通过内核提供的6个名称空间和chroot实现的。

    内核在设计之初并没有提供如上的资源隔离机制,如下是各个名称空间隔离在内核实现的对应关系。
    资源隔离对应内核版本号

    namespace 系统调用参数 隔离内容 内核版本
    UTS CLONE_NEWUTS 主机和域名 2.6.19
    IPC CLONE_NEWIPC 信号量,消息队列和共享内存 2.6.19
    PID CLONE_NEWPID 进程编号 2.6.24
    Network CLONE_NEWNET 网络设备、网络栈、端口等 2.6.29
    Mount CLONE_NEWNS 挂载点(文件系统) 2.4.19
    User CLONE_NEWUSER 用户和用户组 3.8

    Cgroups

    Cgroups是什么

    cgroups,其名称源自控制组群(英语:control groups)的简写,是Linux内核的一个功能,用来限制、控制与分离一个进程组的资源(如CPU、内存、磁盘输入输出等)。

    这个项目最早是由Google的工程师(主要是Paul Menage和Rohit Seth)在2006年发起,最早的名称为进程容器(process containers)。在2007年时,因为在Linux内核中,容器(container)这个名词有许多不同的意义,为避免混乱,被重命名为cgroups,并且被合并到2.6.24版的内核中去。自那以后,又添加了很多功能。

    Cgroups解决什么问题

    有过个容器在跑,万一有一个容器内部的进程出现意外情况,像脱缰的野马一样疯狂的抢占系统资源,如CPU,内存等。CPU因为是可压缩性资源所以其实还好,内存一旦被使用完系统将会发生OOM(暴头程序)等异常,且其他容器内的进程也会因没有内存而无法运行。因为容器共用一个内核所以一旦资源被疯狂掠夺,其他运行的进程将受影响。这怎么能行呢? 于是Cgroup就用来解决容器资源限制的问题。在内核中用Cgroup针对每一种名称空间进行资源限制。

    Cgroups如何工作

    Cgroups无非是把系统级的资源分成多个资源组(子系统),然后把每个组内的资源量指派或分配到特定用户空间的进程来实现。

    Cgroups可以将资源分成多个资源组(子系统) 如下所示:

    1. blkio: 块设备IO
    2. cpu: CPU
    3. cpuacct: CPU资源使用报告
    4. cpuset: 多处理器平台上的CPU集合
    5. devices:设备访问
    6. freezer: 挂起或恢复任务
    7. memory: 内存用量及报告
    8. perf_event: 对cgroup中的人种进行统一的性能测试
    9. net_cls: cgroup中的任务创建的数据报文的类别标识符

    Cgroups层级结构(Hierarchy)

    内核使用cgroup结构体来表示一个control group对某一个或多个cgroups资源组的资源限制。cgroup结构体可以组织成一颗树的形式,每一棵cgroup组成的树称之为一个cgroups层级结构。 cgroups层级结构可以attach 一个或多个cgroups资源组,层级结构可以使用被attach的cgroups资源组进行资源限制。
    Cgroup绑定关系
    上图所示 一个cgroups层级结构,一个层级结构中是一颗树形结构,树的每一个节点是一个cgroup结构体(如cpuRoot,cpu2,CM3)。 这个cgroups层级结构attach了cpu资源组和cpuacct资源组,于是当前资源组就可以对cpu资源进行限制,并且对进程的cpu使用情况进行统计。 在每一个cgroups层级结构中,每一个节点(cgroup结构体)可以对资源设置不同的限制权重,子节点默认会遵循父节点的权重。如上图cpu2组中的进程可以使用60%的cpu时间片而CM3组的进程可以使用40%的cpu时间片。

    进程和层级结构关系

    在创建了cgroups层级结构中的节点(cgroup结构体)之后,可以把进程加入到某一个节点的控制任务列表中,一个节点的控制列表中的所有进程都会受到当前节点的资源限制。同事某一个进程也可以被加入到不同的cgroups层级的节点中,因为不同的cgroups层级结构可以负责不同的系统资源。进程和节点(cgroup结构体)是多对多的关系,但是节点(cgroup结构体)不可以是同一个cgroups层级结构中的。

    LXC

    LXC是什么

    在这里插入图片描述

    LXC,其名称来自Linux软件容器(Linux Containers)的缩写,一种操作系统层虚拟化(Operating system–level virtualization)技术,为Linux内核容器功能的一个用户空间接口。它将应用软件系统打包成一个软件容器(Container),内含应用软件本身的代码,以及所需要的操作系统核心和库。透过统一的名字空间和共享API来分配不同软件容器的可用硬件资源,创造出应用程序的独立沙箱运行环境,使得Linux用户可以容易的创建和管理系统或应用容器。

    在Linux内核中,提供了cgroups功能,来达成资源的区隔化。它同时也提供了名称空间区隔化的功能,使应用程序看到的操作系统环境被区隔成独立区间,包括行程树,网络,用户id,以及挂载的文件系统。但是cgroups并不一定需要引导任何虚拟机。

    LXC利用cgroups与名称空间的功能,提供应用软件一个独立的操作系统环境。LXC不需要Hypervisor这个软件层,软件容器(Container)本身极为轻量化,提升了创建虚拟机的速度。软件Docker被用来管理LXC的环境。

    LXC解决什么问题

    通过上面的介绍,我们知道容器(6个名称空间)和cgroups组合即可实现完整并且保证隔离的容器环境。但是控制名称空间和cgroups都是系统调用,又有多少人能掌握呢? 于是LXC出现了,LXC就是让用户可以轻松地创建和管理系统或应用程序容器

    LXC如何工作

    LXC架构
    LXC容器通常被认为是在chroot和传统虚拟化之间的。LXC的目标是创建一个尽可能接近标准的linux安装环境,但不需要单独的内核。换而言之LXC就像是传统虚拟化一样提供一个VM只是和寄宿系统公用同一个内核(与docker不一样)

    LXC工作模式是这样的,使用lxc-create创建一个容器(名称空间),然后通过模板(早期shell脚本,目前yaml脚本),执行安装过程。这个模板,会自动实现安装过程,这个安装就是指向了你想创建的容器(名称空间)的系统发行版的仓库,利用仓库中的程序包下载至本地来完成安装过程。于是这个容器(名称空间)就像虚拟机一样使用。

    lxc-centos模板示例
    lxc-centos模板:https://github.com/AtlanCI/LXC-Centos_template/blob/main/lxc-centos

    Dcoker

    Docker是什么

    在这里插入图片描述

    Docker 是一个开放源代码软件,是一个开放平台,用于开发应用、交付(shipping)应用、运行应用。 Docker允许用户将基础设施(Infrastructure)中的应用单独分割出来,形成更小的颗粒(容器),从而提高交付软件的速度。

    Docker容器与虚拟机类似,但二者在原理上不同。容器是将操作系统层虚拟化,虚拟机则是虚拟化硬件,因此容器更具有便携性、高效地利用服务器。 容器更多的用于表示 软件的一个标准化单元。由于容器的标准化,因此它可以无视基础设施(Infrastructure)的差异,部署到任何一个地方。另外,Docker也为容器提供更强的业界的隔离兼容。

    Docker解决什么问题

    通过上面的描述我们知道了LXC被用来管理容器,但是使用LXC来管理容器将会面临下列问题:

    1. 要想使用LXC管理容器,要学习很对LXC工具。LXC命令列表
    2. 必要时要定制模板
    3. 每一个名称空间都是安装生成的,在该名称空间中运行的进程会生成一些文件(数据库之类的),当该宿主故障时,如何迁移到其他宿主机上
    4. 批量创建较困难

    Docker和LXC架构对比

    总结起来就是通过LXC管理容器比起传统虚拟化的虚拟机的使用复杂度没有多大降低,更何况隔离性也没有虚拟机那么好。当然了好处在于每个容器中的进行都可以直接使用宿主机的性能,中间没有额外开销(节约资源)。LXC在分发和大规模使用上没有很好的方法。于是后来就出现了Docker,早期的Docker可以看作为是LXC的增强版(主要解决分发和大规模使用)。

    Docker本身不是容器,Docker只是容器的易用工具。容器是Linux内核的技术,Docker只是简化容器这种技术的使用

    目前LXC被进一步更新为LXD(当然使用方式还是和虚拟机差不多,分发和大规模使用会好很多),如想了解请参阅:https://linuxcontainers.org/lxd/introduction/

    Docker如何工作

    网上关于Docker的文章一抓一大把,这里只简短介绍如何解决分发和大规模的技术。

    Docker工作流程

    如上所述LXC面临大规模使用和在其他的主机上复刻容器(分发)很难,于是Docker就在这方面着手解决。所以早期的Docker就是LXC的二次封装。功能上是通过LXC作为容器管理引擎,但是创建容器时,不在是用模板现场安装生成,而是事先通过一种叫做镜像的技术。把一个操作系统的用户空间用到了所有组件编排好,编排好以后整体打包成一个文件。这个文件就叫做镜像文件(Image)。使用Docker创建容器时,Docker不会激活LXC的模板创建安装。而是连接到镜像仓库,下载一个创建容器所需要的镜像。 Docker极大的简化了容器的使用,比如想要运行一个nginx 直接docker run nginx 就行了。

    每个容器本身可以运行一个多一组进程,Docker为了使容器的使用更加易于管理,采用在一个Docker容器中之运行一个进程。这样会带来一下好处和坏处。

    好处:

    1.每个容器只运行一个进程,多个进程走容器间通信(更加隔离性,更容器分发)

    坏处:

    1.所需要的存储空间增加了
    2.调试容器中的进程比较困难

    开发人员开发的好的程序只需要打包到一个Docker镜像中,便可以到处运行在拥有在Docker的机器上。一些特殊进程类似数据库这种,需要采用共享存储才可以更好的解决分发问题。通过将应用打包为镜像这种机制,可以很好的解决分发的问题。 在大规模使用场景上也是很简单的,在每个机器上只需要有一份镜像文件便可以启动N个示例。(具体参考Docker镜像,分层部署-联合挂载这一特性)

    有了Docker的镜像机制后就可以很好的解决分发和大规模使用了。 当然想好用好容器还是要有容器编排工具的。

    reference

    Cgroups:https://tech.meituan.com/2015/03/31/cgroups.html
    LXC introduction:https://linuxcontainers.org/lxc/introduction/
    LXD introduction:https://linuxcontainers.org/lxd/introduction/

    展开全文
  • spring容器原理

    千次阅读 2014-06-03 22:47:09
    spring容器原理

      spring IOC使应用中依赖管理变得简单,所以的bean创建,以及当前bean所需要的另外类的实例都由容器来管理。

      想像下,如果不用spring ioc。有业务类A,需要业务类B的实例。而业务类B需要业务类C的实例。这里如果业务类A为入口main方法,我们需要进行以下几个步聚完成A类的实例化:

      1.手动创建C类实例

      2.然后创建B类实例并将之前创建的C类实例插入到B的字段中

      3.最后创建A的实例,并将B的实例插入到A类的字段中

      可以想像实例化,并管理这些依赖的过程对于程序员来说,简直是灾难。如果后续C类又需要D类的字段,又需要改动这段初始化代码。

      基于以上原因,我们想像下,这部分实例化及依赖管理能够由第三方管器来做,而程序员只需关心业务逻辑。

      我们希望,第三方容器的引入对现有项目代码应该影响很小,因此可以考虑用专门的配置文件来做。这样对原有类没有任何侵入。

     spring容器就是基于这样一目标而设计的。

      spring有许多款容器供用户选择,如ApplicationContext,ClassPathXMLApplicationContext等。

      spring 设计容器时,定义了一个beanFactory接口,定义了最常用的几个操作:getBean,containsBean,getType等。

      而基于这个beanFactory,在设计实现时,原则上重用一些代码,这个可以用继承与组合。spring中,用继承来复用大量的代码。

      beanFactory继承体系如下,此处只研究XmlBeanFactory这个分支:

       beanFactory->AutowireCapableBeanFactory->AbstractAutowireCapableBeanFactory->DefaultListableBeanFactory->XmlBeanFactory


    展开全文
  • IOC容器原理与实现

    千次阅读 2015-12-07 15:43:38
    IOC容器原理与实现Spring IOC主要分为两个过程:IOC容器初始化;依赖注入;IOC容器初始化主要分为三个过程: 第一个过程,Resource定位过程,这个过程如能主要是BeanDefintion的资源定位,主要就是找到定义Bean的...

    IOC容器原理与实现

    Spring IOC主要分为两个过程:IOC容器初始化;依赖注入;


    IOC容器初始化主要分为三个过程:
    第一个过程,Resource定位过程,这个过程如能主要是BeanDefintion的资源定位,主要就是找到定义Bean的文件。
    第二个过程,BeanDefinition的载入过程,这个载入过程就是把用户定义好的Bean表示成IOC内部的数据结构,该数据结构就是BeanDefinition。其实就是PoJo对象在IOC容器中的抽象。该过程就是讲用户事先设置好的Bean定义信息载入到一个所谓BeanDefinition的数据结构中。
    第三个过程,向IOC容器注册这些BeanDefinition,该过程主要是讲BeanDefinition注入到一个HashMap中去。
    依赖注入:
    IOC容器初始化后说明已经在IOC容器中建立了BeanDefinition的数据映射(HashMap),依赖注入主要是在用户第一次向IOC容器中所要Bean时触发,当然如果在BeanDefinition信息中设置控制属性lazy-init那么会在初始化中完成注入,注入的过程是通过JVM的反射或者CGLIB来对象Bean进行实例化。

    展开全文
  • Spring IOC 级联容器原理探究

    千次阅读 2018-07-17 23:30:02
    在一般的项目实践中我们只需要一个 IOC 容器来管理所有的 Bean 就可以了,但是这不是必然的,在 Spring MVC 框架中就是用了两级 IOC 容器来更好的管理业务 Bean 与Controller Bean;另外使用级联容器我们可以实现子 ...
  • SpringBoot 默认的web容器 SpringBoot 自动配置类 ServletWebServerFactoryAutoConfiguration,使用@Improt导入三个容器的配置bean 可以发现支持的容器是tomcat,jetty,undertow。 默认使用的是tomcat。而且...
  • .NET IoC容器原理与实现

    千次阅读 2017-12-31 20:08:18
    本文阐述IoC容器原理包含其代码实现,先简单说下IoC容器的出现它主要用于解决那类问题;在最初人们编写代码时大量的直接依赖;造成了如果下层修改签名那么上层受到强烈的影响,项目维护的成本越来越高昂;而为了尽...
  • 【Web容器原理】web容器设计(1)

    千次阅读 2016-07-07 10:24:46
    开发一个web容器涉及很多不同方面不同层面的技术,例如通信层的知识,程序语言层面的知识等等,且一个可用的web容器是一个比较庞大的系统,要说清楚需要很长的篇幅,本文旨在介绍如何设计一个web容器,只探讨实现的...
  • Spring源码剖析——核心IOC容器原理

    万次阅读 多人点赞 2016-08-05 15:06:16
    这里定义的只是一系列的接口方法,通过这一系列的BeanFactory接口,可以使用不同的Bean的检索方法很方便地从Ioc容器中得到需要的Bean,从而忽略具体的Ioc容器的实现,从这个角度上看,这些检索方法代表的是最为基本...
  • 中途用过不少开源代码或者研读过大牛BLOG,现开放双系统设计原理来回报社区。 备注:我是在android6.0上实现的。 这个项目的原型来自于,哥伦比亚大学虚拟化研究室的一篇论文(也有一个DEMO),后来一个以色列公司...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 305,154
精华内容 122,061
关键字:

容器原理