惠新宸,百度php高级顾问,年二十有八,好追根究底,有不良嗜好, 幸性本善。乙酉年识互联网,丁亥年入雅虎,翌年入百度。虽性好安稳,然经变无数,唯常叹人生,菠菜汤尔。 大家好,今天我主要介绍是php在百度一个发展历程,最早的时候百度成立于2000年,2000
惠新宸,百度php高级顾问,年二十有八,好追根究底,有不良嗜好, 幸性本善。乙酉年识互联网,丁亥年入雅虎,翌年入百度。虽性好安稳,然经变无数,唯常叹人生,菠菜汤尔。
大家好,今天我主要介绍是php在百度一个发展历程,最早的时候百度成立于2000年,2000年的时候,百度刚刚成立,刚刚在北大资源宾馆建立百度,直到2001年的竞价排名,我不评价这个产品怎么样,竞价排名当时是第一个采用php,在百度的php系统。从2001年到今年已经10年时间了,这10年时间百度php经历一些什么变化呢?
我们现在看到是百度,那天我自己脑子里想了一遍,当然不是全部,大家能够知道的一些用户产品,无线产品,商业产品。包括贴吧这个比较大了,还有最新的旅游。对于贴吧来说,前端可能是cui,或者业务逻辑,一直到后来已经迁到php。我列出来这些产品,都是使用了php,还有没列出来也是使用了php的,很多。所以,如果说让我去介绍每个产品是怎么用php的,我觉得这个不太现实,我一共只有30分钟。
这30分钟我主要想跟大家分享的我们发现一些问题和怎么去解决,这些问题是大家都会遇到的。我们最早的时候,就像我刚才提到的我们一些,因为处于最高性能要求,以及对于php的不了解,以及对于外部我们可能觉得php很慢,所以我们以前的时候,这些大的访问量产品都是用c来做的。他可能在模板上用cu-i来做展现,这样的方式大家都知道开发,调试,部署都很复杂,成本也比较高,门槛也比较高,招人也比较难招。
后来的时候我们就考虑是不是应该去换一个,当时应该考虑要是java,或者是php。我们在c的时候,c-ui和后面进程去通讯主要是nsheader和mcpack,类似于上面一些打包传输的方式。我们为什么选了php?第一高性能,快速开发要求。我这说高性能,可能下面有一些工程师就笑了,你php讲什么高性能。我说的这些高性能是在相对情况下高性能,当我们wap应用程序不仅仅局限php,瓶颈更大在于数据和文件,以及这些io方面,在这些方面来说,php性能已经足够了。
那么开放开发就不用说了,php不需要编译,不依赖于环境,我所改即所建,改了就能看到,这个调试开发过程非常快,这是一个优点。稳定性,路棒性,安全性,怎么讲呢?有一个玩笑,我跟我们百度几个同学去聊天,他们就抱怨,php工程师真的是这个质量层次不齐,再烂的php工程师写出的代也能跑,跑完了也正常。这是从一个方面,可能他的本意是说我们招聘有一部分人水平本来不一样。但是从另外一个方面,也体现出来php一个特点是什么呢?稳定,鲁棒性很强。再烂,再不懂php的新手去写,你也不会把它写垮掉。
说到这里我有一个小问题,大家知道怎么pk掉一个php进程吗,最简单的方式。其实这个问题还挺难的,我跟我的朋友讲,你们说怎么pk掉一个php进程,我需要调试,其实很简单你写一个无线递归下去就会打掉。php有很多安全措施,比如我们颇为被人争议gph选项,打开之后会对客户进行过滤。还有php对输入做各种各样的转换验证,这方面php对安全性考虑也是多的,当然还有是不建议打开的,那样的话更安全。
灵活和丰富的语法就不用多说了,一个php怎么写,不需要特定格式,随意性也非常强,功能当然也很多了。他应用面这么广,自然是一个例证。良好的运行在linux,可扩展c/c++。php经典搭配是没有问题的,我们都知道,我们当时不选择java一个原因,还有一方面考虑,java那套开发环境比较复杂,重启一下需要30-40秒。更重要一点可扩展,因为我接下来讲的问题就是从可扩展来的,我们的优化方案。
当时我们就想因为php应用很多,一个开源东西,有很多方便第三方房展,我们经常用的pdo,都是扩展的方式,并且他的扩展也非常容易开发,网上有一堆教程,只要你照着教程做一遍。因为php对扩展做的很好,一行命令把自己代码写进去,就是一个很完整的扩家,一个扩展就能用。易部署,易调试,更不用说了php直接拷贝,拷贝到哪都能够运行,不需要依赖系统的共享库,不会因为库的挂接处而出现问题,调试也很容易调试,最经典的方式不停调试,我们还有一个php调试技术手册,我相信在座很多人都看过,那里面介绍一段做单布跟踪调试,这样的调试今天在这里讲,效率往往还不如直接调试快,当时只是一种尝试,或者说一种探索去跟大家分享调试的技术。
展现逻辑分离这个也很重要,对于php来说,本身生来就是做wap开发的,可以把php代码嵌入到wap里面去,这个非常适合于做外部开发的。入门快,刚才也提到了,我们现在招聘新来这些大学生其实他以前可能是做java,是做c,一周时间就可以开始写。所以,入门非常快,社区活跃,这里我要提一下,在我们百度就我所知有400多名做php开发,我们这400多名工程师都在一个群里,大家聊天,问一个问题立马就有人来回答你,这只是在百度社区,更不用说开源社区活跃程度了。
从这些方面我们就觉得php替换现在c的方式是可行的,于是我们就有了经典的方案,就像我这大家看到的,用户浏览器经过的分发,分发以后后台就是这样一个用php脚本,下面可能有一些扩展,再下面就是pip,后面数据,因为这块对于开发来讲,我这块主要从贴吧角度来讲,它是服务其逻辑数据还是用一些比较快的,还是以前那套老东西,只不过把ui这一块做到php,当然其他系统不是这样。
这个时候后台像web services等等提供这种数据,给php脚本,这是一个现在这样一个,应该说比较经典php开发模式,或者在我们百度来说,主要还是以这种方式,php只是做展现。这样的情况下有一个问题,什么问题?比方说你是一个php工程师,你的上级交给你一个任务,你去写一个什么样的系统,你把它部署下去。你刚来很有信心,没问题我去做,你用了一周时间写出来,写完之后你用一天时间把环境搭起来,把代码放上去,四台服务器需要共享,把这些东西都用完你可能用一周半时间,没有问题你这个做的很好,你这个东西也很正常,架构也设计很好。
现在这样的问题还有100个你怎么办?难道你再去部署100次,这不行吧。另外你做的东西放上去之后,你可能出去玩了,下班回家了,那怎么监控呢?谁去监控呢?这也是现在单个产品线都要遇到的问题。还有一个问题资源流量陡增,比方说你这个产品挺好的,日均pv10万,突然一天涨到100万,大家都知道去年的时候69圣战,贴吧经过一次所谓69圣战,流量爆增了多少不知道,但把服务器给压死了。
那么遇到流量陡增怎么办,不能说现在这个产品10万,前台上了100台前台机,我告诉老大,我这个流量某一天陡增10谁信啊,成本也受不了这也是一个问题。规范和标准,这是最头疼的,我到百度以后参与了很多规范制定,也会提很多意见,我每次做这些事情的时候我都是信心慢慢的,我觉得做完之后大家看了之后会去用,会去学,可能咱们普遍共同语言就会多一点。但是发现你标准规范制定出来没人理,这就是规范一个怎么去执行,当然这个问题很难了,另外一个问题,这也是我们现在遇到的问题,我们有编码规范,有部署规范,有目录规范,但是没有办法推卸,没有一个东西去强制让他们这么去做。
还有防攻击容灾,你有4台前端机,仅仅4台,某个不知名相关组织弄了100多台僵尸肉鸡去压你,你有什么办法,没有办法,你只能被攻击。还有一个问题,我们现在产品线这么多,每个产品线使用的框架各不相同,开发模式各不相同,这就造成他们都是异构的,异构会有什么问题,op会很郁闷。op遇到每个产品线,有的配置文件在这放,有的配置文件在那放,就像我们uc就得为各种各样框架命名规则开发一个不同类库。快速开发我就要求我的基础设施足够丰富,我基础设施足够丰富的情况下才能做到快速开发,我框架功能要很强,这样开发才会快。
但是你框架功能很强就带来一个问题,你代码多,就慢,php就这样,怎么办,这也是一个根本矛盾。这些问题有没有解决方案呢?当然是有的,要不然我也不会拿出来讲了。在百度现在对于前面的问题,比方说运维,部署和容灾,一些流量陡增这些问题怎么办呢?看最右边一个bae,就是百度应用开发平台,在这个上面会做一些类似于gae,sae这样的东西,目前来说只是百度内部用。这样的话当我用了这个东西之后,我们开发者不再要求需要关心资源,也不需要关心被攻击,或者流量陡增,这个我待会还会讲。
我们在php这层加了一个小螃蟹,它的名字叫做ap,我待会会介绍ap是什么样东西。然后在脚本和php之间又加了一层odp,又是什么东西?这三个就是解决我刚才提到哪些问题。bae,我刚才提到是来解决我们刚才说的那些问题,比方说我资源怎么管理,流量陡增没法应付了怎么办。bae把所有资源统一调度起来,提供一个很大平台给你,你其中只用一部分,他会把冗余资源调配节给你,满足你陡增的资源需求。
集群化还有一个问题是防攻击,我现在是三大服务器有人来压我了,他拿100台肉鸡来压我,没有关系,我们百度后面还有1千台服务器呢,上,你再来压。如果他真的强大到拿1万台,1千万台来压你,这样成本在国内很难做到。所以,这样情况下能解决我们刚才所说小规模攻击,因为你攻击我就可以迁移,我可以自动迁移。
流量陡增也是一样道理,太多。接下来就是今天我要介绍的重点,就是怎么解决沉重的框架问题。我们现在用的很多框架,各个公司开发都会有用框架,也有自己开发框架。在做开发框架的时候大家都会遇到一个问题,这个框架要不要做的这么重,为什么要做的重呢?因为你工作要提供的多,要提供路由,提供搜索引擎,还有orm等等这样东西。我提供这么多东西,必须有这么多的代码,我有那么多代码,就那么多逻辑,就有一个结果慢了下来,怎么取舍呢?
对于百度来说,我们现在解决方案出来之前流行两种开发模式,一种比较成熟e框架,或者zf框架,还有性能要求比较高的,会使用我们百度自己开发的b-gou框架,只做路由,是一个轻量级框架,是一个非常非常轻量框架,来满足性能问题。有没有一个解决方案做他们俩的取舍呢,下面有一个扩展化。
什么是扩展化?在座都知道php扩展,如果关心这个肯定会知道,可能也有不知道同学,我就提一下什么是php的扩展。php本身是用c语言写的,你所编写的php脚本到最后都是通过c代码执行的,这时候php还提供一种方式可以直接写用c来写一个共享库,动态的共享库,把它加载到php中,通过这种方式让你业务模式以c模式存在在php当中,这个模式就叫扩展,php提供一个很强大模块来支持你自己php扩展。
我刚才提到了其实问题也就很明显了,我们需要用一个php扩展去做一个很重的php框架。还有一个要提的,什么样的情况下我们应该使用扩展,还有一个问题扩展为什么会快,这两个问题,有些看似很简单问题,其实要想起来还是挺难的。第一什么样的情况下我们可以使用扩展,我们有两种方式是需要扩展,第一种方式我们有一些,比方说已经成熟的c库,我们php许多办法直接用,我必须用一个扩展把它桥接过来,这种情况下需要使用php扩展。
还有一种情况我对cpu密集型的东西,比方说我有一个算法,或者我有一个很复杂,很复杂的加密算法。这个算法如果我用php写的话非常慢,对于这种cpu密集型的东西,我是可以把它扩展化用c来实现,这样的话能提高性能,就这两种方式要去使用php扩展。php扩展为什么会快呢?这里我要提一下facebook极致,去年11月份极致把一个应用性能提高到4倍,他是怎么做到的呢?我们大家听各种各样报告,是把php编译成c++,他这个编译其实不是说我根据你的逻辑找到对应的c代码进行编辑,他做的更多是把这个符号解析给拿掉了。我们在php里面,我们的变量,我们的函数都是存储在一个一个关联数字结构里面,他这个结构设计足够精妙,确实也花很大心思去设计,但是当我们使用一个变量,或者一个方式的时候,都需要从这个表里面去查的,这个过程是非常耗时的。
所以,php性能绝大部分低也是这个关键。php就把能在编译期间确定的符号就把它直接替换掉,相当于我们c程序编译的时候把符号直接换成二进制地址的一样,就是一个符号回天。这只是一方面,还有一方面为什么扩展会比php快?这个我们抛开一切问题,一切io,抛开一切内存存储我们来算一个简单算术题,一个1g赫兹cpu能编织多少,这也是php比较慢一个原因。
比方说一个简单icou(音译),如果你用c代码来写,直接写icou2也可以,如果phpicou2先编译,第二部分先分析这个php,找到对应php调用,这个时候有三种情况,这时候拿到一个指令进行执行,当执行这次指令的时候可能会发生多次调用。我一个简单的icou可能在php最后执行的时候,可能有5次以上函数调用,这个就慢了,扩展化就可以避免这些问题。
我们ap就是一个全功能mvc框架,是用扩展来实现,也就是利用c语言去写的一个php扩展。这个地方又有一个问题,我们扩展一般也两种理由去写扩展,扩展还分两类,第一类就是说一个简单我的业务逻辑都是用c代码去做的,我只是简单从php脚本拿到数据,把处理结果反给php,我基本上不怎么使用ap。第二个扩展就是负载php扩展,就是ap,用了大量api,提供相应存量,或者是一些资源给php脚本让用户去进行使用。