Spring Cloud Gateway路由定义存储器源码解析与动态路由实战
自己在网关里加了一个自定义的RouteDefinitionRepository重启之后却发现自己通过代码写入的路由根本不被加载这是我实际项目中踩得最深的一类坑。最初我以为只是 Bean 没注入进来翻来覆去检查配置最后回到 Gateway 的自动装配源码里才看明白问题不在我的 Repository 实现上而在 Spring Cloud Gateway 对“路由定义存储器”这一层接口的组织方式上。RouteDefinitionRepository 在整个网关路由体系中承担的职责比它表面多出来的那两个写方法要大得多。凡是涉及动态路由、多数据源路由管理、配置中心联动扩展点最后都会落到这一层。这篇文章我会沿着数据模型、接口分工、默认实现到基于 Redis 的动态路由落地这条线把 RouteDefinitionRepository 这条链路完整拆开讲一遍。1. RouteDefinition 数据模型存储器里到底长什么样1.1 六个字段一个都不能多想先看存储对象本身。RouteDefinition不是一个复杂的类但它决定了整个动态路由的扩展能力。核心代码基本就是六个字段public class RouteDefinition { private String id; private URI uri; private ListPredicateDefinition predicates new ArrayList(); private ListFilterDefinition filters new ArrayList(); private MapString, Object metadata new HashMap(); private int order 0; }id是路由的唯一标识。在内存实现里它直接作为 ConcurrentHashMap 的 key所以 id 碰撞就意味着旧路由被静默覆盖这是很多“路由突然不对了”的现场。uri是转发目标可以写http://目标服务直接转发也可以写lb://order-service这种形式让网关通过负载均衡客户端去服务注册中心解析实际地址。predicates和filters是路由规则的核心前者决定“什么请求会命中这条路由”后者决定“命中之后怎么加工这个请求”。metadata是个自由扩展区灰度版本号、超时时间、自定义属性都可以塞进去。最后order控制路由之间的优先级数值越小越先匹配。很多人容易忽略的一点是predicates列表里多个条件之间是“并且”的关系装配阶段会把它们合并成一个组合 Predicate而filters列表是有顺序的写在前面的过滤器会先执行。这两个字段虽然都是 List语义上完全不同。1.2 PredicateDefinition 与 FilterDefinition 的 name args 设计再往深一层PredicateDefinition和FilterDefinition的结构几乎一模一样public class PredicateDefinition { private String name; private MapString, String args new LinkedHashMap(); }这个 name args 的设计非常关键。它意味着网关核心并不需要知道每个谓词或过滤器的内部实现只需要拿到一个“工厂名”和一组参数然后在运行时交给对应的 Factory 去创建真正的对象。你在 yaml 里写的- Path/demo/**会被解析成name Path、args {_genkey_0: /demo/**}。为什么会有_genkey_0这种奇怪 key因为短格式配置没有显式参数名工厂内部按位置读取参数_genkey_0只是默认占位键。完整写法则是显式指定 name 和 args- name: Path args: pattern: /demo/**两种写法最终得到的是同一个 PredicateDefinition。这种设计最大的好处是扩展性以后新增一种谓词不需要改动网关本体只要写一个 GatewayPredicateFactory然后注册成 Bean配置文件里立刻就能用新名字。反过来如果 Spring Cloud Gateway 把 Predicate 直接定义成强类型字段那每次加能力都要改核心类扩展成本会高很多。1.3 RouteDefinition 与 Route声明态和运行态的分界线RouteDefinition 只是“声明态”的路由它是纯数据。真正在匹配请求时使用的是Route它的结构里包含的是可执行的 Predicate 实例和一组 GatewayFilterpublic class Route implements Ordered { private final String id; private final URI uri; private final int order; private final Predicate predicate; private final ListGatewayFilter gatewayFilters; private final MapString, Object metadata; }一次请求到达网关后会按 order 顺序遍历 Route依次用predicate.test(exchange)判断是否匹配命中后按顺序执行 gatewayFilters。而 RouteDefinitionRouteLocator 就是连接声明态与运行态的那条流水线它读入 RouteDefinition把 PredicateDefinition 通过工厂转成 Predicate把 FilterDefinition 转成 GatewayFilter最后组装出 Route。理解了这条链路你就明白动态路由的本质改掉 RouteDefinition再让流水线重新走一遍。2. 三个接口的分工Locator、Repository 与 RouteLocator2.1 RouteDefinitionLocator只管读不问来源RouteDefinitionLocator 是整个路由定义体系的根接口全身上下只有一个方法public interface RouteDefinitionLocator { FluxRouteDefinition getRouteDefinitions(); }它表达的含义很朴素我不管你这些路由定义是从配置文件、内存、Redis 还是注册中心拿出来的你只要给我返回一个 RouteDefinition 的响应式流就行。为什么返回FluxRouteDefinition而不是 List因为数据源可能是异步的、流式的比如从消息队列或注册中心持续推送数据用 Flux 可以天然支持异步和背压。这个接口是数据源和路由装配器之间的依赖倒置点装配器只依赖抽象不关心具体实现。2.2 RouteDefinitionRepository在 Locator 之上补了写能力RouteDefinitionRepository 直接继承了 RouteDefinitionLocator并且追加了两个写方法public interface RouteDefinitionRepository extends RouteDefinitionLocator { MonoVoid save(MonoRouteDefinition route); MonoVoid delete(MonoString routeId); }注意 save 和 delete 的参数也被设计成了 Mono而不是普通对象。这是为了让调用方可以把自己异步拿到的数据直接传给 Repository在数据到齐之后再执行写入。如果你有同步数据套一层Mono.just(...)就好。这个接口的出现意味着 Spring Cloud Gateway 把“可管理的路由源”和“只读的路由源”明确区分开了。GatewayAutoConfiguration 里有一段条件装配逻辑如果没有用户自定义的 RouteDefinitionRepository就默认创建一个InMemoryRouteDefinitionRepository。也就是说内存仓库是兜底方案只要你想把路由定义放进外部存储并支持动态增删这个接口就是你的扩展点。2.3 RouteLocator 与 RouteDefinitionRouteLocator装配车间RouteLocator 是另一个层面的接口它直接返回运行态的 Routepublic interface RouteLocator { FluxRoute getRoutes(); }默认实现RouteDefinitionRouteLocator构造时接收四个东西一个 RouteDefinitionLocator、一组 GatewayPredicateFactory、一组 GatewayFilterFactory、以及 GatewayProperties。核心逻辑就是拿 locator 里的定义逐个调用工厂转换成可执行的 Route。这里有一个很常见的误解有人觉得只要自己实现了 RouteDefinitionRepository路由就能自动生效其实中间还隔着一层装配。Repository 只是把“图纸”送进系统真正把图纸变成“零件”的是 RouteDefinitionRouteLocator。三者的职责边界可以这样记Locator 管数据来源Repository 管数据增删RouteLocator 管定义到运行态的转换。接口核心方法语义典型实现RouteDefinitionLocatorgetRouteDefinitions()只读路由定义Properties、自定义 LocatorRouteDefinitionRepositorysave / delete / getRouteDefinitions()可读写的路由定义源InMemory、基于 Redis 的实现RouteLocatorgetRoutes()返回可执行 RouteRouteDefinitionRouteLocator3. 源码拆解内存实现、配置实现、组合器与缓存器3.1 InMemoryRouteDefinitionRepositoryConcurrentHashMap 是怎么接响应式世界的默认的内存实现代码非常短但细节很多public class InMemoryRouteDefinitionRepository implements RouteDefinitionRepository { private final MapString, RouteDefinition routes new ConcurrentHashMap(); Override public MonoVoid save(MonoRouteDefinition route) { return route.flatMap(r - { routes.put(r.getId(), r); return Mono.empty(); }); } Override public MonoVoid delete(MonoString routeId) { return routeId.flatMap(id - { routes.remove(id); return Mono.empty(); }); } Override public FluxRouteDefinition getRouteDefinitions() { return Flux.fromIterable(routes.values()); } }第一眼会好奇为什么用 ConcurrentHashMap 而不是 HashMap因为网关运行在响应式并发模型下路由的增删查可能被多个事件循环线程同时触发HashMap 在并发写时轻则丢数据重则导致迭代死循环所以并发容器是最低要求。第二整个实现没有一个null判断save 如果收到一个空的 MonoflatMap 就不会执行不会写入但如果你传入的 RouteDefinition 本身 id 为 nullput 进去之后后面装配路由时大概率会出奇怪的问题。第三Flux.fromIterable(routes.values())利用的是 ConcurrentHashMap 弱一致性的迭代器它不会抛 ConcurrentModificationException可以放心在读取过程中并发写入。这算是一个把同步集合适配到响应式流的典型范本。3.2 PropertiesRouteDefinitionRepositoryyaml 里的路由是怎么进系统的配置文件里的路由走的是另一个专门的 Locator这个类是 PropertiesRouteDefinitionRepository它组合了 GatewayPropertiespublic class PropertiesRouteDefinitionRepository implements RouteDefinitionLocator { private final GatewayProperties gatewayProperties; public PropertiesRouteDefinitionRepository(GatewayProperties gatewayProperties) { this.gatewayProperties gatewayProperties; } Override public FluxRouteDefinition getRouteDefinitions() { return Flux.fromIterable(gatewayProperties.getRoutes()); } }也就是说spring.cloud.gateway.routes 下那几段配置启动时会被 Spring Boot 的配置绑定机制转成ListRouteDefinition存进 GatewayProperties再由这个 Repository 暴露出去。绑定过程有一个容易忽略的细节yaml 里写- Path/demo/**这种字符串简写转换为 PredicateDefinition 时走的是接受单个字符串的构造方法它会自己拆 name 和 args。所以你在应用里看到的 PredicateDefinition 对象其实是 Boot 在绑定阶段就已经帮你加工好的。顺带一提GatewayProperties 里除了 routes还有 defaultFilters。这些默认过滤器在装配阶段会被拼接进每一条路由的过滤器列表尾部所以配置文件路由和代码动态添加的路由最终都会共享同一套默认过滤器规则。3.3 CompositeRouteDefinitionLocator多个数据源的并集语义实际启动时网关很少只注册一个 Locator。GatewayAutoConfiguration 会把配置类路由、内存仓库、服务发现路由等全部塞进一个 CompositeRouteDefinitionLocatorpublic class CompositeRouteDefinitionLocator implements RouteDefinitionLocator { private final FluxRouteDefinitionLocator delegates; public CompositeRouteDefinitionLocator(FluxRouteDefinitionLocator delegates) { this.delegates delegates; } Override public FluxRouteDefinition getRouteDefinitions() { return delegates.flatMap(RouteDefinitionLocator::getRouteDefinitions); } }flatMap在这里表达的是“多个数据源取并集”的语义。某个数据源返回空会直接跳过不会中断其他源。默认的 concat 顺序基本就是 Bean 注册顺序但强烈不建议依赖这个顺序来让后面的路由覆盖前面的结构。真正容易出问题的是异常行为如果其中一个 Locator 在读取远程数据时抛了异常整条 Flux 都会变成 error 流最直接的结果就是路由刷新失败甚至会拖累原有配置路由。所以自定义 RouteDefinitionRepository 时要格外关注异常边界远程不可用时不能把整个路由装配带崩。3.4 CachingRouteDefinitionLocator一个默认不开的缓存器再看一个容易被忽略的装饰器CachingRouteDefinitionLocatorpublic class CachingRouteDefinitionLocator implements RouteDefinitionLocator { private final RouteDefinitionLocator delegate; private final MapString, RouteDefinition cache new LinkedHashMap(); public CachingRouteDefinitionLocator(RouteDefinitionLocator delegate) { this.delegate delegate; cache.putAll(delegate.getRouteDefinitions() .collectMap(RouteDefinition::getId) .block()); } Override public FluxRouteDefinition getRouteDefinitions() { return Flux.fromIterable(cache.values()); } }构造时它会把 delegate 的路由定义一次性拉取到本地 Map之后读路由直接走缓存。Spring Cloud Gateway 默认不启用这个类原因很直接一是在构造期调用 block() 会阻塞启动如果 delegate 背后是慢速远程存储启动时间会很尴尬二是缓存一旦引入RouteDefinitionRouteLocator 自身的刷新事件只能清掉它自己那一层缓存这个 Caching 类的 Map 并不会被自动清理很容易出现“改了数据源但路由就是不更新”的假象。所以我通常不建议在动态路由场景加这一层如果你因为读源开销太大确实想加必须自己监听 RefreshRoutesEvent在事件里把缓存刷掉否则动态路由的最后一公里永远走不通。4. 动态路由实战用 Redis 实现一个可用的 RouteDefinitionRepository4.1 什么时候该自己动手写存储器配置文件路由用起来简单但一旦进入需要动态调整的场景就会卡住。比如管理后台想临时切走某个服务流量、网关在多个实例间需要共享同一份路由定义、或者运维希望在不重启进程的情况下调整路由参数这时候纯 yaml 方案就不够用了。本地文件在一个实例上改了其他实例的配置还是旧的而且改完还得走发布流程。把路由定义搬到 Redis再用自定义 RouteDefinitionRepository 暴露给网关是目前实现动态路由最直接的一条路子。原因很朴素Redis 读写快、API 简单、多个网关实例天然共享同一份数据而且是 Java 生态里几乎人人都会用的组件。4.2 最小可用实现三个方法加一个 ID 集合写一个最小可用版需要实现三个方法外加一个路由 ID 集合来避免用 keys 命令扫前缀Component public class RedisRouteDefinitionRepository implements RouteDefinitionRepository { private static final String ROUTE_KEY_PREFIX gateway:route:; private static final String ROUTE_IDS_KEY gateway:route:ids; private final StringRedisTemplate redisTemplate; private final ObjectMapper objectMapper; private final ApplicationEventPublisher eventPublisher; public RedisRouteDefinitionRepository(StringRedisTemplate redisTemplate, ObjectMapper objectMapper, ApplicationEventPublisher eventPublisher) { this.redisTemplate redisTemplate; this.objectMapper objectMapper; this.eventPublisher eventPublisher; } Override public FluxRouteDefinition getRouteDefinitions() { SetString routeIds redisTemplate.opsForSet().members(ROUTE_IDS_KEY); if (routeIds null || routeIds.isEmpty()) { return Flux.empty(); } return Flux.fromIterable(routeIds) .map(id - redisTemplate.opsForValue().get(ROUTE_KEY_PREFIX id)) .filter(Objects::nonNull) .map(this::deserialize); } Override public MonoVoid save(MonoRouteDefinition route) { return route.flatMap(r - { if (!StringUtils.hasText(r.getId())) { return Mono.error(new IllegalArgumentException(路由 id 不能为空)); } redisTemplate.opsForValue().set(ROUTE_KEY_PREFIX r.getId(), serialize(r)); redisTemplate.opsForSet().add(ROUTE_IDS_KEY, r.getId()); return Mono.empty(); }); } Override public MonoVoid delete(MonoString routeId) { return routeId.flatMap(id - { redisTemplate.opsForValue().getAndDelete(ROUTE_KEY_PREFIX id); redisTemplate.opsForSet().remove(ROUTE_IDS_KEY, id); return Mono.empty(); }); } private String serialize(RouteDefinition routeDefinition) { try { return objectMapper.writeValueAsString(routeDefinition); } catch (JsonProcessingException e) { throw new IllegalStateException(路由定义序列化失败, e); } } private RouteDefinition deserialize(String json) { try { return objectMapper.readValue(json, RouteDefinition.class); } catch (JsonProcessingException e) { throw new IllegalStateException(路由定义反序列化失败: json, e); } } }几个实现细节值得注意。序列化用的 ObjectMapper一定要复用 Spring Boot 自动配置的那个而不是自己new ObjectMapper()。因为 Boot 托管的 ObjectMapper 已经装配好了 Java 8 时间模块等扩展你自己 new 一个很可能会在序列化 metadata 中的时间字段时翻车。路由 ID 集合我非常推荐单独维护一个 Set不要在生产环境用keys gateway:route:*去扫数据量大时 Redis 会卡。最后delete 方法在新版本 RedisTemplate 里提供了getAndDelete顺手把旧值取出来方便做变更日志。4.3 发布 RefreshRoutesEvent路由变更落地的最后一公里Redis 存储写完之后如果不通知网关内存里那些运行态的 Route 还是老的。Spring Cloud Gateway 的事件机制在这里派上用场标准做法是 publish 一个 RefreshRoutesEventeventPublisher.publishEvent(new RefreshRoutesEvent(this));RouteDefinitionRouteLocator 内部有一个 routeCache它注册了一个事件监听器收到 RefreshRoutesEvent 后会把缓存清空下一次请求进来时重新从 RouteDefinitionLocator 拉取定义并转换。这就是动态路由变更落地的最后一公里。如果你用的是 Spring Boot Actuator也可以直接POST /actuator/gateway/refresh触发同一个事件但要注意这个端点需要暴露之后才可用。这里最容易犯的错是save 只写 Redis不发事件结果接口明明返回了成功网关却一整天都跑在旧路由上。5. 路由不生效时的排查链路与多实例一致性5.1 自定义 Locator 把默认组合器顶掉的坑这是我开头提到的那类问题的根源。GatewayAutoConfiguration 中默认生成的 RouteDefinitionLocator是一个包罗了配置路由、内存路由、服务发现路由的 CompositeRouteDefinitionLocator。但如果你在项目里自己声明了一个实现 RouteDefinitionLocator 接口的 Bean由于自动配置上标了ConditionalOnMissingBean(RouteDefinitionLocator.class)你的 Bean 会直接把默认组合器整个顶替掉。后果就是配置文件里的路由全部消失Spring Cloud Gateway 只认你那一个 Locator。而如果你实现的是 RouteDefinitionRepository则只是往组合器里增加一个数据源配置路由和内存路由都还在。所以扩展点的选择不是随意的凡是能基于 RouteDefinitionRepository 解决的问题就不要去实现 RouteDefinitionLocator。5.2 路由 id 冲突与事件丢失组合器把所有数据源的路由拼在一起之后RouteDefinitionRouteLocator 在装配阶段是按 id 合并的同 id 的路由定义后加载的会覆盖先加载的。若想排查问题先把各数据源的实际 id 打出来看是不是哪个动态路由的 id 和 yaml 里的路由 id 重了。另一个常见现场是“定义了但没生效”多半是事件没发出去。要确认事件链路是否正常可以在 RefreshRoutesEvent 监听器里临时打日志看每次刷新到底清没清缓存。5.3 多实例网关的一致性问题单个实例上动态路由能工作不代表集群里就万事大吉。Redis 作为共享存储确保了所有实例拿到的定义是一致的但 RefreshRoutesEvent 只会在当前实例内部生效。A 实例上改了一条路由A 自己能立刻刷新B、C 实例如果没有任何通知它们会继续沿用本地已经装配好的旧 Route。解决思路通常有两个要么用 Redis 的发布订阅或消息队列把“路由已变更”的通知广播到每个实例每个实例收到后主动发布 RefreshRoutesEvent要么借助配置中心的监听机制感知配置变化后统一刷新。这也是动态路由真正落地的分水岭单机能改不算完全集群同步刷新才是目标。5.4 顺着 actuator 端点反向定位排查时我习惯先用 actuator 的两个端点把状态切开看。GET /actuator/gateway/routedefinitions返回的是声明态的路由定义能看出定义到底有没有进到网关GET /actuator/gateway/routes返回的是运行态 Route能看出定义有没有成功转换并加载。如果 routedefinitions 里有数据routes 里没有说明问题出在装配阶段比如谓词名称写错、URI 无法解析、某个 Filter 工厂不存在。如果 routedefinitions 里都没有说明问题在 Locator/Repository 这一层需要回头检查你自定义的 Repository 有没有被组合器聚合。利用这两个端点把问题范围缩小大部分路由疑难杂症都能在五分钟内定位到具体环节。最后给想自己动手扩展的人一个建议不要一上来就写完整的分布式存储方案先跑通“内存仓库 手动刷新事件”的最小闭环再把存储层换成 Redis最后才考虑多实例广播。我踩过的大部分坑都集中在两件事上一个是扩展接口选错把 Locator 和 Repository 搞混另一个是刷新事件没发对定义了新路由却不通知网关。这两点想清楚后面的路就要顺得多。

