来自:桶哥的一篇关于swoole的心跳的文章,作为Swoole顾问(顾得上就问,是为「顾问」)得推一下这篇文章,最后只留下一配置,其实我也不是太明白原理,我在想如果是局域网里还需要心跳?
——————————————————————————————————————————————————————————————————————
swoole提供了一个心跳的功能,很多朋友感到困惑。
心跳是什么?
顾名思义,心跳是判断一个事物生还是死的一个标准,在swoole里,心跳是指用来判断一个连接是正常还是断开的。
从TCP协议说起
我们都知道一个五元组标识一个网络连接,创建一个连接有三次握手,而断开一个连接有四次挥手。不管是服务器还是客户端
发起连接的关闭,都会完整的走完四次挥手的过程,这样,一切很完美,系统回收这个fd,应用层也可以通过onClose回调处理相关的事情.
fd是什么?
fd学名是文件描述符,在unix的哲学就是一切皆文件中,这个fd就是系统层暴露给业务层的用来表示一个五元组网络连接的标识。你可以简单的理解为一个索引,通过对这个fd的操作,系统层可以找到相应的连接而且进行的一系列操作,如发送数据到网瞳,进行连接关闭等等。
为什么要心跳?
刚才提到,如果我们要关闭某个连接,我们可以在业务层对fd发起关闭连接的操作,以swoole为例:
$server->close($fd);
正常情况下,都会走完整个四次挥手,(swoole会有onClose回调),系统回收fd,以待分配给其他的连接。
那系统为什么要回收fd,因为fd资源是有限的,所以必需重复利用。
但在某些情况下,如突然拔掉网线或蓝翔演习挖断光缆,服务端并不能感知到这个连接的异常,但实际上是这个连接已经失效了,如果没有一个回收机制,这类连接将用光所有的fd,导致系统不再能接受新的连接请求,所以就有了心跳机制。
什么是心跳机制?
心跳机制就是业务层来提供一个连接是否存活的一个方法,让系统能判定一个连接是否失效。一般有两种实现方式:
1: 客户端定时发送一个心跳包,告诉服务器我还活着,服务器定时检测所有客户端列表,看他们最后一个心跳包的时间是否过长,如果过长,则认为已无心跳,判定为死连接,主动关闭这个连接。
2: 服务器定时询问所有的客户端,你们还活着么?如果活着,给我个回馈,没得到回馈的客户端,格杀勿论。
两种心跳方案有什么区别?
第一种方案,对服务器和网络的压力更小,而且更具有灵活性,但需要客户端配合定时发送心跳包。
第二种方案,对服务器和网络压力更大,不建议使用。
心跳在swoole里的实现
swoole采用的是第一种方案
swoole会在主进程独立起一个心跳线程,通过定时轮询所有的连接,来判断连接的生死,所以swoole的心跳不会堵塞任何业务逻辑。
那怎么判断连接的生死了?swoole在connection结构体中有 time_t last_time 字段,用来存放最后一次收包的时间戳,进而通过与这个时间对比来判定是否存活
于是,swoole有两个配置:
heartbeat_check_interval: 服务器定时检测在线列表的时间
heartbeat_idle_time:      连接最大的空闲时间 (如果最后一个心跳包的时间与当前时间之差超过这个值,则认为该连接失效)
配置建议
建议 heartbeat_idle_time 为 heartbeat_check_interval 的两倍多一点。
这个两倍是为了进行容错,允许丢一个包
而多一点是考虑到网络的延时。
你可以跟据实际的业务来调整这个容错率(允许丢几个包)。
补充
1、系统层面也提供心跳机制,只不过粒度相对比较粗,而且时间稍长,没有应用层灵活
2、swoole还提供ping的功能,通过配置ping值,swoole内核可以判断只是一个心跳包,而不会,也没必要把数据包转发应用层(onReceive)。
3、心跳不只是swoole独有,大多数tcp的网络服务都会考虑到这个问题
背景:我们特别是在想对两个都各带一列且没有行对齐且行数不一致的关联性的文件做关联成一行的时候,会想用自己熟悉的语言去先后打开两个文件(可能高级点的语言可以一次读取到内存,以PHP这种擅长处理字符串的语言为例,且文件要小,当然你可以对PHP占用内存作调整配置。),对文件里面的所有列全部读取到数组,再用循环对数组每行进行分割提取出关联行,再读取另外一个文件一样分离出相同的部分形成数组键,值就是一行,对第一个文件里面的关联列一个一个去第二个文件里面的数组里循环查找到查到为止,找到后,对以找到的这行的key定了,当然就对应上了,这个看起来简单,得6到7行,往往伴随着那个一行里面提取部分,也就是说需要arr=explode(sep,line),取arr某些键值和第一个文件(也可能需要类似explode操作)有关联的显示出来,你还会说,这个不难,有Excel可以实现,先对这两个文件所关联列进行排序,然后,复制粘贴在一块就OK了,感觉很简单也挺棒的,但是,假如两行的数据里面有重复行,两个文件不一样的行数,这个再像linux下的paste俩文件一样行去搞可能就会有问题了,是不是有点难搞,还得去重复啥的,其灵活性可能还是欠佳,往往需求上对重复部分只留下一个就OK的处理方式居多,Excel想做到这样引入了去重复后让两行一样多的操作,SO,有没有简单可行,优雅简洁的处理方式呢?有,那就是上面描述的可以用awk一行搞定,听说由三个数学家的名字首字母发明出来的,它优雅的使用两个类似宏的东西NR,FNR两个变量实现了上面一堆功能,对行和列处理应该相当有水平,在此,我向他们致敬。
—————————————————————————————————————————————————————————————————————————
书上说:
NR,表示awk开始执行程序后所读取的数据行数.
FNR,与NR功用类似,不同的是awk每打开一个新文件,FNR便从0重新累计.
下面看两个例子:  
1,对于单个文件NR 和FNR 的 输出结果一样的 :
# awk '{print NR,$0}' file1
1 a b c d
2 a b d c
3 a c b d
#awk '{print FNR,$0}' file1
1 a b c d
2 a b d c
3 a c b d  
2,但是对于多个文件 :
# awk '{print NR,$0}' file1 file2
1 a b c d
2 a b d c
3 a c b d
4 aa bb cc dd
5 aa bb dd cc
6 aa cc bb dd
# awk '{print FNR,$0}' file1 file2
1 a b c d
2 a b d c
3 a c b d
1 aa bb cc dd
2 aa bb dd cc
3 aa cc bb dd
在看一个例子关于NR和FNR的典型应用:
现在有两个文件格式如下:
#cat account
张三|000001
李四|000002
#cat cdr
000001|10
000001|20
000002|30
000002|15
想要得到的结果是将用户名,帐号和金额在同一行打印出来,如下:
张三|000001|10
张三|000001|20
李四|000002|30
李四|000002|15
执行如下代码
#awk -F \| 'NR==FNR{a[$2]=$0;next}{print a[$1]"|"$2}' account cdr
注释:
由NR=FNR为真时,判断当前读入的是第一个文件account,然后使用{a[$2]=$0;next}循环将account文件的每行记录都存入数组a,并使用$2第2个字段作为下标引用.
解释,在读取文件1时候,形成如下数组结构:
a[000001]=张三|000001
a[000002]=李四|000002
                …………
