卓易科技-业务运维 [上海招聘]

回复

求职招聘信息OpenSkill 发起了问题 • 1 人关注 • 0 个回复 • 219 次浏览 • 2017-03-20 13:46 • 来自相关话题

解锁Python集合推导式和字典推导式

编程语言采菊篱下 发表了文章 • 0 个评论 • 165 次浏览 • 2017-03-19 22:23 • 来自相关话题

集合推导式

集合推导式(set comprehensions)跟列表推导式也是类似的, 唯一的区别在于它们使用大括号{}表示。Code:
sets = {x for x in range(10)}
Result:
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}



集合解析把列表解析中的中括号变成大括号,返回集合。
 
下面我们来个应用场景,一直一个列表中有很多元素,我们做到快速去重。Code:
heavy = {x for x in [2, 3, 5, 3, 5, 2, 6]}
print(heavy)
Result:
{2, 3, 5, 6}集合推导式生成内容,结果要是可hash的:





字典推导式

字典推导式(dict comprehensions)和列表推导的使用方法也是类似的。




字典解析也是使用大括号包围,并且需要两个表达式,一个生成key, 一个生成value 两个表达式之间使用冒号分割,返回结果是字典.

说了这么多推导式,为什么没有元组推导式呢,元组和列表的操作几乎是一样的,除了不可变特性以外Code:
tuple([x for x in range(10)])
Result:
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) 查看全部


集合推导式


集合推导式(set comprehensions)跟列表推导式也是类似的, 唯一的区别在于它们使用大括号{}表示。
Code:
sets = {x for x in range(10)}
Result:
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
type.png

集合解析把列表解析中的中括号变成大括号,返回集合。
 
下面我们来个应用场景,一直一个列表中有很多元素,我们做到快速去重。
Code:
heavy = {x for x in [2, 3, 5, 3, 5, 2, 6]}
print(heavy)
Result:
{2, 3, 5, 6}
集合推导式生成内容,结果要是可hash的:
hashable.png


字典推导式


字典推导式(dict comprehensions)和列表推导的使用方法也是类似的。
dictreb.png

字典解析也是使用大括号包围,并且需要两个表达式,一个生成key, 一个生成value 两个表达式之间使用冒号分割,返回结果是字典.

说了这么多推导式,为什么没有元组推导式呢,元组和列表的操作几乎是一样的,除了不可变特性以外
Code:
tuple([x for x in range(10)])
Result:
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

Python使用类来写装饰器

编程语言采菊篱下 发表了文章 • 0 个评论 • 128 次浏览 • 2017-03-19 17:37 • 来自相关话题

前两天发现了装饰器可以直接使用类来写,分享一下,需要用类里面的__call__方法,__call__方法就是可以把这个实例当成一个函数来调用,如果正常使用类里面的方法的话,实例方法要先实例化类,然后才能调用,静态方法、类方法则需要用类名或者实例化之后的对象来调用,而实例化之后的这个对象,是不能被调用的,__call__方法就是把这个实例变成一个可以调用的对象,也就是说实例化之后,这个对象就可以和一个普通函数一样被调用。

示例代码如下:
class Foo:
def __call__(self, *args, **kwargs):
print('call....')
def test(self):#
print('test....')
if __name__ == '__main__':
t = Foo()#实例化类
t.test()#正常调用实例方法
t()#直接调用实例化之后的对象运行结果:
>>>test.... #这个是调用test方法的时候输出的
>>>call....#这个是执行调用这个实例化之后的方法输出的理解了上面的之后,就可以使用class来写一个装饰器了,计算程序的运行时间,当然思想和以前用函数写装饰器是一样的
class Fuck(object):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
import time
start_time = time.time()
res = self.func(*args, **kwargs)
end_time = time.time()
print('the function "%s" run time is %s' % (self.func.__name__,
(end_time - start_time)))
return res
@Fuck
def run(name):
import time
time.sleep(1)
return 'sb_%s' % name
print(run('hyf'))运行结果:
>>>the function "run" run time is 1.0001001358032227#这个是装饰器帮我们计算的函数运行时间
>>>sb_hyf#这个是正常运行run函数的时候,返回的值
原文地址:http://www.nnzhp.cn/blog/2017/01/16/1/  查看全部
前两天发现了装饰器可以直接使用类来写,分享一下,需要用类里面的__call__方法,__call__方法就是可以把这个实例当成一个函数来调用,如果正常使用类里面的方法的话,实例方法要先实例化类,然后才能调用,静态方法、类方法则需要用类名或者实例化之后的对象来调用,而实例化之后的这个对象,是不能被调用的,__call__方法就是把这个实例变成一个可以调用的对象,也就是说实例化之后,这个对象就可以和一个普通函数一样被调用。

示例代码如下:
class Foo:
def __call__(self, *args, **kwargs):
print('call....')
def test(self):#
print('test....')
if __name__ == '__main__':
t = Foo()#实例化类
t.test()#正常调用实例方法
t()#直接调用实例化之后的对象
运行结果:
>>>test.... #这个是调用test方法的时候输出的
>>>call....#这个是执行调用这个实例化之后的方法输出的
理解了上面的之后,就可以使用class来写一个装饰器了,计算程序的运行时间,当然思想和以前用函数写装饰器是一样的
class Fuck(object):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
import time
start_time = time.time()
res = self.func(*args, **kwargs)
end_time = time.time()
print('the function "%s" run time is %s' % (self.func.__name__,
(end_time - start_time)))
return res
@Fuck
def run(name):
import time
time.sleep(1)
return 'sb_%s' % name
print(run('hyf'))
运行结果:
>>>the function "run" run time is 1.0001001358032227#这个是装饰器帮我们计算的函数运行时间
>>>sb_hyf#这个是正常运行run函数的时候,返回的值
原文地址:http://www.nnzhp.cn/blog/2017/01/16/1/ 

