JMX架构深度解析:从MBean到生产环境监控实战
1. 项目概述为什么JMX值得你花时间研究如果你在Java世界里摸爬滚打了一段时间尤其是在处理线上应用监控、性能调优或者动态管理应用配置时大概率会听到“JMX”这个词。它就像是一个被内置在Java虚拟机里的“后门”或者“管理面板”允许你在应用运行时去查看它的内部状态甚至动态调整一些参数而无需重启服务。听起来很酷对吧但很多开发者对JMX的态度是“知道有这么个东西但没怎么用过”或者仅仅用它来连接一下JConsole看看内存和线程。这其实大大低估了它的价值。JMX全称Java Management Extensions是Java平台为管理和监控应用程序、设备、服务等资源而定义的一套标准架构和API。它的核心思想是“管理Bean”也就是MBean。你可以把任何一个你想暴露出去进行管理的Java对象包装成一个MBean然后注册到JMX的MBean服务器中。之后外部的管理工具比如JConsole、VisualVM或者你自己写的客户端就能通过一套标准的协议最常用的是RMI连接到这个服务器发现这些MBean并调用它们的方法、读取或修改它们的属性。我最初接触JMX是为了解决一个线上问题一个核心服务的内存使用模式很奇怪每隔几小时就会缓慢增长但通过常规日志又看不出端倪。重启大法虽然有效但治标不治本。后来我们通过JMX暴露了应用内部的一些缓存统计信息和对象池状态再结合监控工具进行周期性采集很快就定位到是一个第三方库的连接池存在轻微的泄漏。从那以后JMX就成了我工具箱里的常备项。它不仅用于紧急问题排查更可以用于日常的运维自动化比如动态调整日志级别、开关某个功能特性、触发一次数据缓存刷新等。所以这篇详解的目的就是带你从“知道”到“精通”不仅理解JMX的原理更能把它用在实际项目中解决真实问题。无论你是开发、测试还是运维掌握JMX都能让你对运行中的Java应用有更强的掌控力。2. JMX架构核心三要素深度拆解要玩转JMX必须吃透它的三层架构。这不像学习一些应用框架可以“黑盒”使用。理解架构能让你在遇到连接、序列化或权限问题时快速找到根源。2.1 探针层MBean的四种形态与设计抉择探针层由被管理的资源构成具体表现为MBean。MBean有四种类型选择哪种类型直接决定了你代码的复杂度和灵活性。1. 标准MBean这是最简单、最直接的一种。它的管理接口通过一个固定的命名规范来定义实现类名 MBean。例如你有一个实现类叫CacheManager那么它的管理接口就必须定义在一个名为CacheManagerMBean的接口里。// 管理接口 public interface CacheManagerMBean { int getCacheSize(); void setCacheSize(int size); void clearCache(); String getCacheStats(); } // 实现类 public class CacheManager implements CacheManagerMBean { private int cacheSize 1000; Override public int getCacheSize() { return cacheSize; } Override public void setCacheSize(int size) { this.cacheSize size; } Override public void clearCache() { /* 清空缓存逻辑 */ } Override public String getCacheStats() { return 一些统计信息; } }注意标准MBean的接口命名必须严格遵守这个规范否则JMX代理将无法正确识别和注册。这是新手最容易踩的坑之一。我建议在项目初期如果暴露的属性方法比较固定可以使用标准MBean简单明了。2. 动态MBean当你的管理接口在编译期无法确定或者希望更灵活地暴露属性、方法时动态MBean是更好的选择。它通过实现javax.management.DynamicMBean接口在运行时动态地提供元数据MBeanInfo和操作逻辑。public class DynamicCacheManager implements DynamicMBean { private final MapString, Object attributes new HashMap(); private final MBeanInfo mBeanInfo; public DynamicCacheManager() { attributes.put(CacheSize, 1000); attributes.put(HitRate, 0.95); // 动态构建MBeanInfo描述属性、操作等 mBeanInfo createMBeanInfo(); } Override public Object getAttribute(String attribute) { return attributes.get(attribute); } Override public void setAttribute(Attribute attribute) { attributes.put(attribute.getName(), attribute.getValue()); } Override public MBeanInfo getMBeanInfo() { return mBeanInfo; } // ... 其他方法如invoke }动态MBean给了你最大的控制权但代价是代码量增加。它非常适合用来包装那些本身不是为JMX设计的、结构复杂的遗留对象或者需要根据配置动态生成管理界面的场景。3. 开放MBean 模型MBean这两种是更特殊的动态MBean。开放MBean使用一组预定义的、简单的数据类型如SimpleType旨在确保管理客户端即使没有MBean的特定类也能理解其数据。这在需要跨网络、跨语言互操作的复杂管理系统中可能用到但在日常Web应用开发中比较少见。模型MBean提供了一个完整的、默认的实现框架RequiredModelMBean。你不需要实现DynamicMBean的所有方法只需要准备好元数据ModelMBeanInfo和目标管理对象模型MBean会帮你处理调用转发。它可以看作是一个“通用适配器”能快速将任何已有的POJO适配成MBean而无需修改其源代码。Spring的JMX支持底层就大量使用了模型MBean的概念。实操心得如何选择新手或简单场景无脑用标准MBean。规则简单不易出错。需要包装复杂现有对象或接口动态使用动态MBean或借助Spring等框架它们内部使用模型MBean。除非有明确的跨平台互操作需求否则可以暂时忽略开放MBean。2.2 代理层MBeanServer的连接枢纽与注册细节代理层是JMX架构的核心主要由MBean服务器构成。你可以把它理解为一个注册中心或目录服务。所有在应用中创建的MBean实例都必须注册到这个服务器里才能被管理。关键对象MBeanServer通常通过ManagementFactory.getPlatformMBeanServer()获取。这是一个单例的、由JVM平台提供的服务器。注册MBean的学问注册时你需要提供一个唯一的ObjectName。它的格式是一个带域的字符串例如com.yourcompany:typeCache,nameUserCache。com.yourcompany是域通常用公司或组织反向域名避免冲突。type和name是键值对属性用于分类和唯一标识。MBeanServer mbs ManagementFactory.getPlatformMBeanServer(); CacheManager cacheMBean new CacheManager(); ObjectName objectName new ObjectName(com.example:typeCacheManager,nameDefault); mbs.registerMBean(cacheMBean, objectName);重要提示ObjectName的设计要有规划。混乱的命名会导致管理工具中对象树难以浏览。我建议制定一个团队内的命名规范例如[domain]:type[组件类型],subtype[子类型],name[具体实例名]。2.3 分布式服务层连接协议与安全考量这一层负责让远程的管理工具能够访问到代理层的MBean服务器。最经典的方式是使用JMXMP或基于RMI的连接。1. 启用远程JMX连接对于独立Java应用通常在启动JVM时添加参数java -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port9010 \ -Dcom.sun.management.jmxremote.sslfalse \ -Dcom.sun.management.jmxremote.authenticatefalse \ -jar your-app.jarport指定监听端口。ssl是否启用SSL加密。在生产环境务必设置为true否则管理流量是明文的。authenticate是否启用密码认证。生产环境必须开启。2. 更安全的实践通过SSH隧道连接直接暴露JMX RMI端口到公网是极度危险的。更安全的做法是只允许本地访问然后通过SSH隧道将本地端口转发到远程服务器。# 在本地机器执行 ssh -L 9010:localhost:9010 useryour-remote-server这条命令将远程服务器的9010端口映射到本地的9010端口。然后你可以在本地的JConsole中连接localhost:9010流量将通过加密的SSH通道传输。3. 在Spring Boot等现代框架中的应用Spring Boot对JMX有自动配置支持。默认情况下它会在org.springframework.boot域下注册很多应用本身的MBean如端点信息。你也可以轻松地使用ManagedResource、ManagedAttribute、ManagedOperation注解来暴露自己的Bean。Component ManagedResource(objectName com.example:typeBusiness,nameOrderService) public class OrderService { private volatile boolean featureEnabled true; ManagedAttribute(description 是否启用某功能) public boolean isFeatureEnabled() { return featureEnabled; } ManagedAttribute public void setFeatureEnabled(boolean featureEnabled) { this.featureEnabled featureEnabled; } ManagedOperation(description 手动触发订单对账) public String reconcileOrders() { // 执行对账逻辑 return 对账完成; } }Spring Boot会自动将这些注解的Bean注册到MBean服务器无需手动编写registerMBean代码极大地简化了开发。3. 从零到一构建一个可管理的应用实例理论讲完了我们动手构建一个模拟的“用户会话缓存服务”并通过JMX来管理它。这个例子将涵盖属性暴露、操作调用和通知发送。3.1 定义MBean接口与实现我们采用标准MBean方式因为它最清晰。// SessionCacheMBean.java public interface SessionCacheMBean { // 属性 int getMaxSessions(); void setMaxSessions(int max); int getCurrentSessionCount(); long getCacheHitCount(); long getCacheMissCount(); // 操作 String getCacheStatus(); void clearAllSessions(); SessionInfo getSessionDetails(String sessionId); ListString listAllSessionIds(); // 我们还会在实现中发送通知 } // SessionInfo.java (一个简单的值对象) public class SessionInfo implements Serializable { private String sessionId; private String userId; private Date creationTime; private Date lastAccessTime; // getters and setters }// SessionCache.java public class SessionCache implements SessionCacheMBean { private final MapString, SessionInfo cache new ConcurrentHashMap(); private volatile int maxSessions 10000; private final AtomicLong hitCount new AtomicLong(); private final AtomicLong missCount new AtomicLong(); private final MBeanServer mbs; private final ObjectName objectName; private final NotificationBroadcasterSupport broadcaster new NotificationBroadcasterSupport(); public SessionCache() throws Exception { this.mbs ManagementFactory.getPlatformMBeanServer(); this.objectName new ObjectName(com.example.session:typeCache,nameUserSessionCache); mbs.registerMBean(this, objectName); // 注册一个监听器监听自身发出的通知演示用 mbs.addNotificationListener(objectName, this::handleNotification, null, null); } // 属性实现 Override public int getMaxSessions() { return maxSessions; } Override public void setMaxSessions(int max) { if (max 0) throw new IllegalArgumentException(Max sessions cannot be negative); int oldMax this.maxSessions; this.maxSessions max; // 属性改变时发送一个通知 AttributeChangeNotification notification new AttributeChangeNotification( this, System.currentTimeMillis(), System.currentTimeMillis(), MaxSessions changed, MaxSessions, int, String.valueOf(oldMax), String.valueOf(max) ); broadcaster.sendNotification(notification); System.out.println(MaxSessions updated from oldMax to max); } Override public int getCurrentSessionCount() { return cache.size(); } Override public long getCacheHitCount() { return hitCount.get(); } Override public long getCacheMissCount() { return missCount.get(); } // 操作实现 Override public String getCacheStatus() { double hitRate (hitCount.get() missCount.get()) 0 ? 0 : (double) hitCount.get() / (hitCount.get() missCount.get()); return String.format(Sessions: %d/%d, HitRate: %.2f%%, Hits: %d, Misses: %d, cache.size(), maxSessions, hitRate * 100, hitCount.get(), missCount.get()); } Override public void clearAllSessions() { int cleared cache.size(); cache.clear(); System.out.println(Cleared cleared sessions.); // 发送一个自定义通知 Notification notification new Notification( session.cache.cleared, this, System.currentTimeMillis(), All sessions have been cleared. Count: cleared ); broadcaster.sendNotification(notification); } Override public SessionInfo getSessionDetails(String sessionId) { SessionInfo info cache.get(sessionId); if (info ! null) { hitCount.incrementAndGet(); } else { missCount.incrementAndGet(); } return info; } Override public ListString listAllSessionIds() { return new ArrayList(cache.keySet()); } // 业务方法非MBean接口 public void putSession(String sessionId, SessionInfo info) { if (cache.size() maxSessions) { // 简单的LRU实现这里简化为随机移除一个 IteratorString it cache.keySet().iterator(); if (it.hasNext()) { cache.remove(it.next()); } } cache.put(sessionId, info); } // 处理通知的方法 private void handleNotification(Notification notification, Object handback) { System.out.println([JMX Notification Received] Type: notification.getType() , Message: notification.getMessage() , Source: notification.getSource()); } }3.2 启动应用并注册MBean我们需要一个主类来启动应用并初始化我们的缓存管理器。// ApplicationMain.java public class ApplicationMain { public static void main(String[] args) throws Exception { System.out.println(Starting Application with JMX...); // 初始化SessionCache它会在构造函数中自动注册自己 SessionCache sessionCache new SessionCache(); // 模拟一些业务操作 for (int i 0; i 5; i) { String sessionId sess_ i; SessionInfo info new SessionInfo(); info.setSessionId(sessionId); info.setUserId(user_ i); info.setCreationTime(new Date()); sessionCache.putSession(sessionId, info); } System.out.println(Application started. JMX MBean registered.); System.out.println(You can connect via JConsole using local JMX connection.); // 保持主线程运行 Thread.sleep(Long.MAX_VALUE); } }编译并运行这个应用javac -cp . *.java java -cp . ApplicationMain3.3 使用JConsole进行连接与管理打开终端输入jconsole命令启动JConsole。在“新建连接”对话框中找到本地进程列表里的ApplicationMain双击连接。连接成功后切换到“MBean”标签页。在左侧树形导航中展开com.example.session-Cache-UserSessionCache。你现在可以看到属性点击Attributes你能看到CurrentSessionCount,MaxSessions等。尝试双击MaxSessions的值修改为3然后点击“刷新”。你会看到控制台输出属性已更改并且缓存可能会因为新上限而触发清理。操作点击Operations你会看到clearAllSessions,getCacheStatus等方法。点击getCacheStatus的“调用”按钮结果会显示在下方。点击clearAllSessions所有会话将被清空控制台会打印日志并发送通知。通知虽然JConsole对通知的支持不直观但我们的handleNotification方法会在控制台打印出收到的通知信息。通过这个实操你就能直观地感受到JMX如何将应用内部状态和控制权暴露出来实现“运行时管理”。4. 超越JConsole高级客户端与自动化运维JConsole和VisualVM是优秀的图形化入门工具但在生产环境自动化运维中我们更需要编程式访问和集成。4.1 使用JMX API编写自定义客户端你可以编写Java程序远程连接JMX服务器并操作MBean。// JmxClientDemo.java import javax.management.*; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import java.util.Arrays; public class JmxClientDemo { public static void main(String[] args) throws Exception { // 1. 构建JMX服务URL (假设远程服务器IP为192.168.1.100端口9010) String jmxUrl service:jmx:rmi:///jndi/rmi://192.168.1.100:9010/jmxrmi; JMXServiceURL url new JMXServiceURL(jmxUrl); // 2. 创建连接这里省略了认证信息生产环境需要 JMXConnector connector JMXConnectorFactory.connect(url, null); MBeanServerConnection mbsc connector.getMBeanServerConnection(); // 3. 构建要操作的MBean的ObjectName ObjectName objectName new ObjectName(com.example.session:typeCache,nameUserSessionCache); // 4. 获取属性 Integer maxSessions (Integer) mbsc.getAttribute(objectName, MaxSessions); Integer currentCount (Integer) mbsc.getAttribute(objectName, CurrentSessionCount); System.out.printf(Cache Status: %d/%d sessions%n, currentCount, maxSessions); // 5. 设置属性动态调整最大会话数 Attribute newMaxAttr new Attribute(MaxSessions, 5000); mbsc.setAttribute(objectName, newMaxAttr); System.out.println(MaxSessions has been set to 5000); // 6. 调用操作 String status (String) mbsc.invoke(objectName, getCacheStatus, null, null); System.out.println(Cache Status Report: status); // 7. 查询所有匹配的MBean模式查询 SetObjectName mbeans mbsc.queryNames(new ObjectName(com.example.session:*), null); System.out.println(Found MBeans under domain com.example.session:); for (ObjectName name : mbeans) { System.out.println( - name); } connector.close(); } }这个客户端程序可以集成到你的运维脚本或监控系统中定期拉取指标或执行管理操作。4.2 与监控系统集成Prometheus JMX Exporter在现代微服务架构中Prometheus是主流的监控解决方案。但Prometheus使用Pull模型和特定的数据格式无法直接读取JMX。这时就需要一个“翻译官”——JMX Exporter。JMX Exporter是一个Java Agent它作为一个桥梁从MBean服务器中拉取数据并将其转换为Prometheus能够抓取的HTTP端点通常是/metrics。使用步骤下载jmx_prometheus_javaagent.jar。编写配置文件jmx-config.yaml定义哪些MBean属性需要被暴露为Prometheus指标。# jmx-config.yaml lowercaseOutputName: true rules: - pattern: com.example.session:typeCache,nameUserSessionCache name: session_cache labels: cache_name: $1 attrNameSnakeCase: true type: GAUGE attributes: CurrentSessionCount: alias: sessions_current MaxSessions: alias: sessions_max - pattern: com.example.session:typeCache,nameUserSessionCache name: session_cache_operations labels: cache_name: $1 type: COUNTER attributes: CacheHitCount: alias: hits_total CacheMissCount: alias: misses_total启动应用时挂载Agentjava -javaagent:./jmx_prometheus_javaagent.jar9100:./jmx-config.yaml \ -jar your-spring-boot-app.jar这会在应用内部启动一个HTTP服务器监听9100端口并提供/metrics端点。配置Prometheus抓取在Prometheus的scrape_configs中添加这个目标。之后你就可以在Grafana中基于session_cache_sessions_current、session_cache_operations_hits_total等指标创建丰富的监控仪表盘了。这种方式将JMX的管理能力无缝融入了云原生监控体系是生产环境的最佳实践。5. 生产环境实战问题排查与性能调优在实际使用中JMX本身也可能成为问题源。下面记录几个我踩过的坑和对应的解决方案。5.1 常见连接问题与防火墙配置问题无法远程连接JMXConnection refused。排查检查JVM参数确认启动参数中正确设置了-Dcom.sun.management.jmxremote.port并且没有设置-Dcom.sun.management.jmxremote.local.onlytrue该参数限制仅本地连接。检查RMI端口JMX over RMI实际上会使用两个端口一个是你指定的注册端口如9010另一个是随机的高位端口用于数据传输。防火墙必须同时放行这两个端口。解决方案A推荐固定RMI通信端口。添加JVM参数-Dcom.sun.management.jmxremote.rmi.port9011然后确保防火墙开放9010和9011两个端口。解决方案B使用JMXMP连接器需要额外jar包它只使用一个端口。解决方案C如前所述使用SSH隧道绕过复杂的防火墙规则。5.2 MBean注册冲突与内存泄漏问题在Web容器如Tomcat中重新部署应用时可能会报InstanceAlreadyExistsException或者旧的MBean没有被注销导致内存泄漏。原因Web应用停止时其ClassLoader被销毁但注册在平台级MBeanServer中的MBean可能没有被及时清理。解决方案对于Spring/Spring Boot应用利用生命周期回调。实现DisposableBean接口或在Bean上使用PreDestroy注解在Bean销毁时主动注销MBean。Component ManagedResource public class MyManagedService implements DisposableBean { private ObjectName objectName; PostConstruct public void init() throws Exception { MBeanServer mbs ManagementFactory.getPlatformMBeanServer(); this.objectName new ObjectName(com.example:typeMyService); mbs.registerMBean(this, objectName); } Override public void destroy() throws Exception { ManagementFactory.getPlatformMBeanServer().unregisterMBean(objectName); } }对于Servlet应用可以注册一个ServletContextListener在contextDestroyed方法中遍历并注销属于本应用的所有MBean。5.3 安全加固启用SSL与认证生产环境绝对不要使用无认证、无加密的JMX连接。生成密钥库和证书可以使用Java的keytool。配置启用SSL和认证的JVM参数-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port9010 -Dcom.sun.management.jmxremote.ssltrue -Dcom.sun.management.jmxremote.registry.ssltrue -Dcom.sun.management.jmxremote.authenticatetrue -Dcom.sun.management.jmxremote.password.file/path/to/jmxremote.password -Dcom.sun.management.jmxremote.access.file/path/to/jmxremote.access -Djavax.net.ssl.keyStore/path/to/keystore.jks -Djavax.net.ssl.keyStorePasswordchangeit -Djavax.net.ssl.trustStore/path/to/truststore.jks -Djavax.net.ssl.trustStorePasswordchangeit需要正确配置jmxremote.password用户密码和jmxremote.access用户权限文件并确保其文件权限是只读的chmod 400。5.4 性能影响与最佳实践暴露大量MBean或频繁调用MBean操作会对性能产生轻微影响。遵循以下最佳实践可以最小化影响只暴露必要的属性和操作不要为了暴露而暴露。只将真正用于监控和管理的核心指标和管控点做成MBean。属性设计为轻量级getAttribute操作应尽可能快返回基本类型或简单对象。避免在Getter方法中执行复杂的计算或IO操作。对于复杂数据考虑提供专门的getReport()这样的操作方法来获取。谨慎使用通知JMX通知是推模型监听器处理不当可能阻塞MBean服务器线程。确保通知监听器的逻辑是异步且非阻塞的。使用连接池对于自定义的JMX客户端如果需要频繁连接考虑使用连接池来避免重复建立连接的开销。JMX是一个强大但略显“古老”的工具。在现代架构中它的角色更多是作为应用内部指标的“数据源”通过Agent导出到Prometheus等现代监控系统。然而其直接、动态的管理能力在调试、紧急干预和深度诊断场景下依然是不可替代的利器。理解其原理善用其特性能让你在应对复杂的Java应用时更加游刃有余。

