Git AutoCRLF 与 SafeCRLF 换行符问题

Windows和Linux的换行符不一样:

  • CR回车 LF换行
  • Windows/Dos CRLF \r\n
  • Linux/Unix LF \n
  • MacOS CR \r

解决方法:打开命令行,进行设置,如果你是在Windows下开发,建议设置autocrlf为true。 如果文件编码是UTF8且含中文,那设置autocrlf=false,把所有文件转换为Linux编码(即LF\n),开启SafeCRLF检查。

一、AutoCRLF

提交时转换为LF,检出时转换为CRLF

git config –global core.autocrlf true

提交时转换为LF,检出时不转换

git config –global core.autocrlf input

提交检出均不转换

git config –global core.autocrlf false

二、SafeCRLF

拒绝提交包含混合换行符的文件

git config –global core.safecrlf true

允许提交包含混合换行符的文件

git config –global core.safecrlf false

提交包含混合换行符的文件时给出警告

git config –global core.safecrlf warn

有意思的人脸识别API

1、微软提供的接口

https://www.projectoxford.ai/face

应用:http://how-old.net/

2、40多个关于人脸检测/识别的API、库和软件

http://blog.jobbole.com/45936/

3、百度开放云 人脸识别 BFR

https://bce.baidu.com/product/bfr.html

HTTP2.0的奇妙日常(转)

HTTP2.0性能增强的核心:二进制分帧

HTTP 2.0最大的特点: 不会改动HTTP 的语义,HTTP 方法、状态码、URI 及首部字段,等等这些核心概念上一如往常,却能致力于突破上一代标准的性能限制,改进传输性能,实现低延迟和高吞吐量。而之所以叫2.0,是在于新增的二进制分帧层。 既然又要保证HTTP的各种动词,方法,首部都不受影响,那就需要在应用层(HTTP2.0)和传输层(TCP or UDP)之间增加一个二进制分帧层。 在二进制分帧层上,HTTP 2.0 会将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码 ,其中HTTP1.x的首部信息会被封装到Headers帧,而我们的request body则封装到Data帧里面。

然后,HTTP 2.0 通信都在一个连接上完成,这个连接可以承载任意数量的双向数据流。相应地,每个数据流以消息的形式发送,而消息由一或多个帧组成,这些帧可以乱序发送,然后再根据每个帧首部的流标识符重新组装。

HTTP2.0 首部压缩

HTTP 2.0 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送;通信期间几乎不会改变的通用键-值对(用户代理、可接受的媒体类型,等等)只 需发送一次。事实上,如果请求中不包含首部(例如对同一资源的轮询请求),那么 首部开销就是零字节。此时所有首部都自动使用之前请求发送的首部。

如果首部发生变化了,那么只需要发送变化了数据在Headers帧里面,新增或修改的首部帧会被追加到“首部表”。首部表在 HTTP 2.0 的连接存续期内始终存在,由客户端和服务器共同渐进地更新 。

“好了,现在你倒是给我解释一下,这里使用自动化合并文件和Sprite合图是什么回事?”晨伯不解

“本质上,当然是为了减少请求啦,通过多个js或css合并成一个文件,多张小图片拼合成Sprite图,可以让多个HTTP请求减少为一个,减少额外的协议开销,而提升性能。”如是道也

“当然,一个HTTP的请求的body太大也是不合理的,有个度。文件的合并也会牺牲模块化和缓存粒度,可以把“稳定”的代码or 小图 合并为一个文件or一张Sprite,让其充分地缓存起来,从而区分开迭代快的文件” 我不明白晨伯的问题,就稍微补充了一下方案。

所有的HTTP2.0的请求都在一个TCP链接上 HTTP2.0所有通信都是在一个TCP连接上完成。HTTP 2.0 把 HTTP 协议通信的基本单位缩小为一个一个的帧,这些帧对应 着逻辑流中的消息。并行地在同一个 TCP 连接上双向交换消息。就好比,我请求一个页面http://www.qq.com。页面上所有的资源请求都是客户端与服务器上的一条TCP上请求和响应的!

有关注TCP性能的同学就会知道,HTTP性能的关键在于低延迟而不是高带宽!大多数HTTP 连接的时间都很短,而且是突发性的,但TCP 只在长时间连接传输大块数据时效率才最高。HTTP 2.0 通过让所有数据流共用同一个连接,可以更有效地使用TCP 连接,让高带宽也能真正的服务于HTTP的性能提升。

