正则表达式

今天在 使用awk工具处理日志的时候,需要捕获ip地址进行分类,于是随手就写了一个匹配ip的正则((\d{1,3})\.){3}\d{1,3},但是在匹配的时候发现没有任何反应,仔细检查并测试之后,发现并不是我写的正则有问题,而是这是一个历史遗留问题。

正则表达式的种类

纵观整个Regular Expression(正则表达式)的历史,你就会发现,正则表达式是有一个发展过程的,像我上面写的((\d{1,3})\.){3}\d{1,3}这样的正则表达式,其实是比较现代的正则表达式,也就是Perl的正则表达式(Perl Regular Expression),简称PREs。但是在PREs出现之前,人们常用的是BREs(基础正则表达式),和EREs(扩展正则表达式)。

三种正则表达式的区别

如果单从语法的角度看,三种正则表达式并没有多大区别,都是由元字符+普通字符组成,其中元字符“ ^ $ . * + ?  ()  [] {} \ ” 这些基本的元字符都包含在内,这些元字符是正则表达式的基础,但是BREs基础正则表达式对于“* + ? () {}”的支持是需要转义才能使用的,比如在PREs中[0-9]{1,3}匹配1-3个0-9之间的数字,在BREs中的写法则是[0-9]\{1,3\}。

EREs和PREs在“ * + ? () {} ”的使用上则没有什么不同

在PREs中,我们常常使用\d \s \t \n \f \num 等等这种带有转义性质的特殊元字符,在BREs和EREs中是不 支持的

awk sed grep对三种正则表达式的支持

在linux命令行下,我们常常用的awk sed 以及grep命令,默认支持的都是BREs(基础正则表达式),不过grep带上参数之后可以提供对PREs和EREs的支持(grep -P, grep -E),如果习惯使用PREs的话,可以对grep 加上别名

alias grep = "grep -P"

解决方案

了解了三种表达式的区别以后,想要解决之前出现的问题,就非常简单了,只需要把(\d{1,3}\.){3}\d{1,3}改成(\d{1,3}\.)\{3\}\d\{1,3\},就解决了问题了。

正则表达式是一种强大的工具,我觉得任何一个程序员都应该熟练掌握它。

浅析HTTP协议

HTTP协议是什么

HTTP协议是一种网际层协议,HTTP协议是无状态的,HTTP协议对用户是透明的。

每一次HTTP请求都是一次事务,一个HTTP事务是由一条请求命令和一个响应结果组成的,HTTP通信的最基本单位是HTTP报文。

形象通俗的概念理解HTTP协议

其实我觉得HTTP请求就好像去商店(服务器)买东西(请求资源)一样,比如说我拿钱去商店,然后说要买瓶矿泉水,然后商店老板收钱之后把我的矿泉水交到我手里,这就是完成了一次交易,也就是一次HTTP事务。而买东西需要钱就是一个约定,也就是HTTP协议.

理想状态就是拿钱买东西,但是这个过程往往不会永远都那么顺利,总会有各种各样的意外情况。

1.马上放假了,为了准备我的冬眠计划,于是我准备储存一下要过冬的粮食,于是到到商店买了泡面五连包(?_?),给了十块钱,这是时候商店老板很尴尬的说了一句,HTTP 100 continue,不好意思,还差两块五-_-||,没办法,只能再掏出两块五拉,这个时候商店老板很高兴的说了一句HTTP 200 OK,拿好你的东西慢走啊!

2.最近商店决定装修了,门口贴出了一张告示(HTTP 302 Move temporarily),商店装修,临时移动到隔壁了,请到隔壁买东西,那没办法,东西还得买,过冬粮食不能少啊,结果没过两天,商店又贴出告示,(HTTP 301 Moved Permanently),装修花费的时间太长拉,以后就到隔壁买东西吧,好吧,以后就只到隔壁买拉(@_@)

3.商店推出了新的活动,有特价的机械炫酷版键鼠,我看着很心动,于是准备买下来,但是商店老板说:(HTTP 401 Unauthorized ),这是会员专属商品,得办会员卡才能买,好吧~为了买到我心爱的机械键鼠,办卡就办卡吧

刚好这个时候,隔壁的张三同学来了,这个人心眼比较坏,拿着一张20元的假币去买饮料,不巧的是商店老板慧眼如炬,直接就发现了,然后告诉他(HTTP 403 Forbidden),我们这不收假币(-_-||)