相关新闻

丙午年六月廿四观行径

丙午年六月廿四观行径

丙午年六月廿四观行径原来浅缘埋深情,终是真爱葬假欲。连年轨迹见形式,断章取义观几许?人心难测怕久远,冠冕堂皇入残局。明灯映月水中花,暗影黑夜新衣曲?

2026/8/6 7:34:28 阅读更多 →
多智能体系统实战:链式指挥与共享画布构建高效AI协作架构

多智能体系统实战:链式指挥与共享画布构建高效AI协作架构

1. 从单体智能到组织化协作:为什么我们需要“多智能体”?如果你最近在关注AI领域,尤其是大模型的应用,可能会发现一个明显的趋势:大家不再满足于让一个“超级大脑”去处理所有事情了。无论是开发者社区里的讨论&#x…

2026/8/6 7:33:27 阅读更多 →
企业内训知识助手:怎么搭才不踩坑

企业内训知识助手:怎么搭才不踩坑

员工问"年假怎么算"“报销流程是什么”“这个系统怎么用”,过去全靠 HR 和 IT 人肉答。企业搭建内训知识助手,把这些问答自动化,是 AI 落地最稳的场景之一。但搭不好也有坑:知识过期、答非所问、敏感制度外泄。企业 AI …

2026/8/6 7:33:27 阅读更多 →