同时,单链接多资源的方式,使到至上而下的层面都得到了好处:

  • 可以减少服务链接压力,内存占用少了,连接吞吐量大了
  • 由于 TCP 连接减少而使网络拥塞状况得以改观;
  • 慢启动时间减少,拥塞和丢包恢复速度更快。

也就是说,“资源合并减少请求”的优化手段对于HTTP2.0来说是没有效果的,只会增大无用的工作量而已。

他说得好有道理,我竟然掩脸而对(因为脸被打疼了)。

“你在再我说说,这些cdn1.cn,cdn2.cn,cdn3.cn是什么回事啊”晨伯又问到。

“因为HTTP1.x上如果一个只用一个持久链接,请求只能一个一个顺序请求,为了高效地并行下载资源,浏览器允许我们打开多个TCP会话,但是一个域名下限制6个链接。为了突破这些限制,我们可以域名分区,提高并行下载资源能力…..”我只好把我当年知道的说出来

当时我就有预感要giveyoufive,而晨伯总是按套路出牌….

并行双向字节流的请求和响应 在HTTP2.0上,客户端和服务器可以把HTTP 消息分解为互不依赖的帧,然后乱序发送,最后再在另一端把它们重新组合起来。注意,同一链接上有多个不同方向的数据流在传输。客户端可以一边乱序发送stream,也可以一边接收者服务器的响应,而服务器那端同理。

把 HTTP 消息分解为独立的帧,交错发送,然后在另一端重新组装是 HTTP 2.0 最 重要的一项增强。事实上,这个机制会在整个 Web 技术栈中引发一系列连锁反应, 从而带来巨大的性能提升,因为:

  • 可以并行交错地发送请求,请求之间互不影响
  • 可以并行交错地发送响应,响应之间互不干扰
  • 只使用一个连接即可并行发送多个请求和响应
  • 消除不必要的延迟,从而减少页面加载的时间

那么也就是说“域名分区”这种优化手段对于HTTP2.0是无用的,因为资源都是并行交错发送,且没有限制,不需要额外的多域名并行下载。

“既然所有资源都是并行交错发送,会不会出现这样的情况【浏览器明明在等关键的 CSS 和JS,你TMD的服务器还在发送图片】” 我疑问道。

HTTP2.0的请求优先级

每个HTTP2.0流里面有个优先值,这个优先值确定着客户端和服务器处理不同的流采取不同的优先级策略,高优先级的流都应该优先发送,但又不会绝对的。绝对地准守,可能又会引入首队阻塞的问题:高优先级的请求慢导致阻塞其他资源交付。分配处理资源和客户端与服务器间的带宽,不同优先级的混合也是必须的。

“有了优先级,HTTP2.0根本不会发生【浏览器明明在等关键的 CSS 和JS,你TMD的服务器还在发送黄图】”晨伯道。

“我根本没有说是服务器在发黄图,好不好。”我吐槽了一下。

“还有还有,你这里的一段base64内嵌图片又是什么回事?是黄图吗?”晨伯又挑战我了。

内嵌图片这种,有使用条件的优化手段,我还是不要说话好,不然的话按照这个故事的尿性,他应该又要飞拳我。

HTTP2.0的服务器推送

HTTP 2.0 新增的一个强大的新功能,就是服务器可以对一个客户端请求发送多个响应。换句话说,服务器可以强奸你的浏览器,哦不,应该是,除了对最初请求的响应外,服务器还可以额外向客户端推送资源,而无需客户端明确地请求。

当浏览器请求一个html,服务器其实大概知道你是接下来要请求资源了,而不需要等待浏览器得到html后解析页面再发送资源请求。我们常用的内嵌图片也可以理解为一种强制的服务器推送:我请求html,却内嵌了张黄图。

有了HTTP2.0的服务器推送,HTTP1.x时代的内嵌资源的优化手段也变得没有意义了。而且使用服务器推送的资源的方式更加高效,因为客户端还可以缓存起来,甚至可以由不同的页面共享(依旧遵循同源策略)。当然,你是个正直的浏览器,是可以决绝服务器推送的黄图的。

参考文章:

Fiddler 抓取手机 https

开启选项

打开 Fiddler,点击工具栏的 Tools – Fiddler Options

  • 切换到 HTTPS 选项卡,勾选 Capture HTTPS CONNECTs + Decrypt HTTPS trafic
  • 切换到 Connections 选项卡,勾选 Allow remote computers to connect

在手机上安装 Fiddler 根证书

打开 iOS/Android 的浏览器, 访问 http://192.168.1.104:8888 点击底部的 FiddlerRoot certificate 链接将证书安装到手机上(DO_NOT_TRUST_…)