过了一段时间之后,我总感觉自己的电脑很慢,于是我琢磨着要换个好一点的CPU,不要太好的就用core i7 6700的cpu吧,然后我兴致勃勃的跑到商店,结果迎来一盆冷水:你要买的这个东西,暂时还没有货(HTTP 404 not found),好吧,等你们进货了记得告诉我(-_-||)

4.最近流感很严重,我准备到商店买感冒药(ps:万能的商店啊,什么都能买,就像机器猫的口袋一样),但是很不凑巧,商店老板也感冒了,门口特出了告示:(HTTP 500 Internal Server Error),老板生病了,暂不提供服务(-_-||),老板知道这件事情之后,他觉得这样会损失很多生意,于是招了个伙计(网关),然后老板只要收钱就行了,跑腿的事就让伙计去干,正巧我今天刚好下班回家,准备买点八宝粥回去吃,结果新来的伙计还没开始上班,老板只能无奈的说(502 bad gateway),伙计还没来,我感冒还没好,你过一个小时再来吧,过了一个小时,伙计来了,老板让他去仓库里拿那个银鹭的桂圆莲子八宝粥,伙计刚好第一天上班,找了半天没找着,我饿的实在不行了,老板只能很无奈的告诉我(HTTP 504 gateway timeout),新来的伙计不懂业务,你今天还是别吃这个了,弄点泡面吃吧(-_-|| 老板的都知道我爱吃泡面了)

因为店里什么都卖,所以店里的客户越来越多了,老板的精力有限,没有办法记得过来那么多熟人,起初为了让老板能够记住我这个吃泡面的常客,于是我告诉他,我住在你后面那栋楼(IP地址记忆),但是我转念一想,后面那栋楼可能不止我一个人啊,万一我要是搬家了呢,老板岂不是记不住我了-_-||,于是我用了一种比较笨的办法,把我的名字和住址贴到我的衣服上(胖url方式),这样老板每次一看纸条就能知道我是谁了。但是感受到无数人异样的眼光之后,我觉得有必要和商店老板商量一下了,就采用办会员卡(session)的形式来记住那些常客吧,让他们登记一下姓名和电话之后,给他们发一张卡(sessionid),然后每次来只要刷一下卡,就能立刻认出是谁拉。老板听了我的仔细分析之后,觉得这个方法非常好,于是就采用了这种方式来记住客户。后来每次买东西,我只要从口袋(cookie)里掏出我的会员卡刷一下,老板就能立刻知道我是谁了(老板比较健忘,我买了那么多泡面,都记不住我-_-||)

理想是好的,但是老板发现,并不是所有的人都有口袋(客户端禁用cookie),就比如说我楼下的小花,每天都是穿裙子,根本没有口袋啊,那就只能拿在手里拉(把session放在隐藏域表单),或者是挂在自己的脖子上(sessionid放在url中),这样老板就能记住拉,但是直接暴露在别人的视线下,太不安全拉,毕竟财不外漏嘛,虽然放在口袋里,也有被人顺走的情况(cookie劫持),但比放手上要好点吧,果不其然,隔壁的张三同学就使坏,把小花的会员卡(sessionid)给顺手牵羊了,然后直接拿着会员卡去买东西了(跨站请求伪造csrf),但是老板记性不好,只要有卡就行,至于拿卡的是不是本人,那他就管不着了。老板记性很差,这也是没有办法的事情,只能提醒一下各位,请保管好自己的会员卡,老板只认卡不认人(-_-||)

虽然老板记性不是很好,但是为人踏实敬业,随着他的努力,客户越来越多了,这个时候一家店就忙不过来了,于是老板决定开分店(服务器集群,负载均衡),但是分店开起来之后,我发现我在这里办的会员卡在那边分店居然不能使用,这我就不能忍了,为什么都是你开的店,这边的会员卡那边不能用呢(?_?),于是我只能跟老板说,既然都是会员,那么这个会员卡必须是两边都能刷的(seesion共享),不然客户肯定不满意对吧,老板听了我分析之后,决定专门设立一处管理会员卡的地方(session服务器),这样买完东西直接到专门刷卡的地方去就好了。采用了这样的方法之后,办卡的人就越来越多了,为了方便大家刷卡,只能多搞几个会员卡卡管理处了(session集群),这样的话差不多就没有什么大问题了。不过分店开了,会员卡也管理好了,但是这个货物渠道出了点问题,买东西的人太多,一个仓库的货物已经不够用了啊,只能多搞几个仓库拉(分库),水果就专门放水果仓库,蔬菜就专门蔬菜的仓库,零食就弄零食仓库拉,但是水果里面,西瓜进的太多了,没有办法,西瓜多搞点空地放吧(分表),这样管理就差不多了。

