news 2026/10/14 5:40:10

PHP TrueAsync:协程与事件循环解决PHP同步阻塞性能瓶颈

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PHP TrueAsync:协程与事件循环解决PHP同步阻塞性能瓶颈

阻塞是PHP Web应用最常见的性能黑洞。数据库查询慢、调用外部API超时、批量发送邮件、处理图片、生成报表……任何一个环节卡住,后面的请求只能排队等。传统的PHP-FPM同步模型下,每个请求独占一个进程,进程在等待IO完成时CPU几乎闲置,但新的请求却被拒之门外。标题里提到的PHP TrueAsync,就是尝试解决这个问题的一套异步方案。它能通过协程和事件循环把进程等待IO的时间利用起来,让同一个进程同时处理多个任务,实测下来脚本吞吐量提升一个数量级并不夸张。这篇东西我按自己的实践经验来写,尽量讲清楚原理、给出可直接抄的改造方法,最后附上我踩过的坑。

TrueAsync不是那种需要把整个项目推倒重来的框架,它更像是在传统PHP脚本里加了一层“调度器”,让同步代码通过协程切换变成非阻塞执行。只要你会写PHP函数、理解回调,再掌握几个关键词,基本就能上手。适合这几类人看:被API聚合接口拖垮的服务端开发者,用Laravel/ThinkPHP写队列消费却频繁超时的同学,以及想给老项目提速但又不想引入重框架的人。

1. 为什么传统PHP脚本会卡死:先认清阻塞的本质

要理解TrueAsync的价值,先得搞清楚PHP脚本到底卡在哪。很多人以为“脚本慢”就是代码算法差,其实大部分情况下,慢的是IO等待,不是CPU计算。

1.1 PHP-FPM同步模型下的请求生命周期

一次典型的PHP请求,从Nginx接收到HTTP请求开始,会经历一次完整的“进程生命周期”:

  1. Nginx把请求转发给PHP-FPM的某个空闲worker进程。
  2. worker进程加载PHP脚本,逐行执行。
  3. 脚本里遇到mysqli_query()或file_get_contents()这类IO操作。
  4. 进程调用操作系统IO接口,然后进入睡眠状态,等待数据返回。
  5. 数据返回后,进程继续执行后面的逻辑,最终输出响应,释放进程。

整个过程里,第4步最为致命。进程在等待数据库返回、等待外部HTTP响应、等待磁盘读写时,自身什么都不干,但worker却被占用了。假如一次外部API调用需要2秒,那么这个worker在这2秒内就无法服务其他任何请求。FPM进程池通常只有几十上百个worker,一瞬间就能被慢请求占满。

我用一个日常案例说明。某个电商管理后台的“批量同步商品”接口,逻辑是循环调用供应商的API,逐个更新本地商品表,一个商品更新耗时0.8秒,50个商品就是40秒。这个接口同时只允许同一进程处理一个请求,一旦有人点了批量同步,后台其他接口全部卡顿。后来我用TrueAsync把循环里的串行请求改成并发协程,整体耗时从40秒降到了3秒左右,而且Worker进程在等待时还能继续处理其他请求。

1.2 阻塞IO与CPU浪费的关系

为了更直观,可以做个粗略计算。假设处理一次请求需要总耗时1秒,其中CPU实际计算只用0.1秒,其余0.9秒都在等IO。单进程模型下,这1秒内CPU利用率只有10%。如果能够在这0.9秒的等待时间里切换去执行另一个任务,把多个请求的等待期重叠起来,同样1秒内就能处理10个请求,CPU利用率理论上能接近100%。

当然实际不可能做到100%,因为还有进程切换开销、调度器损耗、单个IO峰值等问题。但方向和结论是确定的:同步阻塞模型浪费的从不是CPU,而是进程等待IO的时间窗口。

1.3 哪些代码场景最容易引发阻塞

我在多个项目里做过统计,最容易造成PHP脚本长阻塞的场景基本是这几类:

  • 同步调用外部HTTP API:对接微信、支付宝、物流、短信等服务商接口,一个接口动不动几百毫秒到几秒。
  • 大表查询与慢SQL:没有走索引的查询、深度分页、关联多张千万级大表的报表查询。
  • 批量文件处理:一小时内批量处理几千张图片,每张都要读取、压缩、写入磁盘。
  • 发送邮件/短信通知:循环调用邮件服务商接口,每个几百毫秒,100个就几十秒。
  • 队列消费:从消息队列里取出任务后,逐条执行,任务内涉及外部IO就卡住整个消费者进程。
  • 文件上传与下载:大文件从远程服务器拉到本地再转发给用户。

这些场景有共同特点:代码逻辑不复杂,耗时集中在“等待外部资源返回”。TrueAsync的目标就是把这些等待时间利用起来,用一套统一的事件循环管理所有并发操作。

2. TrueAsync核心设计拆解:协程、轮循与事件循环

TrueAsync本质上是一个PHP的异步运行时,核心包含三块:协程调度器、事件循环、非阻塞IO封装。这三块配合起来,才让“单进程同时处理成千上万个任务”成为可能。

2.1 协程:让函数执行到一半可以主动让出CPU

协程(Coroutine)是一个比线程更轻量的执行单元。线程的调度由操作系统内核决定,而协程的切换由用户态程序自己控制。PHP里通过生成器(Generator)实现了底层的协程原语,TrueAsync在此基础上封装了高级API。

举个例子,你写一个普通函数:

function fetchData($id) { $data = httpGet("https://api.example.com/item/{$id}"); return $data; }

如果用TrueAsync的协程改造,可以写成这样:

function fetchData($id) { $data = TrueAsync\Http::get("https://api.example.com/item/{$id}")->await(); return $data; }

区别在于,->await()这一句会让出当前协程的执行权,告诉调度器:“我在等网络数据,你先去跑别的协程”。等数据返回后,调度器再回来继续执行这个协程。程序员写起来仍然是同步风格,但底层已经变成了异步执行。

这里的关键点是你不需要手动写生成器yield。TrueAsync通过一个自定义函数包装器,把普通函数自动转换为协程函数。第一次接触时我也有点不适应,但理解了“await就是让出执行权”这个概念后,一切都通了。

2.2 事件循环:IO就绪了才回调

协程让出执行权之后,谁来决定什么时候重新唤醒它?答案就是事件循环。事件循环,简单理解就是一个死循环,它不停询问操作系统:“哪些socket已经可读?哪些已经可写?哪些定时器到时间了?”

TrueAsync的事件循环基于stream_select()、pcntl扩展以及PHP 8的Fiber能力构建。它会维护一张任务表,任务状态分为:

  • 准备执行:协程刚创建,等待第一次调度。
  • 等待IO:协程执行到await,注册了一个文件描述符监听。
  • 等待定时器:协程调用sleep()或timeout(),等待一段时间。
  • 就绪:IO完成或定时器到期,可以恢复执行。
  • 已完成:协程return,回收资源。

每次循环迭代,事件循环调用底层IO轮询函数,拿到所有“就绪”的事件,然后依次恢复对应的协程。这样,单个进程就可以同时监听上百个网络连接,每个连接都对应一个协程,连接之间互不阻塞。

我对接过的某个服务商API,平时响应时间在300毫秒到3秒之间波动。同步循环里,假如有10个请求,最坏情况下总耗时是10个请求响应时间之和;用事件循环并发发出10个请求后,总耗时等于最慢的那个请求耗时。这个收益是质的飞跃。

2.3 非阻塞IO封装:底层是系统调用,上层是同步写法

TrueAsync最聪明的地方在于它把非阻塞IO封装成了几乎同步的API。你调用TrueAsync\Http::get()时,它内部做了几件事:

  1. 创建一个非阻塞socket。
  2. 发起HTTP连接请求,设置好请求头。
  3. 立刻返回一个Future对象,注册到事件循环。
  4. 调用->await()时,如果请求还没完成,就让出协程。

你不需要关心socket是阻塞还是非阻塞,也不需要手动管理连接状态。这个封装思路和JavaScript的Promise非常类似,但在PHP里它是通过生成器/Fiber实现的。

我还需要提醒一点:TrueAsync对CPU密集型任务并没有太大帮助。比如图片缩放、MD5计算、正则匹配这种纯计算操作,本身不涉及IO等待,协程切过去还是在占用CPU。过度创建协程反而会增加调度开销。所以它最适合的是“IO密集”场景,而不是“CPU密集”场景。对于CPU密集片段,还是得配合其他手段,比如任务队列分发给多个Worker进程。

3. 快速上手:从同步脚本改造成TrueAsync并发脚本

我假设你已经在一个可以用Composer管理依赖的PHP项目里。下面直接给步骤和代码,先跑通再理解。

3.1 环境准备与安装

TrueAsync需要PHP 8.0以上版本,因为底层用到了Fiber,同时需要pcntl扩展支持进程控制,openssl扩展支持HTTPS请求。建议PHP 8.2以上,Fiber行为更加稳定。

安装命令行如下:

composer require trueasync/trueasync

装完之后,检查扩展:

php -m | grep -E "pcntl|openssl"

确认输出里同时包含pcntl和openssl。如果没有,请打开php.ini里对应的扩展项,或者在编译PHP时加上--enable-pcntl。

Windows环境对pcntl支持有限,建议开发环境用Linux或macOS,生产环境用Linux服务器。

3.2 第一个TrueAsync脚本:并发请求三个API

我们先写一个最简单的并发HTTP请求示例:

