WebSocket
比如A,B,C3人同时在一个页面上浏览,A对B进行了评论,并且提到了C。传统的架构,B,C将无法感知到,只有B,C再次拉取内容时,才会得到此信息。显然B ,C错过了与A交互的最佳时机,而且得知信息的时间延后了很多。
传统的PULL模式,也可以通过定时轮询的方式来尝试拉取数据。但这种技术
1是并不是实时的,信息还是需要到了一定时间间隔才可以得到。
2,这种方式可能大部分请求是无效的,白白浪费了一次网络请求。还造成了web Server的负载大大增高。
真正的PUSH技术目前有3种,
WebSocket,目前还不够成熟,而且IE浏览器或其他低版本浏览器不支持。
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语言特性介绍
Go语言是google推出的一个静态编译型语言,目标是取代C、C++、Java作为系统开发的语言。开发者很多都是来自贝尔实验室的大神。Go语言包含了很多非常酷的语言特性,值得尝试。
目前Google、盛大、金山、百度等公司已经开始使用Go语言开发系统模块了。本文重点介绍下Go语言区别于一般语言的特性。其他语言,比如内置数据结构,内存管理,闭包,反射等共有的特性就不说了,Go语言全部都有。
1、语言级别的原生并发机制: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() 时甚至可以是分布式调用的。
2、语言级别的管道通信机制:channel
大部分语言都是用共享内存方式进行通信,而Go语言完全使用消息传递来进行通信,安全高效无锁。
channel可以干各种事情,用来做消息传递,管道,缓冲区,mutex等等,还可以配合使用select语法。
- ch := make(chan int, 1000)
- go func(){
- time.Sleep(1e9)
- ch <- 999 //写入数据
- }
- num = <- ch //读数据
chan还可以当成参数传递。Go语言还提供了netchan,可以跨越网络实现消息传递。
3、语言级别的延迟执行特性:defer
比如连接mysql,调用完成后,需要关闭连接一般语言要很小心地考虑加在什么地方。如何处理好异常,比如Java中复杂的final语法。Go语言可以非常轻松的实现,只需要在开始的时候加defer,具体什么时间调用,Go语言会帮你处理。
- db.Connect(host, port, db)
- defer db.Close()
- …//读取数据库
4、语言级别的多返回值特性
C/C++、Java、PHP之类语言想要return多个值,需要很复杂的处理。Go语言很简单,语言天然支持。
- ret1, ret2 = func1()
- func func1()(ret1 int, ret2 int){
- ret1 := 1
- ret2 := 2
- return ret1, ret2
- }
5、Go语言不用写 ;结束符
6、Go语言通过首字母大小写来控制public、private
7、Go语言可以跟C语言无缝结合
写好PHP的六个建议
- 慎用全局变量,全局变量不好管理的,会导致你的代码依赖于全局变量,而耦合度太高。
- 一定不要复制粘贴代码,可重用的代码一定要写成函数,或者类。等你代码多了,就知道这个多么重要了。
- 不要硬编码数据到代码中,一定要可配置化。如果是全局使用的就搞个全局config。如果仅在类中使用,请使用类静态变量配置。别直接在代码里头写
- 程序的结构化要做好,先规划一个流程。代码怎么运转的,要很清晰,有主线,从A->B->C,一眼就明白了,而且很容易修改流程和增加,替换环节。不要A直接进入B然后没踪影了,然后在B中又进入C又没踪影了。
- 搞个Trace系统,在你的代码中加入Trace来进行调试。跟踪变量的变化,这样会很方便。发布代码时,可注释掉所有Trace,只需要批量替换即可。
- 多写点单元测试的脚本,一旦更改了代码,做了大的版本更新。不需要你挨个去试,跑一下单元测试就知道是不是有的地方出问题了。
说说产品驱动型管理模式
很多IT公司都采用产品驱动技术的管理模式,我们腾讯也是如此。身为一个程序员不得不对这种模式做点评价。
不可否认这种模式会比较快得作出产品来,虽然开发出的产品不一定会是最好,最起码不会是最差。另外产品开发的成功率也得到了保证,不至于做了一半不搞了。
但是也顺便讲讲他的坏处吧。产品驱动的开发模式最致命的问题是:会让所有程序员彻底失去积极性。无论多么棒的Idea,多么有意思的Idea,只要用了这种模式,程序员的那种积极性,创新性都将不存在了。逐渐会产生另外一个问题,反正不是我主导的,我不用再思考了,你们怎么说我就怎么做吧。效率越来越差劲。如果军队是参谋指挥将军,打起仗来会怎么样?
谈论下Facebook的管理模式吧。他们也有产品经理,但主要产品的是技术人员而不是产品经理,产品经理负责给技术出谋划策,提供信息帮助技术人员。他们的效率很高。
腾讯也是产品驱动型的管理模式,不过广州研发部是个例外,也正是因为例外,所以他们搞出了QQ邮箱,微信这样的重量级产品来。
大型网站运营的技术分享
一、日志系统
对于一个大型网站来说,代码库非常庞大,模块众多。部门协作的人数规模在百人以上,如何跟踪定位问题不像小网站那样容易。而且我们的服务器都是集群化的,动辄几千台。有一套可查询方便使用的日志系统至关重要。
对于日志的使用也有了一定的经验。我们的日志通常会非常详细的记录各种参数,环境变量,HOST等信息,在出现异常的情况下,必须要记录日志。我们使用了MySQL按时间分片的方式来记录日志,所有集群内节点均通过网络方式来写入到中心日志系统。
在管理端我们提供了很方便友好的工具,来查询定位日志,可按用户ID、类型、时间等几种索引方式查询。日志系统帮助我们定位到了很多问题。
二、PHP错误日志收集系统
PHP错误日志是所有PHP程序问题最直接的反馈渠道。通过分析PHP日志可以发现和分析出系统现有的Bug和潜在的问题。我们通过在节点部署监控工具,实时收集PHP错误日志,Fatal Error告警。解决了很多问题
三、数据统计中心
我们有一整套数据上报的系统,系统内各种接口调用、请求响应、错误返回,都会上报到数据统计中心。我们以报表的形式展现出来,可以很方便的看到每个模块,每个接口的可用性,成功率,数据规模。根据数据,我们还做了成功率告警,当接口成功率低于某个数值,比如99.99%时就会发送短信报警。还有历史数据对比报警,当发现今日数据与往期数据差距较大时,可能是系统出现了问题,会及时进行报警。
四、硬件系统报警
我们有一套工具,来监控每个服务器节点的CPU、硬盘、内存、网卡流量信息,以及其他系统关键参数的信息。并以图表方式提供展示,方便了解服务器运行情况。每次新版本,或新功能上线,都通过这些信息来感知访问量变化,以及机器的负载情况。
五、容灾工具
当一组Server中其中一台出现问题时,会及时发现,并踢掉。
给PHP扩展/C语言/网络编程初学者推荐的几本书
Linux/Unix系统
- 深入理解计算机系统
- UNIX环境高级编程
- 深入理解Linux内核
网络通信编程
- UNIX网络编程
- TCP/IP详解
- Linux多线程服务端编程
数据结构与算法
- 算法导论
- 《数据结构》(C语言版)
- C程序设计语言
PHP语言
- PHP5权威编程
原文地址:https://www.cnblogs.com/liang-peng-zhan/p/11395953.html