相关新闻

AutoML在设备维护中的应用:从故障预测到架构落地

AutoML在设备维护中的应用:从故障预测到架构落地

设备维护这个领域,过去十年一直靠“老师傅耳朵听异响、手摸振动”吃饭,现在正在被数据驱动的方式慢慢改变。而AutoML(自动化机器学习)在其中扮演的角色,不是取代老师傅,而是把老师傅的判断经验变成可复制、…

2026/10/16 8:29:30 阅读更多 →
Excel按颜色统计的三种实现方案:GET.CELL、VBA与条件格式实战指南

Excel按颜色统计的三种实现方案:GET.CELL、VBA与条件格式实战指南

就在上个月,一个做运营的朋友跟我抱怨,说她在表格里用红黄绿三种颜色标记了一批客户状态,忙活了一下午,最后想按颜色统计一下到底红色几家、绿色几家,结果在Excel里翻遍了函数列表,愣是没找到一个能直接“按…

2026/10/17 13:19:17 阅读更多 →
古村古镇数字化平台WebGIS开发:从数据到前端的完整实现

古村古镇数字化平台WebGIS开发:从数据到前端的完整实现

简介:面向WebGIS期末作业与入门学习者的古村古镇数字化平台完整源码,前端采用HTML、CSS、JavaScript、jQuery和Bootstrap,GIS部分可结合ArcGIS API或百度地图API调用,实现数据采集存储、地图展示查询、数据分析、数字化展示与用户…