目的:让客户端在之后的通信过程中可以信任该根证书颁发的证书(介绍信)

Fiddler 抓包原理

Fiddler2 使用 man-in-the-middle (中间人) 攻击的方式来截取 HTTPS 流量。在 Web 浏览器面前 Fiddler2 假装成一个 HTTPS 服务器,而在真正的 HTTPS 服务器面前 Fiddler2 假装成浏览器。Fiddler2 会动态地生成 HTTPS 证书来伪装服务器。

我们看到 Fiddler 抓取 HTTPS 协议主要由以下几步进行:

  1. Fiddler 截获客户端发送给服务器的HTTPS请求,Fiddler 伪装成客户端向服务器发送请求进行握手 。
  2. 服务器发回相应,Fiddler 获取到服务器的 CA证书, 用根证书公钥进行解密,验证服务器数据签名,获取到服务器 CA 证书公钥。然后 Fiddler 伪造自己的CA证书, 冒充服务器证书传递给客户端浏览器。
  3. 与普通过程中客户端的操作相同,客户端根据返回的数据进行证书校验、生成密码 Pre_master,用 Fiddler 伪造的证书公钥加密,并生成 HTTPS 通信用的对称密钥 enc_key。
  4. 客户端将重要信息传递给服务器,又被 Fiddler 截获。Fiddler 将截获的密文用自己伪造证书的私钥解开, 获得并计算得到HTTPS通信用的对称密钥 enc_key。Fiddler 将对称密钥用服务器证书公钥加密传递给服务器。
  5. 与普通过程中服务器端的操作相同,服务器用私钥解开后建立信任,然后再发送加密的握手消息给客户端。
  6. Fiddler 截获服务器发送的密文,用对称密钥解开,再用自己伪造证书的私钥加密传给客户端。
  7. 客户端拿到加密信息后,用公钥解开,验证 HASH。握手过程正式完成,客户端与服务器端就这样建立了”信任“。

在之后的正常加密通信过程中,Fiddler如何在服务器与客户端之间充当第三者呢?

服务器—>客户端:Fiddler接收到服务器发送的密文, 用对称密钥解开, 获得服务器发送的明文。再次加密, 发送给客户端。客户端—>服务端:客户端用对称密钥加密,被Fiddler截获后,解密获得明文。再次加密,发送给服务器端。由于Fiddler一直拥有通信用对称密钥enc_key, 所以在整个HTTPS通信过程中信息对其透明。

从上面可以看到,Fiddler抓取HTTPS协议成功的关键是根证书(具体是什么,可Google),这是一个信任链的起点,这也是Fiddler伪造的CA证书能够获得客户端和服务器端信任的关键。接下来我们就来看如果设置让Fiddler抓取HTTPS协议。

参考文章:

Redis 阻塞、安全队列 BLPOP/BRPOPLPUSH

队列优先级怎么做?

方法1. 分N个redis list key,一个高级,一个普通级别 方法2. 如果队列是 rpush,高级的则插队用 lpush(缺点是高级的顺序是反的) 方法3. 用 blpop 的轮训弹出,例如:brpop([‘high_task_queue’, ‘low_task_queue’], 0) 方法4. 有序集合(非阻塞) 方法5. 二分查找在 list 中间找个位置插入

参考链接:http://www.2cto.com/kf/201408/325868.html

阻塞的优点?

节约性能,cli可以休息,不用一直连着,可以处于 WAIT 状态 非阻塞的意思是如果当前队列为空,要求调用方不断轮循(polling+sleep),这对使用者来说是非常不方便的。

==================================================

BLPOP BLPOP key [key …] timeout BLPOP是列表的阻塞式(blocking)弹出原语。

它是LPOP命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被BLPOP命令阻塞,直到等待超时或发现可弹出元素为止。

当给定多个key参数时,按参数key的先后顺序依次检查各个列表,弹出第一个非空列表的头元素。

非阻塞行为

当BLPOP被调用时,如果给定key内至少有一个非空列表,那么弹出遇到的第一个非空列表的头元素,并和被弹出元素所属的列表的名字一起,组成结果返回给调用者。

当存在多个给定key时,BLPOP按给定key参数排列的先后顺序,依次检查各个列表。

假设现在有job、 command和request三个列表,其中job不存在,command和request都持有非空列表。考虑以下命令:

BLPOP job command request 0

BLPOP保证返回的元素来自command,因为它是按”查找job -> 查找command -> 查找request“这样的顺序,第一个找到的非空列表。