由NR=FNR为假时,判断当前读入了第二个文件cdr,然后跳过{a[$2]=$0;next},对第二个文件cdr的每一行都无条件执行{print a[$1]"|"$2},此时变量$1为第二个文件的第一个字段,与读入第一个文件时,采用第一个文件第二个字段$2为数组下标相同.因此可以在此使用a[$1]引用数组。

解释,按顺序读取到第二个文件时候,文件二第一行输出数组和第二列,如下:
a[000001]  | 10    =>   张三|000001 | 10

第一个文件的第二列和第二个文件的第一列关联,a数组存的是第一个文件的按第二列为键值每行。
总结,NR,FNR结合next循环,在数组的key存放关键关联列信息,这个逻辑的核心就在于此,再通过这个awk列$N(N为第几列)优势,只要有关联列,就能这样去匹配出来的行可以任意列输出,相当灵活,优雅,简洁。

=====================自己在日常中的实践如下AddTime:2016-03-25===========================
两个文件里都有UUID的编号及对应的线上机器下载的UUID文件名及后缀,想变成对应的用户上传的中文名加后缀:
(中文名里有各种符号像中文的括号、竖线、空格啥的都得去掉,否则批量肯定会没法成功重命名,需求相当可恶)
windows操作系统虽然好用,但是并不适合研发人员,它的命令行(暂且只说dos, 虽然可以用vb, vbscript,
但是本人不太熟悉,写法上也不太适合做编程)实在是太弱了,想想linux下的shell,用起来还是挺方便的!
方法一:
bianhua_move_comand.txt   //得把那个uuid列先单出来,当然,也可用split进行分割直接取数组1,先讲一次性解决,再讲两步来处理。
cee7b22e-f502-4fed-85a4-1db2c8c42468.mp4
1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4
./bianhua_title_uuid.txt
【新春征集】重庆两江新区《龙兴》        cee7b22e-f502-4fed-85a4-1db2c8c42468
【新春征集】重庆两江新区《伟业》        1aabd2ac-2133-43d6-921d-b5bd2a34182e