2026/10/17 12:13:44 阅读更多 →

最新新闻

Muse-Glimmer-30B-mxfp8 chat_template 详解:正确书写 System Prompt 与多轮图像对话的完整方法

Muse-Glimmer-30B-mxfp8 chat_template 详解:正确书写 System Prompt 与多轮图像对话的完整方法

【免费下载链接】Muse-Glimmer-30B-mxfp8 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/Muse-Glimmer-30B-mxfp8 点击查看 免费下载 Muse-Glimmer-30B-mxfp8 是一个 300 亿参数的多模态视觉语言模型(image-text-to-text)&…

2026/10/17 15:02:41 阅读更多 →
实习面试题总结:从复盘到能力提升的完整指南

实习面试题总结:从复盘到能力提升的完整指南

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

2026/10/17 15:02:41 阅读更多 →
LeetCode接雨水全解法:从暴力到双指针与单调栈

LeetCode接雨水全解法:从暴力到双指针与单调栈

LeetCode 42题,接雨水。如果你刷过几轮算法题,几乎不可能没遇见过它。我自己的感受是,这道题在算法题单里的地位高得吓人,很多面经都把它挂在高频榜上。它不像动态规划有那么曲折的状态定义,也不像图论需要大量前置知识…

2026/10/17 15:02:41 阅读更多 →
OpenResearch:Claude Code、Codex、OpenCode、Cursor 安装配置与协同工作流

