好比A,B,C3人同时在一个页面上浏览,A对B进行了评论,而且提到了C。传统的架构,B,C将没法感知到,只有B,C再次拉取内容时,才会获得此信息。显然B ,C错过了与A交互的最佳时机,并且得知信息的时间延后了不少。java
传统的PULL模式,也能够经过定时轮询的方式来尝试拉取数据。但这种技术mysql
1是并非实时的,信息仍是须要到了必定时间间隔才能够获得。程序员
2,这种方式可能大部分请求是无效的,白白浪费了一次网络请求。还形成了web Server的负载大大增高。web
真正的PUSH技术目前有3种,算法
WebSocket,目前还不够成熟,并且IE浏览器或其余低版本浏览器不支持。sql
Flash Socket,虽然能够实现,但须要依赖Flash第三方组件,并且可能会被防火墙或者其余安全策略拦截,实际效果不理想。数据库
XHR轮询,这种方式目前是最成熟的解决方案,浏览器端开启KeepAlive,Server使用epoll等异步IO方式,效率很是高,实测效果很是好。目前Facebook、人人网都使用此模式。编程
腾讯的PSF框架浏览器
PSF是腾讯开发的一套彻底使用PHP开发的逻辑Server框架,基于epoll异步事件通知模型安全
支持TCP长链接、TCP短链接、UDP,3种模式。
TCP使用了经典的Multi-Reactor模型,UDP使用相似LVS的半同步/半异步模型,运行效率很高。在高并发高负载的环境可快速稳定地运行。
PSF拥有完善的多配置多插件管理体系,健壮的Worker进程管理系统,全自动柔性重启策略。
PSF框架支撑着不少逻辑层Server,有数百台线上服务器运行着PSF的插件。在公司内的四层架构建设中发挥了很大的做用。
PSF使用简单方便,开发人员无需关注底层实现,只需专一于业务逻辑开发。
PSF采用了单一配置文件,开发人员只须要修改配置文件便可调整监听IP、端口、资源分配、协议类型、业务组件的上线/下线以及服务器扩容。配置文件中提供了不少选项,能够针对业务的特征,对Server的运行参数进行微调。
PSF框架性能很是好,并发2000压测,一个简单的EchoServer,TCP每秒可处理4万个请求,UDP可处理6万请求。
近来公司某个域名流量大涨,发现一个外部QQ登陆的接口常常失败,用户登陆老是不成功。通过排查发现是登陆的第一步须要保存一个token_secret。当时的程序员编写此代码时直接用了$_SESSION来保存token_secret。这里在并发量小时问题不大,并发大了以后极有可能会出问题。
假设A,B两个请求同时出发,A,B同时session_start,读取到了一个$SESSION的值。当A完成请求写入$SESSION,但B尚未完成请求,B完成请求后再写$_SESSION,就会覆盖A所设置的值。
相似的数据同步问题其实不少的,好比file_put_contents写PHP的Cache文件,若是不加LOCK_EX就可能会存在同步问题,当一个进程写file时,只写到一半有另外的进程去require此文件,这时就会由于文件不完整,致使PHP语法错误。因此涉及到同时读写同一个文件或数据时必定要加锁,不然在高并发的状况下会产生严重错误。
线程是在同一个进程内的,能够共享内存变量实现线程间通讯
线程比进程更轻量级,开很大量进程会比线程消耗更多系统资源
多线程也存在一些问题:
线程读写变量存在同步问题,须要加锁
锁的粒度过大会有性能问题,可能会致使只有1个线程在运行,其余线程都在等待锁。这样就不是并行了
同时使用多个锁,逻辑复杂,一旦某个锁没被正确释放,可能会发生线程死锁
某个线程发生致命错误会致使整个进程崩溃
多进程方式更加稳定,另外利用进程间通讯(IPC)也能够实现数据共享。
共享内存,这种方式和线程间读写变量是同样的,须要加锁,会有同步、死锁问题。
消息队列,能够采用多个子进程抢队列模式,性能很好
PIPE,UnixSock,TCP,UDP。可使用read/write来传递数据,TCP/UDP方式使用socket来通讯,子进程能够分布运行
利用fork能够实现一个最简单的并发TCP Server。主进程accept链接,有新的链接到来就Fork一个子进程。
子进程中循环recv/send,处理数据。
这种模式在请求量很少状况下很实用,像FTP服务器。过去有不少Linux程序都是这种模式的,简单高效,几十行代码就能够实现。固然这种模型在几百个并发的状况下还算不错,大量并发的状况下就有点消耗过大了。
Go语言是google推出的一个静态编译型语言,目标是取代C、C++、Java做为系统开发的语言。开发者不少都是来自贝尔实验室的大神。Go语言包含了不少很是酷的语言特性,值得尝试。
目前Google、盛大、金山、百度等公司已经开始使用Go语言开发系统模块了。本文重点介绍下Go语言区别于通常语言的特性。其余语言,好比内置数据结构,内存管理,闭包,反射等共有的特性就不说了,Go语言所有都有。
一、语言级别的原生并发机制:goroutine
C/C++、java C#等语言都有并发的库,通常都是对操做系统的线程或进程库作封装,使用很不方便。
好比Pthread线程。
Go语言内建了并发机制,使用很是简单。Go语言会本身调度goroutine。goroutine的实现也很高效,能够同时开启几十万个goroutine,并且goroutine之间互相切换成本很低。
func abc(s sting){
time.Sleep(1);
fmt.Println(s);
}
//普通的串行调用
abc(“hello”)
//Go语言并行调用
go abc(“hello”)
Go语言还提供了远程RPC调用,执行go func() 时甚至能够是分布式调用的。
二、语言级别的管道通讯机制:channel
大部分语言都是用共享内存方式进行通讯,而Go语言彻底使用消息传递来进行通讯,安全高效无锁。
channel能够干各类事情,用来作消息传递,管道,缓冲区,mutex等等,还能够配合使用select语法。
ch := make(chan int, 1000)
go func(){
time.Sleep(1e9)
ch <- 999 //写入数据
}
num = <- ch //读数据
chan还能够当成参数传递。Go语言还提供了netchan,能够跨越网络实现消息传递。
三、语言级别的延迟执行特性:defer
好比链接mysql,调用完成后,须要关闭链接通常语言要很当心地考虑加在什么地方。如何处理好异常,好比Java中复杂的final语法。Go语言能够很是轻松的实现,只须要在开始的时候加defer,具体什么时间调用,Go语言会帮你处理。
db.Connect(host, port, db)
defer db.Close()
…//读取数据库
四、语言级别的多返回值特性
C/C++、Java、PHP之类语言想要return多个值,须要很复杂的处理。Go语言很简单,语言自然支持。
ret1, ret2 = func1()
func func1()(ret1 int, ret2 int){
ret1 := 1
ret2 := 2
return ret1, ret2
}
五、Go语言不用写 ;结束符
六、Go语言经过首字母大小写来控制public、private
七、Go语言能够跟C语言无缝结合
慎用全局变量,全局变量很差管理的,会致使你的代码依赖于全局变量,而耦合度过高。
必定不要复制粘贴代码,可重用的代码必定要写成函数,或者类。等你代码多了,就知道这个多么重要了。
不要硬编码数据到代码中,必定要可配置化。若是是全局使用的就搞个全局config。若是仅在类中使用,请使用类静态变量配置。别直接在代码里头写
程序的结构化要作好,先规划一个流程。代码怎么运转的,要很清晰,有主线,从A->B->C,一眼就明白了,并且很容易修改流程和增长,替换环节。不要A直接进入B而后没踪迹了,而后在B中又进入C又没踪迹了。
搞个Trace系统,在你的代码中加入Trace来进行调试。跟踪变量的变化,这样会很方便。发布代码时,可注释掉全部Trace,只须要批量替换便可。
多写点单元测试的脚本,一旦更改了代码,作了大的版本更新。不须要你挨个去试,跑一下单元测试就知道是否是有的地方出问题了。
不少IT公司都采用产品驱动技术的管理模式,咱们腾讯也是如此。身为一个程序员不得不对这种模式作点评价。
不能否认这种模式会比较快得做出产品来,虽然开发出的产品不必定会是最好,最起码不会是最差。另外产品开发的成功率也获得了保证,不至于作了一半不搞了。
可是也顺便讲讲他的坏处吧。产品驱动的开发模式最致命的问题是:会让全部程序员完全失去积极性。不管多么棒的Idea,多么有意思的Idea,只要用了这种模式,程序员的那种积极性,创新性都将不存在了。逐渐会产生另一个问题,反正不是我主导的,我不用再思考了,大家怎么说我就怎么作吧。效率愈来愈差劲。若是军队是参谋指挥将军,打起仗来会怎么样?
谈论下Facebook的管理模式吧。他们也有产品经理,但主要产品的是技术人员而不是产品经理,产品经理负责给技术出谋划策,提供信息帮助技术人员。他们的效率很高。
腾讯也是产品驱动型的管理模式,不过广州研发部是个例外,也正是由于例外,因此他们搞出了QQ邮箱,微信这样的重量级产品来。
对于一个大型网站来讲,代码库很是庞大,模块众多。部门协做的人数规模在百人以上,如何跟踪定位问题不像小网站那样容易。并且咱们的服务器都是集群化的,动辄几千台。有一套可查询方便使用的日志系统相当重要。
对于日志的使用也有了必定的经验。咱们的日志一般会很是详细的记录各类参数,环境变量,HOST等信息,在出现异常的状况下,必需要记录日志。咱们使用了MySQL按时间分片的方式来记录日志,全部集群内节点均经过网络方式来写入到中心日志系统。
在管理端咱们提供了很方便友好的工具,来查询定位日志,可按用户ID、类型、时间等几种索引方式查询。日志系统帮助咱们定位到了不少问题。
PHP错误日志是全部PHP程序问题最直接的反馈渠道。经过分析PHP日志能够发现和分析出系统现有的Bug和潜在的问题。咱们经过在节点部署监控工具,实时收集PHP错误日志,Fatal Error告警。解决了不少问题
咱们有一整套数据上报的系统,系统内各类接口调用、请求响应、错误返回,都会上报到数据统计中心。咱们以报表的形式展示出来,能够很方便的看到每一个模块,每一个接口的可用性,成功率,数据规模。根据数据,咱们还作了成功率告警,当接口成功率低于某个数值,好比99.99%时就会发送短信报警。还有历史数据对比报警,当发现今日数据与往期数据差距较大时,多是系统出现了问题,会及时进行报警。
咱们有一套工具,来监控每一个服务器节点的CPU、硬盘、内存、网卡流量信息,以及其余系统关键参数的信息。并以图表方式提供展现,方便了解服务器运行状况。每次新版本,或新功能上线,都经过这些信息来感知访问量变化,以及机器的负载状况。
当一组Server中其中一台出现问题时,会及时发现,并踢掉。
深刻理解计算机系统
UNIX环境高级编程
深刻理解Linux内核
UNIX网络编程
TCP/IP详解
Linux多线程服务端编程
算法导论
《数据结构》(C语言版)
C程序设计语言
PHP5权威编程