redis> DEL job command request  # 确保key都被删除
(integer) 0
redis> LPUSH command "update system..."  # 为command列表增加一个值
(integer) 1
redis> LPUSH request "visit page"  # 为request列表增加一个值
(integer) 1

redis> BLPOP job command request 0  # job列表为空,被跳过,紧接着command列表的第一个元素被弹出。
1) "command"    # 弹出元素所属的列表
2) "update system..."   # 弹出元素所属的值

阻塞行为

如果所有给定key都不存在或包含空列表,那么BLPOP命令将阻塞连接,直到等待超时,或有另一个客户端对给定key的任意一个执行LPUSH或RPUSH命令为止。

超时参数timeout接受一个以秒为单位的数字作为值。超时参数设为0表示阻塞时间可以无限期延长(block indefinitely) 。

redis> EXISTS job  # 确保两个key都不存在
(integer) 0
redis> EXISTS command
(integer) 0

redis> BLPOP job command 300  #因为key一开始不存在,所以操作会被阻塞,直到另一客户端对job或者command列表进行PUSH操作。
1) "job"  # 这里被push的是job
2) "do my home work"  # 被弹出的值
(26.26s)  # 等待的秒数

redis> BLPOP job command 5  # 等待超时的情况
(nil)
(5.66s) # 等待的秒数

相同的key被多个客户端同时阻塞

相同的key可以被多个客户端同时阻塞。 不同的客户端被放进一个队列中,按”先阻塞先服务”(first-BLPOP,first-served)的顺序为key执行BLPOP命令。 在MULTI/EXEC事务中的BLPOP

BLPOP可以用于流水线(pipline,批量地发送多个命令并读入多个回复),但把它用在MULTI/EXEC块当中没有意义。因为这要求整个服务器被阻塞以保证块执行时的原子性,该行为阻止了其他客户端执行LPUSH或RPUSH命令。

因此,一个被包裹在MULTI/EXEC块内的BLPOP命令,行为表现得就像LPOP一样,对空列表返回nil,对非空列表弹出列表元素,不进行任何阻塞操作。

情况1:对非空列表进行操作

redis> RPUSH job programming
(integer) 1

redis> MULTI
OK

redis> BLPOP job 30
QUEUED

redis> EXEC  # 不阻塞,立即返回
1) 1) "job"
   2) "programming"

情况2:对空列表进行操作

redis> LLEN job  # 空列表
(integer) 0

redis> MULTI
OK

redis> BLPOP job 30
QUEUED

redis> EXEC  # 不阻塞,立即返回
1) (nil)

时间复杂度:O(1) 返回值:如果列表为空,返回一个nil。 反之,返回一个含有两个元素的列表,第一个元素是被弹出元素所属的key,第二个元素是被弹出元素的值。

用 RPOPLPUSH 实现安全的队列

Redis的列表经常被用作队列(queue),用于在不同程序之间有序地交换消息(message)。一个客户端通过 LPUSH 命令将消息放入队列中,而另一个客户端通过 RPOP 或者 BRPOP 命令取出队列中等待时间最长的消息。

不幸的是,上面的队列方法是『不安全』的,因为在这个过程中,一个客户端可能在取出一个消息之后崩溃,而未处理完的消息也就因此丢失。

使用 RPOPLPUSH 命令(或者它的阻塞版本 BRPOPLPUSH )可以解决这个问题:因为它不仅返回一个消息,同时还将这个消息添加到另一个备份列表当中,如果一切正常的话,当一个客户端完成某个消息的处理之后,可以用 LREM 命令将这个消息从备份表删除。

最后,还可以添加一个客户端专门用于监视备份表,它自动地将超过一定处理时限的消息重新放入队列中去(负责处理该消息的客户端可能已经崩溃),这样就不会丢失任何消息了。

CentOS 自启动失败分析

场景

Tony哥从家里搬来了一台机器做公司内网开发机,我给它上面装了 CentOS 6.6

失败情况

想要服务器自启动执行某些 sh 脚本,想当然加在 /etc/rc.local 里,但不执行。

解决办法:

1、先查看 /etc/rc.d/rc3.d/S99local 指向哪个文件

有些系统指向的是 /etc/rc.local,有一些是 /etc/rc.d/rc.local。

CentOS 6.6 指向的就是:/etc/rc.d/rc.local

2、保证该文件有可执行权限

chmod +x /etc/rc.d/rc.local

3、将 /etc/rc.local 重新软连接为 /etc/rc.d/rc.local

ln -sf /etc/rc.d/rc.local /etc/rc.local