性能提升50%,支持连接池负载均衡、事务嵌套
关于此次更新
有一些热心开发者经常问我imi的性能怎么样,稳定性怎么样。由于imi也才刚刚起步,之前并没有对这方面进行测试和优化。
最近一段时间,经过努力,imi 的启动性能、运行性能以及稳定性,全部都有巨大的提升。
针对返回json
的api
环境(无数据库操作)下测试(worker_num=2,并发1000),新版比旧版并发性能提高了50%以上。
下面详细讲解一下,我们所做的工作。
启动性能
在框架初始化完成事件IMI.INITED
中,运行一个imi/buildRuntime
工具进程。
这个工具里面,扫描项目中所有注解,将它们保存到缓存文件中。(对了,现在的imi拥有一个专门用于存放运行时文件的目录,原本零零散散的文件现在都统一了,默认在临时目录,可以通过配置指定。)
然后在Worker
进程中,加载缓存文件,避免重复扫描注解。降低对硬盘读取次数,提高了海量性能!
同样的,在热更新检测到文件更改后,在重启之前,再一次运行imi/buildRuntime
工具,然后再执行重启操作。
这样,在启动项目以及热重启时,节省了毫无价值的多次硬盘读取。
运行性能
首先,imi
的对象代理,使用的是匿名类继承原本的类的方式。在之前的版本中,生成匿名类的过程中,针对所有方法都做了代理。调用任意方法都需要进入imi
的代理方法中进行额外的处理计算。
在最新版的 imi 中,只针对注入了的方法做代理,所以减少了许多不必要的方法调用以及判断处理等,所以运行性能提升巨大。
稳定性
这个就要说到在 imi 中出现过多次的奇怪问题了,在最近终于弄懂,能够确定是 php
本身的 bug
。
我已经把这个bug
反馈给php
了:https://bugs.php.net/bug.php?id=77050
然而其实这个bug
早在2016
年就被人发现,至今没有修复,先吐槽一下……
这个 bug
是使用 eval
实例化匿名类出现的问题,之前说了,imi 的对象代理使用的是匿名类继承原本的类的方式。具体问题这里不再阐述,具体进 bug
反馈页面里看测试代码吧。
后来 imi 使用的是写入文件,然后include的方式来实例化。然而,在一键协程化的支持后,又出现了新的问题。
很难用语言进行描述,总之目前已经完美解决了这个问题。具体解决方式可以查阅BeanFactory.php
的git日志。
更新日志
新增
-
实现连接池负载均衡,模式:轮流、随机
-
新增 AnnotationManager 来进行注解统一管理
-
新增支持 MySQL 事务嵌套
-
新增支持注入带有注解的方法
-
新增日志trace精简配置项(实现性功能)
-
新增项目初始化完毕提示(App Inited)
优化
-
优化对象代理类性能
-
优化事件处理性能
-
将运行时生成的文件统一归类到runtime目录中
-
实现注解缓存机制,减少Worker进程中不必要的文件I/O
-
当启用Session中间件时,只有写入了数据,才会发送SessionID响应头
-
当启用Session中间件时,如果不写入数据,将不再保存(避免正常访问及压测时,写入了过多无意义的数据)
-
调整Worker::getWorkerID()实现方式
-
优化 Imi::getNamespacePath() 方法尽可能返回绝对路径
-
优化池子异常信息
修复
-
修复删除bean类缓存时,未删除文件夹问题
-
解决实例化Bean类相关、一键协程化开启后的问题
-
修复
BeanFactory::newInstance()
可能会引起的问题 -
优化模型提取属性实现方式,解决特殊情况下影响关联的问题
-
修复 AbstractMessage 和 ServerRequest 问题
-
修复模型 Serializable 注解在特定情况下部分失效的问题
-
修复文件日志驱动可能报warning的问题
-
修复特殊情况下注解扫描加载的问题
-
修正注释问题