感谢各位捧场,但别打着PHP是最好的语言的口号。。。捂脸
今天介绍PHP浅一些,讲一些架构相关的事情,我在这里没少踩坑,分享讨论下
随着网站的发展,我们会发现有很多服务和操作其实都是抽象且独立的。
当我们做了分层后,这一部分服务渐渐的成为最底层服务,他们稳定且固定的为我们提供了方便且坚实的服务。
如业务的:订单服务,用户中心,权限管理,周边景观查找
如底层的:分词服务,队列服务,推送服务,计数服务,短信服务,邮件通知服务。
事当分层到一定程度的时候,我们会将服务分为前端和后端服务器群。并将各个项目隔离开期望有一个科学的方式能够管理各个项目之间的依赖关系。
事实上拆分后意味着我们开始向着平台化更进一步其中前端主承压展示界面并拼装组合来调用后端的业务和服务。后端主业务逻辑不承压、但却需要处理各种复杂的业务逻辑他是一组或多组独立的简洁的业务逻辑封装模块组成,他们会为前端提供了丰富的标准化的接口。
你会发现这个概念其实在渐渐的向SOA方向发展,SOA是个很好的集成概念,特别是当我们抽象的很好的时候。我们可以使用前端的逻辑快速的将过去的服务接口拼装出各种所需业务或者一个业务执行了对另外订阅的业务发送通报怎么处理看其他业务心情。
整理过程是需要架构和开发人员一心去组织标准化后端的接口的,不断抽象总结才能完成这个宏伟的目标,没有整理好的结果会很惨。
要知道项目越复杂隔离性越重要,当某一天你发现你改一行代码要影响很多部门的时候你会发现能够快速整理出依赖关系和后果会有多么幸福。
题外话:Restful不适合PHP特别是互联网,只是简单的增删改查并不能诠释API的所有功用,Restful适合封装数据接口,但是业务接口事实上是SOA里面最重要的组成部分之一。
可能有的读者会被这个SOA的计划惊到了,事实上这也是作者自己在公司一直推广散播的想法,实际上实施过程还是很艰苦和残酷的,很多公司也在做类似的实施期望达到这个目标,但是期间需要很多底层支撑来做后面我会慢慢说。
有很多场景并不适合使用SOA概念去做,如内容发布系统只要生成静态页面就好了,做成接口就算了。不断变化迭代的项目也不太适合这么做,因为往往依赖管理会很痛苦,所以对于那些服务需要公开给前端各个项目使用要好好规划,分析好现状明确哪些项目适合,哪些不适合。
当然这个实现方式并不是最优的,不过PHP使用的公司都开始向这个方向发展了,JAVA这么玩有好几年了。。。他们有自己的集成消息总线及中间件和标准,而PHPER们仍需靠自己丰衣足食至于标准,谁做的谁就是标准大家认同一致就ok。
在前后端分离后,用户的一个请求过来后前端往往会产生平均10~200个请求到后端来完成一个用户一次的页面请求,对此建议常规的数据请求接口和业务接口要有明确的划分,否则页面展示的会很慢且后端压的很惨,实际运行的效率也会极低因为这些接口很有可能是串行调用一个个阻塞执行的。
知识点:
并发:请求是指将一组多个API调用的名称和参数分发给多个服务器同时执行待所有api都执行成功并返回结果后将结果整理一起返回给请求方。当然这个事情给线程做也成,但是PHP线程。。。还是用Swoole通讯其他服务器吧。。。简单粗暴还省心。
同步请求异步请求:当你请求一个接口他执行完毕把结果返回给你后才继续执行吓一跳指令的样子就是同步的,异步只要把请求下发下去不管他或者有空去问问结果的这类都是异步的不阻塞你代码执行的。
说了这么多事项总结如下:
好处:前后分离后,我们可以将业务抽象接口整理的很好,我们都知道一个业务做出来后往往会有很多业务去展示,去使用,如果只是简单的include会导致底层改版的时候很难找到哪些代码和业务会受到影响。分离后我们可以根据接口的关键字进行全站grep很轻松找到所有相关的代码及模块。我们的代码依赖渐渐减少了,因为我们都是通过API相互调用的可以通过日志统计出各个API的被那些人调用,哪些频繁,哪些缓慢等,方便测试,方便管理。
坏处:前后分离后,通讯成了最大的压力,目前我们使用优秀的Swoole作为PHP的RPC通讯支撑。当然如果一个用户请求的前端过多的话仍旧会很慢,我们也提供了优化方案如对用户展示结果没有影响的处理扔到后端异步去做反正操作成功了就行、执行没有先后顺序的请求并发下发到后端应用服务器并发执行等都出结果一起返回结果等,但是这也导致了我们持久层会承受了很大压力,每个请求过来后都会并发下10~20个并发任务给后端去做前端跑4000个请求,后端就要并发8w个处理进程,还是瞬时并行的!后端数据服务连接数也增加20倍,目前正在考察连接池。。。这自己挖的大坑,含着泪也要填完。。。PHP的连接池真不多,swoole的worker启动的太多了目前我们一个服务器启动了4k个task,grep一下满满好几屏幕进程。。。
后话
相信大家看到了好处和坏处,事实上很多互联网公司目前已经都开始这么做了,将展示承压在前端,拼装在前端。复杂的逻辑在后端,但是目前来说PHP这方面差很多、至少总的来说支撑还是太少。
之前如果没有swoole我们一直靠include后端代码来工作,这很形式化开发直接new别的项目对象都可以,很伤心。
我们使用了Swoole哪些特性:TCP定长包头非定长body通讯协议,客户端长连接(不开前端服务器端口肯定不够用),task同步异步处理业务逻辑并定期重启(清理未回收资源),worker接收task结果并判断是否全执行完毕以此返回结果(并发处理任务),客户端超时,worker进程管理。
没有使用curl是因为,前端服务器的端口回收很慢,并发高的时候绝对不够用。三次握手多次会很慢,http每次请求后拿到结果都会马上关闭而开keepalive好难做完善普通开发很难做完善,客户端服务端通讯很难自定义协议都不是包级别的协议定制,弄不好漏到外网就残了,因为业务接口权限是很大的,全删都可以。
目前我们只是让前端直接通讯后端对应服务器上,其实中间我们可以加一个中间件,对消息进行转发和控制,swoole性能很变态已经达到了nginx的性能水准,有这么一层可以通过检测应用服务器的返回结果来判断后端服务器是否太忙或者死掉,可以通过php代码将故障机摘除或者降低投放任务量,并将失败的请求转发到其他活着的应用服务器,当然这都是后话。
很抱歉今天的分享只有这些,最近实在太累了