最新新闻

117、Zephyr RTOS网络协议栈基础:MQTT客户端

117、Zephyr RTOS网络协议栈基础:MQTT客户端

Zephyr RTOS网络协议栈基础:MQTT客户端 上周调试产线上的一个温湿度采集节点,MQTT客户端连上Broker后,每隔十几秒就断线重连一次。抓包看了半天,发现是KeepAlive报文发送时机出了问题——Zephyr的MQTT库默认心跳间隔是60秒,而我设置的Publish频率是30秒,结果Broker以为客…

2026/8/6 8:22:56 阅读更多 →
短视频配音工具哪个好用?2026主流工具横向测评排行榜

短视频配音工具哪个好用?2026主流工具横向测评排行榜

测评背景与说明短视频赛道竞争加剧,配音直接影响视频完播率。2026年AI配音工具迭代速度加快,市面产品在自然度、批量产出、版权、配套功能上差距明显,很多创作者挑选时容易被宣传话术误导,出现配音机械生硬、商用版权存风险、大批…

2026/8/6 8:22:56 阅读更多 →
字符串规范化实战:从特殊字符处理到多语言Slug生成

字符串规范化实战:从特殊字符处理到多语言Slug生成

最近在开发一个需要处理用户输入和动态内容生成的项目时,遇到了一个有趣的挑战:如何优雅地处理那些包含特殊字符、空格甚至非ASCII字符的字符串标识符,比如“芙兰朵露的i cant wait”。这类字符串直接用作文件名、URL路径或数据库键值时&…

