分类: 技术

  • 关于vim的搜索功能

    几个tag

    调查了好一阵子,总算弄清楚了几个东西的差别,简单记一下,几个tag:

    • ctags,vim用的
    • etags,emacs用的
    • cscope,生成的索引相比上面两个索引,信息会多一些,并且包含了一个搜索的指令,可以搜索函数在哪里被调用,以及可以做全局搜索,但是仅限于C/C++
    • gtags,和cscope差不多,提供了gtags生成索引,和gtags-cscope搜索索引。

    gtags

    :: GTAGS:所有变量,函数定义的相关信息
    :: GRTAGS:所有变量,函数被引用的相关信息
    :: GPATH:源代码中每个文件的信息

    跟cscope差不多,不过gtags支持的语言更多,并且和编辑器无关,所以自己也提供了一个搜多功能。

    综上所以现在最先进的索引系统自然是gtags的索引系统,再展示一个这个表格(https://github.com/oracle/opengrok/wiki/Comparison-with-Similar-Tools)可以看到

    本来在写这篇博客之前我是打算再深入了解一下gtags的使用细节,然后看到上面的对比我懵了,OpenGrok好像也不错诶,gtags的搜索支持正则,OpenGrok的支持AND和OR这些搜索语法,并且OpenGrok还多支持一个CVS的历史文件,这个功能有点诱人。

    我还得考虑一下用哪个。

    End。

  • 一本书读懂TCP/IP 读书笔记

    TCP/IP是什么

    互联网包含因特网,因特网包含万维网。

    物理层

    物理层解决最基础的传送通道,涉及问题主要是建立、维护和释放物理链路所需的机械的、电气的/光学的、功能的和规程的特性

    数据链路层

    在相邻的网络节点之间提供简单的、传输以帧为单位的数据,同时它还负责数据链路的流量控制、差错控制。大家要理解,这条链路不具备任何路径选择和转发功能,你可以把它仅仅理解为“一条封闭的路”,除了两端,没有额外出入口。

    本层要提供一定的差错检验和纠正机制。以太网就属于这一层。所以你会经常听到“以太网帧”这一术语。

    传统IP技术就是无连接服务,而改造为MPLS(多协议标签交换)网络后,就属于面向连接的服务了。

    网络层最知名的协议就是IP。

    大名鼎鼎的TCP和UDP就属于传输层。

    表示层就处理通信进程之间交换数据的表示方法,包括语法转换、数据格式的转换、加密与解密、压缩与解压缩等。

    OSI是哲学,而不仅仅是技术!

    以太网是IP通信中数据链路层最常见的形式,除此之外还有PPP、HDLC等。10Gbit/s以下的以太网一般应用于局域网,而PPP、HDLC则应用于广域网范围内居多。

    TCP是一个面向连接的、可靠的协议。它将一台主机发出的字节流无差错地发往互联网上的其他主机。在发送端,它负责把上层传送下来的字节流分成报文段并传递给下层。在接收端,它负责把收到的报文进行重组后递交给上层。TCP还要处理端到端的流量控制。UDP是一个不可靠的、无连接协议,主要适用于不需要对报文进行排序和流量控制的场合。

    由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭

    令牌环网的设计

    高效利用率,但是容错不行,通过抢夺一个令牌互相发言

    以太网的设计点,直接发言,冲突了就随机等待,

    以太网的优点:简单,灵活

    以太网的缺点,不能控制流量和优先级,

    ip层

    ip层以下只认识mac地址,所以局域网内的查找需要先广播一次,然后记住ip对应的mac地址。

    一般查找dns的顺序是dns缓存->hosts文件->dns服务器

    端口:有两种,一种是硬件的路由的端口这种,另一种是应用层的逻辑端口,例如www是80端口。

    在基础层 无连接的技术 > 有链接的技术

    局域网中枢——以太网交换机

    通常情况下,网络中实际的数据流特性与人们在局域网普及之前的估计不同,如果要花大力气去研究数据流特征并用复杂的方案去应对每个细节,不如用一些简单的技术体制来满足大部分的要求。谁最简单?当然非以太网莫属喽!

    今天的全球以太网市场上,三巨头鼎力:思科网络、华为、惠普。

    这一设计简单、便捷、灵活性强,随时可以添加、删除主机,方便非专业人士组网。

    CSMA/CD(载波侦听多路复用-冲突检测),这是以太网的精髓所在!

    当今的以太网大都以以太网交换机为核心来进行网络连接和组织,这样,以太网的拓扑结构就成了星型。

    交换机记录的是每个mac地址的物理接口是哪个,路由器则是用路由表 二层交换机

    因此有人把VLAN称为“广播域”。

    在一个以太网内的主机,如果被划分在不同的VLAN里,他们之间的通信,必须经过路由设备(路由器或者三层交换机)进行

    勤奋的引路者——路由器

    路由器是组成IP网络最主要的选路设备

    路由器专门执行各种路由协议(后面章节将专门介绍路由协议),并进行数据包的转发工作。

    每台路由器都可以按照一定规则动态更新它的记忆,也就是更新自己的路由表(这叫动态路由)。

    核心路由器(也可称作“骨干层路由器”,CR)、汇聚路由器(有人称作“分发层路由器”,BR)和接入路由器(又称“访问层路由器”,AR)

    一般要采用控制部件热备份、双电源热备份、双数据通路等技术保障硬件可靠性。

    信息大脑——主机

    在IBM创立之初,该公司的主要业务是商用打字机、员工计时系统、磅秤(雷倒!)、自动切肉机(再次雷倒!),而后转为文字处理机、穿孔卡片设备等。第二次世界大战期间,IBM甚至还造过武器。 今天的IBM是一艘工业企业的超级航母,在多个领域都有很高造诣。

    不可否认的是,当前主流的操作系统都包含了大量的应用程序,Windows就自带各种游戏、记事本、写字板、网页浏览器(Internet Explorer)等,这些都是商业运作的需要,而非操作系统的初衷。

    人们按照数据模型原理,将数据库系统分成网状数据库、层次数据库和关系型数据库三类。

    IP世界的道路构成

    为了区分单模光纤和多模光纤,人们把单模光纤外套做成黄色,而多模光纤做成桔红色或者灰色。

    TCP/IP经营管理者

    世界上没有绝对的自由。哲学家说:自由是相对的,不自由是绝对的。 世界上没有绝对的开放。IP专家说:IP的开放是相对的。

    关键规则之一:以太网编码规则

    MAC地址长度为48位二进制,前24位由设备商标识符,后24位是设备商自行分配的序列号,常表示为12位的十六进制数。

    关键规则之二:IPv4地址的定义

    不带子网掩码的IP地址是无效的IP地址。

    10.0.0.0/8:10.0.0.0~10.255.255.255; 172.16.0.0/12:172.16.0.0~172.31.255.255; 192.168.0.0/16:192.168.0.0~192.168.255.255。

    关键规则之十一:安全法

    不安全是绝对的,安全是相对的。

    传输层的TCP协议被用来提供IP的可靠传输,但并非安全传输。

    安全问题和效率问题,都是相对的。网络建设者需要把握其中的尺度,避免造成资源浪费和用户体验度的降低。而之所以设计三层安全机制,就是从安全和效率两方面综合评估而制定的。

    关键规则之十二:网络地址转换法

    NAT英文全称是“Network Address Translation”

    LAN概述

    VLAN所指的LAN是广播域,即广播帧(目标MAC地址全部为1)所能传递到的范围,亦即能够直接通信的范围。

    常见中继设备介绍

    一个数据包从一台网络设备到另一台,端口号、源和目的IP地址在过程中不会改变,MAC地址会随之发生变化。

    三层交换就是二层交换技术+三层转发技术

    路由协议

    路由协议是为了满足路由器获取路由表的需要而制定的标准化协议

    应用

    移动互联网——为内容而战

    游戏、导航、音乐、视频、图片、电影、图书、管理软件……在应用商店里应有尽有。 苹果的创造性激发了全行业的思维模式的解放。步后尘的企业一个接着一个。

    PTV、OTT TV网络电视技术

    不论是IPTV还是OTT TV对广电冲击很大,原本电脑、手机、互联网都是工信部的天下,而电视屏幕、各种内容是广电总局的地盘,两者井水不犯河水,现在大家都看好客厅电视屏幕这一块市场,电信运营商搞IPTV,互联网公司搞“盒子”,吃肉吃到广电总局碗里来了,它当然坐不住了,绞尽脑汁,维护自己的利益。先是下发文件,要求:互联网电视集成平台不能与设立在公共互联网上的网站进行相互链接,不能将公共互联网上的内容直接提供给用户。互联网电视集成机构所选择合作的互联网电视终端产品,只能唯一连接互联网电视集成平台,终端产品不得有其他访问互联网的通道,不得与网络运营企业的相关管理系统、数据库进行连接。按照这个规定,盒子不能提供优酷、土豆、Youtube……的内容,甚至连上网浏览都是打擦边球。

    IPRAN分组传送技术

    人们白天在工作区上班,使用手机连上B基站上网(友情提醒,上班时候上网违反劳动纪律)

    云计算

    SaaS: 软件即服务,用户无需安装软件,而是用标准客户端(浏览器)即可使用软件服务,如Google Docs。

    IaaS: 基础设施即服务,用户无需购买硬件,而是租赁云计算提供商的基础设施,部署自己的OS,进行自己的计算,这里的用户一般是商业机构而不是终端消费者。IaaS最有名的提供商是亚马逊的AWS。

    PaaS:与IaaS类似,只是用户不再控制OS,而是利用云计算提供商提供的OS和开发环境做开发。

    物联网

    物联网(Internet of Things)是通过射频识别(RFID)、红外感应器、全球定位系统、激光扫描器等信息传感设备,按约定的协议,把任何物品与互联网连接起来,进行信息交换和通信,以实现智能化识别、定位、跟踪、监控和管理的一种网络。

    SDN软件定义网络

    SDN的本质就是软件定义网络,也就是说希望应用软件可以参与对网络的控制管理,满足上层业务需求,通过自动化业务部署简化网络运维,这是SDN的核心诉求。

    其他思考

    对于这些知识,要了解到什么样的深度呢。取决于阅读的目的,或者是需要解决的问题,现在我就不需要详细阅读每一个实现的标准细节,但是又要了解具体的过程细节。

    我的目的就是解决游戏卡顿,了解网络标准的细节。

  • 代理服务器的理解

    nginx是反向代理,就一直知道反向代理是访问服务,但访问的实际是中间服务器,中间服务器代理到实际服务器去获取结果,再返回到客户端。

    其实我一直没有get到反向代理的含义是什么,今天读这篇文章就get到了。

    正向代理是连接一台中间服务器,所有的请求都由服务器代理转发,核心不是后端的业务,而是客户端主动用服务器代理访问,类似于VPN。

    主要作用可能是:

    • 隐藏自己
    • 访问无法访问的服务
    • 加速访问服务

    反向代理是服务端自带的代理服务器,客户端并不知道访问的是个代理服务器,对客户端来说就像是原始服务器,而反向代理服务器是服务开发方使用的,主要作用是:

    • 保护和隐藏原始资源服务器
    • 负载均衡
    • 缓存加速

    引用:

    https://www.cnblogs.com/dgwblog/p/9630601.html

  • [转] CAP定理的证明

    CAP介绍

    在理论计算机科学中,CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer’s theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点:

    • 一致性(Consistency) (等同于所有节点访问同一份最新的数据副本)
    • 可用性(Availability)(每次请求都能获取到非错的响应——但是不保证获取的数据为最新数据)
    • 分区容错性(Partition tolerance)(以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择)

    对于分布式系统来讲,避免不了分区状态和分区恢复状态,一旦进入,我们必须在C和A之间做出妥协,这个妥协也不是说你只选择C而完全不考虑A,可以在CA的实现比例上进行权衡,比如主A辅C,实现基本可用,最终一致。BASE理论就是用来解决这个问题。

    BASE理论

    BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent (最终一致性)三个短语的缩写,是对 CAP 中 AP 的一个扩展。
    基本可用:分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用。
    软状态:允许系统中存在中间状态,这个状态不影响系统可用性,这里指的是 CAP 中的不一致。
    最终一致:最终一致是指经过一段时间后,所有节点数据都将会达到一致。

    BASE 解决了 CAP 中理论没有网络延迟,在 BASE 中用软状态和最终一致,保证了延迟后的一致性。
    BASE 和 ACID 是相反的,它完全不同于 ACID 的强一致性模型,而是通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态。

    BASE理论的意义在于,我们不必在A或C中做出选择,可以实现部分的A和C

    异步网络
    在异步网络模型中,没有统一时钟,所有节点仅根据接收到的消息和本地的计算进行决策。

    定理一:在一个异步网络模型中,没有可能实现一个满足以下属性的读写数据对象:
    1、可用性
    2、一致性
    对于所有对等运算(包括消息会丢失的)
    证明:
    假设存在一个算法A满足这些条件:一致性、可用性、分区容忍性。我们构造一次A的执行,包括一个返回非一致结果的请求。假设网络包含至少两个节点,那么它可以被分为不相关的非空集合:{G,H}。假设所有G和H之间的通讯消息都丢失,这是可能的。如果这时在G上有一个写操作,接着H上有一个读操作,那么读操作将无法返回早些的写操作。

    推论一:在一个异步网络模型中,没有可能实现一个满足以下属性的读写数据对象:
    1、可用性,所有对等运算
    2、一致性,所有对等运算,但消息不会丢失
    证明:
    主要问题是在异步网络模型中一个算法没有办法去判断一个消息是否丢失或者在传输通道中被延迟。因此,如果在运算中不会丢失任何消息的前提下存在一个能够保证一致性的算法,那么该算法也能够在所有运算(消息可能丢失)情况下保证一致性。这将与定理一矛盾。

    部分同步网络
    假设一个部分同步的网络模型,在这里,所有的节点都有一个时钟,并且所有的时钟以一个相同的速度增长。然而,这些时钟并不是同步的,在相同的时间,它们显示不同的时间值。事实上,时钟扮演计时器的角色:处理器可以根据本地状态变量去衡量流逝了多少时间。一个本地的计时器可以用来调度某事件之后的多长时间间隔进行另一个操作。进一步地,假设每一个消息要么在给定的时间s内到达,要么丢失。并且,所有的节点在给定时间t内处理完一个接收到的消息。

    定理二:在一个部分同步网络模型中,没有可能实现一个满足以下属性的读写数据对象:

    1、可用性
    2、一致性

    对于所有对等运算(包括消息会丢失的)

    证明:
    证明方法与定理一一样。
    但是在部分同步模型中,类似与异步模型推论一的结论就不存在了,因此推论一的假设基于节点无法判断一个消息是否丢失。而在部分同步模型中,存在部分同步算法可以在所有消息传送正常的情况下返回一致性的数据,而仅仅在消息丢失时返回非一致性数据。对于读或写请求,节点发送一个消息给另一个节点,如果消息返回了,那么节点发送请求的数据;如果消息在给定的2s+t时间内没有返回,那么该节点断定消息丢失了,节点就可能返回一个不一致的请求数据。

    理论参考价值

    在Google使用廉价的PC机搭建了强大的、高可靠的计算和存储平台之后,互联网公司一致性地选择使用PC集群支撑全部的业务,这个理论指明了实现满足可用性、分区容忍性的分布式系统是可行的,并且该分布式系统在没有故障的情况下可以提供良好的一致性读写。

    引用: http://blog.fens.me/distribution-cap/

  • 股票软件

    之前想做一个股票软件,想用什么语言什么工具,后来决定用H5,因为方便传播。顺便搜了一下,其实有不少类似的H5工具的,稍微看了一下,倒给我一些提示。

    我这个软件工作内容也非常简单,输入你购买的股票,然后输出若干个推荐购买的短期股票。

    然后这里就有个小问题了,按照我前一篇的文章(点击跳转),把股票当初长期来说是不涨不跌的,但每天都是一个独立的随机涨跌的事件,那么,如何推荐。

    1. 根据我的模型,剔除所有相关板块,例如我买了某只高科技板块的股票,就尽量不在购买这个板块的股票;
    2. 可以选择短期跌了之后轻微抬头的股票,这就涉及到具体的股票数据分析;
    3. 基于上面的第二点,可以进一步引入K线之类的传统数据理论分析;
    4. 从其他工具里看到的更多的是咨询,将来会涨的股票,相当于从原来的独立随机涨跌,变成了涨的偏差更大一点的概率。

    总结来说,我需要学习的是

    • 小程序的工具和语言;
    • 需要一个服务端,分析不能放在本地;
    • 需要学习了解更多股票常用的理论工具,如K线等;
    • 关注咨询,考虑如何去获取这些咨询。

    虽然我觉得咨询这一点,通过网络总还是会慢,毕竟不是第一手信息了,但是相比大部分网友和股民,自动化的工具能够快人一步,虽然我也没想好具体怎么抓这些数据,但是可以从这角度也尝试一下。

    End.

  • 一个小的通用缓存库

    背景

    (使用python语言)

    非常常见的一个应用场景, 经常会有这样的场景,某个服务需要大量读取db,为了缓解db的压力,可以在服务上做一些db的缓存,降低db的压力,提高服务的效率。

    重复写多了就想独立成一个小模块,只需要简单的接口就能在进程上提供缓存命中的库,而且似乎还能提供一种更加通用的功能。遇到了这个场景不止一次,之前每次在这个场景下,我都是重复的用两个dict,一个存上次访问时间,一个存上次访问到的数据,然后是在下次访问的时候判断是否需要重新拉取db。

    这里有一个细节是从来不会主动删除数据,在访问的数据量不大的情况下,我们的业务是能够承受这种级别的内存缓存数据的,之前就没想那么多。

    但这次的工作场景是存不下的,必须要主动删除不必要的缓存数据,就想做一个通用一点的接口。

    接口

    缓存系统内存空间是有上限的,需要主动过期不必要的缓存,常见的选择策略有下面几种

    • Least-Recently-Used(LRU)
    • Least-Frequently-Used(LFU)
    • First in First Out(FIFO)

    提供一个类作为缓存系统,缓存数据为基础缓存存储单元,本身的数据结构:

    1. 外部定时器回调(也可以用单次访问来做触发)
    2. 基础缓存存储单元缓存最大数量
    3. 缓存数据的dict
    4. 过期策略(LRU,LFU)
    5. 缓存过期时间(即使一直在内存中,也需要重新读db)
    6. 使用者要提供缓存数据未命中时,数据生成函数(db访问函数)
    7. 缓存过期回调函数

    基础缓存存储单元本身包含:

    1. 缓存数据的key
    2. 缓存数据本身
    3. 缓存上次访问时间
    4. 缓存上次刷新时间
    5. 过期回调函数

    需要提供的接口:

    1. 缓存删除函数:根据策略,将缓存删除到只剩最大数量;
    2. 访问缓存数据(触发缓存删除函数,并且不存在则触发生成函数);
    3. 新增缓存数据的函数,这个函数会作为数据生成函数的参数提供;

    End。

  • 读书笔记之——Docker基础与实战(基础篇)

    序

    之前读过《第一本Docker书》,所以对docker的使用和概念都是大概清楚的,只是没有实际搭建使用过,这次读本书会配合把本博客使用docker部署,但这本书还是看的很快,笔记做的不一定易懂,不过也没想过是为其他人提供(为主)的,毕竟我做笔记主要是为了让自己阅读可以保持一个良好的习惯,增强自己的阅读效果。

    因为是实用工具类的书,所以笔记还是会稍微长一点,也会转述很多书上的内容下来。

    第一章、Docker

    随着互联网的发展,服务器市场快速转向云环境,但大量服务器的购买和配置会很麻烦,于是出现了“不可变基础设施”的概念,指主机OS和服务器运行环境分离,设置一次环境便不用再设置,每次发布软件只需重新生成镜像就好了。

    最初出现的是虚拟机,但虚拟机会对硬件虚拟化或半虚拟化,每个运行的软件打包要分别对OS、执行文件库和应用程序打包,软件的镜像会过分的大。于是Docker就出现了,Docker对操作系统而不是硬件进行抽象,更加轻量化,每个软件只需要库和应用程序的抽象,减小了镜像的体积。

    Docker最初利用了linux提供的lxc这种系统级虚拟化,它又使用了chroot和cgroups隔离用户空间和硬件空间,从docker0.9版本开始,人们开始开发lxc的替代品libcontainer。

    在配置时,可以进行切换,libcontainer表示为native,LXC表示为lxc。

    Docker有容器和镜像的概念,镜像就是软件,容器就是一个运行中的镜像,一般开发人员开发好一个软件,然后打包相关的以来成镜像,交付给运维人员,运维人员用docker批量运行容器,大概是这样的一个关系。

    Docker另一个非常有特色的地方在于,它使用了类似与git版本管理的方式保存镜像,每次只保存变化的部分,因此每一个更新软件的包都是非常小的。

    读后感

    和《第一本Docker书》同章节对比了一下,《第一本Docker书》的重点放在docker的介绍以及能干什么,而本书本章的重点放在和虚拟机的对比上,以及docker的优点是什么。

    第二章、安装Docker

    (略)

    第三章、使用Docker

    注意:必须总是以root权限运行Docker。

    docker的指令都是以

    $ docker <command>

    运行的,例如docker run, docker push。
    在学习基本用法前,先从Docker Hub下载并运行镜像。

    Docker通过Docker Hub(https://registry.hub.docker.com)搭建镜像共享生态系统。著名的发行版都可以在这里找到镜像,与镜像相关的所有命令默认都设置可以使用Docker Hub。

    1、docker search
    使用docker search 命令在Docker Hub中搜索镜像。

    [~]$ sudo docker search ubuntu
    INDEX       NAME                                        DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    docker.io   docker.io/ubuntu                            Ubuntu is a Debian-based Linux operating s...   5013      [OK]       
    docker.io   docker.io/ubuntu-upstart                    Upstart is an event-based replacement for ...   68        [OK]       
    docker.io   docker.io/rastasheep/ubuntu-sshd            Dockerized SSH service, built on top of of...   47                   [OK]
    docker.io   docker.io/consol/ubuntu-xfce-vnc            Ubuntu container with "headless" VNC sessi...   29                   [OK]
    docker.io   docker.io/torusware/speedus-ubuntu          Always updated official Ubuntu docker imag...   27                   [OK]
    docker.io   docker.io/ubuntu-debootstrap                debootstrap --variant=minbase --components...   27        [OK]       
    docker.io   docker.io/ioft/armhf-ubuntu                 [ABR] Ubuntu Docker images for the ARMv7(a...   19                   [OK]
    docker.io   docker.io/nickistre/ubuntu-lamp             LAMP server on Ubuntu                           10                   [OK]
    docker.io   docker.io/nuagebec/ubuntu                   Simple always updated Ubuntu docker images...   9                    [OK]
    docker.io   docker.io/nickistre/ubuntu-lamp-wordpress   LAMP on Ubuntu with wp-cli installed            7                    [OK]
    docker.io   docker.io/nimmis/ubuntu                     This is a docker images different LTS vers...   5                    [OK]
    docker.io   docker.io/maxexcloo/ubuntu                  Base image built on Ubuntu with init, Supe...   2                    [OK]
    docker.io   docker.io/admiringworm/ubuntu               Base ubuntu images based on the official u...   1                    [OK]
    docker.io   docker.io/darksheer/ubuntu                  Base Ubuntu Image -- Updated hourly             1                    [OK]
    docker.io   docker.io/jordi/ubuntu                      Ubuntu Base Image                               1                    [OK]
    docker.io   docker.io/datenbetrieb/ubuntu               custom flavor of the official ubuntu base ...   0                    [OK]
    docker.io   docker.io/esycat/ubuntu                     Ubuntu LTS                                      0                    [OK]
    docker.io   docker.io/konstruktoid/ubuntu               Ubuntu base image                               0                    [OK]
    docker.io   docker.io/labengine/ubuntu                  Images base ubuntu                              0                    [OK]
    docker.io   docker.io/lynxtp/ubuntu                     https://github.com/lynxtp/docker-ubuntu         0                    [OK]
    docker.io   docker.io/teamrock/ubuntu                   TeamRock's Ubuntu image configured with AW...   0                    [OK]
    docker.io   docker.io/ustclug/ubuntu                    ubuntu image for docker with USTC mirror        0                    [OK]
    docker.io   docker.io/vcatechnology/ubuntu              A Ubuntu image that is updated daily            0                    [OK]
    docker.io   docker.io/webhippie/ubuntu                  Docker images for ubuntu                        0                    [OK]
    docker.io   docker.io/widerplan/ubuntu                  Our basic Ubuntu images.                        0                    [OK]
    

    2、docker pull
    从Docker Hub拉取镜像:

    [~]$ sudo docker pull ubuntu:latest
    

    就成功拉下来了ubuntu linux的镜像,接下来我就能在我的centos上拥有ubuntu的运行环境和库依赖了。
    命令格式为:docker pull <镜像名称>:<标签>。标签latest最新版本,也可以是14.04, 12.10。另外镜像名字中可以在’/’之前制定用户名,比如:yylogo/ubuntu就是拉取我上传的ubuntu,官方镜像不会出现用户名。

    3、docker images
    可以列出本机已经下载的镜像。

    [~]$ sudo docker images
    [~]$ sudo docker images ubuntu

    第一个命令查看本地已经下载的所有镜像,第二个查看镜像名称相同但标签不同的镜像。

    4、docker run
    创建容器,运行容器。
    如前所述,本地已经拥有别人创建的镜像,现在需要使用镜像创建容器,并且将容器运行起来,需要使用的就是docker run命令。
    命令格式:docker run <选项> <镜像名称> <要运行的文件>,如:

    [~]$ sudo docker run -i -t --name hello ubuntu /bin/bash
    root@7db6a454c06e:/#

    其中有三个选项分别是-i, -t, –name.
    他们的作用分别是:
    使用-i(interactive) 选项将容器的STDIN开启,-t(Pseudo-tty)选项告诉docker为容器分配一个伪tty终端,这样新创建的容器才能提供一个交互式shell,若不要运行一个后台服务的容器,则这两个参数是最基本的参数。
    这个–name用于指定容器名称。若不指定名称,Docker会自动生成名称并进行指定。
    现在已经生成了一个和主机OS完全隔离的空间,可以使用exit退出,因为在ubuntu镜像中直接运行/bin/bash可执行文件,所以退出后容器也会终止(stop)。
    7db6a454c06e是docker生成的容器ID。

    5、使用ps命令查看容器列表

    sudo docker ps # 查看所有正在运行的容器
    sudo docker ps -a # 查看所有容器

    6、使用start命令启动容器

    sudo docker start hello
    sudo docker ps

    命令格式为:docker start <容器名称>,也可以使用容器ID代替容器名称。

    7、使用restart命令重启容器
    与重启OS类似,可以重启某个容器。

    sudo docker restart hello

    命令格式为:docker restart <容器名称>,也可以使用容器ID代替容器名称。

    8、使用attach命令连接容器
    docker容器启动的时候会按照docker run命令制定的参数来运行,因此启动后会运行一个交互式shell,可以用docker attach重新附着到该容器的会话上,执行:

    sudo docker attach hello

    但如果运行DB或服务应用程序将无法输入只能看到输出。

    9、使用exec命令从外部运行容器内的命令
    命令格式为:docker exec <容器名称> <命令 <命令参数> >,可以使用容器ID代替名字,只有在容器运行时本命令可用。

    sudo socker exec hello echo "Hello World"

    10、使用stop命令终止容器
    命令格式为:docker stop <容器名称> 名称可用容器ID替代,效果可以使用docker ps查看。

    11、使用rm命令删除容器
    命令格式为:docker rm <容器名称> 也可以用容器ID替代,效果可以用docker ps查看。
    记得必须使用root权限。

    12、使用rmi命令删除镜像(images)
    可以删除指定镜像。
    命令格式为:docker rmi <镜像名称>:<标签>,也可以用镜像ID替代,效果用docker images查看。
    如果不用标签则删除该镜像名称所有标签,如:docker rmi ubuntu。

    读后感

    和《第一本Docker书》同章节对比了一下,介绍的命令少一些,而且命令讲解上也输给《第一本Docker书》。

    另外读到这里,别以为你会docker了,你只是会用docker的基本命令了。

    第四章、创建Docker镜像

    编写地一个Dockerfile:

    [~]$ cd /tmp/
    [tmp]$ mkdir example
    [tmp]$ cd example/
    [example]$ vim Dockerfile
    #输入下面这些:
    FROM ubuntu:latest
    MAINTAINER Foo Bar <foo@bar.com>
    
    RUN apt-get update
    RUN apt-get install -y nginx
    RUN echo "ndaemon off;" >> /etc/nginx/nginx.conf
    RUN chown -R www-data:www-data /var/lib/nginx
    
    VOLUME ["/data", "/etc/nginx/site/enabled", "/var/log/nginx"]
    
    WORKDIR /etc/nginx
    
    CMD ["nginx"]
    
    EXPOSE 80
    EXPOSE 433
    

    上述示例基于Ubuntu 创建Docker镜像,且安装nginx服务器。

    FROM:指定基于的基础镜像。Docker镜像基于已创建的镜像。
    MAINTAINER:维护者信息
    RUN:运行shell脚本或命令。
    VOLUME:要与主机共享的目录,也可以在docker run命令中使用-v选项进行设置。例如:-v /root/data:/data将主机的/root/data目录连接到Docker容器的/data目录。
    CMD:指定容器启动时执行的文件或shell脚本。
    WORKDIR:为CMD中设置的可执行文件设置运行目录。
    EXPOSE:与主机相连的端口号。

    创建镜像的命令是docker build,命令格式:docker build <选项>

    sudo docker build --tag hello:0.1 .
    sudo docker images #稍等片刻即可以生成镜像文件,显示镜像目录.
    sudo docker run --name hello-nginx -d -p 80:80 -v /root/data:/data hello:0.1

    最后一行的参数含义如下:
    -d 选项在后台运行容器.
    -p 80:80 选项将主机的80端口与容器的80端口连接起来,并暴露到外部,接下来使用<主机IP>:80就能访问容器的80端口(http://127.0.0.1:80/)了.
    -v 在前面有介绍,将主机的目录映射到容器的目录中去。

    第五章、查看Docker

    1、使用history查看镜像历史:

    sudo docker history hello:0.1

    命令格式:docker history <镜像名称>:<标签>,可以用镜像ID代替名称。

    2、使用cp命令复制文件
    将容器中的目录复制出来

    sudo docker cp hello-nginx:/etc/nginx/nginx.conf ./

    命令格式:docker cp <容器名称>:<路径> <主机路径>

    3、使用commit命令从容器修改中创建镜像
    假设hello-nginx容器中的文件内容发生变化,将容器创建为镜像文件。

    sudo docker commit -a "Foo Bar <foo@bar.com>" -m "add hello.txt" hello-nginx hello:0.2   # 用docker images查看效果

    4、用diff命令检查容器文件的修改

    sudo docker diff hello-nginx

    命令格式为docker diff <容器名称>,也可以用容器ID替代名称。
    其中A是添加的文件,C是修改的文件,D是删除的文件。

    5、使用inspect命令查看详细信息
    命令格式:docker inspect <容器名称 或 镜像名称> 可以用容器ID或镜像ID替换。

    第六章、灵活使用Docker

    6.1、搭建Docker私有仓库

    docker命令默认使用Docker Hub,下面创建私有仓库服务器。
    Docker仓库服务器名为Docker注册(registry)服务器,使用docker push上传,docker pull下载。
    将镜像数据存储到本地使用的命令是:

    sudo docker pull registry:latest  # 拉取注册服务器镜像
    sudo docker run -d -p 5000:5000 --name hello-registry 
        -v /tmp/registry:/tmp/registry 
        registry      # 创建注册服务器容器并运行,运行端口是5000,并且将镜像文件保存在主机的/tmp/registry下

    部署好了docker私有仓库如何使用呢?

    sudo docker tag hello:0.1 localhost:5000/hello:0.1
    sudo docker push localhost:5000/hello:0.1

    创建标签的命令格式为:docker tag <镜像名称>:<标签> /<镜像名称>:<标签>
    上传镜像的命令格式为:sudo docker push /<镜像名称>:<标签>
    在上传之前一定要先新建一个tag, 相当与指定这个镜像是来自某个注册服务器,然后我的理解是,在任何一个命令,镜像名称前面都可以直接加上/。
    后面提到了如何使用非本地数据存储如Amazon S3,应该是registry内置Amazon S3的支持,所以在运行时指定相应的环境变量即可。

    6.2、连接Docker的容器

    Docker创建镜像时,虽然可以把Web服务器,DB都安装在其中,但一般的做法是分别生成镜像。这样生成镜像时经常需要某个镜像的端口不对外暴露,那么会需要连接相邻的容器,比如Web服务器对外暴露端口,并且连接不对外暴露端口的DB,就可以做到良好封装的数据交换。

    连接容器时要在docker run命令中使用–link选项,格式为–link <容器名称>:<别名>,之后在这个容器内使用<别名>:<端口号>就能直接连接到所link的那个容器了。

    6.3、连接到其他服务器的Docker容器

    前面说了,–link可以将统一服务器的多个容器连接在一起,下面介绍使用Ambassador容器链接不同服务器的容器。

    如上图,Ambassador容器是运行在两个不同服务器的中间容器,可以在客户端容器和服务端容器不感知的情况下就能跨机器部署容器。
    客户端容器连接客户端Ambassador容器,服务端Ambassador容器连接服务端容器,并且服务端Ambassador容器要对外暴露对应的端口。Ambassador容器是这样一个中间容器。

    6.4、使用Docker数据卷

    Docker一般的数据都是存储在容器内,使用Union File System进行管理,但使用数据卷就有一种插入了一块硬盘一样,将主机某个目录挂在进容器的某个目录下,容器对某目录的操作全部都会落实在主机上,并不会通过Union File System。

    可以直接指定-v /data,设置容器内/data目录为数据卷,docker会自动分配一个路径给容器用于数据卷,可用docker inspect查看。
    但一般的命令格式为-v <主机目录>:<容器目录>
    可以让多个容器共享一个目录。

    6.5、使用Docker数据卷容器

    数据卷容器是设置数据卷的容器,专门提供数据卷供其他容器共享。从普通容器连接到数据卷容器后即可直接访问数据卷容器内的数据卷目录。

    sudo docker run -i -t --name hello-volume -v /root/data:/data ubuntu /bin/bash  #创建数据卷容器
    sudo docker run -i -t --volumes-from hello-volume --name hello ubuntu /bin/bash  #普通容器连接数据卷容器

    主要在于–volumes-from <数据卷容器>,可以直接使用其它容器的数据卷

    6.6、创建Docker基础镜像

    一般创建镜像的方法都是基于Docker Hub提供的官方镜像,但docker提供创建基础镜像的命令:docker import,命令格式是docker import <URL或- > <镜像名称>:<标签>
    觉得不太重要就不转具体细节上来了。

    6.6、在Docker内运行Docker

    书上说这是一个实验性质的功能,在最外曾的docker容器创建时加上–privileged,这个选项使得容器内部可以使用主机的所有Linux内核功能。启动了这个容器,这个容器内在创建容器就和正常创建是一样的了。

    第七章、详细了解Dockerfile

    Dockerfile是比较重要的内容,因为这个是自动化打包和部署所必须要了解的内容。
    前面编写过一次Dockerfile,这里介绍一下细节,编写格式为<命令> <形式参数>,#是注释,命令不区分大小写,但一般使用大写字母。Docker会依据Dockerfile文件中的命令顺序依次执行命令,在Dockerfile中,命令总是以FROM开始,没有则无法创建镜像。
    此外,命令是独立运行的,例如运行RUN cd /home/hello也不会对后面的命令产生影响。
    创建镜像时,要在Dockerfile所在的目录使用docker build命令,使用–tag或-t选项设置镜像名称,若想上传到Docker Hub在/之前添加用户名即可。

    7.1>.dockerignore

    所有位于Dockerfile目录下的文件都称为上下文,特别是在创建镜像时,由于所有的上下文都会传送到Docker守护进程,所以请不要将非必要文件放在该目录,需要忽略文件时使用.dockerignore,类似与.gitingore。

    7.2>FROM

    命令格式:FROM <镜像>或FROM <镜像>:<标签>,前者默认使用latest。

    7.3>MAINTAINER

    设置镜像创造者信息,格式自由。

    7.4>RUN

    用于在FROM中设置的镜像上运行脚本或命令。RUN运行结果会生成新的镜像,运行的详细信息记录在镜像历史,是每一次RUN都会产生一个新的镜像,会影响容器的创建速度,因此一般会在层次和启动速度之间有一个平衡,有两种方式:
    1、RUN <命令>,这种方式会用/bin/sh执行命令,若/bin/sh可执行文件不存在,则无法使用。
    2、RUN [“<可执行文件>”, “<形式参数1>”, “<形式参数2>”…]

    RUN apt-get install -y nginx
    RUN echo "Hello Docker" > /tmp/hello
    RUN ["apt-get", "install", "-y", "nginx"]
    RUN ["/usr/local/bin/hello", "--help"]

    7.5>CMD

    用于设置容器启动时运行的脚本或命令,即使用docker run 命令创建容器或者使用docker start 命令启动容器时运行,有几种方式执行:
    1、用/bin/sh运行命令:CMD <命令>
    2、无shell直接运行:CMD [“<命令>”, “<形式参数1>”, “<形式参数2>”…]
    3、使用ENTRYPOINT时:这个特殊一点,可执行程序是ENTRYPOINT指定,参数由CMD指定。

    ENTRYPOINT ["echo"]
    CMD ["hello"]
    $ sudo docker build --tag example .
    $ sudo docker run example
    hello

    7.6>ENTRYPOINT

    虽然CMD和ENTRYPOINT都可以用于设置容器启动时要运行的命令,但docker run命令二者运行方式不同。
    如下图:
    >Dockerfile

    FROM ubuntu:latest
    CMD ["echo", "hello"]
    ###############
    
    $ sudo docker build --tag example .
    $ sudo docker run example echo world
    world

    从执行结果看,忽略了CMD的内容,下面用ENTRYPONT尝试一次
    >Dockerfile

    FROM ubuntu:latest
    ENTRYPOINT ["echo", "hello"]
    ###############
    
    $ sudo docker build --tag example .
    $ sudo docker run example echo world
    hello echo world

    如果设置了ENTRYPOINT,则run后的参数会变成执行文件的参数。

    7.7>EXPOSE

    用于设置与主机相连的端口号,与docker run中的–expose一致。
    注:只与主机连接,不对外暴露。对外暴露在docker run指定-p、-P选项。

    7.8>ENV

    设置环境变量,应用与RUN, CMD, ENTRYPOINT。

    Dockerfile:
    ENV GOPATH /go
    ENV PATH /go/bin:$PATH

    使用格式为ENV <环境变量><值>

    7.9>ADD

    用于向镜像添加文件,使用格式ADD <要复制的路径> <文件在镜像中的路径>。
    Ps:1、要复制的路径以上下文目录为基准,不能使用上下文以外的文件、目录或绝对路径。
    2、设置为目录时,会复制目录下所有文件。另外,也可以使用通配符。
    3、也可以设置为网络文件URL。
    4、解压缩位于本地的压缩文件。但是对于网络上的压缩文件,只进行解压缩,然后添加整个tar文件。
    5、文件在镜像中的路径必须设置为绝对路径,并且若以/结尾,则创建目录并将文件复制到该目录。
    6、像ADD ./ /hello这样添加当前目录时,.dockerignore文件设置的文件与目录被排除在外。

    7.10>COPY

    向镜像中添加文件,与ADD不同,添加压缩文件时不会解压缩,也不能使用URL,其他条款类似ADD。

    7.11>VOLUME

    用于将目录下的内容存储到主机而非容器。

    Dockerfile
    ################
    VOLUME /data
    VOLUME ["/data", "/var/log/hello"]

    使用格式:VOLUME <容器目录>或VOLUME [“容器目录1”, “容器目录2″…]
    但VOLUME不能设置与主机的特定目录进行连接,若想连接必须在docker run命令中使用-v
    选项指定.

    7.12>USER

    用于设置运行命令的用户帐号,该用户会运用与RUN, CMD, ENTRYPOINT,使用格式为:USER <帐号用户名>,USER后面所有的RUN,CMD,ENTRYPOINT都会得到应用,中间可以设置其他用户以更换用户。

    7.13>WORKDIR

    用于设置执行RUN, CMD, ENTRYPOINT命令的目录,使用格式为WORKDIR <路径>,WORKDIR后面所有的RUN,CMD,ENTRYPOINT都会得到应用,中间可以设置其他路径以更换目录。
    可以使用绝对路径或者相对路径,相对路径是相对与上一个WORKDIR的路径,最初基准为/。

    7.14>ONBUILD

    将当前镜像作为基础镜像创建其他镜像时,ONBUILD指令用于执行一些要出发的操作。ONBUILD制定的命令在构建时不执行,而是在其他子镜像中执行。
    指令格式为ONBUILD <Dockerfile命令><Dockerfile命令的形式参数>,除了MAINTAINER和ONBUILD之外的所有指令都可以使用。
    可以用docker inspect命令查看镜像的ONBUILD指令中定义的内容。

  • SGU 101 Domino 翻译 题解

    101. 骨牌
    时间限制:0.5s
    内存限制:4096KB

      

  • tyvj 字符串的展开 解题报告

      纯水题,竟然花了我好几天的时间,真是无聊,我写了好久的代码!这个情况应付不了a-b-c,我的会转变成ab-c,唉,不解释不解释。很水,自己做吧,上代码(我的代码分层的思想可以参考一下,可能有点OO性质):

    (代码等下发)