解锁Python列表推导式

编程语言采菊篱下 发表了文章 • 0 个评论 • 161 次浏览 • 2017-03-18 00:28 • 来自相关话题

Pythonic的核心就是Python之禅,而Python的列表推导式就得以很好的体现。

列表推导式

定义:
列表推导式(又称列表解析式)提供了一种简明扼要的方法来创建列表。

它的结构是在一个中括号里包含一个表达式,然后是一个for语句,然后是0个或多个for或者if语句。那个表达式可以是任意的,意思是你可以在列表中放入任意类型的对象。返回结果将是一个新的列表,在这个以if和for语句为上下文的表达式运行完成之后产生。
 
列表解析的一般形式:
[expr for item in itratorable]
Code: [2 ** n for n in range(10)]

Result: [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]



列表解析返回的是列表, 列表的内容是表达式执行的结果.
 
[expr for item in iterable if cond]

[x ** 0.5 for x in range(10) if x % 2 == 0]
[0.0, 1.4142135623730951, 2.0, 2.449489742783178, 2.8284271247461903][expr for item in iterable if cond1 if cond2]

[x for x in range(10) if x % 2 == 0 if x > 1]
[2, 4, 6, 8][expr for item1 in iterable1 for item2 in iterable2]

[(x, y) for x in range(10) for y in range(10) if (x+y) %2 == 0]







列表解析用于对可迭代对象做过滤和转换,返回值是列表.
 
特性一:代码变短,可读性更好




从上图代码示例中我们明显可以看出,列表推导式相比常规方法,写出来的代码更加符合pythonic,更加简短,可读性更好。
 
有些人甚至更喜欢使用它而不是filter函数生成列表,但是当你使用列表推导式效果会更加,列表推导式在有些情况下超赞,特别是当你需要使用for循环来生成一个新列表.
 
特征二:推导式速度更快
#!/usr/bin/env python3
# author: nock
import timeit

lst = list(range(10))
# 常规方法
def origin(lst):
plus_one = []
for i in lst:
plus_one.append(i + 1)
return plus_one

# 列表推导式
def fast(lst):
return [ x + 1 for x in lst ]

otime = timeit.timeit('origin(range(10))', globals=globals())
print("func origin exec time is {0}".format(otime))

ftime = timeit.timeit('fast(range(10))', globals=globals())
print("func origin exec time is {0}".format(ftime))结果:
func origin exec time is 2.1059355960023822
func origin exec time is 1.6507169340038672
如果你使用map或者filter结合lambda生成列表,也是没有列表推导式速度快的,有兴趣的可以自己Coding一下。
  查看全部
Pythonic的核心就是Python之禅,而Python的列表推导式就得以很好的体现。


列表推导式


定义:
列表推导式(又称列表解析式)提供了一种简明扼要的方法来创建列表。

它的结构是在一个中括号里包含一个表达式,然后是一个for语句,然后是0个或多个for或者if语句。那个表达式可以是任意的,意思是你可以在列表中放入任意类型的对象。返回结果将是一个新的列表,在这个以if和for语句为上下文的表达式运行完成之后产生。
 
列表解析的一般形式:
[expr for item in itratorable]

Code: [2 ** n for n in range(10)]

