今天发现线上一台机器,监控一直在告警,一看是健康检查不通过,就上去查看了下,首先自己curl了下应用的url,果然是超时没有响应,那就开始按顺序排查了:
1、 load非常低,2、gc也正常,3、线程上也没死锁,4、日志一切正常。那是什么情况呢,不能忘记网络啊。果然,netstat命令一把,结果如下:
TIME_WAIT 68 CLOSE_WAIT 194 ESTABLISHED 3941 SYN_RECV 100
问题出来了,SYN_RECV竟然达到100个,正常情况下,半连接的请求应该是很小的。而且我们机器是内部的,不是lvs,不太会有半连接攻击,怎么可能达到这么大呢?
再grep SYN_RECV的连接,看到全部都是nginx在连接这台mtop机器,那接下来就dump tcp包看看了
一看一堆堆的wjas向mtop发起SYN连接请求,可是mtop机器是绝大部分没回应,只有极少的mtop机器syn+ack包。
注:wjas一天向mtop发起了近20亿的健康检查请求,够多的,所以没有外部流量时,还是有一大堆的http请求到应用上。
看系统信息,内核是2.6.32-220.23.2.ali1113.el5.x86_64的,半连接队列的长度是128不同的内核,半连接队列长度算法稍有不同,可以参考文章:linux诡异的半连接(SYN_RECV)队列长度。
可见是mtop半连接队列满了,不再接受新的tcp连接,导致请求没有响应了,但应用其实很空闲。
问题表现很清楚了,接下来就是各种怀疑了,因为这机器为解决之前tcnative的crash bug,刚切换成了nio模式、又昨天我手贱,在上面搞过btrace,aliperf。自己也成嫌疑,但这是半连接队列满,要么受到半连接攻击(排除,内网不太可能有半连接攻击),要么是Accept线程没有及时处理,应用没有接收连接的请求,导致三次握手后的队列连接满再引起半连接队列满了。(总结起来好像很有逻辑,排查的时候没那么明确的,还在想各种可能)
我们知道,tomcat有一个Acceptor线程,监听在端口上,在收到连接请求后,会立刻把请求交个后面线程池处理,bio是直接拿线程等待数据,nio与apr会在poller线程上注册监听,也就是select模式,底层再基于epoll事件触发(和nginx的处理模式有点区别)。那就是这个Acceptor线程难道停止了。
查看堆栈信息,果然
当前的这个acceptor已经被禁用了,需要唤醒,多次dump线程,发现此线程一直是这个状态,这就解释了为什么了。
马上查看tomcat源码,发现此代码是在tomcat的连接数(nio)达到1w的时候,会park当前线程,再请求处理后,会再唤醒,继续接受新的连接,Btrace了一把,果然这个连接数值是1w,但什么情况下,会导致这个值那么大,一直把线程暂停呢?按说如果要达到这么大的连接,我们的T4机器早就鸡飞狗跳了。
Google一把,原来是tomcat7.0.27之前的bug,我们使用的刚好是7.0.26.中枪了,不管是nio,bio,apr,都存在这个问题。Tomcat的代码如下:
当接受连接,出现异常时候,旧版本没有把这个数组减少,这时候就拼人品了,如果异常的请求累积,达到连接的最大值,就发生机器很闲,但tcp的连接队列与半连接队列满的情况了
tomcat在7.0.28修复了此问题,参见Tomcat 7 Changelog 。
1、如有遇到此类似情况,可看看是否这原因。
2、当最新版的jar或者容器稳定后,早点升级吧,特别是bug修复。
3、提供一次问题排查的参考。
相关推荐
为了保证转账的正确性,我们需要在转账操作中加入同步控制。例如,使用`synchronized`关键字修饰转账方法,确保同一时刻只有一个线程能访问该方法,从而避免并发修改余额的问题。或者,我们可以使用`ReentrantLock`...
9. **并发控制**:如果多线程环境下处理转账,还需要考虑线程安全问题。可能需要使用`synchronized`关键字或者锁来保证同一时间只有一个线程能够修改账户余额。 10. **日志记录**:为了追踪和排查问题,日志记录是...
此外,可能还需要处理并发问题,确保转账操作的原子性和一致性。 4. **异常处理**:在银行转账系统中,异常处理至关重要,例如当账户不存在、余额不足或者输入错误时,系统需要抛出并捕获相应的异常,向用户提供...
同时,记录日志可以帮助开发者排查问题,了解转账操作的详细流程。 7. **测试与调试**: - 在实际部署前,应进行详尽的测试,包括单元测试、集成测试,确保转账功能的稳定性和准确性。可以使用支付宝提供的沙箱...
同时,日志记录可以帮助追踪和排查问题,如使用Log4j或SLF4J记录转账过程。 8. **安全考虑**:转账过程中需要验证账户是否存在、余额是否充足,防止恶意转账或非法操作。此外,密码和其他敏感信息的处理也需符合...
并发控制在高并发环境中至关重要,以防止数据冲突和一致性问题。有多种并发控制策略可以应用于RESTful服务: 1. **乐观锁**:在读取数据时不加锁,但在更新时检查数据是否已被其他事务修改。如果发现数据已变,就...
在C#编程环境中,开发一个名为"MyBank"的银行系统涉及到多个关键知识点,其中包括账户管理、交易处理,特别是转账功能。下面将详细讲解这些概念及其实现。 首先,我们需要设计一个银行账户类(Account)。此类应...
*模拟银行账户转账系统: 有A,B两个银行账户,初始金额都为1000元,A,B随机向对方转账,转账金额不得大于账户余额,账户余额为0,无法进行交易,要求用图形界面显示,下方有两个按钮为“交易开始”,“清屏”,当...
9. **权限控制**:在实际应用中,转账操作应受到严格的权限控制,只有具备相应权限的后台用户才能发起转账请求。 10. **测试环境**:在实际开发过程中,可以先在微信提供的测试环境中进行API调用,验证转账逻辑的...
【支付宝批量转账工具】是一种高效便捷的财务管理工具,主要用于企业或个人进行大量支付宝账户之间的资金转移。这款工具的出现极大地简化了传统手动转账的过程,提高了转账效率,尤其适合需要频繁处理众多支付宝账户...
- **日志记录**:为了便于后续问题排查,建议记录每个转账操作的详细信息,包括请求参数、响应内容和处理结果。 5. **安全注意事项**: - **敏感信息保护**:在处理商户私钥和用户账号信息时,必须确保其安全,...
为了便于问题排查和审计,每次转账操作的请求和响应都应该记录在日志中,包括请求参数、响应结果、执行时间等信息。 10. **安全性与合规性**: 遵守金融行业的法规和标准,如数据加密、用户隐私保护、反洗钱规定...
同时,如果转账操作与数据库操作结合,需要确保两者的一致性,避免出现数据不一致的问题。 最后,"dian_fu_bai_de_hei"这个文件名可能是误输入或者加密后的文件,通常在实际的示例代码包中,会包含相关的示例代码、...
3. **执行转账**:如果验证通过,控制器调用模型中的转账函数,该函数通过SQL查询计算新余额,并更新数据库。 4. **返回结果**:模型完成转账后,控制器更新视图,向用户显示转账结果,可能包括成功信息或错误提示。...
本教程将深入探讨Java JDBC中的三层架构(三层架构是指表现层、业务逻辑层和数据访问层)以及事务处理,同时结合具体的转账案例来阐述可能遇到的问题和解决策略。此外,我们还会涉及单例模式和ThreadLocal在实际应用...
总结来说,这个"JSP银行模拟转账系统"是一个包含用户交互、业务逻辑处理、数据库操作和安全控制的综合实践案例。它展示了如何利用JSP和Java技术实现一个完整的Web应用,对于学习Web开发和理解银行系统运作原理具有很...
系统分析阶段,首先需要明确问题定义,即银证转账系统的主要功能和目标。接着进行需求分析,确定用户对系统的基本要求,如账户余额查询、转账操作、交易记录查询等。可行性分析包括技术可行性、运行可行性、资金可行...
10. **日志记录**:为了便于排查问题,需要记录每个转账操作的详细信息,包括请求参数、响应内容以及可能出现的错误信息。 以上就是使用Java实现支付宝批量转账的基本步骤和关键知识点。需要注意的是,实际操作中还...
批量转账涉及到大量的资金流动,必须遵守相关的法律法规,并进行风险控制。开发者需要确保转账行为符合反洗钱、反欺诈的规定,同时监控异常转账行为,防止潜在的风险。 8. **性能优化**: 对于大规模的批量转账,...