乐于分享
好东西不私藏

用Qt5撸一套工业级SCADA插件架构:消息总线也能当插件? MessageBus实现间通信

用Qt5撸一套工业级SCADA插件架构:消息总线也能当插件? MessageBus实现间通信

wx公众号搜索并关注"先瞳编码",获取最新技术分享。

评论区回复关键字 [SCADA插件获取完整源码下载链接

说到工业监控,很多人第一反应是"高大上"的大屏、闪烁的数字、红绿交替的仪表盘。但扒开外衣,核心无非三件事:采数据、传数据、看数据。

今天咱们用Qt5 Widget从零撸一套工业数据采集监控平台,重点攻克三个难点:插件系统、MessageBus通信框架、以及把消息总线本身也做成插件的神操作,通过消息总线,各插件之间也能通过发布订阅的方式实现插件间通信

插件框架参考我之前的文章:Qt插件系统实战:300行代码搭一个可插拔的桌面应用框架

先放一张总览图,让大家有个直观感受:

图1:SCADA实时监控 - 仪表盘与趋势曲线

一、架构概览:先画饼再烙饼

软件工程有句老话:"先设计后编码,先架构后实现"。咱们这套平台可以用一句话概括:一个宿主,多个插件,一条总线串起所有。

1.1 宿主程序:毛坯房 philosophy

宿主程序就像一个"毛坯房"——左边一个QListWidget放插件列表,右边一个QStackedWidget放插件界面,底部一个状态栏显示日志。仅此而已。所有业务逻辑全部下沉到插件DLL中。

好处显而易见:宿主极其稳定,几乎不需要改动;新功能只需要写个DLL扔进plugins目录,重启即生效。这在工业现场特别重要——你不能因为加个温度监测就停机重编整个程序。

1.2 插件系统:插座标准

Qt5提供了QPluginLoader这套机制,天生就是为插件系统设计的。核心思路是:定义一个纯虚接口类PluginInterface,所有插件继承它并编译成独立DLL;宿主运行时扫描DLL,用qobject_cast把入口对象转成PluginInterface指针。

打个比方:PluginInterface就是一份"插座标准"——规定了插头形状和电压。插头上接的是电饭锅还是电视机,宿主不关心,也不需要关心。

1.3 MessageBus:插件中的插件

这是最有意思的设计。MessageBus不是独立库,不是宿主内置组件,而是以"通信插件"身份存在于插件系统中。它同时实现两个接口:PluginInterface(提供监控界面)和IMessageBus(提供publish/subscribe通信能力)。其他业务插件通过全局函数getMessageBus()从qApp属性中获取总线指针。

来看一张MessageBus监控界面的效果图:

图2:MessageBus通信监控 - 总线运行状态一目了然

二、插件接口:四个函数定乾坤

所有插件必须遵守的接口定义非常简洁,四个纯虚函数搞定:

// 插件标准接口(纯虚抽象基类)

class PluginInterface {

virtualPluginInfo pluginInfo() = 0;// 我是谁?

virtualQWidget* createWidget() = 0;// 给我界面

virtualbool initialize() = 0;// 初始化

virtualvoid release() = 0;// 释放资源

};

// 注册接口IID,供qobject_cast识别

Q_DECLARE_INTERFACE(PluginInterface, "com.scada.PluginInterface/1.0")

pluginInfo()返回名称、版本、作者、描述。createWidget()创建插件的可视化界面,宿主把它塞进QStackedWidget。initialize()做准备工作,比如获取MessageBus、订阅消息、启动定时器。release()做清理,取消订阅、停定时器。

这里有个容易忽略的细节:Q_DECLARE_INTERFACE宏注册了接口的IID字符串,宿主和所有插件的IID必须完全一致,否则qobject_cast返回nullptr。这就像蓝牙配对——双方得用同一个PIN码。

说到软件工程,这个接口设计体现了"依赖倒置原则"(DIP)。高层模块(宿主)不依赖低层模块(插件实现),两者都依赖抽象(PluginInterface)。接口一旦发布就不能随便改,这就是"接口契约"的严肃性。

三、插件加载:先通水电,再进场装修

宿主启动时,PluginManager扫描plugins目录下所有DLL。但加载顺序很讲究:MessageBus通信插件必须第一个加载,因为其他业务插件initialize()时需要从qApp属性中获取通信总线指针。

排序逻辑简单粗暴:文件名里包含"messagebus"的排前面。

// 优先加载通信插件,确保业务插件能拿到总线

function prioritizeBusPlugin(files) {

busFiles= files.filter(f => f.contains("messagebus"))

otherFiles= files.filter(f => !f.contains("messagebus"))

returnbusFiles + otherFiles// 通信在前,业务在后

}

加载单个插件的核心流程是五步走:

// 1. QPluginLoader加载DLL,触发Q_OBJECT注册

loader = new QPluginLoader(filePath)

instance = loader->instance()

// 2. qobject_cast转换为插件接口(跨DLL安全)

iface = qobject_cast(instance)

// 3. 调用initialize()注册订阅、启动定时器

iface->initialize()

// 4. 检测是否实现了IMessageBus接口(通信插件检测)

bus = qobject_cast(instance)

if (bus) {

qApp->setProperty("messageBus",bus)// 注入全局属性

}

// 5. createWidget()创建界面,加入QStackedWidget

第四步是点睛之笔。通信插件同时实现了PluginInterface和IMessageBus两个接口,宿主通过qobject_cast检测到IMessageBus能力后,把指针注入qApp属性。业务插件调getMessageBus()就能拿到总线,完全不需要链接宿主EXE。

这里插一句对软件工程的理解。传统依赖注入是构造函数传参或设值注入,但在插件架构中,构造函数你压根碰不到(DLL是动态加载的)。用qApp属性做IoC容器,虽然是Qt特有的"野路子",但实践中非常好用。工业软件不需要Spring那种重量级容器,够用就行。

还有个工程上的细节:加载前会检查绝对路径,防止同一个DLL被重复加载。这听起来是常识,但在实际开发中,重复加载会导致插件管理混乱——同一个插件显示两份,卸载一个另一个也跟着崩。绝对路径比对是最简单有效的防重复手段。

四、消息总线:工业通信的发动机

消息总线是整个系统的通信枢纽。它不是单例,不是全局变量,而是由通信插件创建并持有的一个普通QObject实例。这比单例模式灵活得多:想测试就new一个测试总线,想监控就new一个监控总线。

4.1 消息结构:一个struct走天下

struct Message {

QUuidid;// 全局唯一ID,链路追踪用

QStringtopic;// 主题,如"sensor.data"

QVariantdata;// 载荷,任意Qt类型

qint64timestamp;// 毫秒时间戳

MessagePrioritypriority;// 优先级(0-4)

QStringsender;// 发送方插件名(统计用)

};

QVariant作为消息载荷是Qt生态的惯用手法。你可以在data里塞QVariantMap、QVariantList甚至自定义结构体。代价是运行时类型检查的开销,但对工业SCADA的吞吐量来说完全不是问题。毕竟咱们不是做高频交易,4条/秒的消息量,QVariant的性能损耗可以忽略不计。

4.2 优先级队列:紧急消息插队走

工业场景中,报警消息必须比数据采集消息优先处理。MessageBus用std::priority_queue实现优先级调度。技巧是重载operator<,让数值小的(Critical=0)排前面:

// Critical(0)排最前,Debug(4)排最后

bool operator<(Message& other) {

returnthis.priority > other.priority// 反过来比较

}

这就像医院急诊分诊——心跳骤停的先进,感冒发烧的往后排。工业现场也一样:过热报警的消息必须比日志消息先处理,否则等你打完日志,设备可能已经炸了。

还有个背压保护机制:队列满了一万条时,Normal及以下优先级的消息直接丢弃,但Critical和High强制入队。这就像高速公路的应急车道,堵车时普通车不能走,但救护车消防车必须过。工业系统宁可丢几条温度数据,也不能丢一条过热报警。

4.3 通配符匹配:一个星号订阅全部

订阅者可以指定主题模式,支持通配符匹配。"sensor.*"匹配"sensor.data"、"sensor.status"等。而"*"单独使用则匹配所有消息——MessageBus监控插件就靠这个订阅全部消息来统计收发数据。

bool matches(topic) {

if(pattern == "*") return true// 全局通配

if(pattern == topic) return true// 精确匹配

if(pattern.endsWith(".*")) {// 前缀通配

returntopic.startsWith(prefix + ".")

}

returnfalse

}

这个匹配算法虽然简单,但覆盖了工业SCADA中90%的订阅场景。比起MQTT的+和#通配符,这里的实现更直观,调试也更方便。简单就是美。

4.4 异步分发:50ms一批,不阻塞发布者

MessageBus不是收到消息立刻分发,而是先入队,50ms定时器批量处理。这保证了发布者不会被慢速订阅者阻塞:

// 50ms定时处理队列

void onProcessQueue() {

if(isProcessing) return// 防重入

while(!queue.empty()) {

msg= queue.top()// 取最高优先级

queue.pop()

dispatch(msg)//分发给匹配的订阅者

}

}

这里有个算法上的小技巧:延迟统计用指数加权移动平均(EWMA)。公式是avgLatency = avgLatency * 0.9 + currentLatency * 0.1。EWMA比简单平均更灵敏——最近的数据权重更高,能更快反映延迟变化趋势。这是金融量化分析里的经典算法,放到工业监控也合适。

关于线程安全,用了两把锁:m_mutex保护队列和订阅者列表,m_statsMutex保护统计数据。取队列深度时先锁m_mutex取值再锁m_statsMutex,避免嵌套锁导致死锁。这种"先取值再操作"的锁分离技巧在并发编程中很常见。

五、通信插件:双重身份的变形金刚

MessageBusPlugin是整个架构最精妙的部分。它同时继承PluginInterface和IMessageBus,一个DLL扮演两个角色:对外是普通插件(提供监控界面),对内是通信总线(提供publish/subscribe)。

// 双重接口继承

class MessageBusPlugin

:public QObject

,public PluginInterface// 标准插件接口

,public IMessageBus// 消息总线接口

{

Q_OBJECT

Q_INTERFACES(PluginInterfaceIMessageBus)

Q_PLUGIN_METADATA(IIDPLUGIN_INTERFACE_IID)

};

initialize()中创建内部MessageBus引擎实例,以通配符"*"订阅全部主题,捕获总线上每一条消息用于监控展示。IMessageBus的publish/subscribe等方法全部转发到内部引擎。

5.1 回调包装:统计无侵入

插件收发统计是本项目的特色功能。通过在subscribe()转发层包装回调,自动统计每个插件的发送和接收消息数,业务插件完全感知不到被包装过:

// 包装回调:在调用原始回调前,累计接收统计

wrappedCallback = [this, origCallback, name](msg) {

pluginStats[name].receivedCount++//先计数

origCallback(msg)//再执行原回调

}

// 发送统计在onMessage回调中通过msg.sender字段累计

这种AOP(面向切面编程)的思路在C++里就是函数包装。不侵入业务代码,统计逻辑全在转发层完成。这在互联网后端叫"拦截器模式",在C++叫"装饰器模式",本质都一样:在不修改原函数的前提下,增强其行为。

5.2 监控界面:五段式布局

通信插件的监控界面采用QSplitter垂直五段式布局:总线状态栏、统计卡片、优先级分布面板、实时消息日志、订阅者概览表。每个区域各司其职,信息密度高但不杂乱。

总线状态栏显示运行时长、健康状态、队列深度和吞吐趋势。统计卡片展示累计消息数、每秒消息数、平均延迟、丢弃消息数。优先级分布用五种颜色标注Critical到Debug的消息计数。实时日志记录最近200条消息的时间、优先级和发送方。订阅者概览表展示所有活跃订阅者的名称、执行策略和优先级。

从效果图可以看到,数据源模拟器发了940条消息,SCADA实时监控、设备状态网格、报警管理各按订阅模式收到对应消息。这种可视化让系统行为一目了然,出了问题能快速定位是发送方没发还是接收方没收到。

六、数据源模拟器:随机游走造数据

没有真实PLC?那就自己造。数据源模拟器用随机游走算法模拟4台反应釜的传感器数据,每秒发4条sensor.data消息。

图3:数据源模拟器 - 4台反应釜实时采集数据

// 随机游走:值 += [-delta, +delta]的随机数,再钳位到量程

void randomWalk(param) {

r= random() * 2.0 - 1.0// [-1, 1)

param.value+= r * param.delta

param.value= clamp(param.value, min, max)

}

随机游走(Random Walk)是金融领域常用的模拟算法,放到工业场景也合适。每步加减一个随机量,累积出连续变化的曲线。比纯正弦波更真实,比纯随机噪声更平滑。

报警检测采用上升沿触发策略:值首次越限才发报警消息(Critical优先级),回落自动清除。避免每秒重复发同一个报警。这是工业SCADA的标准去抖策略——想象一下,如果温度在150.0和150.1之间来回跳,没有去抖,你每秒都会收到一条报警,报警表很快就会被刷爆。

发送消息时会设置sender字段为"数据源模拟器",这样MessageBus监控插件就能统计到它的发送数。消息发送本身很简单:构造Message结构体,设置topic为"sensor.data",priority为Normal,然后调bus->publish(msg)。

七、SCADA实时监控:仪表盘+趋势曲线

SCADA监控插件订阅sensor.data主题,把数据画成圆形仪表盘和实时趋势曲线。仪表盘用QPainter手绘,三色区间(绿/黄/红)直观显示参数是否越限。

图4:SCADA实时监控 - 四仪表盘与趋势曲线联动

仪表盘的关键技巧是paintEvent中先画背景圆弧(灰色),再画值圆弧(彩色),最后画指针和数值文字。每次setValue时调用update()触发重绘。三色区间用QConicalGradient绘制,0-60%绿色、60-80%黄色、80-100%红色。

趋势曲线维护一个滑动窗口队列(最多300个点),paintEvent中用QPainterPath连线绘制。新数据push_back,超过容量pop_front,实现"滚动"效果。这种做法内存开销固定,不会因为运行时间长了就OOM。

纯手工绘制控件虽然开发量比用QChart大,但有两个好处:一是完全可控,想画成什么样就画成什么样;二是没有第三方依赖,编译出来的DLL干干净净,拷到任何机器上都能跑。工业软件最怕依赖地狱,Qt5原生模块打天下才是正道。

这里插一段行业理解。工业软件的UI设计有自己的逻辑:不是越炫酷越好,而是信息密度要高、状态指示要明确、操作路径要短。深色主题不是为了好看,是为了7x24小时盯着屏幕的操作员减少视觉疲劳。三色区间不是为了花哨,是因为操作员需要在0.5秒内判断设备是否正常。每个设计决策背后都有工程考量。

八、设备状态网格:一眼看全部设备

设备状态插件以2x2彩色卡片网格展示4台反应釜的运行状态。卡片背景色随状态变化:绿色运行、橙色预警、红色故障、灰色离线。

图5:设备状态网格 - 2x2彩色卡片实时状态

状态判定采用优先级链:故障 > 预警 > 正常。任何一个参数超过报警阈值就是故障,超过预警阈值就是预警。这种"最坏情况优先"的策略在工业安全领域是铁律——宁可误报,不可漏报。

还有个离线检测定时器,超过10秒没收到数据的设备自动标灰。这在实际工业场景中非常重要——传感器通信中断是常见故障,如果不能及时发现,操作员可能一直盯着一个已经失效的数据以为设备正常运行。

这里有个生命周期管理的小坑:宿主卸载插件时会先delete界面控件,再调release()。所以定时器的父对象不能设为界面控件,否则界面被delete后定时器变野指针。解决方案是定时器父对象设为插件本身(QObject),release()里只停定时器、置空指针,不访问已销毁的界面。这种Qt对象树的管理是Qt开发的基本功。

九、报警管理:闪烁+确认+导出三件套

报警管理插件订阅alarm.new消息,收到后插入表格顶部(最新优先)。未确认行每500ms闪烁——紧急级别红/深红交替,其他级别黄/深黄交替。

图6:报警管理 - 告警表格与确认机制

当前所有参数在正常范围内,暂无报警记录。当温度或压力超过阈值时,数据源模拟器会发送alarm.new消息,报警表格会自动插入新行并开始闪烁。

支持右键确认和CSV导出。CSV导出用UTF-8 BOM编码,确保Excel能正确识别中文——这个小细节很多人踩过坑:不加BOM的UTF-8文件在Excel里中文会变成乱码。表格超过500行自动移除最旧记录,防止内存无限增长。

闪烁效果用QTimer定时切换背景色实现。确认后停止闪烁,背景变灰。这种视觉反馈符合工业监控的操作习惯:操作员一眼就能看出哪些报警还没处理。

十、写在最后:一些技术感悟

10.1 关于插件架构

插件架构的核心价值不是"代码分文件",而是"编译期解耦"。传统模块化设计里,加一个功能得重编整个程序;插件架构下,加功能只需要编一个DLL丢进去。这在工业现场的价值巨大——很多工厂的产线7x24小时运行,停机一小时可能损失几十万。热插拔插件意味着"不停机迭代",这是工业软件的刚需。

但插件架构也有代价:调试更困难(跨DLL断点不好打)、接口设计要极其谨慎(一旦发布就不能随便改)、版本兼容性管理复杂。所以"是否用插件"本质上是个ROI问题——如果系统会长期演进、功能会持续扩展、部署环境不允许频繁停机,那插件架构的投资就值得。

10.2 关于MessageBus设计

消息总线解决了插件间通信的"N方问题"——N个插件互相调用需要N*(N-1)/2个接口,用总线只需要N个订阅。但总线不是银弹:它引入了间接性,调试时追踪数据流更麻烦(得看日志才知道谁发了什么谁收了什么);异步语义增加了时序复杂度。

我们的实现选择了"定时器驱动批量处理"而非"事件驱动即时处理",这是有意的权衡:牺牲少量延迟(最多50ms)换取更高的吞吐量和更简单的线程模型。工业场景下50ms延迟完全可以接受——人眼分辨极限是100ms左右,PLC扫描周期通常也是几十毫秒级。

10.3 关于工业软件开发

工业软件和互联网软件有本质区别。互联网软件追求"快速迭代、灰度发布、A/B测试";工业软件追求"稳定可靠、可维护可追溯、7x24不停机"。这意味着工业软件的架构设计要更保守——能用纯虚接口就不用模板元编程,能用QList就不用std::vector,能用定时器就不用多线程。

但也不要太保守。我们的MessageBus用了std::priority_queue、std::atomic、lambda回调、enum class——这些都是C++11/14的现代特性,既安全又高效。关键判断标准是:这个特性是否被主流编译器广泛支持、是否有成熟的最佳实践、是否能让代码更清晰而不是更炫技。

10.4 关于解耦

这个项目里用了很多解耦手段:纯虚接口隔离实现、QPluginLoader动态加载、qApp属性做依赖注入、回调包装做AOP统计。这些手段的本质都是"让变化发生在局部"。业务逻辑变了只改插件,通信协议变了只改总线,UI样式变了只改QSS。这就是高内聚低耦合在代码层面的体现。

软件工程的终极目标不是写出能运行的代码,而是写出能演进的代码。能运行的代码三个月后可能变成技术债,能演进的代码三年后依然是资产。插件架构、消息总线、接口抽象——这些设计模式的价值不在于让代码更复杂,而在于让变化更可控。

十一、总结

这篇文章从架构设计到代码实现,完整拆解了一套工业数据采集监控平台的三大核心:插件系统实现编译期解耦,MessageBus通信框架以插件形式提供发布-订阅通信,业务插件各司其职完成数据采集、SCADA监控、报警管理和设备状态展示。

核心设计三句话:

1. 插件通过PluginInterface接口与宿主解耦,QPluginLoader实现动态加载。

2. MessageBus以通信插件身份存在,通过qApp属性注入实现跨DLL共享。

3. 业务插件通过getMessageBus()获取总线,publish/subscribe完成数据流转。

如果这篇文章对你有帮助,请点赞、收藏、转发三连!

关注微信公众号"先瞳编码",回复关键字"SCADA插件"获取本文完整源码下载链接。

你们的支持是我持续分享的最大动力,我们下期再见!

--- END ---

点赞 | 收藏 | 关注

wx公众号: 先瞳编码

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-10 06:51:47 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/900670.html
  2. 运行时间 : 0.222321s [ 吞吐率:4.50req/s ] 内存消耗:4,732.79kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=fb984d6fb448f44f8c6c4f94d4f9b435
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 4.22 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.11 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.001216s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001718s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000876s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000733s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001728s ]
  6. SELECT * FROM `set` [ RunTime:0.000735s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.002071s ]
  8. SELECT * FROM `article` WHERE `id` = 900670 LIMIT 1 [ RunTime:0.001276s ]
  9. UPDATE `article` SET `lasttime` = 1786315907 WHERE `id` = 900670 [ RunTime:0.008298s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.001421s ]
  11. SELECT * FROM `article` WHERE `id` < 900670 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001204s ]
  12. SELECT * FROM `article` WHERE `id` > 900670 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001143s ]
  13. SELECT * FROM `article` WHERE `id` < 900670 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.006565s ]
  14. SELECT * FROM `article` WHERE `id` < 900670 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.002830s ]
  15. SELECT * FROM `article` WHERE `id` < 900670 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001767s ]
0.225954s