Laravel API接口和Lumen用于API服务器性能对比

项目的后台和API服务, 在15年之前用的都是ThinkPHP(3.2), 鉴于TP在大项目中的问题以及不太适合做API服务器, 所以16年我痛下决心,后台系统PHP框架改为Laravel框架,API服务器改用Lumen框架.经过2个月的并行过渡期后,在团队的努力下,系统平稳过渡到了新架构,但是因为后台和API是两个git项目,也带来了一些问题:

1. 同样的逻辑要分别在两个系统中写两遍,尤其是那些比较复杂的业务逻辑
2. 因为系统非常复杂,并且京东的业务逻辑变化比较快,也要同步修改两个系统的业务代码
3. Lumen虽然是Laravel的子系统,但是在使用的时候,有些地方和Laravel还是有区别的,尤其是Collection的一些操作会有区别
4. Collection作为基础的数据操作工具,不同版本的差异导致Laravel业务逻辑转化到Lumen时,需要进行“翻译”,并且要重新测试

当时选择这么操作,最主要的原因就是Laravel当时的版本只提供有web访问的route,并且鉴于Laravel本身比较庞大,每次访问都需要绑定很多耗费资源的中间件(EncryptCookies/AddQueuedCookiesToResponse/StartSession/VerifyCsrfToken),而API服务的认证是基于JWT的,根本不需要这些。项目中高峰时期,每秒高达3k多的TPS,Laravel是不好承担的.Lumen当时是Laravel的一个主要面向API服务器的子框架,没有Web框架的那一堆默认服务,速度很快,并且在用法和Laravel类似,所以选择.但是也带来了上马说的那些问题.

不过看到最新版本的Laravel的route做了调整,提供了单独的API操作接口,看了源码后,发现api相关的route和常见的web操作route是不一样的:

‘web’ => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],

‘api’ => [
‘throttle:60,1’,
‘bindings’,
],

看起来,如果抛弃Lumen,直接用Laravel作为api服务器,是否可行那? 需要先测试下性能再说.测试场景有3个(暂时不测试数据事务,数据库事务并不涉及框架性能):

  • 简单的的”Hello World”输出
  • 读取5条数据库记录并输出
  • POST一条数据并写入数据库;然后删除这条数据

场景1只是个toy,在生产中的意义不大;场景2/场景3是常见的实际环境.

在一台分配2GB内存的虚拟机上,web服务器选择apache,PHP版本为7.1,结果如下:

Lumen的得分最好,这个没有意外.但是在最常见的场景2中(涉及数据库读取),其实Lumen只比Laravel快了不到5%而已.而场景1这种不涉及数据库读写的操作,现实中应该是基本看不到的。

并且当前项目中,订单和用户表的数据都是千万行的级别,api每次请求的60%时间都耗费在数据库上,所以我相信如果用生产数据区别测试的话,这个差距会更小。

Leave a Reply

Your email address will not be published. Required fields are marked *