Hello Vagrant
回想以前,想要安装个虚拟机是多么的麻烦。先要费尽心机找到想要的操作系统镜像文件,然后安装虚拟化软件,按照其提供的GUI界面操作一步步创建,整个过程费时费力。但是,自从使用了Vagrant以后,咱腰不酸了,腿不痛了,一口气起5个虚拟机还不费劲。
Vagrant是什么?
这是官网上Vagrant的介绍。
Create and Configure lightweight, reproducible, and portable development environments.
即用来创建和配置轻量级、可重现的、便携式的开发环境。
使用Vagrant可以将创建虚拟机的整个过程自动化起来,并具有高度的重用性。假如你是个开发者,你可以很容易为每个团队成员创建一模一样的开发环境,从根本上防止‘在我的机器上可以工作’之类的bug。假如你是个测试人员,可以一键创建多个一模一样的测试环境并行跑测试,并且跑完测试后还可以一键销毁这些测试环境,达到真正的按需创建。如果你是devops成员,需要和AWS、Chef之类的工具打交道,那么Vagrant是个很好的结合点。你可以通过Vagrant在AWS上直接创建虚拟机,并且自动运行Chef的脚本配置你的新虚拟机。
几个概念
正式介绍Vagrant功能之前先了解一下Vagrant使用的一些概念。
-
Provider - 供应商,在这里指Vagrant调用的虚拟化工具。Vagrant本身并没有能力创建虚拟机,它是调用一些虚拟化工具来创建,如VirtualBox,VMWare,甚至AWS。
-
Box - 可被Vagrant直接使用的虚拟机镜像文件。针对不同的Provider,Box文件的格式是不一样的。
-
Vagrantfile - Vagrant根据Vagrantfile中的配置来创建虚拟机。在Vagrantfile文件中你需要指明使用哪个Box,需要预安装哪些软件,虚拟机的网络配置等。
Vagrant的安装
安装Vagrant非常简单,可以在Downloads页面选择最新的版本安装。Vagrant支持Windows、Linux、Mac等平台。
Box管理
使用Vagrant之前先要给Vagrant添加Box,也就是可供Vagrant使用的虚拟机镜像文件。Vagrant官网本身维护了一些镜像文件,我们可以直接使用。http://www.vagrantbox.es/上面有更多的box可以供我们使用。
1 2 3 4 5 6 |
|
可以看到Box与Provider是相关的,每个Box都必须指定Provier,只有使用对应的Provier才能正确使用Box。
创建并运行虚拟机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
vagrant init precise32
会在当前目录下生成一个Vagrantfie文件,其使用precise32作为box。vagrant up
则是使用virtual box这个provider来初始化并启动precise32这个虚拟机。
我们可以详细的看看Vagrantfile这个文件。
Vagrantfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
|
从上述的文件可以看出Vagrantfile可以配置很多东西,比如使用的Box,需要转发的端口,同步指定的目录,使用Chef、puppet等对虚拟机进行预配置等。
如果修改了Vagrantfile中的配置,只需要执行vagrant reload
来应用新配置。
同步目录
虚拟机启动起来以后就可以ssh上去了。
1 2 3 4 5 6 7 8 9 10 11 |
|
Vagrant会自动给虚拟机根目录下创建一个名为vagrant的目录。这个目录可以与主机Vagrantfile所在的目录保持同步。这个同步是相互的,无论改动了主机目录中的文件,还是虚拟机目录中的文件,都可以自动同步到另一方。
1 2 3 4 5 6 7 8 9 |
|
多机器管理
其实Vagrantfile支持配置多台机器,如果你需要设置多台服务器及数据库环境,可以用一个Vagrantfile搞定。
Vagrantfile
1 2 |
|
这个文件配置了两个box,一个叫web,一个叫db。现在启动虚拟机就需要加上虚拟机名了。
1 2 3 4 5 6 7 8 |
|
关闭虚拟机
Vagrant提供了好几种方法来关闭虚拟机,你可以根据不同的情况选择不同的方式。
vagrant suspend
将虚拟机置于休眠状态。这时候主机会保存虚拟机的当前状态。再用vagrant up
启动虚拟机时能够返回之前工作的状态。这种方式优点是休眠和启动速度都很快,只有几秒钟。缺点是需要额外的磁盘空间来存储当前状态。
vagrant halt
则是关机。如果想再次启动还是使用vagrant up
命令,不过需要多花些时间。
vagrant destroy
则会将虚拟机从磁盘中删除。如果想重新创建还是使用vagrant up
命令。
另外1.2以上版本的Vagrant还引用了插件机制。可以通过vagrant plugin
来添加各种各样的plugin,这给Vagrant的应用带来了更大的灵活性和针对性。比如可以添加vagrant-windows
的插件来增加对windows系统的支持,通过添加vagrant-aws
插件来实现给AWS创建虚拟机的功能。你也可以编写自己的插件。由于Vagrant是ruby写的一个gem,其插件的编写也是使用的Ruby语言。这里就不多做介绍了。感兴趣的可以去官网查看。
出处:http://www.cnblogs.com/huang0925
黄博文的地盘
本文版权归本人和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
前文详细介绍了Façade模式、Adapter模式、Strategy模式和Bridge模式,并进行了比较。本文将再介绍四个常用的设计模式:Abstract Factory(抽象工厂)模式、Decorator(装饰)模式、Observer(观察者)模式、Template Method(模板)模式。开始介绍之前,笔者想说一下自己经常纠结的一个问题,什么时候开始考虑应用模式?作为一个新手,刚接触设计模式时都会为之倾倒,自觉醍醐灌顶,非常的迫切将所学的设计模式应用于实践,所以在编程的初期就会考虑各种模式的应用。个人的经验告诉我,对业务的理解是一个渐进明细的过程,开发的初期往往很难看到整个业务需求的全貌和本质,此时强行应用设计模式往往会导致Over Engineering。笔者认为应用设计模式的最佳时机往往是在代码重构的时候,彼时你已掌握业务的本质,对模式的应用往往能够恰到好处,其实这也是JIT的思想。
一.Abstract Factory模式
1. 目标:需要为特定的客户(或情况)提供对象组,组内之间的对象处于一个上下文环境。
2. 问题:需要实例化一组相关的对象,并从对象创建逻辑层面保证对象之间正确的关系,例如:在游戏设计中,在非洲大陆,不能够创建出美洲豹对象。
3. 解决方案:协调对象组的创建。提供一种方式,将如何执行对象实例化的规则从使用这些对象的客户对象中提取出来,实现对象创建和对象使用的解耦。
4. 参与者和协作者:Abstract Factory为如何创建对象组的每个成员定义公共接口。特定的ConcreteFactory创建其所对应的具体对象组。
5. 效果:抽象工厂模式将“使用那些对象”的规则与“如何使用这些对象”的逻辑进行解耦,实现关注点分离。
6. 实现:定义一个抽象类来指定创建哪些对象。然后为每个组实现一个具体类。UML图如下:
二.Decorator模式
1. 目的:在运行时,实现动态的为每一个对象添加职责。
2. 问题:要使用的对象将执行所需要的基本功能。但是,这些基本功能确定以后,可能需要为这个对象添加一些其他的附加功能,并且对于不同的情况可能添加的附加功能的种类和数量都是不确定的。
3. 解决方案:通过添加装饰类,而不是扩展子类,在运行时为基本类对象扩充功能。抽象的说:有一个基本功能,还有些可选功能,每一个具体的对象,在基本功能的基础上通过选用不同的可选功能来定制。基本功能作为:ConcreteComponent;可选功能作为:ConcreteDecorator。
4. 参与者和协作者:ConcreteComponent让Decorator对象为自己添加功能。有时候用ConcreteComponent的派生类提供核心功能,在这种情况下ConcreteComponent不再是具体的,而是抽象的。Component类定义了所有这些类的接口。
5. 效果:附加功能放在Decorator对象中。好处是可以在ConcreteComponent对象的功能之前或之后添加功能(取决于Decorator类的具体实现),但是对象链总是终于ConcreteComponent对象。
6. 实现:创建一个抽象类来表示原类和要添加到这个类的功能。在装饰类中,将对新功能的调用放在对紧随其后对象的调用之前或之后,以获得正确的顺序。调用方式为new ConcreteDecorator(new ConcreteComponent())。UML图如下:
三.Observer模式
1. 目标:解开观察者和主体之间的耦合,二者之间的关系在运行时动态建立,实现订阅--发布模型(Pub-Sub Model).
2. 问题:对象间经常存在这样一种关系:某个对象状态的改变将导致另一些对象的状态变化。或者说,有些对象作为观察者在始终盯着某个对象,一旦有事发生就需要立即行动。抽象的说:当主体发生变化时,不同的观察者做出不同的行动,而且他们的行动是自我控制的,无需主体发出指令。
3. 解决方案:通过将主体和观察者分开,而不是简单的将观察者的行为硬编码到主体类中,观察者通过监测主体类的实践实现自我控制。
4. 参与者和协作者:Subject由三个函数构成:Attach(添加新的观察者)、Detach(删除过时的观察者)、Notify(依次更新观测者的信息);Observer定时更新自己的状态,根据主体的变化,做出相应的反应。
5. 效果:观察者对主体而言是透明的,观察者可以自发的做出反应。
6. 实现:创建一个Subject类,包含有三个函数。还有一个ConcreteSubject类获得主体的状态信息。创建一个Observer的抽象基类,还有不同观测者的ConcreteObserver类,定时更新自己的信息。UML图如下:
四.Template Method模式
1. 目标:定义业务逻辑中算法的骨架,将一些步骤推迟到子类中实现。可以不改变算法的结构而重新实现这个算法中的某些步骤。
2. 问题:要完成在某一细节层次一致的一个过程或一系列步骤,但其中个别步骤在更细节的层次上有不同的实现。
3. 解决方案:允许定义可变的子步骤,同时保持基本步骤和步骤之间的执行顺序不变。
4. 参与者和协作者:Abstract Class,该类中有一个定义了一般算法的方法(Template Method)这个方法调用了代表算法中各步骤的方法(Primitive Operation)。Concrete Class,实现Primitive Operation以完成算法中与特定子类相关的步骤。
5. 效果:提供了一个很好的代码复用平台,并且从结构上减少了算法出错的概率。同时,提供了一种机制,使得约束、规则可以一次编码,处处使用。对于具体类的实现者而言,无需关注整个算法,只需关注该具体类中特殊的实现逻辑即可。
6. 实现:创建一个抽象类,用抽象方法实现一个过程。这些抽象方法必须在子类中实现,以执行过程的每个步骤。如果这些步骤是独立变化的,那么每个步骤都可以是Strategy模式来实现(很多情况下,模式都不是独立使用,而是组合使用)。UML图如下: