news 2026/9/9 6:36:30

开源Web SCADA/HMI平台FUXA的Docker部署与可视化实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
开源Web SCADA/HMI平台FUXA的Docker部署与可视化实战

之前有个现场需求,客户要求在一面大屏上实时展示车间设备状态,不仅办公室要看,产线旁边还得摆几台平板随时点按操作。传统思路是上组态软件,可授权费不便宜、Windows 部署也重,还得绑定固定的显示终端。后来我在这类项目里改用 FUXA 这个开源 Web SCADA/HMI 组态平台,配合 Docker 部署,从拉镜像到出第一个可视化画面,基本二十分钟就能干完。这篇文章就记录我实际部署、接线、做画面的完整过程,以及那些文档里不会写清楚的坑。

FUXA 对我这种经常要快速交付监控界面的场景来说,价值很直接:它把传统组态软件里的“数据采集”和“画面组态”搬到了浏览器里,服务器端负责采集设备数据,前端负责拖拽式画面设计。而且官方提供 Docker 镜像,部署环节被大幅压缩。你不需要在自己的电脑上装 Node.js 环境,也不用折腾 npm 依赖,一条 docker run 就能把整个平台跑起来。这篇文章适合三类人:一是刚接触 SCADA/HMI,想找个免费好上手的平台练手的工控工程师;二是前端或全栈开发,需要在短时间内部署一个可视化的数据监控后台;三是做设备配套项目的朋友,要给客户交付一套能远程看、能分组管理的监控系统。

1. 先认清 FUXA 是什么,以及为什么这套组合值得用

1.1 一句话理解 FUXA:浏览器里的组态软件

组态软件这个词,老工控人都熟悉,像 WinCC、组态王、iFIX 都是这一类,干的事就是连接设备数据、画监控画面、做报警记录。FUXA 做的事情基本一致,但它把整个系统做成 B/S 架构,也就是服务器端 + 浏览器端。你在服务器上跑一个 FUXA 服务,任何一台能上网的电脑或平板,打开浏览器输入地址就能看到监控画面,不需要额外安装客户端,不需要授权加密狗,更不需要装一堆运行库。

FUXA 本身用 Node.js 和 Angular 开发,开源协议是 MIT,这意味着你拿它做商业项目、二次开发都没有授权成本。对项目型公司来说,这点很关键,方案里省去一笔不小的组态软件授权费,投标和交付的压力都会小很多。技术上,它原生支持的设备协议也不少:Modbus RTU/TCP、OPC UA、Siemens S7、BACnet 等,基本覆盖了常见的 PLC、仪表和楼宇设备。更实用的是它自带一个可视化的画面编辑器,可以直接在网页上拖控件、画管线、搭工艺图,不用写一行前端代码。

我自己的理解是,FUXA 比较像把“组态软件”和“Web 前端框架”揉在了一起,但它做得足够轻,我拉起来跑一个几百点的小项目,内存占用也就一百多兆,比开一个虚拟机装 Windows 再跑组态软件轻太多。

1.2 用 Docker 跑 FUXA,解决的是环境问题和交付问题

直接跑 FUXA 也不是不行,官方文档也给了 npm 启动的方式,但我强烈推荐用 Docker,原因不是装腔,而是环境太烦了。FUXA 依赖 Node.js,而且对版本有要求,我曾经在一台 Ubuntu 服务器上为了装 FUXA,先折腾 Node 版本切换,又遇到 npm 安装编译慢,最后还在 Python 版本的坑里耗了半天。用 Docker 之后这些全没了,镜像把 Node 运行时、依赖包、应用代码全部打包好,拉下来只管跑。

另一个我觉得很值的地方是交付。给客户部署系统的时候,我只要把 docker-compose.yml 文件和一个数据目录复制过去,执行一句 docker compose up -d,系统就起来了。即便客户要换服务器,迁移成本也极低,把数据目录一打包,到新机器上再跑一次命令就完成迁移。相比之下,传统组态软件迁移要考虑授权重新激活、运行库版本、数据库驱动,能折腾一整天。

升级和回滚也方便。FUXA 官方镜像有版本标签,我固定某个版本跑,等确认新版本功能没问题后,只需拉新镜像重建容器。万一升级出问题,还能用旧镜像秒回滚。这一步在传统组态系统里几乎没有这么干净的方案。

1.3 适合哪些场景,哪些场景不适合硬上