awk能够指定分隔符既可以为制表符,又可以为点,那么处理将会变得简单。可以使用正则表达式来指定多个分隔符,格式为 -F[\\t.],
直接指定两个分割符号,分别是\t,和.点,注意斜杠需要转义,awk中-F可指定两种或多种分割符号用[]括起来,awk语句及执行如下所示:

结果达到了mv移动的目的:                                                                            ......
mv /path/cee7b22e-f502-4fed-85a4-1db2c8c42468.mp4 /path/newfolder/【新春征集】重庆两江新区《龙兴》.mp4
mv /path/1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4 /path/newfolder/【新春征集】重庆两江新区《伟业》.mp4

方法二:
当然,也可分两次来做,把关联的列都单独出来后,再用awk去做这个事情,总之,都需要写split分割,如下步骤:
awk -F. '{print $1"\t"$0"\t"$2}' bianhua_move_cond.txmat  > bianhua_move_comand2.txt
bianhua_move_comand2.txt
经上面的awk处理后其 ./bianhua_move_comand2.txt 结构如下所示:
1aabd2ac-2133-43d6-921d-b5bd2a34182e 1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4        .mp4
1aabd2ac-2133-43d6-921d-b5bd2a34182e 1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4        .mp4

把以UUID的文件移到新的目录,并以中文对应名进行赋值,如下:
awk -F\\t 'NR==FNR{a[$1]=$0;next}NR>FNR{if($2 in a) split(a[$2],array,"\\t");print "mv /path/"array[2] " /path/newfolder/"$1array[3]}'  bianhua_move_comand2.txt  bianhua_title_uuid.txt

其实,去掉NR>FNR也一样可以运行,如下:

最后,还可以去掉in的数组判断,更加简化:


mv /path/cee7b22e-f502-4fed-85a4-1db2c8c42468.mp4 /path/newfolder/【新春征集】重庆两江新区《龙兴》.mp4
mv /path/1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4 /path/newfolder/【新春征集】重庆两江新区《伟业》.mp4

附录:
split(str,array,sep)
使用分隔符sep把字符串分解成数组array
if($2 in a) //假如这个$2变量在数组里面
-F \\t \|  //以斜杠转义下斜杠,制表符和竖线,-F是awk指定的分割符。
假如用PHP实现的大致的流程,和上面一行解决问题起到一个比对作用:
rename.php

实践的最初素材来自:http://www.linuxidc.com/wap.aspx?nid=61174 ,及相关人的讲解,Thanks...
首先让我们来回忆一下历史久远的手动记录日志功能:“文件”——“会话日志”,选择日志文件的存放位置并拟定文件名,点击保存。
自动记录日志功能:
1.       选择“选项”——“全局选项”,打开全局选项,在常规设置中找到“默认会话”设置项,点击右侧的“编辑默认设置”:
英文版下:选择“Options”——“Global Options”,打开全局选项,在常规设置中找到“default session”设置项,点击右侧的“edit default settings”:
2.       上一步骤操作后,打开如下图所示的界面,选择“日志文件”(英文版下选择“Log file”),如下图所示,让我们分别解释一下右侧四个红色方框部分。

