基于Atlas的MySQL读写分离与分库分表实践指南
1. 项目整体设计与适用场景解析1.1 这个项目到底解决什么问题做后端开发的人应该都有这种感觉业务量一上来数据库最先扛不住。单库单表跑到一定量级写入并发和查询延迟都会明显恶化这时候大部分人第一反应是上缓存、做读写分离再不行就分库分表。但真到了分库分表的阶段麻烦事就接踵而至——你希望应用层像访问一个数据库一样访问多个数据库实例而不希望在 DAO 层写一堆路由逻辑。Atlas 就是为这个场景而生的。它本质上是一个基于 MySQL 协议的数据访问中间件部署在应用服务器和 MySQL 实例之间对外伪装成一个 MySQL 服务器应用端不用改任何代码只要把数据库连接地址改成 Atlas 的地址就能获得读写分离、分库分表、连接池管理、SQL 过滤等能力。我在实际项目里第一次接触 Atlas是因为当时接手了一个线上商城系统订单表已经到了千万级单库单表写入经常把主库拖垮。团队讨论过 Sharding-JDBC、MyCat 这些方案但当时 Java 那套还比较重MyCat 引入成本也不小反而是 Atlas 这种中间层代理方式最适合我们当时的架构——应用端改动最小运维也最省心。1.2 适合谁用、不适合谁用Atlas 适合以下场景需要快速实现读写分离主库扛写入、从库扛查询应用层零改动。分库分表需求明确比如订单按用户 ID 分 4 个库、每库再按月份分表路由规则可以配置在 Atlas 层。不想侵入应用代码团队没有精力在 Java/PHP/Go 各个语言里分别实现数据库路由逻辑只想在中间层统一处理。运维能力一般的中小型团队Atlas 配置相对简单部署模式清晰不需要像某些分布式数据库那样搞一堆协调节点。不适合的场景追求极致性能的场景比如每秒几十万 QPS 的纯查询Atlas 的多一层转发确实会带来微秒级到毫秒级的额外延迟。需要复杂分布式事务支持的场景Atlas 本身不擅长跨库事务最多做数据库层面的单库事务。团队如果已经有完善的 Sharding-JDBC 体系没必要为了用 Atlas 而用 Atlas。我在技术选型时的一个重要心得是不要因为某个中间件功能强大就选它而要看你的团队能承担多少维护成本。Atlas 的优势恰恰在于轻量、部署简单、配置直观适合大多数 MySQL 垂直分层的需求。2. 核心原理拆解读 wrote 分离、分库分表与连接管理2.1 读写分离本质是基于 MySQL 主从复制Atlas 的读写分离能力底层依赖的是 MySQL 自带的主从复制机制。理解了这条链路你才能理解 Atlas 到底在“代理”什么。架构通常是这样的主库Master处理写入操作INSERT、UPDATE、DELETE、DDL。一个或多个从库Slave同步主库的 binlog处理查询操作SELECT、SHOW 等。Atlas 位于应用和 MySQL 之间解析应用发来的 SQL判断是读还是写然后转发到对应的数据库实例。判断逻辑并不复杂Atlas 内部对 SQL 文本做解析看语句类型和关键字。比如语句以 SELECT 开头一般归类为读请求以 INSERT、UPDATE、DELETE、ALTER、CREATE 等开头归类为写请求。但这里有个坑SELECT ... FOR UPDATE 和 SELECT ... LOCK IN SHARE MODE 虽然是 SELECT但它们本质是写操作或需要主库数据一致性绝对不能路由到从库。Atlas 这一块处理得比较完善不光是看关键字还会检查 SQL 有没有 FOR UPDATE 这类特殊子句。从库延迟是读写分离最头疼的问题。主库写入一条记录binlog 同步到从库需要时间如果刚写入就去从库查很可能查不到。Atlas 层面没有做延迟感知所以这部分的解决方案通常要落到业务上对实时性要求极高的数据比如支付结果、库存扣减要么强制走主库要么接受秒级延迟。我当时的做法是在应用层维护一个简单的“读主库标记”需要强一致性的查询走一个单独的 DB 连接池这个池直接连到 Atlas 的路由规则里的主库。虽然绕了半圈但效果可靠。2.2 分库分表的路由规则是如何工作的分库分表是 Atlas 另一个核心价值。它的思路是在配置里声明一个“逻辑表”然后告诉 Atlas 这个逻辑表对应的物理库表分布规则。举个例子订单表 order 要做分库分表规则是 userId 取模4 个库order_0、order_1、order_2、order_3每个库 4 张表order_0、order_1、order_2、order_3应用端正常发送INSERT INTO order_order (order_id, user_id, amount) VALUES (…)Atlas 解析 SQL 后根据语句中的 user_id 字段值计算 user_id % 4 得到表后缀再计算出库后缀可能跟表后缀相同也可以用独立规则然后改写 SQL 并发送到对应的库表。这里要特别注意Atlas 的分表算法是基于 SQL 中某个字段的这个字段必须有值且是整数类型常用的是取模运算。如果你的 SQL 里没有这个字段Atlas 无法判断该去哪个库表会直接报错或拒绝执行。所以使用分库分表时所有涉及分表字段的查询条件都必须带上这个字段否则只能做全表扫描式的路由这在生产者设计上是不允许的。Atlas 的配置文件通常是conf/atlas.conf里的分表配置段大概长这样# 分表规则 tbl_order user_id:4:0,1,2,3这里的意思是逻辑表名为 tbl_order分表字段为 user_id一共分 4 个物理表物理表后缀分别为 0、1、2、3。分库规则如果也配置了就按类似格式指定库后缀。当然取模路由只是其中一种方式实际生产环境还会用到范围路由比如按时间范围分表、一致性哈希路由等但 Atlas 本身内置的规则比较简单主要还是取模。如果你需要更复杂的路由算法要么自己在 SQL 层面处理要么换更重的中间件。2.3 连接池与会话管理Atlas 如何维持大量数据库连接应用端连接 Atlas 时Atlas 会为它建立一个前端连接。但同时 Atlas 也要连接后端的 MySQL 实例这部分叫后端连接。如果每个前端连接都对应一个后端连接那连接数会爆炸数据库根本扛不住。Atlas 的做法是维护一个连接池后端连接可以被复用。具体来说一个前端连接执行完一条 SQL 后这个后端连接可能不会立刻释放而是被放回连接池下一个前端连接执行 SQL 时可以复用同一个后端连接。连接池的大小、空闲超时时间、连接存活检查等参数都在配置文件里可调。这并不意味着一对一关系不存在了。如果你有 200 个前端连接而连接池空闲容量只有 100那么 200 个前端连接会竞争 100 个后端连接。执行完 SQL 的释放、等待、竞争都由 Atlas 管理对应用透明。这种设计有一个好处应用端只需要配置一个 Atlas 地址和端口不用担心后端的连接数限制。也有一个坑如果后端 MySQL 的max_connections设置得过低即使 Atlas 做了连接池复用高并发下依然可能出现Too many connections错误。这种时候别光调整 MySQL 配置还是要结合 Atlas 的连接池参数一起调。我在压测时遇到过这个问题。当时 Atlas 连接池设置得偏大后端 MySQL 只有 200 个连接上限结果高并发压测时 MySQL 直接拒绝新连接。优化方案是把 Atlas 的连接池上限调低同时把 MySQL 的max_connections提到 500这才稳住了。3. 实操过程从部署到配置读写分离的完整流程3.1 环境准备与安装部署Atlas 本身是一个独立的服务进程基于 C 语言开发安装包通常是提前编译好的二进制文件。不同的系统版本会有不同的安装包我以 CentOS 7 系统为例来演示安装过程。先下载对应版本的 Atlas 安装包然后解压到指定目录。# 下载示例版本号以实际发布版本为准 wget http://example.com/atlas/atlas-2.2.1.el6.x86_64.rpm # 安装 RPM 包 rpm -ivh atlas-2.2.1.el6.x86_64.rpm如果你使用的是源码包一般步骤是tar -zxf atlas-2.2.1.tar.gz cd atlas-2.2.1 ./configure --prefix/usr/local/mysql-proxy make make install安装完成后的目录结构大致是这样bin/底下有可执行文件核心是mysql-proxyAtlas 基于 MySQL Proxy 二次开发。conf/底下有atlas.conf这是核心配置文件。log/存放运行日志。启动方式也很简单/usr/local/mysql-proxy/bin/mysql-proxy --defaults-file/usr/local/mysql-proxy/conf/atlas.conf如果你需要后台运行可以这样nohup /usr/local/mysql-proxy/bin/mysql-proxy --defaults-file/usr/local/mysql-proxy/conf/atlas.conf /dev/null 21 3.2 核心配置详解atlas.conf 逐行拆解Atlas 的配置是 INI 风格看起来像下面这样我逐段解释。[mysql-proxy] # 管理接口的 IP 和端口用于登录 Atlas 管理后台 admin-address 0.0.0.0:2345 # 管理接口的用户名和密码 admin-username admin admin-password admin123 # 代理监听地址应用连接这里 proxy-address 0.0.0.0:1234 # 后端 MySQL 主库地址 proxy-backend-addresses 192.168.1.10:3306 # 后端 MySQL 从库地址多个从库用逗号分隔 proxy-read-only-backend-addresses 192.168.1.11:3306,192.168.1.12:3306 # 连接池相关配置 proxy-pool-min-size 10 proxy-pool-max-size 200 # 超时配置 proxy-connect-timeout 3 proxy-read-timeout 10 proxy-write-timeout 10 # 日志级别message、warning、critical、error log-level message log-path /usr/local/mysql-proxy/log几个关键参数我再展开讲一下。proxy-backend-addresses配置主库多个主库之间可以做写负载均衡但实际场景中通常只有一个主库。proxy-read-only-backend-addresses配置从库读请求会按权重轮询转发到这些从库。连接池大小proxy-pool-max-size如果你设置得太大后端数据库压力大连接数不够会报错设置得太小高并发时后端连接不够前端 SQL 会排队等待。一般建议先设为 100压测后慢慢调整。管理接口admin-address是独立的通过 MySQL 客户端可以登录这个端口执行一些管理命令比如查看后端状态、手动切换读写状态等。命令格式如下mysql -h127.0.0.1 -P2345 -uadmin -padmin123登录后可以执行SELECT * FROM backends;查看后端状态也可以执行SET offline/SET online来手动下线或上线某个后端库。这个功能在运维排查时非常实用。3.3 配置读写分离的完整示例假设我们的业务场景是主库192.168.1.10:3306从库两个192.168.1.11:3306、192.168.1.12:3306应用连接 Atlas 的地址127.0.0.1:1234那么配置文件中就设置proxy-address 0.0.0.0:1234 proxy-backend-addresses 192.168.1.10:3306 proxy-read-only-backend-addresses 192.168.1.11:3306,192.168.1.12:3306保存配置文件后重启 Atlas。启动后我们在应用服务器上用 MySQL 客户端测试连接mysql -h127.0.0.1 -P1234 -uapp_user -papp_passwd -e SELECT NOW();如果 Atlas 配置正确这个 SQL 会返回成功。此时我们来验证读写分离是否生效。在从库上开启通用查询日志general log或者从库的processlist里观察是否有 SELECT 查询进入。-- 在从库执行 SET GLOBAL general_log ON;然后在应用端执行几条 SELECT 和 INSERT 语句SELECT id, name FROM users WHERE id 1; INSERT INTO users (name) VALUES (test);观察从库日志你会发现 SELECT 走到了从库观察主库日志INSERT 走到了主库。读写分离链路通了。需要说明的是Atlas 不会把同一个连接里的所有语句固定路由到同一个后端它是逐条 SQL 判断的。这意味着你在应用端开启了一个事务事务里先 INSERT 再 SELECT事务前半段走主库后半段的 SELECT 也可能走从库。这在事务一致性上是个隐患。针对这种情况Atlas 提供了一个配置项不同版本有差异或在管理接口中设置强制走主库的会话变量。我们当时的做法是在应用端对需要事务内一致性的业务使用一个独立的数据库账号这个账号在 Atlas 配置里只指向主库。相当于你有两个数据库账号一个普通账号走读写分离一个专用账号全走主库。虽然有点土但在当时足够好用。3.4 分库分表配置实操配置分库分表的核心是把逻辑表映射到物理库表。假设你要对order表做分库分表规则是4 个库order_db_0、order_db_1、order_db_2、order_db_3每个库 4 张表order_0、order_1、order_2、order_3分表键user_id在配置文件的 SQL 解析部分需要设置分表规则。Atlas 的配置格式大致如下不同版本可能略有差异以官方文档为准# 逻辑表名 分表字段:分表数量:分表后缀 tbl_order user_id:4:0,1,2,3如果分库也要做需要指定库后缀的映射规则这取决于 Atlas 版本支持的程度。如果只支持分表而不支持分库那你可能需要预先在应用层或 Proxy 层做库的映射。实际测试时插入一条数据INSERT INTO order (user_id, order_id, amount) VALUES (1001, 20240001, 99.00);根据取模规则1001 % 4 1所以这条记录会进入 order_db_1 库的 order_1 表。查询时也必须带上 user_id 条件SELECT * FROM order WHERE user_id 1001 AND order_id 20240001;这样才能路由到正确的分表。如果不带 user_id 查询Atlas 无法确定路由通常会执行全表遍历如果 Atlas 支持或直接报错。实际生产环境里我会在应用层强制要求所有订单查询都带上用户 ID这也是分库分表方案通用的一条铁律。3.5 启动验证与状态检查配置完成后启动 Atlas 并验证状态。登录管理接口mysql -h127.0.0.1 -P2345 -uadmin -padmin123执行SELECT * FROM backends;这个命令会列出所有后端 MySQL 的状态。重点关注每个后端的 typerw 或 ro、statusup 或 down、权重等信息。如果某个从库状态 down 了读写分离会把它的流量摘除吗Atlas 的自动摘除机制主要靠心跳检测如果探测不到后端存活就自动将它移除出可用列表。这个机制在早期版本里并不稳定有时需要手动登录管理接口执行SET offline ...;所以日常巡检时我习惯写一个定时脚本定期查询 Atlas 管理接口把 down 状态的后端及时处理掉。脚本内容不复杂核心逻辑就是连接管理接口执行SELECT * FROM backends;解析文本检查状态。3.6 在应用端如何优雅切流这是整个接入过程里最关键的一步。新老系统切换时我建议分三步走先在一台测试服务器上部署 Atlas把测试应用连接指向 Atlas验证所有核心链路。在预发环境开启少量流量比如 5% 的请求到 Atlas 环境观察错误率和延迟。全部流量切换到 Atlas 后保留旧连接方式一周以上方便随时回滚。应用端切换非常简单即修改数据库连接配置原来的jdbc:mysql://192.168.1.10:3306/app_db 现在的jdbc:mysql://127.0.0.1:1234/app_db注意用户名和密码必须以 Atlas 配置中的为准而不是后端 MySQL 的真实账号密码。Atlas 会代理认证也就是说应用端的账号密码是 Atlas 自己维护的账号体系跟后端的 MySQL 账号可以不一样。我踩过一个坑当时团队有个老系统数据库连接串里面带了useSSLtrue连 MySQL 没事连 Atlas 却反复握手失败。查了半天发现 Atlas 对 SSL 的支持有限需要把该参数去掉才能正常连接。如果你遇到类似问题记得检查驱动连接串的 SSL、字符集参数是否跟 Atlas 兼容。4. 常见问题与排查技巧实录4.1 连接被拒绝Atlas 启动失败排查症状应用连接 Atlas 提示Can’t connect to MySQL server on 127.0.0.1 (111)。排查步骤检查进程是否存在ps -ef | grep mysql-proxy检查监听端口netstat -tlnp | grep 1234查看日志文件重点看log/目录下的信息。日志中出现类似[ERROR] proxy-backend-addresses is required说明配置文件中必填项缺失补上即可。如果是[ERROR] bind() failed: Address already in use说明端口被占用换端口或杀掉占用进程。启动失败里最高频的原因其实是配置文件写错了。例如 IP 地址后多了一个空格或者端口号写成字符串这些细节错误在 Atlas 启动时未必会立刻报出来但运行时该后端库始终是 down 状态。所以改完配置记得仔细检查一遍格式。4.2 读写分离不生效所有请求都走了主库有时候配置了从库但 SELECT 请求依然打到主库。常见原因有三个proxy-read-only-backend-addresses没写对或者空值被注释掉了。从库权重设置为 0导致不会被选中。Atlas 对某些 SQL 类型做了特殊处理比如带函数的 SELECT、带锁的 SELECT默认走主库。排查时先登录管理接口看后端列表SELECT * FROM backends;确认从库的 type 是否为ro、status 是否为up、权重是否大于 0。再检查 SQL 是否属于特殊类型。最简单的验证方法是在从库开启 general log然后执行几条典型查询看看是否会出现在从库日志里。4.3 从库延迟导致的数据不一致这个问题不算 Atlas 本身故障但 Atlas 会把读请求均匀分发到从库如果从库复制延迟很大用户会看到数据一会有一会没有。我更推荐的做法是根据业务容忍度拆分实时性要求高的读走主库。允许秒级延迟的读走从库。Atlas 没有在配置层面支持“按 SQL 标记强制走主库”所以只能靠应用层拆分连接。比如在 Spring 里配置两个数据源一个数据源指向 Atlas 普通端口读写分离另一个数据源指向 Atlas 的只主库端口或者直接指向主库。4.4 高并发下出现 Too many connections我压测时踩过的这个坑本质原因是连接池和后端 MySQL 连接数上限不匹配。两层都要调MySQL 端提高max_connections同时注意max_connections不是越大越好它会消耗内存。Atlas 端调小proxy-pool-max-size让后端连接数控制在 MySQL 承受范围内。一个粗略的经验公式max_connections Atlas的pool-max-size 其他来源连接数 20%余量如果你有 3 个后端 MySQL 实例每个实例的max_connections是 500那 Atlas 的proxy-pool-max-size可以设置为 300 左右留出运维和备份连接的余量。4.5 长连接被 MySQL 主动断开MySQL 的wait_timeout默认是 8 小时。如果应用通过 Atlas 建立了一个长连接但 8 小时内没有新的 SQL 进来MySQL 可能主动断开连接。Atlas 连接池里的后端连接也可能被这样清理掉但前端应用不知道下次发了 SQL 才发现连接失效。处理方案有三个在应用端连接池如 HikariCP、Druid配置test-on-borrow或connection-test-per-connection发送一个SELECT 1探活。在应用端设置连接最大空闲时间小于 MySQL 的wait_timeout。如果应用无法改动那就把 MySQL 的wait_timeout调大或者配置 Atlas 的连接池定期保活。我比较推荐前两种因为保活机制会让数据库处理更多无意义的探测请求但如果连接数不大效果也不错。4.6 SQL 语法兼容问题Atlas 内置的 SQL 解析器并非 100% 兼容所有 MySQL SQL 语法。我遇到过的典型问题包括带ON DUPLICATE KEY UPDATE的 INSERT 语句某些版本转发时可能解析异常。LOAD DATA INFILE这类文件导入语句Atlas 基本不支持。某些带 HINT 的 SQL比如/* MAX_EXECUTION_TIME(1000) */ SELECT ...可能解析不出来。遇到这类问题最快的排查方式是把 SQL 单独拿出来用 MySQL 客户端直连 Atlas 测试然后观察日志输出。如果确定是 SQL 解析问题一般有三种解法改写 SQL兼容 Atlas 解析。给 Atlas 打补丁或换个版本。这类 SQL 走旁路绕过 Atlas 直接连接真正的 MySQL 实例。我通常优先选第一种因为最简单。比如把INSERT INTO ... ON DUPLICATE KEY UPDATE拆成先SELECT再UPDATE虽然多一次交互但能保证兼容性也更便于后续排查。4.7 Atlas 的高可用部署生产环境里Atlas 本身不能成为单点。如果只部署一个 Atlas 实例它挂了应用就彻底无法访问数据库。常见做法是部署两个或多个 Atlas 实例前面加一层负载均衡LVS、HAProxy、Nginx Stream 都可以。如果 Atlas 实例挂了负载均衡器将流量切到另一个实例。两个 Atlas 实例之间不需要同步会话状态因为数据库状态本身在后端 MySQL 里Atlas 只做转发。这也是中间层代理架构的高可用便利之处不需要额外引入 ZooKeeper 之类的东西来协调状态只要保证至少一个实例存活即可。我当时的部署拓扑是两台 Atlas 实例一台主一台备。前端用 HAProxy 做 33060 端口的 VIP转发到两台 Atlas 的 1234 端口。两个 Atlas 实例配置一致后端都指向同一组 MySQL 主从。切换测试也很顺利杀掉主 Atlas 进程HAProxy 在健康检查失败后自动把流量切到备 Atlas应用侧几乎没有感知只有少量 TCP 连接会报错重连。整体效果符合预期。5. 监控与运维最佳实践5.1 需要重点关注的监控指标Atlas 运行时的健康状态我主要关注几类指标连接数Atlas 前端连接数应用连接 Atlas 的连接数和后端连接数Atlas 连接 MySQL 的连接数。连接数异常增长往往意味着应用端连接池泄漏或高并发到来。请求量Atlas 每秒钟处理的 SQL 数量和类型。通过日志统计可以观察读写比例是否合理如果读比例极高但从库负载很低需要检查路由是否正常。延迟Atlas 转发 SQL 到后端 MySQL 的响应时间。如果延迟突然飙升可能是后端数据库出问题也可能是网络抖动。后端状态每个后端 MySQL 是 up 还是 down主库和从库的角色是否正常。其中没有现成的 Grafana Dashboard 能直接用最简便的采集方式是通过管理接口SELECT * FROM backends;定期抓取再写入自己的监控系统。虽然粗粒度但足够覆盖日常需求。5.2 配置变更和版本升级注意事项Atlas 的配置变更要重新启动进程才生效。这一点容易踩坑因为很多人以为修改配置后会热加载。建议变更流程备份当前配置文件和当前进程状态。修改配置文件尽量用 diff 检查改动。先在后端从库或多实例环境测试。生产环境操作选择一个低峰期重启 Atlas 进程。重启后立刻验证连接和路由。版本升级时先查一下官方 release notes重点看 SQL 解析逻辑、连接池行为、配置项兼容性。有些版本切换后旧的配置项被废弃不检查的话会启动失败。5.3 日志切割与清理Atlas 日志如果不定期清理会占用大量磁盘空间。log-level message级别下每条 SQL 的执行都会记录日志跑一天下来几个 GB 很正常。建议配置 logrotate 做日志轮转保留最近 7 天的日志即可。切割方式类似于/usr/local/mysql-proxy/log/*.log { daily rotate 7 copytruncate compress missingok }copytruncate很重要因为 Atlas 进程一直在写日志文件直接移走文件可能导致句柄问题copytruncate可以拷贝后再清空原文件。5.4 安全加固技巧Atlas 不直接暴露给公网只允许应用服务器访问。安全方面注意以下几点防火墙只放行应用服务器所在网段访问 Atlas 的代理端口和管理端口。管理端口admin-address不要绑定 0.0.0.0最好是只绑定内网运维跳板机的 IP否则任何人能连管理接口就麻烦了。修改默认的管理员密码不要保留 admin/admin123。如果业务对数据敏感Atlas 层面的 SQL 审计日志要开启记录所有经过代理的 SQL。注意这会显著增加磁盘 I/O建议在合规要求下权衡开启。6. 我踩过的那些坑与总结性建议做数据库中间件选型时最忌讳的不是选错方案而是选了一个运维起来完全超出团队能力的方案。Atlas 很轻量但它本质上依然是一个需要认真运维的独立服务。你不仅要多部署一层服务还得为它设计监控、容灾、变更流程这些成本必须提前算进项目里。我在 Atlas 落地过程中最大的体会是三个字先验证。不要直接在生产环境拍板上 Atlas先在测试环境完整走一遍读写分离、分库分表、故障切换的演练。特别是故障切换很多人会在切换过程中发现自己的连接池没有配置重连机制或者 Atlas 备机的端口没有启动这些都是上线后才发现就会手忙脚乱的问题。一个小技巧想分享给后来者给 Atlas 的管理接口写一个简单的 shell 巡检脚本每天定时跑一次输出后端的 up/down 状态和连接数。脚本一共不到 30 行但能帮你节省大量排查时间。我在很多集群里都用了这个笨办法简单但可靠。最后再说回 Atlas 本身。它不像某些新潮的分布式数据库那样自带管理面板和一键扩缩容但它胜在稳定、透明、容易理解。只要你的业务场景是 MySQL 体系下的读写分离和水平分表Atlas 绝对是一个值得认真考虑的选择。