用了一段时间后,我总结 FUXA 适合的场景和不太适合的场景,方便大家判断。

适合的场景不适合的场景
中小规模的数据采集监控,几十到几百个数据点要求高可用、冗余架构的大型 SCADA 系统
设备配套的可视化大屏、状态看板对亚秒级实时性有苛刻要求的控制场景
快速原型验证、教学演示、实验室监控需要复杂批次管理、高级报表引擎的场景
给客户做一套可远程访问的轻量监控界面涉及关键工艺安全联锁的控制系统
需要跨平台访问,手机平板都要看的情况和西门子 WinCC 深度耦合、大量使用脚本的存量系统

注意,FUXA 再怎么说也是个开源项目,别指望它能直接替代大型工业 SCADA。如果你的项目涉及安全联锁、核心工艺闭环控制,该上专业控制系统还得上。FUXA 更适合做“看得见、管得着”的监控展示层,数据采集走它没问题,但控制功能要谨慎,我一般只让它写少量非关键设定值,关键操作还是留给 PLC 逻辑和正牌 HMI。

2. 部署前的准备:镜像、端口、数据卷三件事先想清楚

2.1 官方镜像与版本选择

FUXA 官方镜像在 Docker Hub 上,名字是fuxa/fuxa,直接docker pull fuxa/fuxa就能拉。不过这里有个经验,别直接用latest标签,因为latest的更新不受控,你昨天跑得好好的,今天重新拉一次镜像可能就变成新版本了,新版本的行为变化可能让你的画面配置突然出问题。我习惯在确认某个版本能正常满足需求后,就把镜像 tag 固定下来,比如fuxa/fuxa:2.0.5这种形式(具体 tag 以 Docker Hub 上实际存在的为准)。

如果你对版本不敏感,刚开始只是想体验一下,那用latest也没问题。但一旦进入正式项目,建议把版本固定,并且把 tag 写进 docker-compose 文件里,这样每次部署都确定,回滚也有明确目标。

另外提一句,Windows 环境下建议先装 Docker Desktop,Mac 和 Linux 则直接用各自的 Docker Engine 就行。安装好之后先确认docker version能正常输出,再继续后面的步骤。

2.2 端口、数据卷、时区这三个参数背后的逻辑

部署 FUXA 需要关心的核心配置项,就三个:端口、数据卷、时区。

先说端口。FUXA 容器内部的默认 Web 服务端口是 1881,启动时要把宿主机的某个端口映射到容器的 1881。映射哪个端口由你决定,想用 80 端口直接访问就写-p 80:1881,但要注意宿主机 80 端口可能被 Nginx 或其他 Web 服务占用。我一般保留 1881 作为内网直接访问的端口,对外统一用 Nginx 反代。

然后是数据卷,这个最关键。FUXA 的系统配置、项目文件、SQLite 数据库、报警记录、仪表盘配置统统写在容器内的/data目录。如果不做数据卷映射,容器一旦被删除重建,你之前画的画面、建的设备、配的标签全都没了。这是新手最容易踩的坑,很多人调试了半天,最后因为重建容器导致所有配置归零,心态直接崩。所以必须把/data挂载出来,可以用具名数据卷,也可以直接挂到宿主机某个目录,比如./fuxa-data:/data。我个人倾向于挂宿主机目录,因为备份只需要拷贝一个文件夹。

最后是时区。FUXA 容器默认可能使用 UTC 时区,如果你不设置TZ环境变量,历史趋势和时间戳会显示成标准时间,和北京时间差 8 小时。表面看没什么,等你真要排查报警时间或者做报表统计,就会发现所有时间都对不上。所以启动时环境变量TZ=Asia/Shanghai建议直接带上。

2.3 docker run 与 docker-compose 两种落地方式

为了让大家直接抄作业,我给两份配置。先是最简单的 docker run 方式:

docker pull fuxa/fuxa docker run -d --name fuxa \ -p 1881:1881 \ -v ./fuxa-data:/data \ -e TZ=Asia/Shanghai \ --restart unless-stopped \ fuxa/fuxa

解释一下每个参数的作用:-d表示后台运行,--name fuxa给容器起名,-p 1881:1881映射端口,-v ./fuxa-data:/data把当前目录下的 fuxa-data 目录挂载成容器里的数据目录,-e TZ=Asia/Shanghai设置时区,--restart unless-stopped让容器在服务器重启后自动拉起。这里./fuxa-data是相对路径,建议改成绝对路径,避免以后在别的目录执行命令找不到挂载点。

