破解北京pk10冠亚和值 1比0.95刷流水教程 pk10稳赚技巧方案 北京pk10怎么研究走势 北京pk赛车一天多少期 北京pk赛车历史记录 全天北京pk10赛车计划 北京pk10冠军单双技巧 北京pk两期免费计划 北京pk10冠军公式大全 pk10高手单期人工计划 北京pk10免费人工计划 pk10一天赚300好搞吗 北京pk10杀3码公式 app软件购买北京pk10 北京pk10每天开多少期 北京pk10精准一期计划 北京pk拾全天精准计划 二分pk10怎么玩 pk10怎么引诱别人玩 北京赛車pk10网站 北京pk2期计划在线网站 pk10前三跨度怎么算 赌场最怕什么样的赌法 北京pk赛车彩票官网 怎样控制自己每天赢500 北京pk10正规彩票网站 北京pk10前五1码计划 一无所有怎么白手起家 北京pk10去一尾图解

Http Server : 一个差生的逆袭

时间:2019-01-09   来源:尚学堂   阅读:332

  我刚毕业那会儿,国家还是包分配工作的,我的死党小明被分配到了一个叫数据库的大城市,天天都可以坐在高端大气上档次的机房里,在那里专门执行SQL查询优化,工作稳定又舒适;

  隔壁宿舍的小白被送到了编译器镇,在那里专门把C?#27425;?#20214;编译成EXE程序,虽然累,但是技术含量非常高,工资高,假期多。

  我成绩不太好,典型的差生,四级补考了两次才过,被发配到了一个不知道什么名字的村庄,据说要处理什么HTTP请求,这个村庄其实就是一个破旧的电脑,令我欣慰的是可以上网,时不时能和死党们通个信什么的。

  ?#36824;?#36741;导员说了,我们都有光明?#37027;?#36884;。

 

  1、HttpServer1.0

  HTTP是个新鲜的事物,能够激起我一点点工作的兴趣,不至于沉沦下去。

  一上班,操作系统老大扔给我一大堆文档:“这是HTTP协议,两天看完!”

  我这样的英文水平,这几十页的英文HTTP协议我不吃不喝不睡两天?#37096;?#19981;完,死猪不怕开水烫,慢慢磨吧。

  两个星期以后,我终于大概明白了这HTTP是怎么回事?#20309;?#38750;是?#34892;?#30005;脑上的浏览器向我这个?#39057;?#33041;发送一个预先定义好的文本(Httprequest),然后我这边处理一下(通常是从?#25165;?#19978;取一个后缀名是html的文件),然后再把这个文件通过文本方式发回去(httpresponse),就这么简单。

  唯一麻烦的实?#37073;?#25105;?#20204;?#25805;作系统给我建立Http层下面的TCP连接通道,因为所有的文本数据都得通过这些TCP通道接收和发送,这个通道是用socket建立的。

  弄明白了原理,我很快就搞出了第一版程序,这个程序长这个样子:

  (注:详情参加文章《张大胖的socket》)

  看看,这些socket,bind,listen,accept...都是操作系统老大提供的接口,我能做的也就是把他们组装起来:先在80端口监听,然后进入无限循环,如果有连接请求来了,就接受(accept),创建新的socket,最后才可以通过这个socket来接收,发送http数据。

  老大给我的程序起了个名称,HttpServer,版本1.0。

  这个名字听起来挺高端的,我?#19981;丁?/span>

  我兴冲冲的拿来实验,程序启动了,在80端口“?#36164;亍保?#36807;了一会儿就有连接请求了,赶紧Accept,建立新的socket,成功!接下来就需要从socket中读取HttpRequest了。

  可是这个receive调用好慢,我足足等了100毫秒还没有响应!我被阻塞(block)住了!

  操作系统老大说:“别急啊,我也在等着从网卡那里读数据,读完以后就会复制给你。”

  我乐?#37027;逑校?#21487;以休息一下。

  可是操作系统老大说:“别介啊,后边还有很多浏览器要发起连接,你不能在这儿歇着啊。”

  我说不歇着怎么办?receive调用在你这里阻塞着,我除了加入阻塞队?#26657;?#35753;出CPU让别人用还能干什么?

  老大说:“唉,大学里没听说过多进程吗?你现在很明显是单进程,一旦阻塞就完蛋了,想办法用下多进程,每个进程处理一个请求!”

  老大教训的是,我忘了多进程并发编程了。

 

  2、Http2.0:多进程

  多进程的思路非常简单,当accept连接以后,对于这个新的socket,不在主进程里处理,而是新创建子进程来接管。这样主进程就不会阻塞在receive上,可以继续接受新的连接了。

  我改写了代码,把Httpserver升级为V2.0,这次运行顺畅了很多,能并发的处理很多连接了。

  这个时候Web刚刚兴起,我这个HttpServer访问的人还不多,每分钟也就那么几十个连接发过来,我轻松应对。

  由于是新?#36866;?#29289;,我还有资本给搞数据库的小明和做编译的小白吹吹牛,告诉他们我可是网络高手。

  ?#36824;?#20960;年,Web迅速发展,我所在的破旧机器也不行了,换成了一个性能强悍的服务器,也搬到了四季如春的机房里。

  现在每秒中都有上百个连接请求了,?#34892;?#36830;接?#20013;?#30340;时间还相当的长,所以我经常?#20040;?#24314;成百上千的进程来处理他们,每个进程都得耗费大量的系统资源,很明显操作系统老大已经不堪重负了。

  他说:“咱们不能这么干了,这么多进程,光是做进程切换就把我累死了。”

  “要不对每个Socket连接我不用进程了,使用线程?”

  “可能好一点,但我还是得切换线程啊,你想想办法限制一下数量吧。”

  我怎么限制?我只能说同一时刻,我只能支持x个连接,其他的连?#21448;?#33021;排队等待了。

  这肯定不是一个好的办法。

 

  3、HttpServer3.0:Select模型

  老大说:“我们仔?#36127;?#35745;合计,对我来说,一个Socket连接就是一个所谓的文件描述符(FileDescriptor,简称fd,是个整数),这个fd背后是一个简单的数据结构,但是我们用了一个非常重量级的东西--进程--来表示对它的读写操作,有点浪费啊。”

  我说:“要不咱们还切换回单进程模型?但是又会回到?#19979;?#19978;去,一个receive的阻塞就什么事都干不了了”

  “单进程也不是不可以,但是我们要改变一下工作方式。”

  “改成什么?”我想不透老大在卖什么关子。

  “你想想你阻塞的本?#35797;?#22240;,还不是因为人家浏览器还没有把数据发过来,我自然也没法给你,而你又迫不及待的想去读,我只好把你阻塞。在单进程情况下,一阻塞,别的事儿都干不了。“

  “对,就是这样”

  ?#20843;?#20197;你接受了客户端连接以后,不能那么着急的去读,咱们这么办,你的每个socketfd都有编?#29275;?#20320;把这些编号告诉我,就可以阻塞休息了”

  我问道:“这不和以前一样吗?原来是调用receive时阻塞,现在还是阻塞”

  “听我说完,我会在后台检查这些编号的socket,如果发现这些socket可以读写,我会把对应的socket做个标记,把你?#21483;?#21435;处理这些socket的数据,你处理完了,再把你的那些socketfd告诉我,再次进入阻塞,如此循环往复。”

  我有点明白了:“这是我们俩的一种通信方式,我告诉你我要等待什么东西,然后阻塞,如果事件发生了,你就把我?#21483;眩?#35753;我做事情。”

  “对,关键点是你等我的通知,我把你从阻塞状态?#21483;?#21518;,你一定要去遍历一遍所有的socketfd,看看谁有标记,有标记的做相应处理。我把这种方式叫做select”

  我用select的方式改写了Httpserver,抛弃了一个socket请求对于一个进程的模式,现在我用一个进程就可以处理所有的socket了。

 

  4、HttpServer4.0:epoll

  这种称为select的方式运行了一段时间,效果还不错,我?#36824;?#25226;socketfd告诉老大,然后等着他通知我就行了。

  有一次我无意中问老大:“我每次最多可以告诉你多少个socketfd?”

  “1024个”

  “那就是说我一个进程最多只能监控1024个socket了?”

  "是的,你可以考虑多用几个进程啊"

  这倒是一个办法,?#36824;?select"的方式用的多了,我就发现了弊端,最大的问题就是我从阻塞中恢复以后,需要遍历这1000多个socketfd,看看有没有标志位需要处理。

  ?#23548;实那?#20917;是,很多socket并?#25442;?#36291;,在一段时间内浏览器并没有数据发过来,这1000多个socket可能只有那么几十个需要真正的处理,但是我不得不查看所有的socketfd,这挺烦人的。

  ?#35757;览?#22823;不能把那些发生了变化的socket告诉我吗?

  我把这个想法给老大说了下,他说:?#29677;牛?#29616;在访问量越来越大,select方式已经不满足要求,我?#20999;?#35201;与时俱进了,我想了一个新的方式,叫做epoll”

  “看到没有,使用epoll和select其实类似“老大接着说:”不同的地方是第3步和第4步,我只会告诉你那些可以读写的socket,你呢只需要处理这些'ready'的socket就可以了“

  “看来老大想的很周全,这种方式对我来说?#22270;?#21333;的多了。”

  我用epoll把HttpServer再次升级,由于不需要遍历全部集合,只需要处理哪些有变化的,活跃的socket文件描述符,系统的处理能力有了飞跃的提升。

  我的HttpServer受到了广泛的欢迎,全世界有无数人在使用,最后死党数据库小明也知道了,他问我:“大家都?#30340;?#33021;轻松的支持好几万的并发连接,真是这样吗?”

  我谦虚的说:“过奖,其实还得做系统的优化啦。”

  他说:“厉害啊,你小子走了狗屎运了啊。”

  我回答:“毕业那会儿辅导员不是说过吗,每个人都有光明?#37027;?#36884;。”

  (完)