相关新闻

从索引策略到查询性能飞跃:SQL优化实战全解析

从索引策略到查询性能飞跃:SQL优化实战全解析

接手过一个让人头疼的性能工单:业务方反馈某个查询在数据量涨到百万级之后,响应时间从几十毫秒直接飙升到十几秒,前端超时,接口报警刷屏。第一反应以为是数据库负载问题,结果一查,表结构里有索引&#xff0…

2026/10/19 14:16:37 阅读更多 →
YOLOv5/YOLOv8水果好坏检测实战:从数据标注到模型部署

YOLOv5/YOLOv8水果好坏检测实战:从数据标注到模型部署

我前阵子接了个果蔬分拣相关的视觉项目,核心需求就是把大小不一的水果照片按“好果”和“坏果”自动分好类。这类需求在农产品标准化、商超自动结算、生鲜供应链质检场景里特别常见。我们最终选型就用 YOLOv5 和 YOLOv8 做了整套方案,配套整理了一份带标…

2026/10/19 14:16:37 阅读更多 →
Crypto-XOR2实战:循环密钥与字节反转的完整解密思路

Crypto-XOR2实战:循环密钥与字节反转的完整解密思路

简介:一份面向广东大学生网络攻防大赛参赛者、CTF Crypto方向练习者的crypto-xor2题目附件包,重点考察异或(XOR)加密原理与密文分析思路。资源包共2个文件,压缩后仅460B,包含密文文件cipher和同名Python脚本task.py,后…