看到商场越来越大,我觉得很欣慰。恰好又是要过冬的时候了,该储备粮食拉,我拿着会员卡说买个五连包,但是零食卖的太快了,商店的柜台上(缓存)没有了,然后老板让伙计(网关)去仓库拿一些过来,伙计按照老板的吩咐来到了仓库,发现仓库正在进货(表级锁定),不让取货物,这个可把我等坏了,我不就买了泡面么,居然等了几个小时,时间再长一点,我都要饿死了(?_?),这样很明显是不对的吧,我只能再次的给老板建议拉,你这个进货和拿货应该分开来弄(读写分离),弄一个仓库专门进货,另一个仓库专门拿货比较好(主从配置),然后让这个拿货的仓库安排一个专门的工作人员,把新进的货物运到这个仓库来就好了啊,这样就不会存在让客户等好长时间了。健忘的老板果断的采用了这一建议,看着我买泡面的地方,一步步的成长到这个高度,我感觉非常的欣慰,我决定了,以后吃泡面就认准这家店了,其他地方哪都不去(@_@)

浅谈session&cookie

session&cookie的出现

众所周知,HTTP协议是一种无状态的协议,当次请求下一次请求没有任何的关联,所以单纯的用HTTP来记住用户信息是行不通的。每次点击一个链接都需要需要输入用户名和密码的感觉是一种怎样的酸爽体验,为了展现用户的友好性,于是聪明(lan duo)的程序员们就想到了session这种解决方案来保存用户信息。

session是什么

  其实session没有多神奇的地方,只是保存在服务器的一小段数据而已,然后生成一个唯一标识,记作sessionid,然后把这个sessionid发送给用户,这样每次用户请求的时候只要带着这个sessionid,服务器就能知道这个用户的身份了。

cookie是什么

  cookie和session类似,只不过cookie保存在客户端,是以字符串的形式保存的,每次发送http请求的时候,都会把cookie放在请求的首部中,服务器可以通过解析首部从而得到cookie数据,从而得到用户信息,但是由于每次传输cookie需要消耗一定的带宽,所以为了节省资源,程序员们没有把所有的信息都保存在cookie中,而是生成了一个用来记录用户所有信息的id存放在cookie中

session&cookie的生命周期

  如果没有设置生命周期,那么session和cookie的数据是保存在内存中的,随着浏览器的关闭,所有的数据都会丢失,但是如果设置了生命周期,那么在生命周期的时间内,不主动的释放session的话,session会非常顽固的一直存在服务器中,采用这一特性有时候可以进行关键字的记录

用通俗的概念理解session&cookie

  假设服务器是一个大型的商场,用户每次请求就相当于一次购物,那么用户每次购物都需要把私人物品存放在存包处的柜子(session),然后用户会得到一个钥匙(sessionid),通常情况下,用户会把钥匙放在口袋中(cookie),每次购物结束,只需要拿着钥匙直接开启柜子(session)直接拿走自己的个人物品,那么就结束购物了。

但是实际情况总会有些偏差,假设今天客户是个妹子,穿的是裙子来没有口袋怎么办(客户端禁用了cookie),那么柜台人员只能告诉她你最好把钥匙放在手上(把sessionid放在表单的隐藏域中)或者直接带在脖子上(把sessionid放在url中)

钥匙放在手上或者口袋里,总有可能被有心人利用,偷到了钥匙,把客户的私人物品给顺手牵羊了(CSRF跨站请求伪造),这样肯定会给用户造成一定的损失,虽然可以通过让管理处的管理人员记住客户的长相(IP地址),但是还是没办法完全保证数据的安全性

有些时候商场也会造贼,柜子的锁被翘了(session丢失),给客户造成了相当严重的损失,所以为了避免这种情况,存包处的柜子一定要放在安全的地方并且有专人看守(seesion持久化).

商场经过这一系列的优化操作之后,开了分店了(负载均衡),这个时候如果客户来买东西,只把私人物品存到其中一个商场的话,逛完分店的时候还得回到原来的地方拿东西,肯定会给客户造成相当严重的困扰,于是聪明的商场管理人员就想到了一个折衷的解决方案,在两个商场之间设立了一个专门存放私人物品的地方(服务器集群,session共享),存完东西之后你可以任意的选择一个商场进行购物,买完东西只需要去专门管理私人物品的地方拿回自己的东西就好了