Result: [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
listresult.png

列表解析返回的是列表, 列表的内容是表达式执行的结果.
 
[expr for item in iterable if cond]

[x ** 0.5 for x in range(10) if x % 2 == 0]
[0.0, 1.4142135623730951, 2.0, 2.449489742783178, 2.8284271247461903]
[expr for item in iterable if cond1 if cond2]

[x for x in range(10) if x % 2 == 0 if x > 1]
[2, 4, 6, 8]
[expr for item1 in iterable1 for item2 in iterable2]

[(x, y) for x in range(10) for y in range(10) if (x+y) %2 == 0]
listerror.png

listdie.png

列表解析用于对可迭代对象做过滤和转换,返回值是列表.
 
特性一:代码变短,可读性更好
list.png

从上图代码示例中我们明显可以看出,列表推导式相比常规方法,写出来的代码更加符合pythonic,更加简短,可读性更好。
 
有些人甚至更喜欢使用它而不是filter函数生成列表,但是当你使用列表推导式效果会更加,列表推导式在有些情况下超赞,特别是当你需要使用for循环来生成一个新列表.
 
特征二:推导式速度更快
#!/usr/bin/env python3
# author: nock
import timeit

lst = list(range(10))
# 常规方法
def origin(lst):
plus_one = []
for i in lst:
plus_one.append(i + 1)
return plus_one

# 列表推导式
def fast(lst):
return [ x + 1 for x in lst ]

otime = timeit.timeit('origin(range(10))', globals=globals())
print("func origin exec time is {0}".format(otime))

ftime = timeit.timeit('fast(range(10))', globals=globals())
print("func origin exec time is {0}".format(ftime))
结果:
func origin exec time is 2.1059355960023822
func origin exec time is 1.6507169340038672

如果你使用map或者filter结合lambda生成列表,也是没有列表推导式速度快的,有兴趣的可以自己Coding一下。
 

Nginx缓存静态页面

运维技术mark 发表了文章 • 0 个评论 • 228 次浏览 • 2017-03-16 15:01 • 来自相关话题

首先介绍一下弄这个的初衷。
其实初衷很简单公司需要这个,然后你就去实现没有什么更高大上的理由,原理什么的我也不打算介绍了, 个人不太喜欢这些咬文爵字的东西。
 
其次做这个需要用到ngx_cache_purge 缓存模块。
不清楚自己的nginx有没有添加这个模块的童鞋可以使用nginx -V查看具体如下:[root@localhost sbin]# ./nginx -V
nginx version: nginx/1.10.3
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-ipv6 --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --add-module=/root/ngx_cache_purge-2.3 --with-http_perl_module --with-ld-opt=-Wl,-E

如果看到了ngx_cache_purge则已经添加了这个模块。你可以直接跳到最下面看看是不是你想要的, 好了,废话不多说。

一、编译安装Nginx

首先下载nginx和ngx_cache_purge 缓存模块
附:
nginx下载地址:http://nginx.org/download/nginx-1.10.3.tar.gz
ngx_cache_purge下载地址:http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
 
开始编译安装cd /usr/local/
wget http://nginx.org/download/nginx-1.10.3.tar.gz
tar zxvf nginx-1.10.3.tar.gz
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
tar -xvf ngx_cache_purge-2.3.tar.gz
./configure --prefix=/usr/local/nginx --add-module=../ngx_cache_purge-2.3 --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-ipv6 --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_perl_module --with-ld-opt="-Wl,-E"


 附Nginx编译安装时可能遇到的问题:/configure: error: the HTTP rewrite module requires the PCRE library.
解决方法:安装pcre
# yum -y install pcre pcre-devel

缺少ssl错误,错误信息如下:
./configure: error: the HTTP cache module requires md5 functions
from OpenSSL library. You can either disable the module by using
--without-http-cache option, or install the OpenSSL library into the system,
or build the OpenSSL library statically from the source with nginx by using
--with-http_ssl_module --with-openssl=<path> options.
解决方法:安装openssl
# yum -y install openssl openssl-devel

缺少编译器,错误信息如下:
./configure: error: C compiler cc is not found
解决方法:安装gcc-c++
# yum -y install gcc-c++ autoconf automake
autoconf是自动配置,automake是自动编译

缺少zlib包,错误信息如下:
./configure: error: the HTTP gzip module requires the zlib library.
You can either disable the module by using –without-http_gzip_module
option, or install the zlib library into the system, or build the zlib
library
statically from the source with nginx by using –with-zlib=<path> option.
解决方法:安装zlib
# yum install -y zlib-devel

缺少libxml2,错误信息如下:
./configure: error: the HTTP XSLT module requires the libxml2/libxslt
libraries. You can either do not enable the module or install the libraries.
解决方法:
# yum -y install libxml2 libxml2-dev
# yum -y install libxslt-devel

http_image_filter_module是nginx提供的集成图片处理模块,需要gd-devel的支持,错误信息如下:
./configure: error: the HTTP image filter module requires the GD library.
You can either do not enable the module or install the libraries.
解决方法:
# yum -y install gd-devel

缺少ExtUtils,错误信息如下:
./configure: error: perl module ExtUtils::Embed is required
解决方法:
# yum -y install perl-devel perl-ExtUtils-Embed

缺少GeoIP,错误信息如下:
./configure: error: the GeoIP module requires the GeoIP library.
You can either do not enable the module or install the library.
解决方法:
# yum -y install GeoIP GeoIP-devel GeoIP-data

 

二、配置nginx.conf

安装完成后编辑nginx的配置文件位于/usr/local/nginx/conf/nginx.conf# cd /usr/local/nginx/conf/
# cp nginx.conf nginx.conf.bak #先将nginx的配置文件进行备份
可以利用nginx -V查看是否添加了ngx_cache_purge 缓存模块(如何查看文章头部)
配置的一些详细的参数我在我的nginx配置文件中有详细的注释。
所以这里就不多讲,可以根据我的进行修改
最后附上自己的配置文件[root@localhost sbin]# cat ../conf/nginx.conf
user nobody;
worker_processes 1;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid logs/nginx.pid;


events {
#epoll是多路复用IO(I/O Multiplexing)中的一种方式,
#仅用于linux2.6以上内核,可以大大提高nginx的性能
use epoll;
worker_connections 1024; #单个后台worker process进程的最大并发链接数
# 并发总数是 worker_processes 和 worker_connections 的乘积
# 即 max_clients = worker_processes * worker_connections
# 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4 为什么
# 为什么上面反向代理要除以4,应该说是一个经验值
# 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000
# worker_connections 值的设置跟物理内存大小有关
# 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数
# 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右
# 我们来看看360M内存的VPS可以打开的文件句柄数是多少:
# $ cat /proc/sys/fs/file-max
# 输出 34336
# 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围之内
# 所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置
# 使得并发总数小于操作系统可以打开的最大文件数目
# 其实质也就是根据主机的物理CPU和内存进行配置
# 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。
# ulimit -SHn 65535
}
http {
#设定mime类型,类型由mime.type文件定义
include mime.types;
default_type application/octet-stream;
#设定日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on; #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
#对于普通应用,必须设为 on,
#如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
#以平衡磁盘与网络I/O处理速度,降低系统的uptime.
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65; #连接超时时间
tcp_nodelay on;
gzip on; #开启gzip压缩
gzip_disable "MSIE [1-6].";
client_header_buffer_size 128k; #设定请求缓冲
large_client_header_buffers 4 128k;
proxy_buffering on; #开启代理缓存
proxy_connect_timeout 5; #连接超时时间,超时时间设置不要超过75秒,至于为什么i don't konw
proxy_read_timeout 60; #设置与代理服务器两次读取的间隔时间
proxy_send_timeout 5; #设置后端服务器数据回传时间就是在规定时间之内后端服务器必须传完所有的数据,如果超时nginx会关闭连接
proxy_buffer_size 16k; #设置nginx保存用户头部信息的缓存区大小
proxy_buffers 4 64k; #缓存区大小
proxy_busy_buffers_size 128k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 128k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
proxy_temp_path /tmp/temp_cache1; #临时缓存目录
proxy_cache_path /tmp/cache1 levels=1:2 keys_zone=cache_one:200m inactive=30d max_size=5g;
#注:proxy_temp_path和proxy_cache_path指定的路径必须在同一分区
#设置Web缓存区名称为cache_one,内存缓存空间大小为200MB,30天没有被访问的内容自动清除,硬盘缓存空间大小为5GB。

#定义反向代理
upstream backend_server {
server 192.168.58.139:80 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.58.140:80 weight=1 max_fails=2 fail_timeout=30s;
}

server {
listen 80;
server_name localhost;

# #charset koi8-r;
# #access_log logs/host.access.log main;

#缓存html页面,可以缓存伪静态
location ~ .*\.html$ {
proxy_pass http://backend_server;
proxy_redirect off;
proxy_set_header Host $host;
proxy_cache cache_one;
proxy_next_upstream http_502 http_504 error timeout invalid_header; #如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移。
proxy_cache_valid 200 302 1d; #状态为200、302的缓存1天
proxy_cache_valid 301 2d; #状态为301的缓存2天
proxy_cache_valid any 1m; #有效缓存大小
expires 1d; #浏览器过期时间设置1天
proxy_cache_key $host$uri$is_args$args; #以域名、URI、参数组合成Web缓存的Key值,Nginx根据Key值哈希,存储缓存内容到二级缓存目录内
proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie"; #忽略头部禁止缓存申明,类似与CDN的强制缓存功能
add_header Nginx-Cache "$upstream_cache_status"; #在header中插入缓存状态,命中缓存为HIT,没命中则为MISS
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}

#禁止访问 .htxxx 文件
location ~ /\.ht {
deny all;
}

#用于清除缓存,假设一个URL为http://192.168.8.42/test.txt,通过访问http://192.168.8.42/purge/test.txt就可以清除该URL的缓存。
location ~ /purge(/.*) {
#设置只允许指定的IP或IP段才可以清除URL缓存。
allow 127.0.0.1;
allow 192.168.58.0/24;
deny all;
proxy_cache_purge cache_one $host$1$is_args$args;
}

#动态页面直接放过不缓存
location ~ .*\.(php|jsp|cgi)(.*){
proxy_pass http://backend_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

#设置缓存黑名单,不缓存指定页面,比如wp后台或其他需要登录态的页面,用分隔符隔开
#location ~ ^/(wp-admin|system)(.*)$ {
# proxy_pass http://backend_server;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#}

#location / {
# proxy_cache cache_one;
# proxy_next_upstream http_502 http_504 error timeout invalid_header; #如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移。
# proxy_cache_valid 200 304 12h; #对不同的HTTP状态码设置不同的缓存时间
# proxy_cache_key $host$uri$is_args$args; #以域名、URI、参数组合成Web缓存的Key值,Nginx根据Key值哈希,存储缓存内容到二级缓存目录内
# proxy_set_header Host $host;
# proxy_set_header X-Forwarded-For $remote_addr;
# proxy_pass http://backend_server;
# expires 1d;
#}

}

}

打完收工.................... 查看全部
首先介绍一下弄这个的初衷。
其实初衷很简单公司需要这个,然后你就去实现没有什么更高大上的理由,原理什么的我也不打算介绍了, 个人不太喜欢这些咬文爵字的东西。
 
其次做这个需要用到ngx_cache_purge 缓存模块。
不清楚自己的nginx有没有添加这个模块的童鞋可以使用nginx -V查看具体如下:
[root@localhost sbin]# ./nginx -V
nginx version: nginx/1.10.3
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-ipv6 --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --add-module=/root/ngx_cache_purge-2.3 --with-http_perl_module --with-ld-opt=-Wl,-E

如果看到了ngx_cache_purge则已经添加了这个模块。你可以直接跳到最下面看看是不是你想要的, 好了,废话不多说。


一、编译安装Nginx


首先下载nginx和ngx_cache_purge 缓存模块
附:
nginx下载地址:http://nginx.org/download/nginx-1.10.3.tar.gz
ngx_cache_purge下载地址:http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
 
开始编译安装
cd /usr/local/
wget http://nginx.org/download/nginx-1.10.3.tar.gz
tar zxvf nginx-1.10.3.tar.gz
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
tar -xvf ngx_cache_purge-2.3.tar.gz
./configure --prefix=/usr/local/nginx --add-module=../ngx_cache_purge-2.3 --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-ipv6 --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_perl_module --with-ld-opt="-Wl,-E"


 附Nginx编译安装时可能遇到的问题:
/configure: error: the HTTP rewrite module requires the PCRE library.
解决方法:安装pcre
# yum -y install pcre pcre-devel

缺少ssl错误,错误信息如下:
./configure: error: the HTTP cache module requires md5 functions
from OpenSSL library. You can either disable the module by using
--without-http-cache option, or install the OpenSSL library into the system,
or build the OpenSSL library statically from the source with nginx by using
--with-http_ssl_module --with-openssl=<path> options.
解决方法:安装openssl
# yum -y install openssl openssl-devel

缺少编译器,错误信息如下:
./configure: error: C compiler cc is not found
解决方法:安装gcc-c++
# yum -y install gcc-c++ autoconf automake
autoconf是自动配置,automake是自动编译

缺少zlib包,错误信息如下:
./configure: error: the HTTP gzip module requires the zlib library.
You can either disable the module by using –without-http_gzip_module
option, or install the zlib library into the system, or build the zlib
library
statically from the source with nginx by using –with-zlib=<path> option.
解决方法:安装zlib
# yum install -y zlib-devel

缺少libxml2,错误信息如下:
./configure: error: the HTTP XSLT module requires the libxml2/libxslt
libraries. You can either do not enable the module or install the libraries.
解决方法:
# yum -y install libxml2 libxml2-dev
# yum -y install libxslt-devel

http_image_filter_module是nginx提供的集成图片处理模块,需要gd-devel的支持,错误信息如下:
./configure: error: the HTTP image filter module requires the GD library.
You can either do not enable the module or install the libraries.
解决方法:
# yum -y install gd-devel

缺少ExtUtils,错误信息如下:
./configure: error: perl module ExtUtils::Embed is required
解决方法:
# yum -y install perl-devel perl-ExtUtils-Embed

缺少GeoIP,错误信息如下:
./configure: error: the GeoIP module requires the GeoIP library.
You can either do not enable the module or install the library.
解决方法:
# yum -y install GeoIP GeoIP-devel GeoIP-data

 


二、配置nginx.conf


安装完成后编辑nginx的配置文件位于/usr/local/nginx/conf/nginx.conf
# cd /usr/local/nginx/conf/
# cp nginx.conf nginx.conf.bak #先将nginx的配置文件进行备份

可以利用nginx -V查看是否添加了ngx_cache_purge 缓存模块(如何查看文章头部)
配置的一些详细的参数我在我的nginx配置文件中有详细的注释。
所以这里就不多讲,可以根据我的进行修改
最后附上自己的配置文件
[root@localhost sbin]# cat ../conf/nginx.conf
user nobody;
worker_processes 1;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid logs/nginx.pid;


events {
#epoll是多路复用IO(I/O Multiplexing)中的一种方式,
#仅用于linux2.6以上内核,可以大大提高nginx的性能
use epoll;
worker_connections 1024; #单个后台worker process进程的最大并发链接数
# 并发总数是 worker_processes 和 worker_connections 的乘积
# 即 max_clients = worker_processes * worker_connections
# 在设置了反向代理的情况下,max_clients = worker_processes * worker_connections / 4 为什么
# 为什么上面反向代理要除以4,应该说是一个经验值
# 根据以上条件,正常情况下的Nginx Server可以应付的最大连接数为:4 * 8000 = 32000
# worker_connections 值的设置跟物理内存大小有关
# 因为并发受IO约束,max_clients的值须小于系统可以打开的最大文件数
# 而系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右
# 我们来看看360M内存的VPS可以打开的文件句柄数是多少:
# $ cat /proc/sys/fs/file-max
# 输出 34336
# 32000 < 34336,即并发连接总数小于系统可以打开的文件句柄总数,这样就在操作系统可以承受的范围之内
# 所以,worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置
# 使得并发总数小于操作系统可以打开的最大文件数目
# 其实质也就是根据主机的物理CPU和内存进行配置
# 当然,理论上的并发总数可能会和实际有所偏差,因为主机还有其他的工作进程需要消耗系统资源。
# ulimit -SHn 65535
}
http {
#设定mime类型,类型由mime.type文件定义
include mime.types;
default_type application/octet-stream;
#设定日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on; #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,
#对于普通应用,必须设为 on,
#如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,
#以平衡磁盘与网络I/O处理速度,降低系统的uptime.
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65; #连接超时时间
tcp_nodelay on;
gzip on; #开启gzip压缩
gzip_disable "MSIE [1-6].";
client_header_buffer_size 128k; #设定请求缓冲
large_client_header_buffers 4 128k;
proxy_buffering on; #开启代理缓存
proxy_connect_timeout 5; #连接超时时间,超时时间设置不要超过75秒,至于为什么i don't konw
proxy_read_timeout 60; #设置与代理服务器两次读取的间隔时间
proxy_send_timeout 5; #设置后端服务器数据回传时间就是在规定时间之内后端服务器必须传完所有的数据,如果超时nginx会关闭连接
proxy_buffer_size 16k; #设置nginx保存用户头部信息的缓存区大小
proxy_buffers 4 64k; #缓存区大小
proxy_busy_buffers_size 128k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 128k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
proxy_temp_path /tmp/temp_cache1; #临时缓存目录
proxy_cache_path /tmp/cache1 levels=1:2 keys_zone=cache_one:200m inactive=30d max_size=5g;
#注:proxy_temp_path和proxy_cache_path指定的路径必须在同一分区
#设置Web缓存区名称为cache_one,内存缓存空间大小为200MB,30天没有被访问的内容自动清除,硬盘缓存空间大小为5GB。

#定义反向代理
upstream backend_server {
server 192.168.58.139:80 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.58.140:80 weight=1 max_fails=2 fail_timeout=30s;
}

server {
listen 80;
server_name localhost;

# #charset koi8-r;
# #access_log logs/host.access.log main;

#缓存html页面,可以缓存伪静态
location ~ .*\.html$ {
proxy_pass http://backend_server;
proxy_redirect off;
proxy_set_header Host $host;
proxy_cache cache_one;
proxy_next_upstream http_502 http_504 error timeout invalid_header; #如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移。
proxy_cache_valid 200 302 1d; #状态为200、302的缓存1天
proxy_cache_valid 301 2d; #状态为301的缓存2天
proxy_cache_valid any 1m; #有效缓存大小
expires 1d; #浏览器过期时间设置1天
proxy_cache_key $host$uri$is_args$args; #以域名、URI、参数组合成Web缓存的Key值,Nginx根据Key值哈希,存储缓存内容到二级缓存目录内
proxy_ignore_headers "Cache-Control" "Expires" "Set-Cookie"; #忽略头部禁止缓存申明,类似与CDN的强制缓存功能
add_header Nginx-Cache "$upstream_cache_status"; #在header中插入缓存状态,命中缓存为HIT,没命中则为MISS
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}

#禁止访问 .htxxx 文件
location ~ /\.ht {
deny all;
}

#用于清除缓存,假设一个URL为http://192.168.8.42/test.txt,通过访问http://192.168.8.42/purge/test.txt就可以清除该URL的缓存。
location ~ /purge(/.*) {
#设置只允许指定的IP或IP段才可以清除URL缓存。
allow 127.0.0.1;
allow 192.168.58.0/24;
deny all;
proxy_cache_purge cache_one $host$1$is_args$args;
}

#动态页面直接放过不缓存
location ~ .*\.(php|jsp|cgi)(.*){
proxy_pass http://backend_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

#设置缓存黑名单,不缓存指定页面,比如wp后台或其他需要登录态的页面,用分隔符隔开
#location ~ ^/(wp-admin|system)(.*)$ {
# proxy_pass http://backend_server;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#}

#location / {
# proxy_cache cache_one;
# proxy_next_upstream http_502 http_504 error timeout invalid_header; #如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移。
# proxy_cache_valid 200 304 12h; #对不同的HTTP状态码设置不同的缓存时间
# proxy_cache_key $host$uri$is_args$args; #以域名、URI、参数组合成Web缓存的Key值,Nginx根据Key值哈希,存储缓存内容到二级缓存目录内
# proxy_set_header Host $host;
# proxy_set_header X-Forwarded-For $remote_addr;
# proxy_pass http://backend_server;
# expires 1d;
#}

}

}

打完收工....................

Mac下最简单翻墙的方法

运维技术采菊篱下 发表了文章 • 0 个评论 • 240 次浏览 • 2017-03-13 15:32 • 来自相关话题

自动代理配置url: https://raw.githubusercontent.com/bannedbook/fanqiang/master/ios/ios.pac 
 
图示:




 
完美解决: 查看全部
googleproxy.png

自动代理配置url: https://raw.githubusercontent.com/bannedbook/fanqiang/master/ios/ios.pac 
 
图示:
urlsetting.png

 
完美解决:
pian.png

Centos7下添加开机自启动服务和脚本

运维技术push 发表了文章 • 0 个评论 • 226 次浏览 • 2017-03-10 20:41 • 来自相关话题

最近刚玩Centos7的系统,跟Centos6还是很多方面有改变的,这里记录一下怎么在Centos7下添加开机自启动脚本和服务的方法。
 

1、添加开机自启服务

我这里以docker 服务为例,设置如下两条命令即可:
# systemctl enable docker.service #设置docker服务为自启动服务 相当于我们的 chkconfig docker on
# sysstemctl start docker.service #启动docker服务

2、添加开机自启脚本

在centos7中增加脚本有两种常用的方法,以脚本StartTomcat.sh为例:
#!/bin/bash
# description:开机自启脚本
/usr/local/tomcat/bin/startup.sh #启动tomcat方法一:
1、赋予脚本可执行权限(/opt/script/StartTomcat.sh是你的脚本路径)
# chmod +x /opt/script/StartTomcat.sh2、打开/etc/rc.d/rc.local文件,在末尾增加如下内容
echo "/opt/script/StartTomcat.sh" >> /etc/rc.d/rc.local3、在centos7中,/etc/rc.d/rc.local的权限被降低了,所以需要执行如下命令赋予其可执行权限
chmod +x /etc/rc.d/rc.local
方法二:
1、将脚本移动到/etc/rc.d/init.d目录下
# mv /opt/script/StartTomcat.sh /etc/rc.d/init.d2、增加脚本的可执行权限
chmod +x /etc/rc.d/init.d/StartTomcat.sh3、添加脚本到开机自动启动项目中
cd /etc/rc.d/init.d
chkconfig --add StartTomcat.sh
chkconfig StartTomcat.sh on 查看全部
最近刚玩Centos7的系统,跟Centos6还是很多方面有改变的,这里记录一下怎么在Centos7下添加开机自启动脚本和服务的方法。
 


1、添加开机自启服务


我这里以docker 服务为例,设置如下两条命令即可:
# systemctl enable docker.service  #设置docker服务为自启动服务 相当于我们的 chkconfig docker on
# sysstemctl start docker.service #启动docker服务


2、添加开机自启脚本


在centos7中增加脚本有两种常用的方法,以脚本StartTomcat.sh为例:
#!/bin/bash
# description:开机自启脚本
/usr/local/tomcat/bin/startup.sh #启动tomcat
方法一:
1、赋予脚本可执行权限(/opt/script/StartTomcat.sh是你的脚本路径)
# chmod +x /opt/script/StartTomcat.sh
2、打开/etc/rc.d/rc.local文件,在末尾增加如下内容
echo "/opt/script/StartTomcat.sh" >> /etc/rc.d/rc.local
3、在centos7中,/etc/rc.d/rc.local的权限被降低了,所以需要执行如下命令赋予其可执行权限
chmod +x /etc/rc.d/rc.local

方法二:
1、将脚本移动到/etc/rc.d/init.d目录下
# mv  /opt/script/StartTomcat.sh /etc/rc.d/init.d
2、增加脚本的可执行权限
chmod +x  /etc/rc.d/init.d/StartTomcat.sh
3、添加脚本到开机自动启动项目中
cd /etc/rc.d/init.d
chkconfig --add StartTomcat.sh
chkconfig StartTomcat.sh on

阿里云和Azure ICON图标矢量素材分享

学习资源OS小编 发表了文章 • 0 个评论 • 230 次浏览 • 2017-03-10 10:35 • 来自相关话题

我们经常画图会用到一些图标,下面分享阿里云和微软云的一些矢量素材。

阿里云










Azure









图标下载地址:https://pan.baidu.com/s/1i5smr69  查看全部
icon.png

我们经常画图会用到一些图标,下面分享阿里云和微软云的一些矢量素材。


阿里云


AliyunIcon1.png

AliyunIcon2.png


Azure


AzureIcon1.png

AzureIcon2.png

图标下载地址:https://pan.baidu.com/s/1i5smr69 

设置转发和代理访问阿里MongoDB云数据库

大数据/云计算采菊篱下 发表了文章 • 0 个评论 • 202 次浏览 • 2017-03-09 21:34 • 来自相关话题

摘要:基于安全原因考虑,阿里云MongoDB云数据库目前只支持从阿里云ECS上访问,无法通过公网直接访问,不方便用户在本地开发环境里直接进行测试,但是开发就是要测试性能,没有办法作为一个运维你必须想办法了,本文介绍能让用户通过公网访问MongoDB云数据库的方案。

环境架构说明
环境说明:
包含公网 + 私网ip的ECS
公网IP地址:121.196.197.64内网IP地址:10.0.0.110
 
MongoDB云数据库
节点1:s-uf6745fa496c28d4.mongodb.rds.aliyuncs.com:3717(Primary,通过ping域名来获取对应的ip,获取到ip地址10.0.0.119,因域名对应的ip可能发生变化,在生产环境切勿直接指定ip,可以直接用域名)节点2:s-uf624ab1be981c34.mongodb.rds.aliyuncs.com:3717
 
结构示意图如下:




目标:
通过121.196.197.64:27017能访问到10.0.0.119:3717提供的MongoDB云服务。

方案一:Iptables实现
利用iptables的nat机制,可以方便的实现请求转发,首先需要ECS开启包转发的支持echo 1 > /proc/sys/net/ipv4/ip_forward配置转发规则iptables -t nat -A PREROUTING -d 121.196.197.64 -p tcp --dport 27017 -j DNAT --to-destination 10.0.0.119:3717
iptables -t nat -A POSTROUTING -d 10.0.0.119 -p tcp --dport 3717 -j SNAT --to-source 10.0.0.110此时你就能在任意能连通公网的机器上连接121.196.197.64:27017访问MongoDB云服务,所有的请求都会转发到10.0.0.119:3717上,如果你需要严格限制,只允许你办公区公网ip地址访问的话,添加第一条规则的时候还可以增加一个 -s 参数,限制访问源!

需要注意的是,此时访问121.196.197.64:27017只能以单节点的方式直连,而不能按复制集的方式访问。mongo --host 121.196.197.64:27017 --authenticationDatabase admin -uroot -pxxoo
方案二:Harpoxy四层代理实现
haproxy支持tcp(四层)、http(七层)2种转发模式,类似于iptables,我们也可以利用haproxy来实现公网访问MongoDB云数据库。

修改/etc/haproxy/haproxy.cfg配置文件内容,根据默认的配置文件稍作修改,主要配置tcp转发模式、前端、后端服务的地址信息。(haproxy版本为1.5.4)global
log 127.0.0.1 local2

chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon

# turn on stats unix socket
stats socket /var/lib/haproxy/stats

defaults
# 使用tcp转发模式
mode tcp
log global
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000

# 前端地址信息, 121.196.197.64:27017
frontend main 121.196.197.64:27017
default_backend app

# 后端地址信息,10.0.0.119:3717
backend app
balance roundrobin
server app1 10.0.0.119:3717 check启动haproxyhaproxy -f /etc/haproxy/haproxy.cfg此时你就能在任意能连通公网的机器上连接121.196.197.64:27017访问MongoDB云服务,所有的请求都会转发到10.0.0.119:3717上。

需要注意的是,此时访问121.196.197.64:27017只能以单节点的方式直连,也不能按复制集的方式访问。mongo --host 121.196.197.64:27017 --authenticationDatabase admin -uroot -pxxoo以上服务同样适用于RDS、Redis云数据库,但切记仅能用于测试开发环境,生产环境请做好安全心里准备! 查看全部
AliyunMongodb.png


摘要:基于安全原因考虑,阿里云MongoDB云数据库目前只支持从阿里云ECS上访问,无法通过公网直接访问,不方便用户在本地开发环境里直接进行测试,但是开发就是要测试性能,没有办法作为一个运维你必须想办法了,本文介绍能让用户通过公网访问MongoDB云数据库的方案。


环境架构说明
环境说明:
包含公网 + 私网ip的ECS
  • 公网IP地址:121.196.197.64
  • 内网IP地址:10.0.0.110

 
MongoDB云数据库
  • 节点1:s-uf6745fa496c28d4.mongodb.rds.aliyuncs.com:3717(Primary,通过ping域名来获取对应的ip,获取到ip地址10.0.0.119,因域名对应的ip可能发生变化,在生产环境切勿直接指定ip,可以直接用域名)
  • 节点2:s-uf624ab1be981c34.mongodb.rds.aliyuncs.com:3717

 
结构示意图如下:
MongodbArch.png

目标:
通过121.196.197.64:27017能访问到10.0.0.119:3717提供的MongoDB云服务。

方案一:Iptables实现
利用iptables的nat机制,可以方便的实现请求转发,首先需要ECS开启包转发的支持
echo 1 > /proc/sys/net/ipv4/ip_forward
配置转发规则
iptables -t nat -A PREROUTING -d 121.196.197.64 -p tcp --dport 27017 -j DNAT --to-destination 10.0.0.119:3717
iptables -t nat -A POSTROUTING -d 10.0.0.119 -p tcp --dport 3717 -j SNAT --to-source 10.0.0.110
此时你就能在任意能连通公网的机器上连接121.196.197.64:27017访问MongoDB云服务,所有的请求都会转发到10.0.0.119:3717上,如果你需要严格限制,只允许你办公区公网ip地址访问的话,添加第一条规则的时候还可以增加一个 -s 参数,限制访问源!

需要注意的是,此时访问121.196.197.64:27017只能以单节点的方式直连,而不能按复制集的方式访问。
mongo --host 121.196.197.64:27017 --authenticationDatabase admin -uroot -pxxoo

方案二:Harpoxy四层代理实现
haproxy支持tcp(四层)、http(七层)2种转发模式,类似于iptables,我们也可以利用haproxy来实现公网访问MongoDB云数据库。

修改/etc/haproxy/haproxy.cfg配置文件内容,根据默认的配置文件稍作修改,主要配置tcp转发模式、前端、后端服务的地址信息。(haproxy版本为1.5.4)
global
log 127.0.0.1 local2

chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon

# turn on stats unix socket
stats socket /var/lib/haproxy/stats

defaults
# 使用tcp转发模式
mode tcp
log global
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000

# 前端地址信息, 121.196.197.64:27017
frontend main 121.196.197.64:27017
default_backend app

# 后端地址信息,10.0.0.119:3717
backend app
balance roundrobin
server app1 10.0.0.119:3717 check
启动haproxy
haproxy -f /etc/haproxy/haproxy.cfg
此时你就能在任意能连通公网的机器上连接121.196.197.64:27017访问MongoDB云服务,所有的请求都会转发到10.0.0.119:3717上。

需要注意的是,此时访问121.196.197.64:27017只能以单节点的方式直连,也不能按复制集的方式访问。
mongo --host 121.196.197.64:27017 --authenticationDatabase admin -uroot -pxxoo
以上服务同样适用于RDS、Redis云数据库,但切记仅能用于测试开发环境,生产环境请做好安全心里准备!

Docker容器启动过程

大数据/云计算Something 发表了文章 • 0 个评论 • 200 次浏览 • 2017-03-09 15:02 • 来自相关话题

下面让我们看看一个Docker容器它启动过程中,背后到底做了什么?docker run -i -t ubuntu /bin/bash输入上面这行命令,启动一个ubuntu容器时,到底发生了什么?
 
大致过程可以用下图描述:




首先系统要有一个docker daemon的后台进程在运行,当刚才这行命令敲下时,发生了如下动作:
docker client(即:docker终端命令行)会调用docker daemon请求启动一个容器,docker daemon会向host os(即:linux)请求创建容器linux会创建一个空的容器(可以简单理解为:一个未安装操作系统的裸机,只有虚拟出来的CPU、内存等硬件资源)docker daemon请检查本机是否存在docker镜像文件(可以简单理解为操作系统安装光盘),如果有,则加载到容器中(即:光盘插入裸机,准备安装操作系统)将镜像文件加载到容器中(即:裸机上安装好了操作系统,不再是裸机状态)
 
最后,我们就得到了一个ubuntu的虚拟机,然后就可以进行各种操作了。
 
 
如果在第4步检查本机镜像文件时,发现文件不存在,则会到默认的docker镜像注册机构(即:docker hub网站)去联网下载,下载回来后,再进行装载到容器的动作,即下图所示:




另外官网有一张图也很形象的描述了这个过程:




原文地址:http://www.cnblogs.com/yjmyzz/p/docker-container-start-up-analysis.html 

参考文章:
https://www.gitbook.com/book/joshhu/docker_theory_install/details  
https://docs.docker.com/engine/introduction/understanding-docker/  查看全部
下面让我们看看一个Docker容器它启动过程中,背后到底做了什么?
docker run -i -t ubuntu /bin/bash
输入上面这行命令,启动一个ubuntu容器时,到底发生了什么?
 
大致过程可以用下图描述:
dockerflow.png

首先系统要有一个docker daemon的后台进程在运行,当刚才这行命令敲下时,发生了如下动作:
  1. docker client(即:docker终端命令行)会调用docker daemon请求启动一个容器,
  2. docker daemon会向host os(即:linux)请求创建容器
  3. linux会创建一个空的容器(可以简单理解为:一个未安装操作系统的裸机,只有虚拟出来的CPU、内存等硬件资源)
  4. docker daemon请检查本机是否存在docker镜像文件(可以简单理解为操作系统安装光盘),如果有,则加载到容器中(即:光盘插入裸机,准备安装操作系统)
  5. 将镜像文件加载到容器中(即:裸机上安装好了操作系统,不再是裸机状态)

 
最后,我们就得到了一个ubuntu的虚拟机,然后就可以进行各种操作了。
 
 
如果在第4步检查本机镜像文件时,发现文件不存在,则会到默认的docker镜像注册机构(即:docker hub网站)去联网下载,下载回来后,再进行装载到容器的动作,即下图所示:
dockerload.png

另外官网有一张图也很形象的描述了这个过程:
dockerfollow.png

原文地址:http://www.cnblogs.com/yjmyzz/p/docker-container-start-up-analysis.html 

参考文章:
https://www.gitbook.com/book/joshhu/docker_theory_install/details  
https://docs.docker.com/engine/introduction/understanding-docker/