2026/10/19 14:16:37 阅读更多 →

最新新闻

APP生命周期管理:从状态机到进程回收的工程实践

APP生命周期管理:从状态机到进程回收的工程实践

1. 从一个被忽视的崩溃说起:为什么“APP生命周期”值得单独拎出来讲 做移动端开发的人,几乎都遇到过这样一种情况:测试同学跑过来跟你说,“这个页面偶尔会白屏,复现不出来”,或者“用户反馈切到后台再回来&…

2026/10/19 15:06:01 阅读更多 →
EasyEdit2 实操指南:轻松上手大模型知识编辑与参数定位

EasyEdit2 实操指南:轻松上手大模型知识编辑与参数定位

做模型编辑这几年有个很深的感受:学术界一直在追求"更高分",但落地的人只想要"能跑通"。EasyEdit2 这篇论文解读,标题里最扎眼的其实是 "Easy-to-use"(易用)这个词。做大型语言模型编辑…

2026/10/19 15:06:01 阅读更多 →
Android自定义SeekBar:Drawable层级解耦与像素级进度控制

Android自定义SeekBar:Drawable层级解耦与像素级进度控制

简介:本资源是一份面向Android中高级开发者的自定义SeekBar控件实战项目,聚焦UI个性化定制需求,解决系统默认SeekBar样式单一、难以融入品牌设计的问题。项目通过继承原生SeekBar并注入图片资源,实现背景与进度条的双图驱动效果&a…