我个人更推荐 docker-compose 方式,因为可读性和可维护性更好。创建一个项目目录,比如/opt/fuxa,在里面放一个docker-compose.yml

version: '3.8' services: fuxa: image: fuxa/fuxa:2.0.5 container_name: fuxa ports: - "1881:1881" environment: - TZ=Asia/Shanghai volumes: - /opt/fuxa/data:/data restart: unless-stopped

然后在/opt/fuxa目录下执行docker compose up -d,服务就起来了。后续查看日志用docker compose logs -f fuxa,停止用docker compose down。这种方式的另一个好处是,整个部署配置就是一个文本文件,放在项目里跟代码一起管理,后面给客户移植环境也省事。

如果你在拉镜像时遇到下载慢的问题,可以去配置一下 Docker 镜像加速器。Linux 上编辑/etc/docker/daemon.json,加上registry-mirrors配置,然后重启 Docker 服务。这是国内网络环境下比较常见的优化手段,注意配置完要确认 docker info 里能看到你设置的镜像加速地址。

3. 启动 FUXA 并完成首个可视化页面

3.1 启动、登录与初始化配置

容器起来之后,浏览器访问http://服务器IP:1881,就能看到 FUXA 的登录界面。首次访问时系统会引导你创建管理员账号,新版本基本都会要求设置用户名和密码,建议一开始就用一个强密码。老版本里可能存在默认的 admin/admin,如果你用的版本还能用默认账号登录,登录后第一件事就是改掉密码。

登录成功后看到的就是 FUXA 的主界面,左侧是主导航区,包含 Projects(项目管理)、Data Tags(数据标签)、Devices(设备)、Alarms(报警)等模块,中间和右侧是内容展示区。第一次进来可能有点空,但界面结构不难理解。我建议步骤是:先建一个 Project,相当于一个独立的应用空间;然后在 Project 下创建设备和数据标签;最后在 Dashboard 或者画布上开始设计画面。

FUXA 的整体概念可以类比成传统组态软件里的“工程管理”:Project 就是工程,Devices 就是下面挂的 PLC 或仪表,Data Tags 是这些设备的寄存器点位,Dashboard 就是画面。搞清楚这个对应关系,后面操作就顺了。

3.2 连接第一个数据源:Modbus TCP 从零配置

我第一次部署 FUXA 时,最想干的事就是赶紧接一台真实的 Modbus 设备看看数据能不能读到。这里以最常见、最容易测试的 Modbus TCP 为例,把配置流程走一遍。

先准备一个支持 Modbus TCP 的设备或者用模拟器替代,确认 IP 能 ping 通,端口 502 能访问。进入 FUXA 的设备管理界面,点新增设备,选择协议类型为 Modbus TCP,填上设备的 IP 地址。端口默认 502 一般不用改,然后设置轮询间隔(Polling Time),我通常设 500ms,如果设备数量多、通信压力大,会放宽到 1000ms。轮询时间设置这里有个权衡:太短会加重设备通信负担,太长页面数据刷新不够及时。一般监控类应用 500ms 到 1000ms 足够。

设备创建好之后,在设备下面添加数据标签(Tag)。这里需要明白一个关键点:FUXA 的 Tag 就是你要采集的具体数据点,每个 Tag 要指定寄存器类型、地址、数据类型等信息。以 Modbus 保持寄存器为例,填写时需要把寄存器起始地址搞清楚。很多设备手册上写的地址是 40001、40002 这种偏置后的“协议地址”,但 FUXA 里填的地址是从 0 开始的 Modbus 地址。也就是说,手册里的 40001 对应 FUXA 里的地址 0,40002 对应地址 1,这个偏移量是新手最容易搞错的地方。

还有数据类型的选择。默认情况下可能按 16 位整数处理,但如果你读的是压力、温度这种带小数的模拟量,设备端多半是 32 位浮点数,占用两个连续寄存器。这时候不仅要把数据类型选成 Float,还要注意字节顺序。字节序错了,读出来的数值会是天文数字或者完全不对,这个问题我在后面常见问题里专门展开。

配置好 Tag 之后,回到项目界面,给 Project 添加这些 Tag。注意,数据标签添加到设备下还不够,工程里要用到的点位,需要把它们关联到 Project 下,画面绑定数据的时候才能搜到。