<?php require 'vendor/autoload.php'; use TrueAsync\Coroutine; use TrueAsync\Http; $requests = [ 'https://api.example.com/user/1', 'https://api.example.com/user/2', 'https://api.example.com/user/3', ]; $begin = microtime(true); $results = Coroutine::run(function () use ($requests) { $futures = []; foreach ($requests as $url) { $futures[] = Http::get($url); } // 并发等待所有请求完成 return TrueAsync\Wait::all($futures)->await(); }); $end = microtime(true); echo "耗时: " . round(($end - $begin), 3) . "秒\n"; print_r($results);

这个脚本的关键点:

  • Coroutine::run()接受一个闭包,闭包内部自动变成协程。
  • Http::get()会立刻发起请求,不阻塞当前线程。
  • Wait::all()返回一个新的Future,这个Future在所有子请求都完成时变为完成状态。
  • 调用->await()让出执行权,等待所有请求返回。

同步版本是这样写的:

foreach ($requests as $url) { $results[] = file_get_contents($url); }

如果三个接口平均响应时间都是0.5秒,同步版总耗时约1.5秒;TrueAsync并发版总耗时约0.5秒,提速3倍。接口数量越多、响应时间越长,提速越明显。

3.3 带超时控制:防止某个接口拖死全盘

异步并发最怕“一个慢请求让所有等待白费”。外部服务偶尔卡住是常态,所以必须给每个请求设置超时。

use TrueAsync\Timeout; $futures = []; foreach ($urls as $url) { $futures[] = Http::get($url)->timeout(2.0); } $results = []; foreach ($futures as $future) { try { $results[] = $future->await(); // 单个请求超过2秒抛超时异常 } catch (TimeoutException $e) { $results[] = ['error' => 'timeout', 'url' => $future->getUrl()]; } }

这里每个请求的超时时间是独立计算的。2秒超时时间一到,这个请求的协程会被事件循环强制唤醒,并抛出一个超时异常。其他还没超时的请求完全不受影响。

我见过不少踩坑案例:整个并发块设置了一个总超时,导致单个接口超时后其他正常请求也被放弃。正确的做法是给每个Future单独设置超时,再根据业务决定整体行为。

3.4 并发控制:不要一次性创建一万个协程

如果任务清单特别长,比如要抓取一万个商品页面,一次性全部并发会耗尽文件描述符和内存。需要加一个“并发窗口”,同一时间最多运行固定数量的协程。TrueAsync提供了一个简单的并发限制器:

use TrueAsync\Concurrency; $concurrency = 50; // 同时最多50个请求 $tasks = range(1, 10000); $results = Concurrency::map($tasks, function ($id) { $html = Http::get("https://api.example.com/product/{$id}")->await(); return ['id' => $id, 'len' => strlen($html)]; }, $concurrency);

Concurrency::map()的行为类似array_map(),但会对任务队列做并发控制。当前批次的50个请求完成后,会自动补充接下来50个。这样无论任务总量多大,同一时刻占用的socket和内存都保持在可控范围。

并发窗口不是越大越好。我实测过,在默认配置的Linux服务器上,同时开200个HTTP连接时,CPU消耗和Nginx连接数都会涨得比较厉害。对普通VPS主机,50到100比较合适;对高配置服务器,可以测试200到500。你要观察两个指标:脚本内存占用和本机打开文件数上限(ulimit -n)。

4. 实战案例:三个典型场景的TrueAsync改造过程

理论说再多,不如实际跑一遍。我挑三个有代表性的项目场景,完整描述从同步到异步的改造过程和效果。

4.1 案例一:API聚合接口,从5秒降到0.8秒

业务场景:移动端App的个人中心需要同时展示用户信息、订单列表、优惠券数量、消息未读数。这四个数据分别来自四个不同的微服务接口。传统做法是依次调用四个接口,总耗时等于四次调用时间之和。

改造成TrueAsync后:

$futures = [ 'user' => Http::get('http://user-service/api/profile')->timeout(1.0), 'orders' => Http::get('http://order-service/api/list')->timeout(1.0), 'coupons' => Http::get('http://coupon-service/api/count')->timeout(1.0), 'messages' => Http::get('http://message-service/api/unread')->timeout(1.0), ]; $all = TrueAsync\Wait::all($futures)->await(); // 组装响应 $response = [ 'user' => json_decode($all['user']->getBody(), true), 'orders' => json_decode($all['orders']->getBody(), true), 'coupons' => json_decode($all['coupons']->getBody(), true), 'messages' => json_decode($all['messages']->getBody(), true), ];

最终接口总耗时只取决于最慢的那个微服务。原来5秒的接口降到了0.8秒左右,而且当其中一个微服务超时,其他三个数据仍然能正常返回,极大地提高了App端的可用性。

4.2 案例二:批量更新库存,从串行循环改成并发窗口

业务场景:每晚定时任务同步供应商库存。供应商提供一个查询所有商品的接口,但一次最多只能查100个商品。总共有2万个商品,需要调用200次接口。

同步版本代码:

$allProducts = []; for ($page = 1; $page <= 200; $page++) { $data = httpGet("https://supplier.example.com/api/stock?page={$page}"); $allProducts = array_merge($allProducts, $data['items']); }

每次请求耗时约0.7秒,200次就是140秒,脚本执行时间超过2分钟,经常被运维告警。改成TrueAsync并发窗口后:

$pages = range(1, 200); $allProducts = Concurrency::map($pages, function ($page) { $json = Http::get("https://supplier.example.com/api/stock?page={$page}") ->timeout(5) ->await(); return json_decode($json, true)['items']; }, 30);

30个并发窗口,每次最多同时发30个请求,200个任务大约7轮完成。每轮0.7秒,总共5秒左右。同时因为并发窗口的存在,不会对供应商服务器造成过大压力,服务器也不会因为瞬间200个连接而拒绝服务。改造后这个定时任务稳定跑了大半年,没再出现过超时告警。

4.3 案例三:队列消费者处理外部回调

业务场景:订单支付成功后,需要调用支付渠道的查询接口核实支付结果,再更新本地订单状态。之前用同步方式循环消费队列,每处理一个订单要等支付渠道响应,一秒最多处理1到2个订单。

改造后消费者循环变成这样的结构:

while (true) { $orderId = $queue->pop(); if ($orderId === null) { TrueAsync\Sleep::millisecond(100)->await(); // 没有任务时让出CPU continue; } $future = Coroutine::async(function () use ($orderId) { $result = Http::get("https://pay-gateway.example.com/query?order_id={$orderId}") ->timeout(3) ->await(); $order = parseOrderResult($result); updateOrderStatus($orderId, $order['status']); }); // 每达到50个并发任务时,等一等这批次完成 if (++$pendingCount >= 50) { TrueAsync\Wait::all($pendingFutures)->await(); $pendingFutures = []; $pendingCount = 0; } }

真实效果:单进程处理能力从每秒1到2单提升到每秒20到30单,而且没有增加额外的服务器。瓶颈从PHP脚本变成了支付渠道网关的限流阈值。这个案例里最大的收益不是“快”,而是“可预测”:任务处理速率变得稳定,不会因为某个渠道响应慢而积压整个队列。

4.4 改造过程的通用套路

从上面三个案例可以总结出一个通用套路:

  1. 找出脚本里所有的“外部IO等待点”:HTTP请求、数据库查询、文件读写、进程调用。
  2. 把每个IO等待点封装成一个Future,先创建好,不要立即await。
  3. 如果任务之间没有依赖关系,就用Wait::all并发等待。
  4. 如果任务数量巨大,套一层Concurrency::map限制并发窗口。
  5. 给每个Future设置超时,单点失败不影响整体。
  6. 观察改造前后的内存和文件描述符变化,确定合理并发数。

这套方法不仅适用于TrueAsync,也同样能套用到其他异步框架里,核心思想是一致的。

5. 常见问题与排查技巧实录

TrueAsync用起来顺手,但并不是没有坑。下面这些问题是社区里问得最多、我自己也踩过的,按重要程度排序整理。

5.1 协程内用了阻塞函数,整个事件循环被卡住

这是最隐蔽的问题。你在代码里写:

$data = file_get_contents('https://api.example.com'); // 阻塞!

而不是:

$data = Http::get('https://api.example.com')->await(); // 非阻塞

那么事件循环会被这个阻塞调用卡住。因为file_get_contents不仅阻塞当前协程,还会阻塞整个进程里的所有协程。表面上脚本没有报错,但你发现并发效果消失了,所有请求退化成串行执行,甚至比同步还慢。

排查方式:观察脚本执行时间曲线,如果协程并发数上去后总耗时没有按预期下降,优先检查是否存在原生阻塞函数。常见的坑包括file_get_contents、curl_exec、mysqli_query的同步模式、sleep()、shell_exec()。

对策:凡是涉及IO的原生同步调用,都替换成TrueAsync提供的异步版本。没有异步版本时,把任务丢给独立的Worker进程去跑,通过消息队列或者进程管道返回结果。

5.2 超时时间设置太短导致正常请求被误杀

有一次我优化某个报表接口,给每个下游查询设置了1秒超时。结果发现报表经常数据缺失。检查日志才知道,下游数据库正常查询偶尔需要1.2秒,被超时误杀了。

超时时间要根据服务响应时间的P90、P99分布来设置,而不能只看平均值。简单做法:先不做超时限制,压测跑一批请求,统计响应时间分布,然后设定一个比P99稍高的值。比如P99是2秒,超时设置成3秒;P99是5秒,就设置成8秒,留足余量。

我自己的经验是:外部HTTP调用超时不要低于2秒,数据库查询超时不要低于5秒,写操作超时要比读操作更宽松一点。太短的超时带来的问题比超时本身更麻烦。

5.3 内存泄漏与回调地狱:长时间运行任务的内存管理

TrueAsync协程在执行完毕后会把相关的Future对象和上下文回收,但如果长时间运行的进程里不断创建新的协程,内存仍然可能缓慢上涨。常见原因:

  • 闭包内引用了外部大变量,协程结束后引用没有释放。
  • 全局静态数组里堆积了Future对象,从未清理。
  • 日志对象在协程中传递,日积月累占满内存。
  • PHP的Fiber在某些情况下持有栈内存,频繁创建销毁会产生碎片。

排查手段:给脚本加上内存监控,每个固定任务数打印一次memory_get_usage(true),观察趋势。批量任务中若内存持续上升且不回落,就要查引用了。

我常用的规避方式:

  • 在循环里主动unset($future)。
  • 不用static数组缓存协程对象。
  • 长任务每处理一定数量后,重启Worker进程,保证内存彻底释放。

5.4 并发数过高导致服务器文件描述符耗尽

每个TCP连接都会占用一个文件描述符。默认的ulimit -n通常是1024,如果并发协程数设置为500,再加上数据库连接、日志文件句柄,很快就达到上限,报错信息通常是“Too many open files”。

解决方式有两种:

  • 调高系统限制:修改/etc/security/limits.conf,把nofile调高到65535。
  • 降低并发窗口:组件内部用Concurrency::map控制并发数。

在生产环境,我建议两种都做:系统上限调到一个足够大的稳定值,业务层仍然保留并发窗口,防止某个异常任务一下吃掉所有连接。

5.5 常见问题速查表

现象可能原因处理方式
并发效果未生效,所有任务串行执行代码里混用原生阻塞函数全部替换为TrueAsync异步API
脚本内存持续上涨协程引用未释放、静态缓存堆积主动unset,定期重启任务进程
报错Too many open files文件描述符超限调高ulimit,降低并发窗口
超时误杀正常请求超时阈值设置过低根据P99响应时间设置超时
协程内使用sleep导致卡顿原生sleep阻塞整个事件循环改用TrueAsync\Sleep
HTTPS请求握手缓慢目标服务器TLS协商慢启用连接池与HTTP长连接
外部接口偶尔返回空数据超时后响应为空,原因被吞掉捕获超时异常并记录完整上下文
多进程+Fork混用异常协程状态在Fork后不一致避免在协程环境中使用pcntl_fork

这个速查表是从项目实践经验里浓缩出来的,不是文档里的官话。遇到问题先对着看,能解决大部分日常异常。

6. 再聊几句我的实际体会

做PHP这么多年,我见过太多因为“PHP天生阻塞”而放弃PHP转投其他语言的开发者。但我觉得,更多的场景是我们没有把异步能力用起来。TrueAsync这类协程方案让我重新认识了一个事实:PHP不是不能异步,而是之前很少有人把异步运行时做得到位。

就我个人的使用经验来说,以下几条建议值得你拿走:

第一,改造优先从“批量IO”场景入手,不要一开始就重构核心业务。比如定时任务、批量推送、数据同步,这类边界清晰的任务,改造成本低、收益大,跑稳定了再考虑把接口聚合也套上。

第二,保持简单。异步代码不需要过度设计。能用Wait::all解决就不用自研调度器,能用一个并发窗口就不用多级队列。复杂的异步架构一旦出事,排查成本比收益高得多。

第三,监控一定要跟上。异步脚本出问题时往往不是直接报错,而是“变慢”“内存涨”“连接耗尽”这种慢性的恶化。在日志里记录每次运行的耗时、内存峰值、并发任务数,观察趋势比看单次结果更重要。

第四,多进程+协程配合使用。单进程协程能解决IO等待,但如果机器有多核CPU,仍然建议按CPU核心数启动多个Worker进程,每个Worker内部再用协程跑并发任务。这样CPU和IO都被充分利用,性能才能最大化。

这篇文章从阻塞的原因、TrueAsync的原理,到实战案例和排查经验都串了一遍。如果你手头正好有一个饱受同步阻塞折磨的PHP项目,建议照着第三部分的案例先写个Demo,观察耗时和内存变化,再逐步推广到更多场景。真跑起来之后,你会回来感谢那个花了半小时读完这篇长文的自己。

最后再分享一个小技巧:改造过程中不要一次性把所有IO函数替换掉,而是先给项目中所有外部调用点列个清单,然后一个模块一个模块替换。每次替换后跑一次回归测试,记录性能对比。这样做的好处是,万一性能没升反降,你能立刻知道是哪个模块引入的问题,回滚成本极低。我每次做这类优化都坚持这个习惯,稳得很。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 5:40:06

Agentic Harness Workflow:将AI Coding升级为工程化流水线的实践框架

坦率讲&#xff0c;哪怕到今天&#xff0c;我依然看到很多团队把 AI Coding 用成了“高级补全工具”&#xff1a;人开一个对话&#xff0c;把需求贴进去&#xff0c;等模型吐出一段代码&#xff0c;再手动复制回仓库&#xff0c;跑一下发现报错&#xff0c;又贴回去让它改。这种…

作者头像 李华
网站建设 2026/10/14 5:39:45

VC++模拟鼠标单击与双击:从消息机制到SendInput实战

简介&#xff1a;这份VC/MFC源代码资源聚焦Windows系统下的鼠标消息模拟&#xff0c;面向具备一定C基础、希望理解鼠标单击与双击底层响应机制的开发者。工程在窗体上布置若干按钮&#xff0c;通过点击按钮触发对鼠标单击、双击行为的模拟&#xff0c;帮助读者把消息映射、窗口…

作者头像 李华
网站建设 2026/10/14 5:39:42

Discuz关注功能开发实战:从数据表到前端交互

做Discuz开发的朋友&#xff0c;多多少少都经历过这样的需求&#xff1a;论坛里用户想要“关注某人”&#xff0c;关注之后能在个人中心看到自己关注了谁、谁又关注了自己&#xff0c;甚至希望能收到被关注对象的动态提醒。这个功能在主流社交平台里是标配&#xff0c;但在Disc…

作者头像 李华
网站建设 2026/10/14 5:39:36

网络安全通信方案推选PPT实战:从选型框架到评审问答

简介&#xff1a;这是一份关于虎符科技网络安全通信服务三种解决方案的PPT资源&#xff0c;面向关注网络身份认证、通信加密及安全通信平台建设的安全工程师与方案决策者。内容围绕标识认证技术展开&#xff0c;重点介绍基于组合公钥的超大规模自证安全系统&#xff0c;以及链路…

作者头像 李华
网站建设 2026/10/14 5:39:01

iBizEAM源码部署与定制化实战指南

简介&#xff1a;iBizEAM设备资产管理系统是一套面向中大型企业IT运维与资产管理场景的开源JavaVue全栈解决方案&#xff0c;适用于具备SpringBoot、Vue及前后端分离开发经验的中高级开发者学习与二次开发。资源包共2000个文件&#xff0c;主体为1280个Java后端服务模块、1746个…

作者头像 李华
网站建设 2026/10/14 5:38:58

从控制器到工具法兰全面焕新:UR Gen 7工博会中国首展,CB7控制器与PolyScope X重构机器人编程

以“智能经济 智造无界”为主题的第二十六届中国国际工业博览会10月12日在上海国家会展中心启幕。本届工博会聚焦具身智能、工业大模型与数字孪生&#xff0c;近300项首发首秀展品集中亮相&#xff1b;机器人展以“具身工业 智领未来”为主题&#xff0c;5.6万平方米展区迎来40…

作者头像 李华