zoukankan      html  css  js  c++  java
  • 【疑难系列】 是程序卡住了还是怎么了?

    起因

    客户说:“今天的预报又没有发出去,帮忙看下怎么回事?”

    “...”

    经过

    登陆服务器,发现程序一直在打印

    running
    running
    running
    ...
    

    这是代码中写的

            public static void Main(string[] args)
            {
                Console.Title = string.Format("Grib2压码程序 请勿关闭");
                ActiveMq();
                while (hasMessage)
                {
                    Console.WriteLine("running");
                    Thread.Sleep(1000);
                }
            }
    

    程序通过启动ActiveMQ,然后判断是否仍有消息在处理,如果在处理就Sleep当前线程,等待处理完毕

    当接收到消息时的处理主逻辑:

    
            public static void OnMessage(IMessage message)
            {
                var msg = message as ITextMessage;
                if(msg != null)
                {
                   
                    hasMessage = true;
                    String date = msg.Text;
                    Compress(date);
                    mq.send(date);
                    hasMessage = false;
                }
            }
    

    那么问题应该是Compress或者 mq.send 一直在处理,卡住了??

    因为是.net程序,所以不能用jstack来分析线程了

    通过windows自带的任务管理器,把程序dump出来

    如何dump

    然后使用windbg分析一下线程,直接通过文件, "open dump file",打开导出的dmp文件。

    dump文件结果

    windbg第一次使用,不是很懂得使用,但是注意到右下角threads的线程信息,发现只有一个主线程在运行!!

    也就是说:我们的监听线程退出了!!!

    那么,什么情况下会退出呢?

    一般是线程运行过程中抛出异常没有处理

    检查源代码,发现程序没有对出现异常做任何处理

    所以,修改方案如下:

    		public static void OnMessage(IMessage message)
            {
                var msg = message as ITextMessage;
                if(msg != null)
                {
                   
                    hasMessage = true;
                    String date = msg.Text;
                    if(Compress(date, 3))
                    {
                        mq.send(date);
                    }
                    else
                    {
                        mq.fail(date);
                    }
                    hasMessage = false;
                }
            }
    
            public static bool Compress(string date, int retry)
            {
                if (retry == 0)
                {
                    return false;
                }
                try
                {
                    Compress(date);
                    return true;
                }
                catch (Exception ex)
                {
                    Log.writeException(ex);
                    return Compress(date, retry - 1);
                }
            }
    

    将监听消息部分的代码进行修改,增加重试,并进行try catch异常处理,出现异常时,在文件中记录日志

    当然mq.send 也有可能出现异常,将send方法也进行try catch异常处理

    替换程序,上线运行(这种问题看能否重现了,重现了就可以在error.log中找到了)

    总结分析

    windbg第一应用,表示很多信息都看不懂

    主线程中需要考虑子线程的异常,有些线程,你以为在运行,实际上它退出了

    其它

    面试的时候,面试官问我

    “你遇到过最难解决的问题,你是怎么解决的?”

    “我特么都是问题解决了就忘记了,所以没啥印象”

    不过,我是在心里说的

    所以,对于别人问我的问题,我决定记录下来,免得将来忘记了

  • 相关阅读:
    用ruby抓取网页
    [转] 从项目管理角度看敏捷开发
    ruby学习笔记(9)
    [转] 从项目管理角度看敏捷开发
    ruby学习笔记(8)
    ruby学习笔记(7)
    [转] 什么是敏捷开发
    netbeans tomcat
    maven
    jersey
  • 原文地址:https://www.cnblogs.com/binblog/p/11030812.html
Copyright © 2011-2022 走看看