2026/10/19 15:06:01 阅读更多 →
疲劳驾驶检测系统实战:基于YOLOv11与PERCLOS的实时监测方案

疲劳驾驶检测系统实战:基于YOLOv11与PERCLOS的实时监测方案

1. 系统整体设计与方案选型先说结论:这个项目看起来只是一个“YOLOv11疲劳驾驶检测”的常规组合,但真正落地时,你需要考虑的东西远比跑通一个模型要多得多。我最初接手类似项目时也踩了不少坑,所以这篇把我自己的实操过程和最终方…

2026/10/19 15:06:01 阅读更多 →
基于YOLOv11的花生霉变检测系统:从数据标注到桌面部署实战

基于YOLOv11的花生霉变检测系统:从数据标注到桌面部署实战

1. 项目概述与技术选型解析1.1 这个项目到底是做什么的花生的霉变问题在仓储和加工环节里一直是个老大难。发霉的花生不仅口感变差,更致命的是会产生黄曲霉毒素,这东西耐高温、难去除,误食后对肝脏损伤很大。过去做霉变检测主要靠人工肉眼挑拣…

2026/10/19 15:06:01 阅读更多 →
智能问卷设计全流程:从逻辑配置到数据清洗的落地实践

智能问卷设计全流程:从逻辑配置到数据清洗的落地实践

问卷调研这事,看着简单,翻车的人排着队。发出去一千份问卷,回来五百份,清洗完能用的可能不到两百。这些问题我在项目里碰过太多次,后来把整套方法沉淀下来,落地成代号就叫“百考通智能问卷设计”的工作链路…

2026/10/19 15:05:00 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

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

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/18 12:16:16 阅读更多 →