相关资讯

  • 北京校区
  • 山西校区
  • 郑州校区
  • 武汉校区
  • 四川校区
  • 长沙校区
  • 深圳校区
  • 上海校区
  • 广州校区
  • 保定招生办

北京海淀区校区(总部):北京市海淀区西三旗街道建材城西?#20998;?#33150;建华商务大厦东侧二层尚学堂
北京京南校区:北京亦庄经济开发区科创十四街6号院1?#24597;?赛蒂国际工业园
咨询电话:400-009-1906 / 010-56233821
面授课程: JavaEE培训大数据就业班培训大数据云计算周末班培训零基础大数据连读班培训大数据云计算高手班培训人工智能周末班培训人工智能+Python全栈培训H5+PHP全?#36824;?#31243;师培训

山西学区地址:山西省晋中市榆次区大学城大学生活广场万科商业A1座702

郑州学区地址?#27721;?#21335;电子商务产业园6?#24597;?层407
咨询电话:0371-55177956

武汉学区地址?#27721;?#21271;省武汉市江?#37027;?#27743;夏大道26号 宏信悦谷创业园4楼
咨询电话:027-87989193

四川学区地址:成都市高新区锦晖西一街99号布鲁明顿大厦2栋1003室
咨询电话:028-65176856 / 13880900114

网址:http://www.cssxt.com/
咨询电话:0731-83072091

深圳校区地址:深圳市宝安区航城街道航城大道航城创新创业园A4栋210(固戍地铁站C出口)
咨询电话:0755-23061965 / 18898413781

上海尚学堂?#23665;?#26657;区地址:上海市?#23665;?#21306;荣乐东路2369弄45?#24597;?#22320;伯顿大厦2层
咨询电话:021-67690939

广州校区地址:广州市天河区元岗横路31号慧通产业广场B区B1栋6楼尚学堂(地铁3号线或6号线到“天河客运站”D出口,右拐?#24330;?#32422;800米)
咨询电话:020-2989 6995

保定招生办公室

地址?#27721;?#21271;省保定市竞秀区朝阳南大街777号鸿悦国际1101室

电话:15132423123

Copyright 2006-2019 北京尚学堂科技有限公司  京ICP备13018289号-19  京公网安备11010802015183  
?#25945;?#32852;系:18610174079 ?#35780;?#24072;  
pk10单双最好方法