3.3 画面编辑器的核心操作:拖控件、绑数据、做交互

数据通了之后,接下来就是画监控画面。FUXA 的画面编辑器是我觉得它做得最接近传统组态软件的地方。新建一个页面或者 Dashboard 后,从右侧控件库拖拽图形到画布上,可以用线条画管道、用矩形画设备、用文本做标注,整个操作跟画图软件差不多。

控件的属性面板可以设置外观、位置、尺寸,最关键的是数据绑定(Data Binding)。选中一个控件,点击绑定按钮,搜索你要绑定的 Tag,确认后这个控件就会实时显示对应数据点的值。如果你要画一个电机状态,拖两个圆和一段文字,把颜色变化绑定到电机运行的布尔量 Tag 上,运行状态和停止状态用不同颜色区分,这样画面动态效果就出来了。

我习惯把整个画面分成几个区域:设备状态区用指示灯和颜色块,趋势区放历史曲线图,操作区放按钮和输入控件。趋势图控件绑定对应 Tag 后,能直接看到最近时间段的数据曲线,这在现场调试时非常好用。

交互操作方面,按钮可以配置点击事件,比如点击按钮往某个保持寄存器写一个数值。这里的坑点是,你要明白 FUXA 写值默认是针对 Tag 的写操作,如果设备的寄存器是只读的,写入就会失败。遇到“按钮点了没反应”的情况,先别怀疑控件,先去设备管理页面看这个 Tag 当前有没有显示 Connected,再看设备侧寄存器是否允许写入。

关于热词里有人提到的 FUXA 中 Select Value 控件的使用,我实际用下来场景比较多的是设定值切换和配方选择。拖一个 Select Value 控件,在属性里配置选项列表,比如“低速、高速、自动”三个选项,每个选项对应一个要写入的值,然后把它绑定到要写值的 Tag 上。操作员在下拉列表里选择一项,FUXA 就把对应值写入该 Tag。启用这个控件前,一定确认目标寄存器支持写入,否则选了也没反应。

4. 生产环境化:反向代理、认证与数据备份

4.1 用 Nginx 反代并支持 WebSocket

FUXA 在局域网里直接用 IP 加端口访问没问题,但如果要把系统暴露到公网,或者想统一入口管理多个 Web 服务,就需要在前面加一层 Nginx 反向代理。这里有个技术重点:FUXA 的实时数据推送用了 WebSocket 技术,反代配置必须支持 WebSocket 升级,否则页面能打开,但数据不会实时刷新。

我用的 Nginx 配置大致是这样:

