23. Exceptions

本文介绍了C#中的异常处理机制,对比了C#与C++的异常处理方式,并详细阐述了C#中所有异常必须是System.Exception类派生类的实例这一特性。此外,文章还提到了C#特有的finally块,它可以确保无论是在正常执行还是异常情况下都能执行终止代码。
Exceptions in C# provide a structured, uniform, and type-safe way of
handling both system level and
application-level error conditions. [Note: The exception mechanism is C# is
quite similar to that of C++,
with a few important differences:
? In C#, all exceptions must be represented by an instance of a class type
derived from
System.Exception. In C++, any value of any type can be used to represent an
exception.
? In C#, a finally block (§15.10) can be used to write termination code
that executes in both normal
execution and exceptional conditions. C++ has no equivalent construct.
? In C#, system-level exceptions such as overflow, divide-by-zero, and null
dereferences have well
defined exception classes and are on a par with application-level error
conditions.
end note]
2025-10-23 14:37:22.339 [http-nio-9001-exec-13] INFO c.k.k.admin.service.impl.IdGeneratorServiceImp - KEY:PACKING, 序列号生成:0010, 过期时间:2025-10-23 23:59:59 2025-10-23 14:39:51.614 [Druid-ConnectionPool-Create-2061372360] ERROR com.alibaba.druid.pool.DruidDataSource - create connection SQLException, url: jdbc:mysql://rm-uf66985258r4o1kdjzo.mysql.rds.aliyuncs.com/kpsnc_upom_mes?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone, errorCode 0, state 08001 java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up. at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73) at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:906) at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:831) at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456) at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246) at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:156) at com.alibaba.druid.filter.FilterAdapter.connection_connect(FilterAdapter.java:787) at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:150) at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:218) at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:150) at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1646) at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1710) at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2779) Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:89) at com.mysql.cj.NativeSession.connect(NativeSession.java:144) at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:850) ... 12 common frames omitted Caused by: java.net.UnknownHostException: rm-uf66985258r4o1kdjzo.mysql.rds.aliyuncs.com at java.net.InetAddress$CachedAddresses.get(InetAddress.java:764) at java.net.InetAddress.getAllByName0(InetAddress.java:1291) at java.net.InetAddress.getAllByName(InetAddress.java:1144) at java.net.InetAddress.getAllByName(InetAddress.java:1065) at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:132) at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63) ... 14 common frames omitted 2025-10-23 14:39:55.639 [Druid-ConnectionPool-Create-2061372360] ERROR com.alibaba.druid.pool.DruidDataSource - create connection SQLException, url: jdbc:mysql://rm-uf66985258r4o1kdjzo.mysql.rds.aliyuncs.com/kpsnc_upom_mes?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone, errorCode 0, state 08001 java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up. at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73) at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:906) at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:831) at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456) at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246) at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:156) at com.alibaba.druid.filter.FilterAdapter.connection_connect(FilterAdapter.java:787) at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:150) at com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:218) at com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:150) at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1646) at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1710) at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2779) Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:89) at com.mysql.cj.NativeSession.connect(NativeSession.java:144) at com.mysql.cj.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:850) ... 12 common frames omitted Caused by: java.net.UnknownHostException: rm-uf66985258r4o1kdjzo.mysql.rds.aliyuncs.com at java.net.InetAddress$CachedAddresses.get(InetAddress.java:764) at java.net.InetAddress.getAllByName0(InetAddress.java:1291) at java.net.InetAddress.getAllByName(InetAddress.java:1144) at java.net.InetAddress.getAllByName(InetAddress.java:1065) at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:132) at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63) ... 14 common frames omitted 2025-10-23 14:39:55.639 [Druid-ConnectionPool-Create-2061372360] INFO com.alibaba.druid.pool.DruidAbstractDataSource - {dataSource-1} failContinuous is true
最新发布
10-24
你提供的日志信息显示了一个典型的 **数据库连接失败问题**,具体表现为:Java 应用通过 Druid 连接池尝试连接阿里云 RDS MySQL 实例时,出现了 `java.net.UnknownHostException`,导致无法建立数据库连接。 --- ### 🔍 问题分析 关键错误如下: ```log Caused by: java.net.UnknownHostException: rm-uf66985258r4o1kdjzo.mysql.rds.aliyuncs.com ``` 这个异常说明: > JVM 在进行 DNS 解析时,无法将域名 `rm-uf66985258r4o1kdjzo.mysql.rds.aliyuncs.com` 解析为 IP 地址。 这意味着: - 网络不通或 DNS 配置有问题; - 或者该数据库实例已被删除/停机; - 或者当前服务器不具备访问公网(或内网)的能力; - 或者是安全组、VPC、白名单等网络策略限制了访问。 此外还有: ```log java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up. ``` 这表明连接重试机制已触发但无效,属于**非瞬时性连接异常**,不会自动恢复。 --- ### ✅ 解决方案与排查步骤 #### ✅ 步骤 1:确认域名是否正确 检查你的 JDBC URL 中的主机名是否拼写正确: ```url jdbc:mysql://rm-uf66985258r4o1kdjzo.mysql.rds.aliyuncs.com/kpsnc_upom_mes?... ``` 请登录 [阿里云控制台](https://rds.console.aliyun.com/),进入对应 RDS 实例详情页,在「连接信息」中核对 **实际的内网或外网地址** 是否与此一致。 > ⚠️ 常见错误:使用了已释放的实例地址、复制错字符、用了不可达的外网地址等。 --- #### ✅ 步骤 2:测试 DNS 解析能力(在应用服务器上执行) 登录运行该 Java 应用的服务器,执行以下命令: ```bash nslookup rm-uf66985258r4o1kdjzo.mysql.rds.aliyuncs.com # 或 ping rm-uf66985258r4o1kdjzo.mysql.rds.aliyuncs.com ``` 如果返回类似: ``` Host rm-uf66985258r4o1kdjzo.mysql.rds.aliyuncs.com not found: 3(NXDOMAIN) ``` 说明 DNS 无法解析。可能原因包括: - 服务器未配置正确的 DNS(如缺少 8.8.8.8 或阿里云 DNS) - 使用的是 VPC 内网地址,但从公网环境访问 - 实例已被释放,域名不再有效 🔧 **修复方法**: 如果是内网连接,请确保: - 应用部署在与 RDS 同一地域、同一 VPC 的 ECS 上; - 使用 RDS 提供的 **内网连接地址**; - 安全组允许从 ECS 到 RDS 的 3306 端口通信。 --- #### ✅ 步骤 3:检查网络连通性(端口可达性) 即使能 ping 通也不代表可用(MySQL 不响应 ping),需测试端口: ```bash telnet rm-uf66985258r4o1kdjzo.mysql.rds.aliyuncs.com 3306 # 或 nc -zv rm-uf66985258r4o1kdjzo.mysql.rds.aliyuncs.com 3306 ``` 预期输出应为连接成功。若失败,则可能是: - 安全组未放行目标端口; - RDS 实例设置了白名单(IP 白名单为空或未包含当前服务器 IP); - 跨区域跨 VPC 导致路由不可达。 📌 **建议操作**: 前往阿里云 RDS 控制台 → 设置白名单 → 将当前应用服务器的公网/IP 加入白名单(生产环境慎用公网访问)。 --- #### ✅ 步骤 4:调整 JDBC 参数以增强健壮性(可选优化) 虽然不能解决根本问题,但可以避免频繁重试和超时过长: ```properties jdbc.url=jdbc:mysql://rm-uf66985258r4o1kdjzo.mysql.rds.aliyuncs.com:3306/kpsnc_upom_mes\ ?characterEncoding=utf8\ &connectTimeout=3000\ &socketTimeout=5000\ &autoReconnect=false\ # 推荐关闭自动重连,由连接池管理 &useSSL=false\ &serverTimezone=Asia/Shanghai\ &allowPublicKeyRetrieval=true ``` 同时,在 Druid 数据源配置中设置合理参数: ```java @Bean public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:..."); dataSource.setUsername("..."); dataSource.setPassword("..."); // 连接池配置 dataSource.setInitialSize(5); dataSource.setMinIdle(5); dataSource.setMaxActive(20); dataSource.setPoolPreparedStatements(true); // 连接检测(重要!) dataSource.setTestOnBorrow(false); // 可开启 TestWhileIdle + ValidationQuery 更高效 dataSource.setTestWhileIdle(true); dataSource.setValidationQuery("SELECT 1"); // 避免无限等待 dataSource.setConnectTimeout(3000); dataSource.setSocketTimeout(5000); return dataSource; } ``` --- #### ✅ 步骤 5:查看 RDS 实例状态 登录阿里云控制台,确认: - RDS 实例状态是否为“运行中”; - 是否到期被锁定或释放; - 是否切换为主备、正在进行维护; - 是否开启了“SSL 加密”,而客户端未配置相应证书。 --- ### 🧩 总结解决方案流程图 ``` [应用报 UnknownHostException] ↓ → 检查域名拼写 ✅ ↓ → 在服务器执行 nslookup / ping / telnet 测试 ↓ ↗ 成功 → 可能是临时抖动 → 增加重试/监控 ↘ 失败 ↓ → 是内网地址?必须同 VPC 内访问 ✅ ↓ → 安全组 & 白名单是否放行? ✅ ↓ → 实例是否存在且运行正常? ✅ ↓ → 修改为正确地址或修复网络环境 ✅ ``` --- ### 💡 补充建议 1. **不要依赖公网连接生产数据库**,尽量使用内网 + VPC 架构。 2. 使用 **内网域名**(如 `rm-xxxx.mysql.internal`)而非外网域名。 3. 开启 **专有网络 VPC 内的 PrivateLink 或 CEN 跨账号互通**,提高安全性。 4. 添加健康检查接口 `/health/db` 返回数据库连接状态,便于运维监控。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值