标签 Debug 下的文章 - 第 2 页 - 酷游博客
首页
关于
友链
Search
1
阿里的简历多久可以投递一次?次数多了有没有影响?可以同时进行吗?
45 阅读
2
Java中泛型的理解
40 阅读
3
Java 14 发布了,再也不怕 NullPointerException 了!
38 阅读
4
Java中的可变参数
37 阅读
5
该如何创建字符串,使用" "还是构造函数?
29 阅读
技术
登录
/
注册
找到
22
篇与
Debug
相关的结果
- 第 2 页
2025-01-22
一次数据库连接池满问题排查与解决
之前一段时间,业务在线上经常出现频繁的数据库连接池满的报警,报错信息如下: Caused by: ERR-CODE: [TDDL-4103][ERR_ATOM_CONNECTION_POOL_FULL] Pool of DB 'cn-zhxxx_i-xxx_fin_risk_xxx_30xx:33.10.xxx.xx:30xx' is full. Message from pool: wait millis 5000, active 10, maxActive 10. AppName:FIN_RISK_xxx_APP, Env:ONLINE, UnitName:null. 然后去排查了一下SQL耗时,发现有大量的耗时SQL,并且执行耗时和锁耗时差不多是相等的。 然后看下这条具体的SQL语句: UPDATE collection_case SET gmt_modified = now(), lock_version = lock_version + ?, hands_count = ?, case_state = ?, max_ovd_days = ?, case_class = ?, cur_ovd_principal = ?,collection_amount = ? WHERE id = ? AND deleted = ? AND lock_version = ? 其实就是简单的一个更新语句,其中使用了乐观锁进行并发控制。 为什么乐观锁还会导致大量的锁耗时呢? 虽然乐观锁是不需要加锁的,通过CAS的方式进行无锁并发控制进行更新的。但是InnoDB的update语句是要加锁的。当并发冲突比较大,发生热点更新的时候,多个update语句就会排队获取锁。 而这个排队的过程就会占用数据库链接,一旦排队的事务比较多的时候,就会导致数据库连接被耗尽。 这类问题的解决思路有以下几个: 1、基于缓存进行热点数据更新,如Redis。 2、通过异步更新的方式,将高并发的更新削峰填谷掉。 3、将热点数据进行拆分,分散到不同的库、不同的表中,减少并发冲突。 4、合并更新请求,通过打批执行的方式来降低冲突。 其中,第2个和第4个方案,存在一定的延迟性,会把实时更新变更异步更新,存在一定的数据实时性问题。 第1个和第3个方案,实现起来成本比较高,但是相对来说更加完整一点。 根据我们的实际业务场景,我们选择了第4个方案,将更新操作进行合并,批量执行。 比如本来需要100个并发都给用户增加积分,那么改成10分钟更新一次,一次就把10分钟中内的所有需要增加的积分汇总之后一次更新用户积分表即可。
技术
# Debug
酷游
1月22日
0
22
0
2025-01-22
webx项目启动报错:Could not resolve placeholder “displayName” ....
在使用form表单的自动提交的时候,程序启动报错。 问题 报错其实说的很清楚:无法解析的占位符 “displayName” 原因 分析原因,是因为我们没有在引入支持占位符的服务。 解决 在webx文件中加入下面的内容: common 注意以上代码中的这个common,根据你的form.xml文件所在的位置,这个common替换成对应的模块名, 写入以上这段代码的webx.xml文件也不一定,有的项目有多个Module,每一个module下面都有一个webx-moduleName.xml文件, 根据form.xml文件所使用位置,将该内容添加在对应的webx.xml文件中
技术
# Debug
酷游
1月22日
0
24
0
2025-01-22
明明有自动清理,日志还是把我的服务干爆了!
本文要介绍的是一个发生在我们线上环境的真实案例,问题发生在某次大促期间,对我们的线上集群造成了比较大的影响,这篇文章简单复盘一下这个问题。问了方便大家理解,实际排查和解决过程可能和本文描述的并不完全一致,但是思路是一样的。 问题过程 某次大促期间,某一个线上应用突然发生大量报警,提示磁盘占用率过高,一度达到了80%多。 这种情况我们第一时间登录线上机器,查看线上机器的磁盘使用情况。使用命令:df查看磁盘占用情况。 $df Filesystem 1K-blocks Used Available Use% Mounted on / 62914560 58911440 4003120 93% / /dev/sda2 62914560 58911440 4003120 93% /home/admin 发现机器磁盘确实耗费的比较严重,因为大促期间请求量比较多,于是我们最先开始怀疑是不是日志太多了,导致磁盘耗尽。 这里插播一个背景,我们的线上机器是配置了日志的自动压缩和清理的,单个文件达到一定的大小,或者机器内容达到一定的阈值之后,就会自动触发。 但是大促当天并没有触发日志的清理,导致机器磁盘一度被耗尽。 经过排查,我们发现是应用的某一些Log文件,占用了极大的磁盘空间,并且还在不断的增大。 du -sm * | sort -nr 512 service.log.20201105193331 256 service.log 428 service.log.20201106151311 286 service.log.20201107195011 356 service.log.20201108155838 du -sm * | sort -nr :统计当前目录下文件大小,并按照大小排序 于是经过和运维同学沟通,我们决定进行紧急处理。 首先采取的手段就是手动清理日志文件,运维同学登录到服务器上面之后,手动的清理了一些不太重要的日志文件。 rm service.log.20201105193331 但是执行了清理命令之后,发现机器上面的磁盘使用率并没有减少,而且还是在不断的增加。 $df Filesystem 1K-blocks Used Available Use% Mounted on / 62914560 58911440 4003120 93% / /dev/sda2 62914560 58911440 4003120 93% /home/admin 于是我们开始排查为什么日志被删除之后,磁盘空间没有被释放,通过命令,我们查到了是有一个进程还在对文件进行读取。 lsof |grep deleted SLS 11526 root 3r REG 253,0 2665433605 104181296 /home/admin/****/service.log.20201205193331 (deleted) lsof |grep deleted 的作用是:查看所有已打开文件并筛选出其中已删除状态的文件 经过排查,这个进程是一个SLS进程,在不断的从机器上读取日志内容。 SLS是阿里的一个日志服务,提供一站式提供数据收集、清洗、分析、可视化和告警功能。简单点说就是会把服务器上面的日志采集到,持久化,然后供查询、分析等。 我们线上日志都会通过SLS进行采集,所以,通过分析,我们发现磁盘空间没释放,和SLS的日志读取有关。 到这里,问题基本已经定位到了,那么我们插播一下原理,介绍一下这背后的背景知识。 背景知识 Linux系统中是通过link的数量来控制文件删除的,只有当一个文件不存在任何link的时候,这个文件才会被删除。 一般来说,每个文件都有2个link计数器:i_count 和 i_nlink,也就是说:Linux系统中只有i_nlink及i_count都为0的时候,这个文件才会真正被删除。 i_count表示当前文件使用者(或被调用)的数量 i_nlink表示介质连接的数量(硬链接的数量); 可以理解为i_count是内存引用计数器,i_nlink是磁盘的引用计数器。 当一个文件被某一个进程引用时,对应i_count数就会增加;当创建文件的硬链接的时候,对应i_nlink数就会增加。 在Linux或者Unix系统中,通过rm或者文件管理器删除文件,只是将它会从文件系统的目录结构上解除链接(unlink),实际上就是减少磁盘引用计数i_nlink,但是并不会减少i_count数。 如果一个文件正在被某个进程调用,用户使用rm命令把文件”删除”了,这时候通过ls等文件管理命令就无法找到这个文件了,但是并不意味着这个文件真正的从磁盘上删除了。 因为还有一个进程在正常的执行,在向文件中读取或写入,也就是说文件其实并没有被真正的”删除”,所以磁盘空间也就会一直被占用。 而我们的线上问题就是这个原理,因为有一个进程正在对日志文件进行操作,所以其实rm操作并没有将文件真正的删除,所以磁盘空间并未释放。 问题解决 在了解了线上的问题现象以及以上的相关背景知识之后,我们就可以想到办法来解决这个问题了。 那就是想办法把SLS进程对这个日志文件的引用干掉,文件就可以真正的被删除,磁盘空间就能真正的被释放掉了。 kill -9 11526 $df Filesystem 1K-blocks Used Available Use% Mounted on / 62914560 50331648 12582912 80% / /dev/sda2 62914560 50331648 12582912 80% /home/admin 特别提醒下,在执行kill -9 之前,一定要考虑下执行的后果是什么,背后原理可以参考:我到服务器执行kill -9后,就被通知第二天别来了! 事后,我们经过复盘,发现之所以出现这样的问题,主要有两个原因: 1、线上日志打印太多,太频繁 2、SLS日志拉取速度太慢 深入分析后我们发现,这个应用打印了很多过程日志,最初日志打印是为了方便排查线上的问题,或者做数据分析用的,但是大促期间日志量激增,导致磁盘空间占用极速上升。 另外,因为该应用和几个其他的大应用共用了一份SLS的project,导致SLS拉取速度被拉低,进而导致进程一直无法结束。 事后,我们也总结了一些改进项,对于第二个问题,我们对于该应用的SLS配置做拆分,独立出来进行管理。 对于第一个问题,那就是大促期间引入日志降级的策略,一旦发生磁盘爆满,就是将日志降级掉。 关于日志降级,我开发了一个通用的工具,就是通过配置的方式,动态推送日志级别,动态修改线上的日志输出级别。并且把这份配置的修改配置到我们的预案平台上,大促期间进行定时或者紧急预案处理,即可避免这个问题。 关于日志降级工具的开发思路和相关代码,下一篇文章中给大家分享。 思考 每次大促之后我们复盘,都会发现其实大多数问题都是由几个不起眼的小问题堆积到一起而引发的。 在问题分析过程中往往会需要运用到很多非开发技能相关的知识,如操作系统、计算机网络、数据库、甚至硬件相关的知识。 所以我一直认为,判断一个程序员是否牛X,就看他的解决问题的能力!
技术
# Debug
酷游
1月22日
0
20
0
2025-01-22
Could not find data resolver for DataResolverContext
com.alibaba.citrus.service.dataresolver.DataResolverNotFoundException: Could not find data resolver for DataResolverContext 在使用webx的表单验证过程中,访问action报错: com.alibaba.citrus.service.dataresolver.DataResolverNotFoundException: Could not find data resolver for DataResolverContext 原因 报错信息说了:无法找到解析器 j解决 在webx中,可以配置多个注入参数,在webx.xml中(我的项目中配置在webx-component-and-root.xml中)加入对应的解析器就可以了。 其中就是支持表单注入的解析器。
技术
# Debug
酷游
1月22日
0
24
0
2025-01-22
Could not connect to SMTP host: smtp.***.com, port: 465, response: -1
背景 在使用javamail进行邮件发送的时候,报错: Could not connect to SMTP host: smtp.***.com, port: 465, response: -1 原因: 465端口是为SMTPS(SMTP-over-SSL)协议服务开放的,这是SMTP协议基于SSL安全协议之上的一种变种协议。 解决: 加上如下代码即可: props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 扩展-邮件服务端口 25端口(SMTP):25端口为SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)服务所开放的,是用于发送邮件。 如今绝大多数邮件服务器都使用该协议。当你给别人发送邮件时,你的机器的某个动态端口(大于1024)就会与邮件服务器的25号端口建立一个连接,你发送的邮件就会通过这个连接传送到邮件服务器上,保存起来。 109端口(POP2):109端口是为POP2(Post Office Protocol Version 2,邮局协议2)服务开放的,是用于接收邮件的。 110端口(POP3):110端口是为POP3(Post Office Protocol Version 3,邮局协议3)服务开放的,是用于接收邮件的。 143端口(IMAP):143端口是为IMAP(INTERNET MESSAGE ACCESS PROTOCOL)服务开放的,是用于接收邮件的。 目前POP3使用的比POP2广得多,POP2几乎被淘汰,也有某些服务器同时支持POP2和POP3协议。客户端可以使用POP3协议来访问服务端的邮件服务,如今ISP的绝大多数邮件服务器都是使用POP3协议(极少用POP2协议)。在使用邮件客户端程序的时候,会要求输入POP3服务器地址,默认情况下使用的就是110端口。当你用邮件客户端(比如、Thunderbird、foxmail、MS Outlook Express以及各类邮件精灵)登录时,你的机器就会自动用机器的某一个动态端口(大于1024)连接邮件服务器的110端口,服务器就把别人给你发的邮件(之前保存在邮件服务器上),发送到你机器,这样你就可以看到你客户端工具上的收件箱里的新邮件了。 IMAP协议,和POP3协议一样是用来接收邮件的,但是它有它的特别和新颖之处,它是面向用户的,它和POP3协议的主要区别是:用户可以不用把所有的邮件内容全部下载,而是只下载邮件标题和发件人等基本信息,用户可以由标题等基本信息,去决定是否下载邮件全文,用户可以通过客户端的浏览器直接对服务器上的邮件进行操作(比如:打开阅读全文、丢进垃圾箱、永久删除、整理到某文件夹下、归档、)。再简单来说就是:浏览器用的IMAP协议(143端口)来为你接收邮件以及让你很方便的操作服务器上的邮件。邮件客户端用的POP3协议(110端口)来为你接收邮件的全部信息和全文内容保存到你的本地机器成为一个副本,你对邮件客户端上的副本邮件的任何操作都是在副本上,不干涉邮件服务器上为你保存的邮件原本。 上面介绍的SMTP协议、POP2协议、POP3协议、IMAP协议都是不安全的协议。因考虑到网络安全的因素,下面给你介绍基于SSL(Secure Sockets Layer 安全套接层)协议的安全的邮件收发协议。你的邮件在传输过程中可能被网络黑客截取邮件内容,如果你的邮件机密性非常强,不想被收件人以外的任何人和任何黑客截取,或者是涉及国家机密安全的,等等。那么你的邮件就不该使用上述的三种协议进行收发。 若你采用SMTP协议发邮件,那么你发出的邮件从你的机器传到服务器的过程中,可能被黑客截取从而泄露。****若你采用POP2或者POP3协议收取邮件,那么你的邮件从服务器传至你当前机器的过程可能被黑客截取从而泄露。 465端口(SMTPS):465端口是为SMTPS(SMTP-over-SSL)协议服务开放的,这是SMTP协议基于SSL安全协议之上的一种变种协议,它继承了SSL安全协议的非对称加密的高度安全可靠性,可防止邮件泄露。SMTPS和SMTP协议一样,也是用来发送邮件的,只是更安全些,防止邮件被黑客截取泄露,还可实现邮件发送者抗抵赖功能。防止发送者发送之后删除已发邮件,拒不承认发送过这样一份邮件。 995端口(POP3S):995端口是为POP3S(POP3-over-SSL)协议服务开放的,这是POP3协议基于SSL安全协议之上的一种变种协议,它继承了SSL安全协议的非对称加密的高度安全可靠性,可防止邮件泄露。POP3S和POP3协议一样,也是用来接收邮件的,只是更安全些,防止邮件被黑客截取泄露,还可实现邮件接收方抗抵赖功能。防止收件者收件之后删除已收邮件,拒不承认收到过这样一封邮件。 993端口(IMAPS):993端口是为IMAPS(IMAP-over-SSL)协议服务开放的,这是IMAP协议基于SSL安全协议之上的一种变种协议,它继承了SSL安全协议的非对称加密的高度安全可靠性,可防止邮件泄露。IMAPS和IMAP协议一样,也是用来接收邮件的,只是更安全些,防止邮件被黑客截取泄露,还可实现邮件接收方抗抵赖功能。防止收件者收件之后删除已收邮件,拒不承认收到过这样一封邮件。
技术
# Debug
酷游
1月22日
0
8
0
上一页
1
2
3
...
5
下一页
易航博客