IMI 是基于 Swoole 开发的协程 PHP 开发框架,拥有常驻内存、协程异步非阻塞IO等优点
基于 Swoole 开发的协程 PHP 开发框架,常驻内存、协程异步,致力于丰富框架文档,上手容易,让开发者跟使用传统 MVC 框架一样顺手2019年度最受欢迎中国开源软件评选,投一票 imi 吧,谢谢!
https://www.oschina.net/project/top_cn_2019#imi
新增
-
新增支持通过beans注入配置,随服务启动进程
-
新增 @PoolClean 注解,可以在 Tool、Process 的入口方法上使用,用于剔除或保留指定连接池
-
新增支持连接池心跳机制,支持设置当获取资源时是否检测连接状态
优化
-
优化 Statement 的写入和清理机制
-
优化视图处理性能
-
优化动作执行参数处理效率
-
热更新不占用连接池
-
优化模型转数组性能
-
process/start 工具,现在的返回码是进程返回的
-
优化:关闭连接池时停止心跳,并且清空资源池
-
连接池的自动GC和心跳,在非 worker 进程中,只要有协程运行就能启用
Assets
2
新增
- 启动提示新增网卡ip显示,优化启动提示显示 #29
优化
-
重构 RequestContext,使用 Swoole 内置的协程上下文管理方法实现。同时废除 create、destroy、exists 方法
-
优化测试用例服务器在多核情况下的启动效率
-
优化一些代码
修复
-
修复模型增删改查字段名为关键字的问题
-
修复联合主键的模型使用 find() 方法的问题
-
修复模型 update() 方法可能存在的问题
-
修复控制器单例模式问题
Assets
2
紧急修复单例控制器问题
Assets
2
又周五了,最近学习 imi 的用户越来越多,imi 也在变得越来越好。预祝大家周末快乐~
以下是此次更新日志:
新增
-
新增模型性能测试
-
新增 Redis 模型测试用例
-
模型生成工具新增
-entity
参数,是否开启使用驼峰命名,默认开启 (#27)
优化
-
完善 Redis 模型方法返回值
-
当连接池不使用负载均衡(只有1个连接配置)时,直接返回资源
-
优化模型
-
优化测试用例
-
将树形模型的 getAssocList() 封装为 ArrayUtil::toTreeAssoc() 通用方法
修复
-
修复 Session Cookie lifetime 设为 0 无效问题
-
修复使用 Redis 模型时,调用 ModelManager::getFields() 的问题
-
修复 ArrayUtil::recursiveMerge(),合并以数字为键的数组时,丢失键的问题
Assets
2
本周主要推出了一个进程池和高性能协程服务器,相比传统模式,即便是跟 BASE 模式相比,也有非常大的性能提升。
新增
-
新增支持高性能 Swoole 协程服务器,性能更加强悍,需要 Swoole 4.4+
-
新增一个可以替代 Swoole\Process\Pool 的更强大的进程池。支持信号监听、重启进程(可指定)、Pool Master 与 Worker 消息通讯等。
-
支持在项目中配置 imi 启用哪些功能模块
优化
- 优化 http 路由性能,当路由数量多时效果明显
修复
- 修复部分情况下的热更新进程残留问题
Assets
2
本周主要优化了框架底层、请求上下文处理性能,另外做了一些功能上的小增强。
测试用例做到全覆盖:PHP 7.1、7.2、7.3、7.4、nightly、Swoole 4.3、4.4、master
新增
-
验证注解新增支持:非必验证参数,只有当值存在才验证
-
新增 File::putContents() 方法,写入内容到文件,如果目录不存在自动创建多级目录
-
File::createFile() 新增 $content 参数
-
新增 ConnectContext::muiltiSet() 方法批量设置上下文数据
-
新增 RequestContext::use() 方法
优化
-
优化一波框架底层性能
-
优化一些请求上下文处理性能
-
优化 StatementManager
-
支持 @app.db.statement.cache 配置是否开启 statement 缓存,默认开启
-
ConnectContext::create() 支持传入初始化参数
修复
- 修复在自定义进程中操作 ConnectContext、ConnectGroup 导致进程卡死问题
Assets
2
本周主要新增了门面(Facade),以及性能有优化提升。
新增
-
新增支持 Facade 门面
-
新增 generate/facade 工具
-
支持定义中间件分组
-
IHttpNotFoundHandler->handler() 方法增加 $requesthandler 参数
-
RequestContext create 方法支持传入初始数据,新增 muiltiSet 方法用于批量写入值
-
新增注解类转注释文本的方法
-
支持通过配置,指定服务器事件是否监听,以及自定义事件监听
优化
-
提升框架底层使用频率较高的事件性能
-
提升触发未监听事件的性能
-
优化 http-message 相关实现代码
-
未初始化完成时挂起请求,改为拒绝请求
-
废除 BufferFull、BufferEmpty 事件
-
更新 doctrine-annotations 版本,合并官方 1.7 版本
修复
-
修复数据库操作 errorInfo() 有时获取信息为空的问题
-
修复非对象方法的路由设置问题
-
避免 Swoole 4.4.x 下的一个奇怪 bug
Assets
2
新增
-
新增
Inherit
注解,用于在子类中继承父级注解,可指定继承哪些注解,支持:类、方法、属性、常量 -
新增
OptionsMiddleware
,解决了使用application/json
请求时,浏览器会先发送一个OPTIONS
请求问题 -
新增
IMI.HOTUPDATE.BEGIN_BUILD
事件,可以影响热更新 build 操作 -
新增
Imi\Util\ClassObject::inNamespace()
方法用于判断某类是否在指定命名空间下 -
新增一个枚举文件方法,支持自定义是否进入目录继续遍历
优化
-
中间件默认加上
Bean
名称,可以在使用时,直接使用 Bean 名称 -
http 动作方法参数值支持自动传入
parsedBody()
中的值 -
提升热更新遍历文件性能
-
热更新检测时间间隔支持毫秒级,单位依然是秒,传小数即可
-
优化生成出的模型的属性注释
修复
-
修复设置 Bean 名称后,在 beans 配置中使用类名注入无效问题
-
修复
SessionCookie
的httponly
配置无效问题 -
修复增量更新问题
Assets
2
本周主要针对模型做了增强。
这周有一个基于 imi 的开源项目正在开始立项研发,如有兴趣参与可以联系宇润!
新增
- 新增分页查询方法 Db::query()->paginate()
查询总记录数、总页数:
$page = 1;
$count = 10;
$data = Db::query()->from('xxxtable')->paginate($page, $count);
$result->getList(); // 列表数据
$result->getTotal(); // 总记录数
$result->getLimit(); // $count === 10
$result->getPageCount(); // 总页数
var_dump(json_encode($result)); // 支持序列化
// 数据格式如下:
[
'list' => [],
'total' => 100,
'limit' => 10,
'page_count' => 10,
]
不查询总记录数、总页数:
$page = 1;
$count = 10;
$data = Db::query()->from('xxxtable')->paginate($page, $count, [
'total' => false,
]);
var_dump(json_encode($result)); // 支持序列化
// 数据格式如下:
[
'list' => [],
'limit' => 10,
]
- 新增树形模型支持(getChildIds、getChildrenIds、getChildrenList、getParent、getParents、getAssocList)
文档:https://doc.imiphp.com/components/orm/TreeModel.html
- 新增支持 imi -h 命令
优化
-
模型 getter 方法引用返回现在变得有意义了
-
模型字段驼峰命名缓存优化,性能提升
修复
- 修复 Swoole 版本兼容问题
Assets
2
本周的更新,第一阶段的单元测试编写工作完成。
imi 的单侧目前有 235 个测试用例,1035 个断言(不含独立组件)。
imi 的 travis 自动化测试涵盖了 PHP 7.1-7.3、Swoole 4.3.x、4.4.x、master。宇润和 Swoole 开发组大佬们保持着密切联系,发现问题立即反馈。所以当 Swoole 发布新版时,imi 能够很轻松地以最快速度做到兼容。
目前 imi 保持着每周一个小版本的速度进行更新迭代,各种实用组件正在开发中。
imi 组件库:https://github.com/imiphp
欢迎各路新人和大佬的加入,只要有心,就可以参与进来!
本周具体更新日志如下:
增强
-
Smarty 模版引擎组件:https://github.com/imiphp/imi-smarty
-
Swoole Tracker 服务监控组件:https://github.com/imiphp/imi-swoole-tracker
-
ArrayData、ArrayList、FilterableList 允许被 count()
-
新增 Imi\Util* 等多个类的测试用例
-
新增 File::deleteDir() 方法
-
新增 Imi\Util\Digital 工具类
修复
-
修复 Fixed Imi\Db\Query::WhereEx() 问题(@loyating #25)
-
修复 ArrayUtil::remove() 方法无法移除对象问题,新增 ArrayUtil::removeKeepKey() 方法
-
修复测试用例在低配电脑上出现的奇怪问题(Swoole v4.4.4 更新后出现)
-
修复 File::path() 拼接 xxx:// 路径问题
-
修复 Imi\Util\Imi::checkCompareValue() 判断不等于结果不正确问题
-
修复随机生成小数是科学计数格式的问题
优化
-
重构 Event,移除 KVStorage 依赖,使用类对象代替 kv 数组存储底层数据
-
优化 Http Middleware 机制
-
优化 WebSocket Middleware 机制
-
优化 TCP Middleware 机制
-
优化 UDP Middleware 机制
-
优化测试用例
-
Imi\Util\ClassObject 类注释完善
-
支持将 task_worker_num 设为 0
-
优化 AppInitReceiver
-
移除 File::readFile()、File::writeFile() 方法(Hook 协程化后用 file_get_contents()、file_put_contents() 即可)
-
移除 KVStorage
-
文件日志驱动写入时上锁
-
Query 动态参数编号全部从 1 开始
Assets
2
更新日志
增强
-
开源协议从 Apache V2 切换为 木兰宽松许可证(Mulan PSL v1) ,更加自由!
-
增加自定义 SessionId 获取方式的测试用例(感谢 @loyating)
-
View 注解的 template 为空时默认使用当前方法名
-
新增 Imi\Util\File::isEmptyDir() 方法,判断目录是否为空
-
新增 InEnum 验证注解,用于验证值是否存在于枚举列表中
-
Request 对象增加 request()、hasRequest() 方法,request 数据包含 get/post/cookie
-
新增验证类测试用例
-
新增自动验证注解测试用例
修复
-
修复 ConnectContextRedis 导致进程阻塞的问题
-
修复 WebSocket 热重启后无法握手问题
-
修复使用 vendor/bin/imi 无法启动项目问题
优化
-
将 IMI 文字描述大写全部改为小写 imi
-
增加 HttpServer 测试用例的请求日志记录
-
WS 请求测试后将 YurunHttp Handler 切换为 Curl
-
重构 ViewHandler
-
增加测试脚本配置和运行说明,测试用例中的 MySQL、Redis 的配置,都可以通过系统环境变量配置
Assets
2
更新日志
增强
-
模型 Column 注解支持 updateTime 参数,设为 true 时,当save/update时,会自动写入当前时间
支持字段类型: date/time/datetime/timestamp/year/int/bigint
当字段为 int 类型,写入秒级时间戳
当字段为 bigint 类型,写入毫秒级时间戳 -
支持使用 vendor/bin/imi 启动项目
会自动尝试加载 vendor/autoload.php,顺序如下:
工作目录
框架目录
没有则抛出错误 -
ConnectContext、Group、Session 的 Redis 驱动,默认 key 自动带上项目命名空间
-
新增 Lock->getLockCoId() 用法
-
优化热更新错误提示
-
完善 TCP 测试用例
-
优化 .travis 测试用例错误后的日志输出
-
ConnectContext 获得锁失败抛出异常
-
优化:服务器会使用,服务器配置的 beanScan 中的命名空间列表包含的控制器
修复
-
修复 Swoole 4.4.3 bug 导致的热更新报错问题
-
修复 Redis Lock 问题
-
修复 WebSocket 握手不向 RequestContext 写入 routeResult 问题
-
修复保存 WebSocket httpRouteResult 报错问题
Assets
2
更新日志
本周主要针对注解、路由底层数据关系存储做了重构,把原本的数组kv存储,改为对象存储。内存占用更少,调用速度更快,维护更加便捷。
截止发布前,imi 兼容了最新的 Swoole 4.4.3 版本。
测试用例持续完善中,目前有 134 个测试,480 个断言。
官网 (https://www.imiphp.com/) 船新改版,感谢 @封尘 大佬~
增强
-
增加 WebSocket Server 测试用例
-
增加 TCP Server 测试用例
-
增加 UDP Server 测试用例
-
新增 Model 测试用例
-
增加 Log 测试用例
-
支持直接从 bin/imi 启动
-
新增 imiGetEnv() 函数,是 getenv() 函数的封装,支持默认值
-
generate/model 增加 basePath 参数
修复
-
修复 Model 的 save() 方法执行后,无法通过属性获取自增主键值问题
-
修复连接分组 status 未生效问题
优化
-
AnnotationManager 重构,使用对象替换键值数组
-
Route 重构,使用对象替换键值数组
Assets
2
更新日志
Lock
-
新增 Lock 快捷类
-
新增 Atomic 进程锁
-
新增 Lock 测试用例
-
新增 Lock Annotation 测试用例
-
Lock 接口强类型定义
-
支持配置定义 Lock,根据 lockId 操作
-
修复 tryLock() 执行回调时,不返回 boolean 问题
MemoryTable
-
MemoryTable 支持使用类来定义结构
-
支持在配置中设定 MemoryTable
-
新增 MemoryTable 测试用例
-
修复 MemoryTableManager 问题
ConnectContext
-
重构,现在ConnectContext不再本地存储数据,不再怕多个worker进程同时去读写
-
新增 ConnectContext 锁支持,现在读写数据不会冲突,必须设置锁,升级请注意!
-
新增内存表 ConnectContext Handler 支持
Cache
-
新增 RedisHash Handler defaultHashKey
-
新增缓存测试用例
-
新增缓存注解测试用例
-
修复 Cache Redis/RedisHash Handler 返回值问题
-
修复 Cache File delete() 不删除 .ex 文件问题
-
修复 Cache File clear() 无返回值问题
-
修复 Cache File getMultiple() 方法返回键为数字问题
WebSocket
-
新增 WebSocket open 事件
-
WebSocket 的连接上下文创建移动到中间件执行之前,在中间件中就可以操作连接上下文
其它
-
使用 defer 实现自动释放 RequestContext
-
新增支持 redis 的 options 配置项(支持:\Redis::OPT_XXX)
-
支持设定 ServerGroup 的 status,是否启用分组
-
调整:当PoolResource->checkState()为false时,先close()再open()
-
initWorker() 中清除池和缓存对象
-
让测试用例在协程下运行
-
修复 GroupRedis、ConnectContextRedis 不等待执行完毕的就 App Inited 的问题
-
Db Statement 释放移入 Db 下
-
HttpDispatcher->dispatch() 增加返回值 Response
-
修复 AtomicManager::wakeup() 返回值问题
Assets
2
增强
-
海量提升热更新性能,注解、代码的热更新从秒级变为 毫秒级
-
小幅提升冷启动性能
-
增加文件上传测试用例
修复
-
修复 Db Statement 缓存释放问题
-
修复 Inotify 热更新问题
Assets
2
- 修复 where 条件解析 SQL 问题
- 新增 whereEx 测试用例
Assets
2
Yurunsoft released this
更新内容
新增
-
增加单元测试(PHP7.1-7.4、nightly 全部通过),从此不再担心修复一个 bug,产生更多 bug。这是一个长期任务,需要不断充实测试用例。参与开源项目经历是个很好的面试谈判筹码,欢迎大家来贡献测试代码,你好我好大家好!
-
新增 Imi\Util\Coroutine::create(),与 imigo() 行为一致
-
新增 Imi\Util\Http\MessageUtil 类
-
新增框架优先级定义,常量类:Imi\Util\ImiPriority
修复
-
修复热重启问题:worker exit timeout, forced to terminate
-
修复 PDO Statement 无法命中缓存问题
-
修复日志重复写入问题
-
修复 MySQL->query() 方法不记录最后执行 SQL 语句问题
-
修复当设置task_enable_coroutine但不设置enable_coroutine时,task事件监听参数错误问题
-
修复类型声明
-
修复 RedisManager::getNewInstance() 无法被 RedisManager::release() 释放问题
-
修正 Redis 相关类型注释
-
修复 withAddedHeader() 问题
-
修复使用 TAutoInject 时,有父类导致无法正常注入的问题
-
修复Callback、CallableValue注解无法注入属性问题
-
修复配置值注入、常量注入注解,无法注入到属性问题
优化
-
优化 BeanProxy::getConfigInjects()
-
优化 Imi\Db\Query\Result
-
非 worker 进程投递的 task,不再自动 finish
-
同步池子 getResource() 不再有可能返回 null,一律抛出异常
-
ITaskHandler->handle() 支持返回值自动 finish
-
规范内部监听 IMI.INITED 事件的优先级
-
优化 BeanProxy,现在不用等到回收周期,立即会被释放
-
注入属性值的注解类改为 Imi\Aop\Annotation\BaseInjectValue
-
进程、进程池进程,强制开启协程化
测试用例计划及进度
- Aop
- Config
- Cache
- Db
- Enum
- Event
- Inject
- Redis
- HttpServer
- HttpValidate
- WebSocketServer
- TCPServer
- UDPServer
- Task
- Lock
- Log
- Model
- Process
- Utils
Assets
2
imi 介绍
imi 是基于 PHP 协程应用开发框架,它支持 HttpApi、WebSocket、TCP、UDP 应用开发。
由 Swoole 提供强力驱动,Swoole 拥有常驻内存、协程非阻塞 IO 等特性。
框架遵守 PSR 标准规范,提供 AOP、注解、连接池、请求上下文管理、ORM模型等常用组件。
imi 的模型支持关联关系的定义,增删改查一把梭!
作者介绍
宇润,江苏无锡人,94年出生。初中自己接触易语言,从此踏入代码的世界。
2013 年开发并发布 YurunPHP 框架(现已停止维护)。
2017 年开始正式玩 git 和发布开源项目,开源的东西都是自己能用到才会去做,不会为了造轮子而造,一切为了实用。
2018 年接触 Swoole,打开了新世界的大门,原来 PHP 还能这么玩!
2018年4月16日,我为 imi 写下了第一个字节的代码。
2018年6月21日,发布了第一个公开版本 v0.0.1。
经过一年实战,2019年6月21日,一周年之际正式发布 v1.0.0 版本。
宇润部分开源项目:imi、YurunHttp、YurunOAuthLogin、PaySDK、ChineseUtil
核心组件
- Server (Http/Websocket/Tcp/Udp)
- 容器 (PSR-11)
- Aop 注入
- Http 中间件 (PSR-15)
- MySQL 连接池 (协程&同步,主从,负载均衡)
- Redis 连接池 (协程&同步,负载均衡)
- Db 连贯操作
- 关系型数据库 模型
- 跨进程共享内存表 模型
- Redis 模型
- 日志 (PSR-3 / File + Console)
- 缓存 (PSR-16 / File + Redis)
- 验证器 (Valitation)
- Task 异步任务
- 进程/进程池
- 命令行开发辅助工具
- 业务代码热更新
扩展组件
开始使用
基于 imi 的项目
SixMQ (宇润)
慢点博客 (慢点)
其它项目因工作原因不便透露,已知我所在公司、私单项目正在运行 imi。
起源 & 设计 & 未来
起源
上面提到,我 2018 年接触 Swoole,打开了新世界的大门,原来 PHP 还能这么玩!
我认为的最好的学习方法,那就是去用,没有实际的功能去实现,学了也会容易忘,不算真正学会。之前我也有 YurunPHP 框架的开发经验,于是决定造个框架吧。
设计
开发 imi 之前,研究了好几个当时比较出名的框架,看到 Swoft 后,最终决定在 imi 框架大量使用注解。至于注解的优缺点,相比百度能比我说得更好,这里就不再复制粘贴一遍了。
目前大部分 Swoole 框架大都在强调微服务,但 imi 的设计理念确是:
微服务可以有,但不是必须
我认为绝大部分开发者的公司,用不着,或者根本没有必要上微服务。微服务的开发、维护成本会比较大,没有一定规模和业务量的,如果强行上微服务会本末倒置,给自己找麻烦。
imi 目前实现了最基础的 imi-rpc 组件,以及支持了 hprose 协议。虽然还没有更多深入的实现,但这都说明了 imi 的设计理念,可以有,就看做不做。
所以,imi 目前主打的还是单体应用开发。项目跑在 Swoole 下,可以比在 fpm 下性能更好,承载访问量更大,尤其是在大量调用第三方接口的 I/O 密集型场景。
WebSocket、TCP、UDP 协议的开发,也是 Swoole 带来的一大优势。
当然,Swoole 用来开发中间件也是相当不错的,不能只把眼光放在 curd 上。
未来
imi 未来也会逐步向微服务方面探索和发展,只不过现在更想做好眼前的单体应用开发。
联系我们
Github 反馈:https://github.com/Yurunsoft/IMI/issues
Segmentfault 提问:https://segmentfault.com/
开源中国 问答:https://www.oschina.net/question
欢迎真正喜欢代码,而不是仅仅当作是工作的朋友,加入 imi 开发组!
Assets
2
2个多月没有刷版本号,imi并没有凉,而是因为我实在太忙啦!
我们公司项目使用imi已经上线,这两个多月大部分时候是针对imi做bug修复,以及开发体验的细节上的提升。
这次 v0.3 版本发布是这两个月工作成果的一次总结,在此感谢群友们为imi做出的贡献!
最后,距离imi的 v1.0 正式版发布越来越近啦!
更新日志
新增
-
新增方法参数过滤器FilterArg
-
新增ArrayUtil::random()方法,获取随机成员
-
新增imigo函数(启动一个协程,自动创建和销毁上下文)
-
新增imiCallable函数(为传入的回调自动创建和销毁上下文,并返回新的回调)
-
新增IMI.REQUEST_CONTENT.CREATE、IMI.REQUEST_CONTENT.DESTROY事件
-
新增注解:DbInject、RedisInject、PoolResource
可用于注入连接池中的资源对象到属性 -
新增支持根据记录数计算总页数,Pagination->calcPageCount
-
缓存注解允许指定hash方法,默认为md5
调整/增强
-
调整模型生成逻辑,生成表结构定义在基类,实际的模型类继承基类
修改了表结构重新生成模型,也不用担心会覆盖掉模型类中自己写的方法 -
现在注入方法的Before也可以修改参数了
-
ExtractData 注解从此脱离 HttpValidation 注解依赖
-
调整默认runtime路径为:项目命名空间根下的.runtime目录中
避免默认在/tmp目录中,可能被linux内置清理给清掉了 -
热更新进程默认将runtime目录加入排除
-
调整连接池配置maxActiveTime默认值为null,新增maxUsedTime参数
-
调整连接池配置,当gcInterval为null时,不启动定时器
-
禁止在 MacOS 下设置进程名,解决报错问题
-
连接池配置默认minResources调整为1
-
数据库查询器的join方法现在支持对表名使用as设定别名
例:Db::query()->join('table as alias') -
为 PDO Statement 兼容支持 bool 类型值代入
-
Cache相关注解的key属性,支持用{:args}代入所有方法参数的 hash 值
-
当使用Swoole协程Redis时,支持使用_serialize()方法
-
新增路由初始化时的服务器类型判断
-
调整热更新检测用到的文件路径到runtime中
-
View 注解的 renderType 属性默认设置从 html 改为 json
原因:使用 imi 更推荐是用于开发接口,而不是用于后端页面渲染
修复
-
修正错误的注释
-
修复Session中间件潜在问题
-
修复ExtractData注解在特定情况无效问题
-
修复内存表模型,当属性名和Column注解中设定不一致时的问题
-
修复使用内存表模型时的Trying to get property of non-object问题
-
修复buildRuntime问题
-
修复Statement问题
-
修复数据库连接回收后还有残留的问题(Statement缓存化的原因)
-
修复连接池资源释放,以及并发情况下数量超过maxResources配置的问题
-
修复池子重复初始化问题
-
修复数据库关键词处理逻辑问题
-
修复当删除文件时,热更新报错问题
-
修复一个notice问题
-
修复部分场景下,框架内部无法正常启动命令行
-
修复查询器leftJoin()方法实际为inner join的问题
-
修复WS、TCP、UDP注解中间件问题
-
修复缓存功能在非服务器上下文下无法使用的问题
-
修复使用 ? 预处理SQL的问题
-
修复 imi/buildImiRuntime 后存在的注解修改无效问题
-
修复重复 send() 导致的 Http request is finished 问题
-
修复WebSocket无法握手问题
-
修复少数环境中无法正常启动项目的问题
-
修复配置文件注入属性的问题
-
修复 logCacheNumber 数字判定 bug
-
修复 Call to a member function isVariadic() on null 问题
-
修复 TCP、UDP 作为子服务器时的 setting 问题
-
修复配置路由问题
-
修复进程池进程名称问题
-
修复命令行参数解析不严谨的问题
-
修复类没有被use的问题
-
修复验证失败时,buildMessage存在的问题
Assets
2
Assets
2
距离上次发布差不多一个月了,这期间 imi 稳步推进,修复各项问题的同时,增加了不少实用组件和注解。
此次更新,在开发项目的体验也有巨大的提升。imi 的热更新采用了最新的增量更新技术,原本我们的实际项目在 WSL 下热重启需要 6 秒(根据文件增多,逐渐变慢),现在使用框架核心运行时缓存
+热更新重启采用增量方式
,不管文件增加多少只需 1 秒左右,即可完成热重新重启,极速的体验~
另外我们的框架核心运行时缓存、项目运行时缓存、数据库 Statement
复用等优化,也为开发、生产时的性能及体验打下了坚实的基础。
我们将持续为性能优化,为可靠性优化。
在此要特别感谢 @wi1dcard 一直以来的讨论交流,感谢群里每一位同学。
当前 imi 还不是正式版,就快了,请耐心等待哦!
更新日志:
新增
Redis
-
新增RedisManager类(getNewInstance/getInstance/release/getDefaultPoolName)
-
新增Redis类,用于快捷操作,如:Imi\Redis\Redis::set($key, $value)
-
新增 redis.quickFromRequestContext 配置项,支持配置Redis快捷操作类,使用RequestContext独享连接还是连接池实时争抢
-
Redis连接池配置新增支持uri格式
缓存
-
新增RedisHash缓存驱动
-
新增 Cacheable、CacheEvict、CachePut 注解
-
实现 Cacheable 注解中的 Lockable 嵌套使用
锁
- 新增 Lock,支持注解锁 Lockable,默认带有 RedisLock 支持
配置
-
新增支持 Config::get('@currentServer.xxx') 用法,当前服务器配置中不存在则取 @app 中的配置
-
增加注入值注解的概念,支持 ConfigValue 等注解,可用于注解参数使用配置值
注解
-
新增 Callback 注解,其 class 可配合 Inject 注解,实现表示bean类方法回调
-
Condition注解的args属性,增加默认值
-
新增 Compare、ValidateValue 用于验证的注解
-
新增 ConstValue 注解,从从常量中读取值注入注解属性
验证器
-
Http 验证器新增支持验证 $headers、$cookie、$session
-
为验证器增加$this支持
其它
-
新增支持忽略路由URL大小写
-
实现进程名称统一管理
-
新增支持方法参数注入
-
为Bean类统一增加__clone支持
-
实现了unset()模型类属性的处理
-
新增用于过滤字段的列表 Imi\Util\FilterableList
-
MySQL、Redis连接池配置新增支持uri格式
-
新增支持.env环境变量
-
数据库查询器支持 replace into 用法
-
Model->save()实现方式改为replace
-
@ExtractData 现在可以导出单独的$get/$post/$body等数据了
-
新增jsonBodyIsObject配置项,设置post body为json时,转为对象还是数组,默认为false数组。可以和@app.jsonBodyIsObject或@currentServer.jsonBodyIsObject配合使用
-
新增 Pagination 分页计算类
-
新增 Imi\Util\ObjectArrayHelper::filter() 过滤对象或数组属性的方法
-
新增热重启耗时输出
优化
-
完善CoroutineRedisHandler类魔术方法注释
-
因PHP BUG,放弃使用匿名类,Bean类采用eval()+动态类名,不再使用include Bean缓存文件,Bean缓存相关配置及方法移除。因此,性能有所提升。
-
Worker 进程启动时,重新加载项目配置及组件
-
调整Db、Redis获取默认连接池名称,使用@currentServer配置
-
现在缓存的$ttl参数支持传递\DateInterval类型了
-
完善 LazyArrayObject
-
将Redis模块中获取到的实例对象,统一改为 Imi\Redis\RedisHandler
-
优化热更新提示内容、重启逻辑,改为增量方式,性能更高
-
新增支持构建框架预加载缓存,提升项目开发时的热更新性能
-
优化onShutdown()时,日志处理如果发生错误或异常,直接输出错误信息
不兼容的调整
-
Imi\Redis\Redis 类更名为 Imi\Redis\CoroutineRedisHandler (连接池中如果有指定,请修改)
-
方法验证抛出的异常信息,不再包含 "xxx Parameter verification is incorrect" 信息
-
调整验证注解的args参数格式,注意与之前版本不兼容
-
弃用Swoole内置序列化,改为php序列化。原因:Swoole官方未来将不再维护序列化功能
-
信息提示英文规范
修复
-
修复Db类获取默认连接池名称问题
-
修复常量注解处理错误
-
修复master进程的事件无法触发问题
-
修复服务器配置中注入HttpRoute失效问题
-
修复热更新在特定情况下filemtime warning问题
-
修复当使用Swoole MySQL驱动时,Result->getRowCount()报错问题
-
修复开启一键协程化时,文件缓存写入失败问题
-
修复一些场景下的可变参数处理问题
-
修复使用Swoole协程MySQL时,fetchAll \PDO::FETCH_COLUMN 如果不指定$fetchArgument,结果为null问题
-
修复热重启后,@app.pools配置更改无效问题
-
修复一处潜在的notice问题
-
修复出现重复中间件时的问题
-
修复因@serializable注解导致的,模型插入更新数据缺失问题
-
修复dev/ext生成问题
Assets
2
此次更新除了日常修复bug以外,提升了数据库操作性能,新增验证器、Http 验证器、枚举。距离1.0
正式版发布已经不远啦!
验证器
// 限于篇幅,只列出其中一种验证,其它的请查阅文档
@Decimal(min=-0.01, max=999.99, accuracy=2, message="小数必须大于等于{min},小于等于{max},小数点最多保留{accuracy}位小数,当前值为{:value}")
枚举
<?php
namespace ImiDemo\HttpDemo\MainServer\Enum;
use Imi\Enum\BaseEnum;
use Imi\Enum\Annotation\EnumItem;
class Status extends BaseEnum
{
/**
* @EnumItem("正确")
*/
const YES = 1;
/**
* @EnumItem("错误")
*/
const NO = 0;
}
// 使用:
// 根据名称获得常量值
Status::getValue('YES');
// 根据值获得文字说明
Status::getText(Status::YES);
// 根据值获得 @EnumItem 注解对象
Status::getData(Status::YES);
// 获取枚举类中所有名称
Status::getNames();
// 获取枚举类中所有值
Status::getValues();
更新日志:
新增
- 新增支持类常量注解,支持Enum枚举(https://doc.imiphp.com/components/struct/enum.html)
- 新增验证器(https://doc.imiphp.com/components/validation/index.html)
- 新增Http参数验证器(https://doc.imiphp.com/components/httpserver/validation.html)
- 新增 Worker::isTask() 方法
- 新增 dev/ext 工具,生成 IDE 帮助文件
优化
- 注解扫描支持更多命名空间
- 完善 buildRuntime 报错提示
- 优化冷启动、热重启时错误刷屏问题
- 调整BeanFactory实例化对象初始化执行顺序为:__construct -> injectProps -> __init
- 新增支持数据库 statement 缓存化,避免重复创建 statement,提升性能
- 优化数据库查询器查询时出现错误的处理
- AroundJoinPoint->proceed()方法支持传参
修复
- 修复 IMI.MAIN_SERVER.WORKER.START.APP 只执行一次的问题
- 修复致命错误出错代码定位错误问题
- 修正 PoolItem 未按照设计思路计数的问题
- 修复注入属性问题
- 修复修改注解并热重启后没有生效的问题
- 修复部分类无法注入问题
- 修复PDO模式下,MySQL超时报MySQL server has gone away的问题
Assets
2
关于此次更新
有一些热心开发者经常问我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的问题
-
修复特殊情况下注解扫描加载的问题
-
修正注释问题
支持中间件+控制器开发WebSocket/TCP/UDP应用
Yurunsoft released this
-
新增支持中间件+控制器开发WebSocket/TCP/UDP应用
-
新增支持连接会话数据持久化
-
新增获取分组中连接总数方法
-
新增Redis分组redisDb属性指定数据库
-
新增监听WorkerError事件
-
开放一些BeanProxy方法
-
模型生成支持视图
-
imi 服务器类中新增getSwoolePort()方法
-
优化模型的字段、方法注释,加上数据库字段注释,更加方便理解
-
优化数据库模型update/delete/save处理,现在当主键为null时,update/delete可能会抛出异常
-
优化命名,将work改为worker
-
优化Redis事务延迟收包处理
-
连接数据持久化、连接分组Redis驱动心跳数据使用事务写入,防止极端情况
-
补充服务器close事件的$reactorID参数
-
提取获取进程ID的方法到工具类
-
修复模型生成的前缀处理问题
-
修复数据库查询对in和not in条件的处理错误
-
修复Bean类缓存清除问题
新增支持使用控制器开发WebSocket服务&其它18项改进
Yurunsoft released this
-
新增支持使用控制器开发WebSocket服务
-
新增支持WebSocket连接逻辑分组
-
新增Http路由匹配缓存机制
-
现在Session::get()方法不传参数时,返回全部数据
-
新增PHP内置Session的序列化和反序列化实现
-
Session支持a.b.c形式参数,Session::get('a.b.c')同Session::get('a')['b']['c']
-
新增支持Session Prefix前缀
-
支持在非RequestContext环境下使用PoolManager::use()方法
-
调整RequestContext中的container为按需实例化
-
同步Redis连接方式默认timeout改为68年(绝对够用!flag!)
-
修复AtomicManager::sub()参数无默认值问题
-
修复并发访问时,类似Session加载会出错的问题
-
修复LazyArrayObject类问题
-
修正设置进程名称的错误位置
-
修正一个方法拼写错误
-
解决BeanFactory中可能存在的变量名重复问题
-
优化延迟收包recv()执行逻辑
-
服务器事件修改优化
-
调整Bean类实例化eval()改为include 缓存文件
周常更新,庆祝小米上市!imi:爱米,我米
Yurunsoft released this
周常更新,庆祝小米上市!imi:爱米,我米
-
新增连接池资源掉线自动重连
-
新增Model支持$model->propertyName读写
-
实现局部中间件注解+配置
-
新增热更新重启时清除apc、opcache缓存
-
新增@view注解baseDir属性,支持设置基础路径
-
ServerRequest类属性增加默认值
-
增加Uri类常用协议标准端口返回
-
服务器启动时清除不必要的东西
-
修复模型相关BUG
-
修复进程启动工具错误
-
修正PSR-7 Header处理
-
调整BeanFactory实例化类构造方法调用时机
-
修复实例化默认值问题
-
修复Uri转字符串BUG
-
修正withAddedHeader()值传入数组报错问题
-
调整Imi\Util\File::path()参数为可变参数,支持无限个路径拼接
支持 PHP 7.0 + Swoole 4.0,支持 Redis 模型
Yurunsoft released this
-
框架依赖更新:php >= 7.1 + swoole >= 4.0.0 (之前为 php 7.0 + swoole 2.2.0)
-
新增 Redis 模型
-
新增双驼峰转换方法
-
新增文件,目录创建操作方法
-
新增session操作类自动创建目录的功能
-
新增支持池子资源重置
-
改进转换驼峰命名方法性能
-
调整内存表key相关属性和方法,防止和字段冲突
-
修复投递任务每次都在同一个task进程问题
-
修复BaseAsyncPool->tryGetResource()问题
第一个版本
Watchers:25 |
Star:440 |
Fork:43 |
创建时间: 2018-06-21 08:54:24 |
最后Commits: 5天前 |
许可协议:View license |
958a3c5
新增
新增强大的定时任务功能 (文档传送门)
新增支持 Http2 服务开发
新增 Http2、gRPC 相关常量到 MediaType、RequestHeader
支持应用上下文读写,支持只读写入
新增支持获取当前代码运行在何种进程中(master、manager、worker、task_worker、process)
新增支持正则路由(#31)
支持自定义错误级别,将错误转为异常捕获
优化
HttpErrorHandler 中使用服务器上文容器获取执行器实例
支持注入修改默认的 ActionMiddleware
支持给容器对象类手动绑定
进程退出自动释放资源
事件监听、取消监听支持传入数组指定多个事件
新增支持在注解设定进程是否默认启用协程
优化 parseDotRule 性能 (#32)
修复
修复会获取到不应该存在的请求头问题
修复锁不在同一个协程无法解锁的问题