http://jingyan.baidu.com/article/335530da88aa0b19cb41c3b9.html
浏览器和服务器之间是通过 HTTP 协议进行连接通讯的。这是一种基于请求和响应模型的协议。浏览器通过 URL 向服务器发起请求,Web 服务器接收到请求,执行一段程序,然后做出响应,发送相应的html代码给客户端。
这就有了一个问题,Web 服务器执行一段程序,可能几毫秒就完成,也可能几分钟都完不成。如果程序执行缓慢,用户可能没有耐心等下去,就关闭浏览器了。
而有的时候,我们更本不关心这些耗时的脚本的返回结果,但却还要等他执行完返回,才能继续下一步。
那么有没有什么办法,只是简单的触发调用这些耗时的脚本然后就继续下一步,让这些耗时的脚本在服务端慢慢执行?
经过试验,总结出来几种方法,和大家share:
1. 最简单的办法,就是在返回给客户端的HTML代码中,嵌入AJAX调用,或者,嵌入一个img标签,src指向要执行的耗时脚本。
这种方法最简单,也最快。服务器端不用做任何的调用。
但是缺点是,一般来说Ajax都应该在onLoad以后触发,也就是说,用户点开页面后,就关闭,那就不会触发我们的后台脚本了。
而使用img标签的话,这种方式不能称为严格意义上的异步执行。用户浏览器会长时间等待php脚本的执行完成,也就是用户浏览器的状态栏一直显示还在load。
当然,还可以使用其他的类似原理的方法,比如script标签等等。
2. popen()
resource popen ( string command, string mode );
//打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。
所以可以通过调用它,但忽略它的输出。
pclose(popen("/home/xinchen/backend.php &"
这个方法避免了第一个方法的缺点,并且也很快。但是问题是,这种方法不能通过HTTP协议请求另外的一个WebService,只能执行本地的脚本文件。并且只能单向打开,无法穿大量参数给被调用脚本。
并且如果,访问量很高的时候,会产生大量的进程。如果使用到了外部资源,还要自己考虑竞争。
3. 使用CURL
这个方法,设置CUROPT_TIMEOUT为1(最小为1,郁闷)。也就是说,客户端至少必须等待1秒钟。
$ch = curl_init(); $curl_opt = array(CURLOPT_URL, 'http://www.example.com/backend.php', CURLOPT_RETURNTRANSFER, 1, CURLOPT_TIMEOUT, 1,); curl_setopt_array($ch, $curl_opt); curl_exec($ch); curl_close($ch);
4. 使用fsockopen
这个方法应该是最完美的,但是缺点是,你需要自己拼出HTTP的header部分。
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30); if (!$fp) { echo "$errstr ($errno)<br />\n"; } else { $out = "GET /backend.php / HTTP/1.1\r\n"; $out .= "Host: www.example.com\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); /*忽略执行结果 while (!feof($fp)) { echo fgets($fp, 128); }*/ fclose($fp); }
所以,总体来看,最好用,最简单的还是第一种方法。
最完美的应该是最后一种,但是比较复杂
如果有更好的办法,欢迎交流。
来自:http://www.laruence.com/2008/04/14/318.html

背景:运行指定扩展配置文件extension.ini的扫描目录,这样结构化有利于运维进行模块添加,也是后来我运维时看到并实践的文章,参考文章,http://jackxiang.com/post/8613/。


/usr/local/php/etc/php.d/redis.ini
php -m|grep redis
redis
是因为有:
--with-config-file-scan-dir=/usr/local/php/etc/php.d \
--with-config-file-scan-dir是搜索下面的ini文件和php.ini一起使用,好处就是扩展的那些extension="xx.so"可以放里面,每个扩展一个ini文件,可以方便的用自动化脚本或者部署脚本来搞,看起来模块化了


'—with-config-file-path=/data/software/php-5.6.15/lib/php.ini

open("/data/software/php-5.6.15/bin/php-cli.ini", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/data/software/php-5.6.15/lib/php.ini/php-cli.ini", O_RDONLY) = -1 ENOTDIR (Not a directory)
open("/data/software/php-5.6.15/bin/php.ini", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/data/software/php-5.6.15/lib/php.ini/php.ini", O_RDONLY) = -1 ENOTDIR (Not a directory)


求问这是bug么?
--with-config-file-path=PATH
  --with-config-file-scan-dir=PATH
—with-config-file-path 这个是用来指定目录,不是指定文件。
scan这个干嘛的?还能指定php去这个配置目录扫描?
http://php.net/manual/zh/function.php-ini-scanned-files.php
php.conf.d/*.ini

应该一个是cli,一个是运行服务的吧?
不是吧 应该是搜索这个目录下的 *.ini 文件吧

scan是扩展配置文件目录
cli sapi默认都是编译时指定的位置,也可以手动指定

嗯,--with-config-file-scan-dir是搜索下面的ini文件和php.ini一起使用,好处就是扩展的那些extension="xx.so"可以放里面,每个扩展一个ini文件,可以方便的用自动化脚本或者部署脚本来搞,看起来模块化了


关于opcache想编译成静态所谓提高效率:

PHP 5.5.0 及后续版本,
OPcache 只能编译为共享扩展。
—————————————————
理论上性能好点儿,高并发可能瓶颈不在这儿,所以不明显。
静态这个是迷信 嘿嘿,嗯 所以我说这是我自己的迷信 嘿嘿。
F11相当于windows中的“显示桌面”:
fn + F11 显示桌面。
背景:有时查看目录结构,这个tree非常有用,yum -y install tree安装就能使用。
常常加 -C,表示颜色,-L表示层级。 如:tree -C -L 2。

阅读全文
php7 memcache 扩展你们用哪个版本安装成功的?
https://github.com/php-memcached-dev/php-memcached/tree/php7
php7 的redis扩展 有吗?
https://github.com/phpredis/phpredis/tree/php7@tru
背景:对于kohana早期框架对类里面的before after以及controller和action的函数均可以用反射类来灵活按既定顺序执行,而在执行的时候假如异常,可以通过PHP提供的异常捕获进行捕获输出,这就涉及到类变对象后其参数的传递问题了,怎么给反射类里面的函数传递多参数乃至引用参数,这个PHP也提供了对应的反射类里函数传入的方法ReflectionMethod::invokeArgs。
使用代码片段如下:

参考更多相关反射的文章:
http://flandycheng.blog.51cto.com/855176/326021/
http://www.phperz.com/article/14/0809/17371.html

自己研究:http://jackxiang.com/post/2090/

ReflectionMethod::invokeArgs

(PHP 5 >= 5.1.0)

ReflectionMethod::invokeArgs — 带参数执行

说明

public mixed ReflectionMethod::invokeArgs ( object $object , array $args )
使用数组给方法传送参数,并执行他。
参数
object
调用方法的对象,如果是静态对象,设置为 null
args
使用 array 传送的方法参数。
返回值
返回方法返回值
错误/异常
如果 object 指定的实例无法执行方法,那么产生 ReflectionException 异常。
如果方法调用失败,产生 ReflectionException
范例
Example #1 ReflectionMethod::invokeArgs() example

<?php
class HelloWorld {

    public function sayHelloTo($name) {
        return 'Hello ' . $name;
    }

}

$reflectionMethod = new ReflectionMethod('HelloWorld', 'sayHelloTo');
echo $reflectionMethod->invokeArgs(new HelloWorld(), array('Mike'));
?>
以上例程会输出:
Hello Mike
注释
Note:
如果函数有参数需为引用,那么它们必须以引用方式传入。
参见
ReflectionMethod::invoke() - Invoke
__invoke()
call_user_func_array() - 调用回调函数,并把一个数组参数作为回调函数的参数
来自:http://help.bitscn.com/php/reflectionmethod.invokeargs.html
背景:这玩意是感觉把rpc的生成变成他自己的了,有点意思,不知底层是不是还是xdr交换统一数据结构,还是php的unpack实现客户端的。
http://www.tuicool.com/articles/NV3Yni3

背景:对于ip限定缩小范围,最好是采用出口IP通过公司的所有进行放行,而获取用户Ip地址通用方法常见安全隐患(HTTP_X_FORWARDED_FOR)的,所以最好是nginx在代理时就限定死:
deny  *.*.*.66;
deny  *.*.*.79;
deny  *.*.*.80;
deny  *.*.*.77;
Nginx的日志的最后一个IP并不安全:


*.*.*.57 - jackxiang.com [15/Mar/2016:18:02:33 +0800] "GET /h5ds/themes/common/mobile/js/maps/swiper.min.js.map HTTP/1.0" 404 20 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53" 202.*.*.78  
分析过程
这个来自一些项目中,获取用户Ip,进行用户操作行为的记录,是常见并且经常使用的。 一般朋友,都会看到如下通用获取IP地址方法。

function getIP() {
  if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $realip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
    $realip = $_SERVER['HTTP_CLIENT_IP'];
  } else {
    $realip = $_SERVER['REMOTE_ADDR'];
    }
    return $realip;
  }
这个是网上常见获取,ip函数,用这些值获取IP,我们首先要弄清楚,这些数据是从那个地方传过来的。

IP获取来源
1.’REMOTE_ADDR’  是远端IP,默认来自tcp 连接是,客户端的Ip。可以说,它最准确,确定是,只会得到直接连服务器客户端IP。如果对方通过代理服务器上网,就发现。获取到的是代理服务器IP了。

如:a->b(proxy)->c  ,如果c 通过’REMOTE_ADDR’ ,只能获取到b的IP,获取不到a的IP了。

另外:该IP想篡改将很难实现,在传递知道生成php server值,都是直接生成的。

2.’HTTP_X_FORWARDED_FOR’,’HTTP_CLIENT_IP’ 为了能在大型网络中,获取到最原始用户IP,或者代理IP地址。对HTTp协议进行扩展。定义了实体头。

HTTP_X_FORWARDED_FOR = clientip,proxy1,proxy2  所有IP用”,”分割。 HTTP_CLIENT_IP 在高级匿名代理中,这个代表了代理服务器IP。既然是http协议扩展一个实体头,并且这个值对于传入端是信任的,信任传入方按照规则格式输入的。以下以x_forword_for例子加以说明,正常情况下,这个值变化过程。

来自:http://blog.chacuo.net/98.html
背景:目前虚拟机和云的兴起,对一些应用的封装啥的还没有火起来,比如:FreeBSD的jail啥的,目前出了一个叫docker的,可以了解了解。

基本概念
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上。
Docker是一个重新定义了程序开发测试、交付和部署过程的开放平台,Docker则可以称为构建一次,到处运行,这就是docker提出的“Build once,Run anywhere”

备注:java提出的是” compile Once,Run Anywhere”
Docker与linux内核的关系
docker与linux内核的关系
Cgroup: 对资源进行限制(如对物理资源CPU、内存、I/O的限制)
Namespace:对进程进行隔离
Chroot: 能改变当前运行的进程和子进程的根目录
AUFS:联合文件系统,Docker利用AUFS将不同的Layer结合到1个image中去
Docker架构
Docker采用C/S架构,客户端与服务器端不一定要在一起。客户端可以运行在windows、linux等机器上,然后服务器端必须运行在linux 64bit的操作系统上。
Docker“组件间”关系
ü  主机:运行容器的机器
ü  镜像:文件的层次结构,以及包含如何运行容器的元数据, Dockerfile中的每条命令都会在文件系统中创建一个新的层次结构,文件系统在这些层次上构建起来,镜像就构建于这些联合的文件系统之上
ü  容器:一个从镜像中启动,包含正在运行的程序的进程
ü  Registry(镜像仓库):存放镜像的地方,如Docker Hub
ü  Volumn(卷):将物理机的文件夹挂载到容器内部.与openstack的volumn不一样,openstack中的卷是块存储,不能共享。而这里的volumn可以共享。
ü  Dockerfile:用于创建镜像的脚本
Docker应用场景
面向开发人员:快速开发、交付应用程序
主要体现在三个方面:
ü  代码一致:
在没有docker之前,开发、测试、生成环境可能不一样,如发布某个服务的端口时,开发是1000,而生产是2000,这就导致配置文件不一致。然而使用docker后,我在容器内的端口都是一样的,而容器对外暴露的端口可能不一样。
ü  开发环境与生产环境的一致性
我们知道,在生产环境的部署比较复杂,服务非常繁多。通过docker,我们可以单机版上通过容器来模拟生产环境的分布式环境。从而让开发人员的开发更有效率。
ü  快速部署
可以将docker理解为轻量级的虚拟机,启动docker容器速度很快,启动虚拟机很慢。
面向运维人员:降低运维成本
ü  节约安装各种软件的时间。
     在没有docker之前,在部署程序之前,势必要搭建环境,而搭建环境很花费时间,还要解决环境的各种依赖,而docker通过镜像机制,将你的代码和运行环境直接打包成镜像,扔到容器启动即可。
ü  降低运维成本。
在没有docker之前,由于技术不断发展,运维也要不停的学习各种软件的使用技能,如Node.js、redis等。有了docker,根本不用关系这些技术(或者少关心),只需要关注容器就可以了,能够正常的发布容器,停止容器、删除容器、迁移容器就可以了。
面向企业: Paas层的实现
Coding.net、Oschina这些代码托管平台,有个功能即提供给用户程序的演示环境,我不知道他们底层到底采用的什么技术,但是如果Iaas层的openstack,给用户直接提供虚拟机,先得太“笨重”,因为虚拟机本身对物理机的开销就比较大,如果采用Docker,我1台物理机可以部署多个容器,可以降低企业的采购物理机的费用,而且运行效率上应该比采用Iaas层的方案快。

Docker基本命令
Docker安装相关命令
参考: https://docs.docker.com/installation/ubuntulinux/

摘自:http://blog.csdn.net/opensure/article/details/46490749
聚贤庄中原各路英雄围攻乔峰,主要矛盾是因为乔峰不是汉人。而乔峰使太祖长拳战尽天下英雄而不败就是为了讽刺这些人。
太祖长拳是宋开国皇帝赵匡胤发明的拳术,又名三十二势长拳、宋太祖拳、太祖拳、赵家拳、赵门、太祖门,有的地方也叫红拳、洪拳、炮捶、赵门炮拳。其精神偶像是赵匡胤。明代,该拳法已名闻天下。并对戚家拳、太极拳、洪洞通背拳等拳种产生了重要影响。因此,又有“百拳之母”的称谓。

林,而少林功夫又发源于西域,那些所谓的英雄围攻乔峰是因为他不是汉人,而他们却都用西域功夫,只有乔峰用本朝太祖的长拳,绝妙的讽刺
阅读全文
总之,这种情况主要还是因为php-fpm.conf或php.ini里有#号引起的,我发现尽管php-fpm.conf里用#号能注释,但是会有影响,
我之前安装的是PHP 5.6.18,在运行程序时往往运行nginx请求出现:Comments starting with '#' are deprecated in Unknown on line 1,
后来我再次安装低版本时默认启动没有问题,再将PHP 5.6.18里的php/etc/php-fpm.conf挪动回来后再启动就发生:Comments starting with '#' are deprecated in Unknown on line ,原来里面有一些以#号的中文注释导致的,如:

结论:尽量别用#号注释,php.conf和php-fpm.conf两个,一个是;注释,别用#号,另一个是尽量别用#号,一个#都不要留更好。

===========================================================================
ErrorException [ 8192 ]: Comments starting with '#' are deprecated in Unknown on line 1

find /usr/local/php/ -name "*.ini" -exec sed -i -re 's/^(\s*)#(.*)/\1;\2/g' {} \;
来自:http://stackoverflow.com/questions/29211550/track-down-php-error-comments-starting-with-are-deprecated-in-unknown-on-li


8192   E_DEPRECATED (integer)   运行时通知。启用后将会对在未来版本中可能无法正常工作的代码给出警告。   since PHP 5.3.0
错误码来自:http://www.jb51.net/article/47793.htm
应该是新版本的PHP出现的一个mysql推荐用mysqlli和pdo提示的问题,把错误关掉,再打开就好了,这块儿可能PHP还是有点问题:
error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED);//解决Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future:                                                                                                  
ini_set('display_startup_errors', 0);
ini_set('display_errors', 0);
阅读全文
背景:对的jquery有一种叫链式操作的dom的,而PHP在写sql时也可以使用类似的方法,如:

这种写法有点类似Jquery的链式写法,如下:


__call函数相关介绍:http://jackxiang.com/post/2834/
=================================================
使用__call()方法来实现数据库连贯操作
  

---------- 调试PHP ----------
SELECT sex, count(sex) FROM  user where sex in ("男","女")   group by sex
                having avg(age) > 25
Output completed (0 sec consumed) - Normal Termination

来自:http://blog.sina.com.cn/s/blog_6109978501017154.html
背景:自己是https的,想调用别人的一些华东解锁验证码的一些js不是https的,于是被阻止了,怎么办?

    从 Firefox 18 开始,如果 HTTPS 页面中包含非加密的 HTTP 内容,浏览器会在控制台输出警告,记录 Mixed Active Content 请求。而从 Firefox 23 开始,浏览器会默认阻止 HTTPS 页面中可能影响网页安全的 HTTP 请求(即阻止 Mixed Active Content)。这样做会牺牲一些网站的兼容性,但对安全性的提高是很有帮助的。

获取 Mixed Content 相当于发起部分加密的连接,其中未加密的部分存在被中间人攻击的可能。不同类型的 Mixed Content 所产生的危害程度也有所不同,Mixed Passive Content 可能会使中间人获取到用户的设备信息,或让用户看到不正确的图片、音频等信息。而 Mixed Active Content 则可能导致用户的敏感数据被窃取,比如账号密码等。

解决问题

解决方案一 (一劳永逸)

避免在 HTTPS 页面中包含 HTTP 的内容。

解决方案二 (让 Firefox 暂时不阻止)

mixed_content_01

解决方案三 (配置本地 Firefox,让其不再阻止)

打开新标签页,在地址栏输入 about:config,进入配置页面。

mixed_content_02

为什么 Mixed Content Blocker 不是阻止所有的 HTTP 请求?

Mixed Content 可以分为两类:

Mixed Passive Content
Mixed Active Content
Mixed Passive Content (a.k.a. Mixed Display Content)

Mixed Passive Content 是在 HTTPS 页面中一些对安全性影响不大的 HTTP 内容,比如 Image、Audio、Video 等。即使这些内容被中间人篡改,所产生的影响也只是 —— 中间人得知了用户的浏览器信息 (through user-agent included by HTTP headers)、用户看到了一张不正确的图片,这些被篡改的内容无法修改 DOM 树,也无法执行。另外,Mixed Passive Content 在 Web 上普遍存在。因此 Firefox 默认不会阻止 Mixed Passive Content。

Mixed Active Content (a.k.a. Mixed Script Content)

Mixed Active Content 是在 HTTPS 页面中一些能够修改 DOM 树的 HTTP 内容,如 JavaScript、CSS、XMLHttpRequest、iFrame 等。这些 HTTP 内容被中间人修改以后,可能会影响原有 HTTPS 内容的安全性,导致敏感的用户数据被盗。因此 Firefox 会默认阻止 Mixed Active Content。

深入思考

为什么 Frame 应该是 Mixed Active Content?

Frame 之所以不能被分类为 Mixed Passive Content 主要有以下几个原因:
一个 frame 可以将外层可靠的 HTTPS 页面跳转到恶意盗取信息的仿造页面。
如果一个 HTTPS 页面嵌套着 HTTP frame,而这个 frame 包含表单用以输入用户信息,那么用户信息将会以 HTTP 方式传送,有被中间攻击者窃取的危险,而用户却毫不知情,还以为一切都在安全的 HTTPS 里。

如何判定 Mixed Content 是 Active 还是 Passive?

该 Mixed Content 是否会影响页面的 DOM 结构。(Yes -> Active, No -> Passive)

来自:http://www.ipeld.net/archives/8860.html
背景:测试人员提出在Html里一次性上传传了个8G文件,为何接口没有立即返回超过限定大小了,这块Html5里有对文件大小作限定,之前也有浏览器也提出过类似问题,接收方但目前如果采用一次性Post目前的PHP上传是没有办法立即通过分析Http协议的content-lenth告诉浏览器,你超了,目前都是通过http上传的httpBody,如Nginx这块配置一下大小,PHP里也配置一下大小进行拦截,测试的这种想法是好,目前但没法实施,除非你用断点上传且得在H5的浏览器的帮助下进行浏览器过滤一次,服务端再过滤一次才可行。

阅读全文
问题一:
在测试PHP代码的过程中,会遇到这样的问题:PHP提示Notice: Undefined variable,遇到这样的问题很纠结,但是很容易解决。
    今天晚上,我就遇到了这样的问题,到网上搜索了很多解决方法,整理如下,仅供参考,同时再次感谢网上各位大牛给大家提供的各式各样的方法!
    
    PHP默认的配置会报这个错误,虽然有利于发现错误,但同时字现实实践中会出现很多问题。
   解决方法如下:
   一、修改php.ini配置文件
            error_reporting设置:
            找到error_reporting = E_ALL
            修改为error_reporting = E_ALL & ~E_NOTICE
             error_reporting(E_ALL ^ E_DEPRECATED ^ E_NOTICE);//解决Deprecated: mysql_connect(): The mysql extension is      deprecated and will be removed in the future
             原理是:减弱PHP的敏感程度,使其遇到这种问题不报错。
    二、在文件的php的头部加入一下代码:
            ini_set("error_reporting","E_ALL & ~E_NOTICE");
           同样也可以解决问题。
    三、参考一下这篇文章:
  《当遇到:Notice …Undefined variable…》
        网址是:http://www.phpiask.com/?p=276


来自:http://blog.csdn.net/chenyanggo/article/details/7430383


问题二:
遇到Warning: Missing argument 1 for checkLogin(), called in C:\wamp\www\library222\admin\main.php on line 4 and defined in C:\wamp\www\library222\admin\inc\conn.php on line 51

/***********************************************************************/
//检查管理员是否登录
function checkLogin($id)
{
   session_start();
if(!isset($_SESSION['sid']))
{
  echo "<script language='javascript'>alert('请先登录!');parent.location.href='index.php';</script>";
}
if($id==0)return;
}
?>


调用函数checkLogin的时候少了参数。
稍微改下:
function checkLogin($id = 0){
...
}

来自:http://zhidao.baidu.com/link?url=wddMxfPvxDPCMFGo-uc5kRc2gflkJgofmKutyj1A2d4fc_6B566BjWftMvRpeQvAgjhR6Guznz1BfLa2uH8_Qi0P53TyIto_GeDYYe81Slq
来自:http://www.thinkindrupal.com/node/495
背景:像下拉这样的控件,有jQuery 插件autocomplete ,现在出来一个select2.js。

     select2.js是一个html select美化模拟类jquery插件,但是select2.js又远非简单的模拟美化那么简单,它还具有搜索功能,多选功能(可限制选择数量),ajax方式加载数据,可以设置placeholder,
可以设置禁用状态disabled,并且设置非常简单,如:$(".js-example-disabled").prop("disabled", false);

select2.js默认值设置:$("#select2").val("1").trigger("change");  多选的默认值可以使用$("#select2").val(["1","2"]).trigger("change");  这样传递数组过去。

select2还有丰富的自定义事件
$("#select2").on("select2:open", function (e) { log("select2:open", e); });
$("#select2").on("select2:close", function (e) { log("select2:close", e); });
$("#select2").on("select2:select", function (e) { log("select2:select", e); });
$("#select2").on("select2:unselect", function (e) { log("select2:unselect", e); });
$("#select2").on("change", function (e) { log("change"); });

更多丰富的select2用法请参考https://select2.github.io/examples.html,懒人建站也会在稍后给出实际应用中的一些例子,和一些方便调用的小花招。

select2小花招:自己定义当前选中的selected值,我们在select2的节点上给出一个<select class="test1" data-selected="2"> 看红色部分,然后我们就可以在设置选中值得时候就可以使用如下js代码,
$("#select2").val(function(){
                  return $(this).data("selected")
              }).trigger("change");

利用val()接收一个函数,而且可以利用 this

本文链接:html select美化模拟jquery插件select2.js
http://www.51xuediannao.com/js/jquery/select2.html
分页: 16/246 第一页 上页 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 下页 最后页 [ 显示模式: 摘要 | 列表 ]