tomcat应用拒绝服务解决过程

问题现象: 应用跑在tomcat上,近期遇到个问题,运行一段时间后就拒绝服务, 其他程序连接不上应用, 出问题后,tomcat和应用不记录任何日志,重启tomcat后,服务恢复。

第一次出现问题时, 根据经验判断是tomcat的线程数满了, 在服务器上查看链接数的确很多, 就修改了tomcat的最大连接数,从 400 改成 800,修改后应用持续到当天晚上21点,又挂了。

为了不影响业务,将最大连接数改成2000, 重启。 

重启后,跟踪链接使用情况,发现从该应用到JOS平台的连接居多,都是ESTABLISHED 状态,并且持续增加,由此可判断问题出在这里。这种问题的第一反应就是,程序里有没有关闭链接的地方,于是开始翻代码,结果发现应用到JOS的连接都是JOS提供的SDK处理的,看了SDK中处理链接的地方,没看出什么问题(此时的关注点还在链接是否被关闭的问题上),代码如下:

public static String doPost(String url, String ctype, byte[] content, int connectTimeout, int readTimeout) throws IOException {
    HttpURLConnection conn = null;
    OutputStream out = null;
    String rsp = null;
    try {
        conn = getConnection(new URL(url), "POST", ctype);
        conn.setConnectTimeout(connectTimeout);
        conn.setReadTimeout(readTimeout);
        out = conn.getOutputStream();
        out.write(content);
        rsp = getResponseAsString(conn);
    } finally {
        if(out != null) {
            out.close();
        }
        if(conn != null) {
            conn.disconnect();
        }
    }
    return rsp;
}

又看了N遍代码,终于发现一个线索,应用程序中初始化jos client方法是这样的:

JdClient client=new DefaultJdClient(Constant.JDURL,sessionkey,appkey,secret);

JOS sdk里的代码是这样的:

public class DefaultJdClient implements JdClient {
    ... ...
    public DefaultJdClient(String serverUrl, String accessToken, String appKey, String appSecret) {
        this.connectTimeout = 0;
        this.readTimeout = 0;
        this.serverUrl = serverUrl;
        this.accessToken = accessToken;
        this.appKey = appKey;
        this.appSecret = appSecret;
    }

    public DefaultJdClient(String serverUrl, String accessToken, String appKey, String appSecret, int connectTimeout, int readTimeout) {
        this(serverUrl, accessToken, appKey, appSecret);
        this.connectTimeout = connectTimeout;
        this.readTimeout = readTimeout;
    }
    ... ...
}

问题来了,如果程序初始化client时不指定超时时间, SDK中默认成了0, 即无穷大,虽然不能确定是不是当前遇到的问题,但这样肯定是不合理的,改了试试再说,

JdClient client=new DefaultJdClient(Constant.JDURL,sessionkey,appkey,secret, 10000, 10000);

修改后,链接数正常了, 不再持续增加, 问题解决了,但是还有两个疑问:

1、出现链接未关闭的根本原因还不清楚;

2、这个应用已经正常运行了2年了, 为嘛现在才出现问题;

看了下应用日志,发现加上超时时间后,日志里有很多这种错误:

11:31:08,352 ERROR JingDongUpdateSkuStockCmd:62 - IO异常:
com.jd.open.api.sdk.JdException: 服务器连接超时,请重试
	at com.jd.open.api.sdk.DefaultJdClient.execute(DefaultJdClient.java:103)

到此,问题就很清晰了:

近期,网络问题或者是JOS平台问题(嫌疑比较大),导致我们这边应用发出的请求得不到响应,而连接没有设置超时时间,导致程序一直走等待,占用线程数,等到线程数满了, tomcat就拒绝服务了。

 

最后甩个锅, 没有设置链接超时时间,是按照JOS平台给的代码示例写的,示例代码这么搞,坑人啊!

转载于:https://my.oschina.net/u/1019737/blog/884347

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值