# hashed wheel timer plugin 延時通知插件
HashedWheelTimer是采用一種定時輪的方式來管理和維護大量的Timer調度算法。 一個 HashedWheelTimer 是環形結構,類似一個時鐘,分為很多槽,一個槽代表一個時間間隔,每個槽又對應一個類似Map結構的對象,使用雙向鏈表存儲定時任務,指針周期性的跳動,跳動到一個槽位,就執行該槽位的定時任務。 環形結構可以根據超時時間的 hash 值將 task 分布到不同的槽位中, 當 tick 到那個槽位時, 只需要遍歷那個槽位的 task 即可知道哪些任務會超時(而使用線性結構, 你每次 tick 都需要遍歷所有 task), 所以, 我們任務量大的時候, 相應的增加 wheel 的 ticksPerWheel 值, 可以減少 tick 時遍歷任務的個數
本插件模擬java HashedWheelTimer 的實現。使用redis做持久存儲。
# 配置方法
配置一個環形結構池
~~~
hashedWheelTimer:
db: default
max_pending_timeouts: 100
wheel:
- {name: aaa, tick_duration: 1, ticks_per_wheel: 60 }
~~~
name 池子名稱,投遞任務的時候需要
tick_duration,時間間隔,1秒
ticks_per_wheel,時間槽數量,60個,代表一分鐘一個輪次
max_pending_timeouts,每一個槽允許的最大協程數,默認100,如果耗時任務或者隊列特別長需要適當增加時間槽數量比如3600。不適合特別精準的延時場景。
db,使用的 redis 配置,強烈建議不要使用default,會占用http服務的連接數,應該復制一份配置專用
# 使用方法
## [](https://github.com/esd-projects/hashed-wheel-timer-plugin#%E6%8A%95%E9%80%92%E4%BB%BB%E5%8A%A1)投遞任務
~~~
//環形池名稱,執行任務的類,投遞參數,延遲執行時間,秒
$this->addTask('aaa', TimerTask::class,['a'=>'b', 'time' => time()], 60);
~~~
## [](https://github.com/esd-projects/hashed-wheel-timer-plugin#%E6%8A%95%E9%80%92%E7%B1%BB)投遞類
投遞的類需要繼承 HashedWheelTimerRunnable
~~~
<?php
namespace app\Controller;
use ESD\Plugins\HashedWheelTimer\HashedWheelTimerRunnable;
class TimerTask extends HashedWheelTimerRunnable{
public function run()
{
/**
//此處可根據延遲次數設置不同的延遲時間,比如支付通知失敗
if($this->getDelayTimes() <= 1){
$this->setDelayTTL(10);
}else if ($this->getDelayTimes() <= 2){
$this->setDelayTTL(20);
} else if ($this->getDelayTimes() <= 3){
$this->setDelayTTL(30);
} else if ($this->getDelayTimes() <= 4){
$this->setDelayTTL(40);
}else if ($this->getDelayTimes() <= 5){
$this->setDelayTTL(40);
}
* **/
//如果 return false 或者該類觸發任意異常,系統會將此任務重新投遞到下一次執行的位置。
//如果不需要失敗重試,需要 return true。可通過 getRetryTimes 獲取重試次數進行判斷
//如超過5次則不再重試,直接return true。
$this->getRetryTimes()
//獲取投遞參數
$params = $this->getParams();
// TODO: Implement run() method.
$this->info('run', $params);
//如果執行 setDelayTTL , 需要return true ,否則會被重新投遞到下一次執行的位置。
return true;
}
}
~~~
- 前言
- 捐贈ESD項目
- 使用篇-通用
- 環境
- 安裝
- 規范
- 壓力測試
- 配置
- 如何設置YML配置
- server配置
- 端口配置
- 項目結構
- 事件派發
- 日志
- 注解
- DI容器
- 自定義進程
- 并發及協程池
- Console插件
- Scheduled插件
- Redis插件
- AOP插件
- Saber插件
- Mysql插件
- mysql事務
- Actuator插件
- Whoops插件
- Cache插件
- PHPUnit插件
- Security插件
- Session插件
- EasyRoute插件
- http路由
- ProcessRpc插件
- AutoReload插件
- AnnotationsScan插件
- Tracing-plugin插件
- MQTT插件
- Pack插件
- AMQP插件
- Validate插件
- Uid插件
- Topic插件
- Blade插件
- CsvReader插件
- hashed-wheel-timer-plugin插件
- 使用篇-HTTP
- 路由
- 靜態文件
- 路由定義
- 修飾方法
- 路由分組
- 資源路由
- 端口作用域
- 異常處理
- 跨域請求
- 路由緩存
- 控制器
- 控制器初始化
- 前置操作
- 跳轉和重定向
- 異常處理
- 請求
- 請求對象
- 請求信息
- request消息
- response消息
- stream消息
- url接口
- 驗證器
- 內置驗證器
- 內置過濾器
- 使用篇-WS
- 如何使用
- 路由
- 使用篇-TCP
- 插件篇-PluginSystem
- 微服務篇-ESDCloud
- CircuitBreaker插件
- SaberCloud插件
- 分布式鏈路追蹤系統
- Consul插件