`
spring-china
  • 浏览: 50628 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

诡异的时区问题+使用eclipse的远程调试(remote debug)功能(2011-3-2)

阅读更多

 

诡异的时区问题+使用eclipse的远程调试(remote debug)功能(2011-3-2)

 

一.分析

 

昨晚和一般兄弟加班到凌晨两点,我花了很长时间诊断了一个错误. QA晚上Log了一个bug,关于在系统的一些search页面不能够正确的按照时间来进行搜索记录.比如需要搜索3月2号的数据,结果里面只能出来3月1号的数据.

拿到这个问题,我首先起了一个本机的服务器,结果可以正确搜索,由于QA使用的是另外一个HK的服务器,所以我又连接到HK server的测试URL上面测试,确实如QA所说存在问题,通过在Firebug我查看了post到后台的数值,时间值没有错误(3月2号),从后台返回的JSON来看,出来的数据是提前了一天的,也就是3月1号的。

好,那我只能通过FileZilla连上HK那边的server去取log文件,晕...140多M..下载了快20分钟. 趁这个空出去吃了个饭... 回来log文件已经拿到,Yeah.

打开log文件,找到相应时间点的记录,拿出log中用来search的sql.如下:

/* Formatted on 2011/3/2 23:59:41 (QP5 v5.114.809.3010) */
SELECT   *
  FROM   v_market_po_advance_search mmp
 WHERE   dept_id IN
               ('DEPT_GAP_2117_000000000000000000',
                'DEPT_GAP_2173_000000000000000000',
                'DEPT_GAP_2142_000000000000000000',
         AND plan_Stock_Date >= TO_DATE ('01/03/2011', 'dd/MM/yyyy')
         AND plan_Stock_Date <= TO_DATE ('01/03/2011', 'dd/MM/yyyy')

看来还真的在前台到后台的过程中发生了错误的转换,我们的系统中对于这种页面的search条件,会有一个构造的过程,也就是说会自动在sql的where条件后去append搜寻条件.而是通过struts2的拦截器(intercepter)来实现的,即在调用action(执行sql去真正的查询)之前,会通过intercepter来对前台传入的数据进行转换,拼成一条最终的sql. 至于这个intercepter的实现也很简单,继承了AbstractIntercepter抽象类而已.这里就不贴代码了,无非是对所有考虑的到的类型进行一些必要的转换.

对代码进行了一些分析.其中对一些特殊日期进行转换的代码是这样的(因为从页面传过来的日期值是EEE MMM d yyyy HH:mm:ss 'GMT'Z这样的format,会在如下的code里面处理)   

private Date parseDateUseSysDateFormat(String str) {
    String[] parsePatterns = new String[] {
        "EEE MMM d yyyy HH:mm:ss 'GMT'Z",
        "EEE MMM d yyyy HH:mm:ss",
        "EEE MMM d HH:mm:ss 'UTC'Z yyyy"
    };
    SimpleDateFormat parser = null;
    ParsePosition pos = new ParsePosition(0);
    for (int i = 0; i < parsePatterns.length; i++) {
        if (i == 0) {
            parser = new SimpleDateFormat(parsePatterns[0], Locale.US);
        } else {
            parser.applyPattern(parsePatterns[i]);
        }
        pos.setIndex(0);
        Date date = parser.parse(str, pos);
        if (date != null && pos.getIndex() == str.length()) {
            return date;
        }
    }
    return null;
}

这段代码没有什么特别之处,通过特定的Pattern和Locale.US构造了一个SimpleDateFormate的paser,然后对日期进行转换,返回值.于是我想会不会是时区的问题,因为我在本地测试,客户端和服务器都是在同一时区,而QA通过本地的浏览器测试远程HK的server,这中间应该是存在时区的差别的,关键取决于server所在机器的时区设置.

 

二.使用Remote Debug实验

 

有了这样的设想,我决定在我本地起一个测试server,然后调整本机所在的时区为UTC+7(北京为UTC+8),然后再通过局域网中的另外一台机器作为客户端,来访问我本地server,并在相应页面通过时间对记录进行查找. Good Idea.. Haha.. 

为了确定数据实际转换过程中的流程,也为了避免繁琐的log信息打印,我决定直接使用eclipse的remote debug功能(这是个很powerful的功能,我用了一次就爱上它了)

我们的项目使用的maven管理,而server就使用小巧的jetty.以下是jetty-debug.bat,直接运行就能就能让jetty去监控一个地址的特定端口.

 

set MAVEN_OPTS=-Xms512m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+CMSPermGenSweepingEnabled -XX:+UseConcMarkSweepGC -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=9999,server=y,suspend=y
mvn jetty:run 2> ..\error.log

然后需要在eclipse中进行必要的设置(见图片remote debug setting.png).

 

设置完成后,首先运行jetty-debug.bat脚本.从输出的信息可以看到,jetty已经在监听9999端口了(见图片jetty-debug.png).

 

然后进入eclipse,在程序里面设置断点,这样就可以开始debug了,按debug configuration中的debug按钮就行,这是可以看到命令行中的输出信息(见图片jetty-debug-done.png).

 

启动之后,进入search页面,通过时间进行search,通过firebug可以看到传入后台的参数如下.

 

Wed Mar 02 2011 00:00:00 GMT+0800 (China Standard Time)

 

同时eclipse也会自动进入debug模式窗口,因为我在上面日期转换那段代码里面设置了断点,这样可以省略前面的一些不重要的步骤,直接奔入主题啦,哈哈.按F6是单步,按F5可以进入相应的方法进行查看,按F7是回退(注:貌似是这样,没有深究)

 

可以看到时间在经过转换之后已经往前推了一天(见图片debug info.png).

 

然后我又将我本地server的时区调整正确,与客户端保持一致,再次进行debug,发现转换前后时间就是一致的了,这就表示确实是server端时区的设置问题了.相关部分就不贴图啦.

 

三.总结

 

通过这个Bug,让我记住了两点

1. 在我们进行项目部署测试的时候,有些问题可能是server端和client端时区差异造成的,其实后来询问过我们经理,这个问题我们在一开始的时候就和客户谈过,明确的告诉了他们会有这样的问题.呵呵.其实我觉得这种问题在前台就进行处理,例如转换成一个字符串,在构成sql之前再把这个字符串转换成日期,而不是在后台进行日期格式的复杂转换可能更好一些,这样也不会造成由于时区的不一致引起的各种问题.

2. Eclipse的Remote debug确实很方便很强大,大家可以尝试尝试,应该能够很方便的和一些主流的中间件集成并进行测试,这里有两篇关于eclipse remote debug的帖子,大家也可以看看:

http://www.itpub.net/thread-854391-1-53.html

http://www.ibm.com/developerworks/cn/opensource/os-eclipse-javadebug/

 

 

 

 

 

 

 

  • 大小: 165 KB
  • 大小: 50.8 KB
  • 大小: 65.5 KB
  • 大小: 157 KB
分享到:
评论

相关推荐

    eclipse远程调试tomcat

    ### Eclipse远程调试Tomcat知识点详解 #### 一、概述 在软件开发过程中,尤其是在Web应用开发领域,远程调试是一项非常重要的技术。它可以帮助开发者在不同的环境中(如远程服务器)调试应用程序,这对于查找和...

    NC eclipse 远程调试

    NC Eclipse 远程调试是指在 Eclipse 集成开发环境中,使用 Java Debug Wire Protocol (JDWP) 实现远程调试 Java 应用程序的功能。JDWP 是一个基于 socket 的通信协议,用于在 debug 客户端和服务器之间传输调试信息...

    使用Tomcat+Eclipse远程Debug

    本文将详细介绍如何通过Eclipse集成开发环境(IDE)配合Apache Tomcat应用服务器实现远程调试的功能。 #### 二、准备工作 在开始配置之前,请确保已经安装了以下组件: - **Eclipse IDE**:推荐使用最新版Eclipse...

    使用Eclipse远程调试Linux服务器Tomcat项目

    "使用Eclipse远程调试Linux服务器Tomcat项目" 一、概述 在开发Java Web应用程序时,需要在远程服务器上进行调试,以便更好地了解程序的执行过程。使用Eclipse远程调试Linux服务器Tomcat项目可以帮助开发者更好地...

    eclipse远程调试最完整教程

    ### Eclipse远程调试详解 #### 一、远程调试概念与应用场景 **远程调试**是指开发者能够通过特定工具在一台机器上(通常称为客户端)对另一台机器(服务端)上正在运行的应用程序进行调试的过程。这种方式使得...

    Eclipse远程调试教程

    Eclipse远程调试教程 Eclipse 远程调试是指在 Eclipse 中对 Java 应用程序进行远程调试,通过配置 Tomcat 和 Eclipse,可以实现对远程服务器上的 Java 应用程序的调试。下面将详细介绍 Eclipse 远程调试的配置和...

    Eclipse远程调试Java代码

    2. **在Eclipse中设置远程调试器** - **新建远程Java应用配置**:在Eclipse中,选择`Run` -&gt; `Debug Configurations`,然后在左侧窗格中选择`Remote Java Application`,点击`New launch Configuration`。 - **...

    IDEA,Eclipse远程调试应用

    Eclipse远程调试项目配置 #### 3.1 选择项目右键选择Debug as 在Eclipse中,右键点击需要远程调试的项目,选择Debug as -&gt; Remote Java Application。 #### 3.2 选择Remote Java Application Eclipse会自动尝试...

    Eclipse 远程调试Tomcat的应用

    ### Eclipse远程调试Tomcat应用详解 #### 一、前言 在软件开发过程中,调试是不可或缺的一环,尤其是在复杂的分布式系统或服务器端应用中。Eclipse作为一款功能强大的集成开发环境(IDE),提供了丰富的工具来支持...

    使用eclipse远程debug .

    Eclipse远程Debug功能允许开发者对运行在另一台机器上的应用程序进行调试,这对于分布式系统或者服务器端应用的调试尤其有用。 首先,我们需要确保Eclipse安装了Remote System Explorer (RSE)插件,因为这是远程...

    Eclipse远程调试Tomcat

    标题 "Eclipse远程调试Tomcat" 指的是在Eclipse集成开发环境中,通过远程调试功能连接并调试在另一台机器上运行的Tomcat服务器。这通常用于在生产环境或测试环境中定位和修复代码问题,而无需直接在该环境中安装IDE...

    Eclipse配置Windchill远程调试

    本文将深入探讨如何在Eclipse集成开发环境中配置Windchill的远程调试环境,以便于高效地定位和解决代码中的问题。 首先,我们需要理解Eclipse作为一款强大的Java开发工具,其内置的调试器功能非常强大,支持多种...

    jvm tomcat eclipse 远程 断点 debug 调试 jpda

    【JVM远程断点调试】 Java虚拟机(JVM)的远程断点调试是一种强大的工具,允许开发者在不中断正常生产环境的情况下,对部署在远程服务器上的...对于Tomcat这样的服务器,通过调整启动参数可以轻松地开启远程调试功能。

    springboot远程调试(eclipse篇)

    ### Spring Boot 远程调试(Eclipse篇) #### 背景介绍 Spring Boot 是一个基于 Spring 框架的快速应用开发框架,它简化了 Spring 应用的初始搭建以及开发过程。在开发过程中,远程调试是一项非常重要的功能,尤其...

    利用eclipse进行远程调试

    本篇文章将详细介绍如何使用Eclipse集成开发环境(IDE)来实现远程调试的功能。 #### 二、准备工作 在正式开始远程调试之前,我们需要确保几个先决条件得到满足: 1. **开发环境**:确保Eclipse IDE已安装并且能够...

    eclipse+Jboss配置远程调试

    1. **创建远程调试配置**:在Eclipse中,依次点击“Run” -&gt; “Debug Configurations” -&gt; “Remote Java Application”,然后双击打开“Remote Java Application”配置页面。 2. **配置连接信息**: - **Project**...

    eclipse linux 远程调试

    标题“Eclipse Linux 远程调试”涉及到的是在Linux环境下使用Eclipse集成开发环境(IDE)进行远程Java应用的调试技术。Eclipse是一款强大的开源IDE,广泛用于Java开发,同时也支持其他编程语言。Linux作为开源操作系统...

    使用 Eclipse 远程调试 Java 应用程序

    Eclipse远程调试的基础是Java Platform Debugger Architecture (JPDA),它由JVM Tool Interface (JVMTI)、Java Debug Interface (JDI)、Java Debug Wire Protocol (JDWP)等组件构成。JPDA定义了一种标准架构,使得...

    eclipse 远程调试was代码

    ### Eclipse远程调试WebSphere Application Server (WAS)代码详解 #### 一、远程调试的意义与应用场景 在软件开发过程中,特别是在分布式系统或大型企业级应用的开发中,开发者经常需要在远程服务器上运行和调试...

Global site tag (gtag.js) - Google Analytics