server { listen 80; server_name your-domain.com; location / { proxy_pass http://127.0.0.1:1881; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 3600s; } }

关键就是UpgradeConnection这两个头,不能丢。proxy_read_timeout我设置得比较长,因为 FUXA 的 WebSocket 长连接如果超时断开,页面上的数据就会停止刷新,又要自动重连。如果你发现反代之后数据不更新,八成是 WebSocket 没代理对,回到配置里检查这两个头。

如果对外使用 HTTPS,我通常会顺手配一下证书,用标准的 certbot 申请证书和自动续期。FUXA 本身不强制 HTTPS,但只要系统出了内网,强烈建议把 HTTPS 打开,否则用户名密码和设备数据全部明文传输,风险很大。

4.2 用户权限与远程访问安全

FUXA 自带用户管理功能,支持 Admin、Engineer、Operator 等角色。默认角色权限差别在于:Admin 能管理一切,Engineer 通常可以改配置和画面,Operator 基本只能看图操作。生产环境里,我建议给现场操作人员分配最低权限的账号,不要让他们拿到管理员权限。这样即便操作工误操作,也只是修改了运行数据,不至于把整个工程的配置改坏。

远程访问的安全除了账号密码,我还建议在网络层做限制。如果系统只给内部使用,可以在防火墙或者安全组里只放开办公室网段的 IP;如果一定要公网访问,配合反向代理加 IP 白名单,或者在前面加一层 Basic Auth。注意,任何暴露在公网的管理后台,默认账号密码不改,就是给自己埋雷。FUXA 部署完,管理员密码必须改,且不要和别的平台共用密码。

另外,如果你把 1881 端口直接映射到公网,而且没加任何反代和认证保护,那就等于把生产监控系统赤裸裸暴露在互联网上,这属于安全底线问题,千万别犯。

4.3 数据备份与容器升级

FUXA 的所有配置和运行数据都在/data目录里,所以备份这件事就变得特别简单:拷贝这个目录即可。但直接拷贝运行中的 SQLite 数据库可能得到不一致的结果,我建议备份前先停掉容器,或者用 docker 命令把目录复制出来。例如:

docker exec fuxa tar czf /tmp/fuxa-backup.tar.gz /data docker cp fuxa:/tmp/fuxa-backup.tar.gz ./ docker exec fuxa rm -f /tmp/fuxa-backup.tar.gz

这是在线备份的一种方式,能保证文件处于静止状态。更稳妥的办法是每天晚上用 crontab 执行自动备份,备份文件保留最近七天。

升级容器的步骤也很简单:先备份当前数据目录,然后拉取新版本镜像,用新的 tag 更新 docker-compose 文件,再执行docker compose up -d重建容器。重启后登录系统,检查几个关键画面和设备连接情况,确认没问题再把旧镜像清理掉。如果出现问题想回滚,把之前固定的镜像 tag 改回去,重新 up 一次即可。整个升级过程最快几分钟完成,这比传统组态系统的升级体验好太多了。

5. 常见问题排查与技术细节实录

5.1 配置保存丢失、设备连不上的几个经典场景

用 Docker 部署 FUXA 后,大部分问题都集中在配置持久化和设备通信上。我这里把实际遇到过的高频问题整理成一张速查表,方便大家对应排查。

现象大概率原因解决方法
容器重建后配置全部丢失没有挂载/data数据卷重新创建容器,用-v或 compose 挂载宿主机目录
容器启动失败,端口冲突1881 被占用换一个宿主机端口映射,如-p 1882:1881
设备状态一直离线防火墙挡了 502 端口宿主机和目标的中间网络放行 Modbus TCP 502
页面能打开,但设备数据不刷新反代没有转发 WebSocket检查 Nginx 的 Upgrade 和 Connection 头
数据读取的是乱码或超大数值字节序、寄存器类型、数据类型配置错误根据设备手册核对 Tag 类型和字节顺序

这里面设备连不上是最常见的。如果是 Modbus TCP,先做两层检查:宿主机上用工具测试到设备 502 端口的联通性,再用 Modbus 测试客户端读一次寄存器,看返回是否正常。如果外部工具能读到,FUXA 却读不到,多半是 Tag 配置里的地址或协议参数不对。

如果是西门子 S7 系列,FUXA 用 S7 协议连接时,还要填对的机架号(Rack)和槽号(Slot)。很多 S7-1200/1500 PLC 默认设置是 Rack 0、Slot 1 或 Slot 2,但这些值在不同 CPU 上可能不同,配置前最好用官方工具确认一下。

5.2 数据读写不对?多半是地址、字节序和类型的问题

读到的数值完全不对,这是数据采集里最让人头大的问题。我举一个实际例子来拆解。假设设备 Registers 里存放了一个 32 位浮点数,两个寄存器的值分别是 0x42F6 和 0xE666,按 IEEE 754 换算应该是 123.4。如果 FUXA 按 16 位整数读,你会得到两个没意义的整数;如果把 32 位 Float 的字节顺序配错,比如寄存器的顺序反了,读出来的浮点数可能是几亿。所以遇到数据不对,第一步先确认数据类型选对没有,第二步再考虑字节序。

Modbus 的字节序问题可以这样理解:32 位数据在多个寄存器里存放,存在两种常见的排列方式,一种是高 16 位在前、低 16 位在后,另一种是反过来。FUXA 里一般有对应的选项,比如 Big Endian、Little Endian、Swapped Word 等。如果你发现读出来的浮点数量级完全不对,就去切换这些字节序选项,通常试一次就能测出来。调试技巧是现场用一个已知的恒定值来对比,比如把压力变送器抬到大气压,读到的值应当为 0 或 1 个标准大气压,如果完全对不上,就去改字节序。

还有一个容易忽略的点是缩放因子。很多仪表实际值=寄存器原始值 × 0.1 或 × 0.01,即设备端把小数放大后存在寄存器里。FUXA 的 Tag 配置里支持设置缩放系数(Scale),你可以在标签里配置“缩放因子”或者“增益”,读到的原始值乘以这个系数才是真实值。我在处理温度、湿度这类模拟量时,直接利用缩放配置把工程量转换在采集层做掉,画面上就不用再写公式了。

5.3 几个提升体验的进阶设置

部署熟练之后,有几个进阶设置值得做,能明显提升系统的稳定性和使用体验。

首先是容器资源限制。FUXA 本身很轻,但为了防止它在异常情况下吃掉服务器所有内存,我习惯在 compose 文件里加上资源限制:

deploy: resources: limits: memory: 512M

这个配置在 Docker Compose 中针对 swarm 模式语义有些区别,普通docker compose up情况下部分版本不生效,更稳妥的做法是 docker run 时加--memory=512m。Linux 的 Docker 支持 cgroup 限制内存,建议生产中加上,避免一个监控服务把整台服务器拖垮。

其次是日志清理。跑久了容器日志会持续增大,我一般会在 compose 里配置 log rotation:

logging: driver: json-file options: max-size: "10m" max-file: "3"

日志轮转看起来不起眼,但能在关键时刻救你一把。如果磁盘被日志塞满,SQLite 数据库写入会失败,那才是真正的大事故。

最后是在浏览器端的使用习惯。FUXA 的画面本质是 Web 页面,建议现场大屏用 Chrome 或 Edge,并且开启自动全屏,配好之后基本可以达到传统组态软件大屏展示的效果。如果在平板上用,把浏览器的地址栏自动隐藏,体验会好很多。偶尔发现页面加载慢,多半是浏览器缓存的旧版本资源,清一下缓存再刷新就好。

我在实际项目里用到现在的体会是,FUXA 加 Docker 的组合特别适合快速交付的设备监控和可视化场景。它最大的优点不是功能多强大,而是省心:部署省心、升级省心、迁移省心。如果你正在评估一个轻量级的 Web SCADA/HMI 方案,用它来做监控展示层的性价比确实不错。

最后分享一个小技巧:每次用 docker compose 重建容器前,我都习惯先把/data目录打个压缩包存到别处,成本一分钟,但能避免绝大多数“意外”。另外生产环境别用latest标签,把版本固定住,配合备份策略,这套东西才能真正放稳在机房里跑上几个月不用管。

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

VO2光学仿真:Matlab计算折射率并导入COMSOL的完整流程

最近做VO2微纳光学仿真时,我遇到一个很现实的问题:可见光近红外波段的二氧化钒折射率、介电常数参数,到底从哪里来?论文里的数据往往只给几个离散波长点,材料库没有现成选项,实验椭偏又没那么快出结果。于是…

作者头像 李华
网站建设 2026/9/9 6:33:22

鲸鱼优化算法WOA复现指南:从数学原理到Python实现与调参

最早接触鲸鱼优化算法(WOA)是在读 Mirjalili 2016 年发表在Advances in Engineering Software上的那篇论文时。当时我正在整理群智能优化算法的实验笔记,本来只是想了解一下这个算法的思想,结果越看越觉得不对劲:论文公…

作者头像 李华
网站建设 2026/9/9 6:31:06

TypeScript开发者必备:5个Agent调试工具实战指南

1. 这不是AI在退化,是人在“误操作”——5个真实工具拆解编程Agent的失效链你有没有试过让AI写一段TypeScript函数,第一次跑通了,改两行注释、调个参数顺序,结果编译报错?再让它修,它开始删import、把async…

作者头像 李华
网站建设 2026/9/9 6:28:02

混合信号验证MSDV实战:从RNM建模到Verilog-on-Top网表落地

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/9 6:27:16

SpringBoot驾校预约管理系统开发实战:从表设计到上线部署

驾校预约管理系统,这个选题我前后正经做过两版。第一版是纯Servlet思路,页面用JSP拼,登录态用Session硬扛,结果还没上线就被并发预约的冲突问题搞到怀疑人生。第二版全部推到重来,用SpringBoot做后端,把预约…

作者头像 李华
网站建设 2026/9/9 6:26:02

opencode实战指南:从安装配置到AI编程代理的高效工作流

从去年开始,我陆续试了一堆终端 AI 编程工具,一开始觉得新鲜,用多了就发现一个问题:很多工具要么绑定单一模型生态,要么只能在 IDE 里面用,换个项目就像换个 IDE 一样难受。最后真正留在我日常工作流里的&a…

作者头像 李华