2026/8/6 8:22:56 阅读更多 →
Qwen3.8-Max vs Kimi K3部署对比:API验证、开放权重与集群规划

Qwen3.8-Max vs Kimi K3部署对比:API验证、开放权重与集群规划

Qwen3.8-Max与Kimi K3都面向Coding、知识工作、多模态和长程Agent,也都公布了万亿级总参数和约1M Token上下文窗口。截至2026年8月5日,两款模型都可通过API开展业务验证,但可用于自托管评估的公开材料处于不同阶段。阿里云百炼当前已经列出模…

2026/8/6 8:22:56 阅读更多 →
Bullet Physics 三维碰撞检测:从原理到工程实践

Bullet Physics 三维碰撞检测:从原理到工程实践

1. 从“撞上”到“检测”:三维碰撞检测的工程意义 在三维虚拟世界里,一个角色能否走上台阶,一颗子弹能否击中目标,一辆赛车是否会撞上护栏,这些看似简单的交互背后,都依赖着一套复杂而精密的计算系统——三…

2026/8/6 8:22:56 阅读更多 →
PyTorch深度学习实验可视化:TensorBoard核心API详解与工程实践

PyTorch深度学习实验可视化:TensorBoard核心API详解与工程实践

1. 项目概述:为什么我们需要TensorBoard 在PyTorch项目里埋头苦干,调参、改网络结构、跑实验,一跑就是几个小时甚至几天。结果出来了,看着命令行里打印的一行行损失值和准确率,是不是总觉得少了点什么?没错…