OpenResearch:Claude Code、Codex、OpenCode、Cursor 安装配置与协同工作流

1. 从 OpenResearch 这个标题说起:它到底想解决什么问题第一次看到 OpenResearch 这个词,我脑子里冒出来的不是某个具体产品,而是一类很典型的需求:把散落在不同 AI 编程工具里的能力、配置、会话和研究成果,收拢到一个…

2026/10/17 15:02:41 阅读更多 →
显存不足也能跑大模型:airllm分层加载推理实战与性能优化

显存不足也能跑大模型:airllm分层加载推理实战与性能优化

1. 当显存告急时,我们还能不能跑大模型 第一次看到 airllm 这个项目名的时候,我正被一张 8GB 显存的显卡折磨得够呛。手头有个 70B 级别的模型想本地跑起来做推理验证,结果加载权重这一步就直接爆显存,连模型的门都没进去。相信很…

2026/10/17 15:02:41 阅读更多 →
工业AI落地实战:视觉质检、预测维护与工艺优化全解析

工业AI落地实战:视觉质检、预测维护与工艺优化全解析

1. 项目概述:当AI不再是PPT里的概念,而是产线上的“新工人” “他山之石可攻玉”这句老话,放在今天的工厂里,突然有了特别实在的分量。我跟过不下二十家不同规模的制造企业做智能化升级咨询,从长三角的精密零部件厂&am…

2026/10/17 15:01:40 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 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/16 21:54:38 阅读更多 →
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/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练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/16 14:23:36 阅读更多 →