微服务时代java异常捕捉
一、尽量不要使用e.printStackTrace(),而是使用log打印。
反例:
try{
// do what you want
}catch(Exception e){
e.printStackTrace();
}
正例:
try{
// do what you want
}catch(Exception e){
log.info("你的程序有异常啦,{}",e);
}
理由:
printStackTrace()打印出的堆栈日志跟业务代码日志是交错混合在一起的,排查异常日志不太方便。
e.printStackTrace()语句产生的字符串记录的是堆栈信息,如果信息太长太多,字符串常量池所在的内存块没有空间了,即内存满了,那么,用户的请求就卡住啦~
二、catch了异常,但是没有打印出具体的exception,无法更好定位问题
反例:
try{
// do what you want
}catch(Exception e){
log.info("你的程序有异常啦");
}
正例:
try{
// do what you want
}catch(Exception e){
log.info("你的程序有异常啦,{}",e);
}
理由:
反例中,并没有把exception出来,到时候排查问题就不好查了啦,到底是SQl写错的异常还是IO异常,还是其他呢?所以应该把exception打印到日志中哦~
三、不要用一个Exception捕捉所有可能的异常
反例:
public void test(){
try{
//…抛出 IOException 的代码调用
//…抛出 SQLException 的代码调用
}catch(Exception e){
//用基类 Exception 捕捉的所有可能的异常,如果多个层次都这样捕捉,会丢失原始异常的有效信息哦
log.info(“Exception in test,exception:{}”, e);
}
}
正例:
public void test(){
try{
//…抛出 IOException 的代码调用
//…抛出 SQLException 的代码调用
}catch(IOException e){
//仅仅捕捉 IOException
log.info(“IOException in test,exception:{}”, e);
}catch(SQLException e){
//仅仅捕捉 SQLException
log.info(“SQLException in test,exception:{}”, e);
}
}
理由:
用基类 Exception 捕捉的所有可能的异常,如果多个层次都这样捕捉,会丢失原始异常的有效信息哦
四、记得使用finally关闭流资源或者直接使用try-with-resource
反例:
FileInputStream fdIn = null;
try {
fdIn = new FileInputStream(new File("/jay.txt"));
//在这里关闭流资源?有没有问题呢?如果发生异常了呢?
fdIn.close();
} catch (FileNotFoundException e) {
log.error(e);
} catch (IOException e) {
log.error(e);
}
正例1:
需要使用finally关闭流资源,如下
FileInputStream fdIn = null;
try {
fdIn = new FileInputStream(new File("/jay.txt"));
} catch (FileNotFoundException e) {
log.error(e);
} catch (IOException e) {
log.error(e);
}finally {
try {
if (fdIn != null) {
fdIn.close();
}
} catch (IOException e) {
log.error(e);
}
}
正例2:
当然,也可以使用JDK7的新特性try-with-resource来处理,它是Java7提供的一个新功能,它用于自动资源管理。
资源是指在程序用完了之后必须要关闭的对象。
try-with-resources保证了每个声明了的资源在语句结束的时候会被关闭
什么样的对象才能当做资源使用呢?只要实现了java.lang.AutoCloseable接口或者java.io.Closeable接口的对象,都OK。
try (FileInputStream inputStream = new FileInputStream(new File("jay.txt")) {
// use resources
} catch (FileNotFoundException e) {
log.error(e);
} catch (IOException e) {
log.error(e);
}
理由:
如果不使用finally或者try-with-resource,当程序发生异常,IO资源流没关闭,那么这个IO资源就会被他一直占着,这样别人就没有办法用了,这就造成资源浪费。
五、捕获异常与抛出异常必须是完全匹配,或者捕获异常是抛异常的父类
反例:
//BizException 是 Exception 的子类
public class BizException extends Exception {}
//抛出父类Exception
public static void test() throws Exception {}
try {
test(); //编译错误
} catch (BizException e) { //捕获异常子类是没法匹配的哦
log.error(e);
}
正例:
//抛出子类Exception
public static void test() throws BizException {}
try {
test();
} catch (Exception e) {
log.error(e);
}
六、捕获到的异常,不能忽略它,至少打点日志吧
反例:
public static void testIgnoreException() throws Exception {
try {
// 搞事情
} catch (Exception e) { //一般不会有这个异常}
}
正例:
public static void testIgnoreException() {
try {
// 搞事情
} catch (Exception e) { //一般不会有这个异常
log.error("这个异常不应该在这里出现的,{}",e);
}
}
理由:
虽然一个正常情况都不会发生的异常,但是如果你捕获到它,就不要忽略呀,至少打个日志吧~
七、注意异常对你的代码层次结构的侵染(早发现早处理)
反例:
public UserInfo queryUserInfoByUserId(Long userid) throw SQLException {
//根据用户Id查询数据库
}
正例:
public UserInfo queryUserInfoByUserId(Long userid) {
try{
//根据用户Id查询数据库
}catch(SQLException e){
log.error("查询数据库异常啦,{}",e);
}finally{
//关闭连接,清理资源
}
}
理由:
我们的项目,一般都会把代码分 Action、Service、Dao 等不同的层次结构,如果你是DAO层处理的异常,尽早处理吧,如果往上 throw SQLException,上层代码就还是要try catch处理啦,这就污染了你的代码~
八、自定义封装异常,不要丢弃原始异常的信息Throwable cause
我们常常会想要在捕获一个异常后抛出另一个异常,并且希望把原始异常的信息保存下来,这被称为异常链。公司的框架提供统一异常处理就用到异常链,我们自定义封装异常,不要丢弃原始异常的信息,否则排查问题就头疼啦
反例:
public class TestChainException {
public void readFile() throws MyException{
try {
InputStream is = new FileInputStream("jay.txt");
Scanner in = new Scanner(is);
while (in.hasNext()) {
System.out.println(in.next());
}
} catch (FileNotFoundException e) {
//e 保存异常信息
throw new MyException("文件在哪里呢");
}
}
public void invokeReadFile() throws MyException{
try {
readFile();
} catch (MyException e) {
//e 保存异常信息
throw new MyException("文件找不到");
}
}
public static void main(String[] args) {
TestChainException t = new TestChainException();
try {
t.invokeReadFile();
} catch (MyException e) {
e.printStackTrace();
}
}
}
//MyException 构造器
public MyException(String message) {
super(message);
}
运行结果如下,没有了Throwable cause,不好排查是什么异常了啦
正例:
public class TestChainException {
public void readFile() throws MyException{
try {
InputStream is = new FileInputStream("jay.txt");
Scanner in = new Scanner(is);
while (in.hasNext()) {
System.out.println(in.next());
}
} catch (FileNotFoundException e) {
//e 保存异常信息
throw new MyException("文件在哪里呢", e);
}
}
public void invokeReadFile() throws MyException{
try {
readFile();
} catch (MyException e) {
//e 保存异常信息
throw new MyException("文件找不到", e);
}
}
public static void main(String[] args) {
TestChainException t = new TestChainException();
try {
t.invokeReadFile();
} catch (MyException e) {
e.printStackTrace();
}
}
}
//MyException 构造器
public MyException(String message, Throwable cause) {
super(message, cause);
}
九、运行时异常RuntimeException ,不应该通过catch 的方式来处理,而是先预检查,比如:NullPointerException处理
反例:
try {
obj.method()
} catch (NullPointerException e) {
...
}
正例:if (obj != null){
...
十、注意异常匹配的顺序,优先捕获具体的异常
注意异常的匹配顺序,因为只有第一个匹配到异常的catch块才会被执行。如果你希望看到,是NumberFormatException异常,就抛出NumberFormatException,如果是IllegalArgumentException就抛出IllegalArgumentException。
反例:
try {
doSomething("test exception");
} catch (IllegalArgumentException e) {
log.error(e);
} catch (NumberFormatException e) {
log.error(e);
}
正例:
try {
doSomething("test exception");
} catch (NumberFormatException e) {
log.error(e);
} catch (IllegalArgumentException e) {
log.error(e);
}
理由:
因为NumberFormatException是IllegalArgumentException 的子类,反例中,不管是哪个异常,都会匹配到IllegalArgumentException,就不会再往下执行啦,因此不知道是否是NumberFormatException。所以需要优先捕获具体的异常,把NumberFormatException放前面~
相关文章:
微服务时代java异常捕捉
一、尽量不要使用e.printStackTrace(),而是使用log打印。 反例: try{ // do what you want }catch(Exception e){ e.printStackTrace(); } 正例: try{ // do what you want }catch(Exception e){ log.info("你的程序有异常啦,{}",e)…...
Hadoop支持LZO压缩
LZO(Lempel-Ziv-Oberhumer)是一种快速压缩算法,特别适用于大数据处理。在Hadoop生态系统中,LZO压缩通常用于Hadoop MapReduce作业的输入和输出数据,以减少存储空间和数据传输的开销。 以下是在Hadoop中使用LZO压缩的一般步骤: 安装LZO库和工具: 首先,需要在Hadoop集群…...
vue3 01-setup函数
1.setup函数的作用: 1.是组合式api的入口2.比beforeCreate 执行更早3.没有this组件实例一开始创建vue3页面的时候是这样的 <template></template> <script> export default{setup(){return{ }} } </script>给容器传参在页面中显示 数据给模板使用,以…...
iOS swift 类似AirDrop的近场数据传输 MultipeerConnectivity 框架
文章目录 1.github上的demo 1.github上的demo insidegui/MultipeerDemo – github insidegui/MultipeerKit – github...
Lnton羚通云算力平台OpenCV-PythonCanny边缘检测教程
Canny 边缘检测是一种经典的边缘检测算法,由 John F. Canny 在 1986 年提出。它被广泛应用于计算机视觉和图像处理领域,用于检测图像中的边缘。 【原理】 1. 去噪 由于边缘检测非常容易收到图像的噪声影响,第一步使用 5x5 高斯滤波去除图…...
2023-8-23 滑动窗口
题目链接:滑动窗口 #include <iostream>using namespace std;const int N 1000010;int n, k; int a[N], q[N];int main() {scanf("%d%d", &n, &k);for(int i 0; i < n; i) scanf("%d", &a[i]);int hh 0, tt -1;for(…...
SOA通信中间件常用的通信协议
摘要: SOA(面向服务的架构)的软件设计原则之一是模块化。 前言 SOA(面向服务的架构)的软件设计原则之一是模块化。模块化可以提高软件系统的可维护性和代码重用性,并且能够隔离故障。举例来说,…...
解决npm安装依赖失败,node和node-sass版本不匹配的问题
npm安装依赖报错: npm ERR! cb() never called! npm ERR! This is an error with npm itself. 一. 问题描述 用npm安装依赖报错: npm ERR! cb() never called! npm ERR! This is an error with npm itself. Please report this error at: npm ERR! …...
2023 网络建设与运维 X86架构计算机操作系统安装与管理题解
任务描述: 随着信息技术的快速发展,集团计划2023年把部分业务由原有的X86架构服务器上迁移到ARM架构服务器上,同时根据目前的部分业务需求进行了部分调整和优化。 一、X86架构计算机操作系统安装与管理 1.PC1系统为ubuntu-desktop-amd64系统(已安装,语言为英文),登录用户…...
LAMP 架构及Discuz论坛与Wordpress博客搭建
目录 1 LAMP 配置与应用 1.1动态资源与语言 1.2 LAMP 架构的组成 1.2.1 主要功能 2 编译安装Apache http 服务 2.1 环境准备 2.1.1 关闭防火墙及selinux服务 2.1.2 安装依赖环境 2.2 安装软件包 2.2.1 解压软件包 2.2.2 移动apr包 apr-util包到安装目录中,并…...
考研C语言进阶题库——更新51-60题
目录 51.银行系中有很多恒星,H 君晚上无聊,便爬上房顶数星星,H 君将整个银河系看做一个平面,左上角为原点(坐标为(1, 1))。现在有 n 颗星星,他给每颗星星都标上坐标&…...
智能算法挑战赛决赛题目——初中组
题目 1. 判断是否存在重复的子序列 从 m 个字符中选取字符,生成 n 个符号的序列,使得其中没有 2 个相邻的子序列相同。如从 1,2,3,生成长度为 5 的序列,序列“12321”是合格的,而“12323”和“…...
一分钟学算法-递归-斐波那契数列递归解法及优化
一分钟学一个算法题目。 今天我们要学习的是用递归算法求解斐波那契数列。 首先我们要知道什么是斐波那契数列。 斐波那契数列,又称黄金分割数列,是一个经典的数学数列,其特点是第一项,第二项为1,后面每个数字都是前…...
选择Rust,并在Ubuntu上使用Rust
在过去的 8 年里,Rust 一直是开发人员最喜欢的语言,并且越来越被各种规模的软件公司采用。然而,它的许多高级规则和抽象创造了一个陡峭的初始学习曲线,这可能会给人留下 Rust 是少数人的保留的印象,但这与事实相去甚远…...
SVM详解
公式太多了,就用图片用笔记呈现,SVM虽然算法本质一目了然,但其中用到的数学推导还是挺多的,其中拉格朗日约束关于α>0这块证明我看了很长时间,到底是因为悟性不够。对偶问题也是,用了一个简单的例子才明…...
mysql全文检索使用
数据库数据量10万左右,使用like %test%要耗费30秒左右,放弃该办法 使用mysql的全文检索 第一步:建立索引 首先修改一下设置: my.ini中ngram_token_size 1 可以通过 show variables like %token%;来查看 接下来建立索引:alter table 表名 add f…...
opencv 进阶17-使用K最近邻和比率检验过滤匹配(图像匹配)
K最近邻(K-Nearest Neighbors,简称KNN)和比率检验(Ratio Test)是在计算机视觉中用于特征匹配的常见技术。它们通常与特征描述子(例如SIFT、SURF、ORB等)一起使用,以在图像中找到相似…...
Mac Flutter web环境搭建
获取 Flutter SDK 下载以下安装包来获取最新的 stable Flutter SDK将文件解压到目标路径, 比如: cd ~/development $ unzip ~/Downloads/flutter_macos_3.13.0-stable.zip 配置 flutter 的 PATH 环境变量: export PATH"$PATH:pwd/flutter/bin" // 这个命…...
在外SSH远程连接macOS服务器
文章目录 前言1. macOS打开远程登录2. 局域网内测试ssh远程3. 公网ssh远程连接macOS3.1 macOS安装配置cpolar3.2 获取ssh隧道公网地址3.3 测试公网ssh远程连接macOS 4. 配置公网固定TCP地址4.1 保留一个固定TCP端口地址4.2 配置固定TCP端口地址 5. 使用固定TCP端口地址ssh远程 …...
Dockerfile文件详细
Dockerfile 是一个文本文件,里面包含组装新镜像时用到的基础镜像和各种指令,使用dockerfile 文件来定义镜像,然后运行镜像,启动容器。 dockerfile文件的组成部分 一个dockerfile文件包含以下部分: 基础镜像信息&…...
C语言学习系列-->看淡指针(3)
文章目录 一、字符指针变量二、数组指针变量2.1 概述2.2 数组指针初始化 三、二维数组传参本质四、函数指针五、typedef关键字六、函数指针数组 一、字符指针变量 在指针的类型中我们知道有⼀种指针类型为字符指针 char* 一般使用: #include<stdio.h>int main…...
Java抽象类详解
抽象类 抽象类的概念 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。比如: 说…...
06-微信小程序-注册程序-场景值
06-微信小程序-注册程序 文章目录 注册小程序参数 Object object案例代码 场景值场景值作用场景值列表案例代码 注册小程序 每个小程序都需要在 app.js 中调用 App 方法注册小程序实例,绑定生命周期回调函数、错误监听和页面不存在监听函数等。 详细的参数含义和使…...
多种方法实现 Nginx 隐藏式跳转(隐式URL,即浏览器 URL 跳转后保持不变)
多种方法实现 Nginx 隐藏式跳转(隐式URL,即浏览器 URL 跳转后保持不变)。 一个新项目,后端使用 PHP 实现,前端不做路由,提供一个模板,由后端路由控制。 Route::get(pages/{name}, [\App\Http\Controllers\ResourceController::class, getResourceVersion])...
视频汇聚云平台EasyCVR视频监控管理平台进行SDN转推的操作步骤
视频汇聚/视频云存储/集中存储/视频监控管理平台EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,实现视频资源的鉴权管理、按需调阅、全网分发、云存储、智能分析等,视频智能分析平台EasyCVR融合性强、开放度…...
SQL 语句继续学习之记录二
三, 聚合与排序 对表进行聚合查询,即使用聚合函数对表中的列进行合计值或者平均值等合计操作。 通常,聚合函数会对null以外的对象进行合计。但是只有count 函数例外,使用count(*) 可以查出包含null在内的全部数据行数。 使用dis…...
【Python原创设计】基于Python Flask 机器学习的全国+上海气象数据采集预测可视化系统-附下载链接以及详细论文报告,原创项目其他均为抄袭
基于Python Flask 机器学习的全国上海气象数据采集预测可视化系统 一、项目简介二、开发环境三、项目技术四、功能结构五、运行截图六、功能实现七、数据库设计八、源码获取 一、项目简介 在信息科技蓬勃发展的当代,我们推出了一款基于Python Flask的全国上海气象数…...
Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)
文章目录 Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四)服务端客户端 Unity进阶–通过PhotonServer实现人物选择和多人同步–PhotonServer(四) 服务端 服务端结构如下: UserModel using System; using System.Collections.Generic; usin…...
【Go 基础篇】Go语言获取用户终端输入:实现交互式程序的关键一步
介绍 在许多编程场景中,我们需要编写交互式程序,以便用户可以在终端中输入数据并与程序进行交互。Go语言提供了丰富的方式来获取用户终端输入,使得编写交互式程序变得简单而有趣。本篇博客将深入探讨Go语言中获取用户终端输入的各种方法&…...
学习笔记:Opencv实现拉普拉斯图像锐化算法
2023.8.19 为了在暑假内实现深度学习的进阶学习,Copy大神的代码,记录学习日常 图像锐化的百科: 图像锐化算法-sharpen_lemonHe_的博客-CSDN博客 在环境配置中要配置opencv: pip install opencv-contrib-python Code and lena.png…...
网页图片设置/seo优化专家
对于刚装完java的环境,在运行jar包时可能会遇到证书问题: javax.net.ssl.SSLHandshakeException sun.security.validator.ValidatorException sun.security.provider.certpath.SunCertPathBuilderException 可以尝试以下办法: 以windows为例&…...
网站的图片水印怎么做/免费平台推广
主要参考文献(资料):[1] 熊杰. 宾馆住宿管理系统的设计[J]. 中国科技博览, 2015(29).[2] 孟小峰, 周龙骧, 王珊. 数据库技术发展趋势[J]. 软件学报, 2004, 15(12).[3] 吕浩音. JSP技术介绍[J]. 陇东学院学报:自然科学版, 2007(2).[4] 张良银. 浅论C/S和B/S体系结构[…...
域名购买网站有哪些问题/公司网络营销实施计划
1 yaml配置文件中是以空格来区分是否是同一层级。在键值对的冒号之后要有空格。 2 属性值:数值、字符串、bool 值,直接写即可。双引号会将特殊字符进行转义,例如:"nice \n good"。输出是"nice 换行 good"&…...
wordpress多语言无效/百度推广登陆首页
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid2865 题意:n个小圆组成的正n边形,中间有一个大圆。有木棍相连的两个圆不能有相同的颜色,旋转后相同视为相同的方案,求着色方案数。 思路:中间选一种颜…...
做前端项目怎么进行网站切图/制作网站首页
ListView使用多选模式好处 交互与数据分离,在多选状态下不需要修改数据源,在最后确定的时候获取选择索引来确定选择的数据。 ListView模式 CHOICE_MODE_NONE:普通模式;CHOICE_MODE_SINGLE:单选模式;CHOICE_…...
Ecshop网站建设总结/网络运营怎么学
往期博客目录 1. 详解Linux(基础篇) 2. 详解Linux(进阶篇) 3. Git&GitHub(基础) 4. Git&GitHub(进阶) 5. java多线程 6. JavaScript 总结 7. SpringMVC(一&…...