2026/8/6 8:21:55 阅读更多 →

日新闻

深入解析LimboAI C++内核:架构设计与性能优化实战

深入解析LimboAI C++内核:架构设计与性能优化实战

1. 项目概述:为什么我们需要深入LimboAI的C内核?如果你是一名使用Godot引擎的游戏开发者,尤其是对AI行为逻辑有较高要求的项目,那么LimboAI这个名字你大概率不会陌生。它作为Godot 4生态中一个备受瞩目的行为树与状态机插件&#…

2026/8/6 0:00:06 阅读更多 →
Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

1. 项目概述与核心思路大家好,我是老张,一个在游戏开发一线摸爬滚打了十多年的老码农。今天咱们接着聊《空洞骑士》风格2D动作游戏的Demo制作。上一期我们搭好了基础框架,处理了角色移动和碰撞,这一期,我们要让游戏世界…

2026/8/6 0:00:06 阅读更多 →
被动防火门市场前景发展趋势

被动防火门市场前景发展趋势

被动防火门依靠材质结构、密闭构造阻隔烟火蔓延,无需电控启动,是建筑被动消防系统核心构件,行业依托新规管控、城市更新、工业安全升级迎来稳定扩容,整体朝着合规化、专项化、低碳化、智能化方向发展。现阶段 GB12955‑2024 新版国…

2026/8/6 0:00:06 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/5 15:00:43 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/5 13:13:56 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/5 10:20:36 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/5 23:28:39 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/5 21:00:14 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/5 23:46:51 阅读更多 →