诡异的时区问题+使用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知识点详解 #### 一、概述 在软件开发过程中,尤其是在Web应用开发领域,远程调试是一项非常重要的技术。它可以帮助开发者在不同的环境中(如远程服务器)调试应用程序,这对于查找和...
NC Eclipse 远程调试是指在 Eclipse 集成开发环境中,使用 Java Debug Wire Protocol (JDWP) 实现远程调试 Java 应用程序的功能。JDWP 是一个基于 socket 的通信协议,用于在 debug 客户端和服务器之间传输调试信息...
本文将详细介绍如何通过Eclipse集成开发环境(IDE)配合Apache Tomcat应用服务器实现远程调试的功能。 #### 二、准备工作 在开始配置之前,请确保已经安装了以下组件: - **Eclipse IDE**:推荐使用最新版Eclipse...
"使用Eclipse远程调试Linux服务器Tomcat项目" 一、概述 在开发Java Web应用程序时,需要在远程服务器上进行调试,以便更好地了解程序的执行过程。使用Eclipse远程调试Linux服务器Tomcat项目可以帮助开发者更好地...
### Eclipse远程调试详解 #### 一、远程调试概念与应用场景 **远程调试**是指开发者能够通过特定工具在一台机器上(通常称为客户端)对另一台机器(服务端)上正在运行的应用程序进行调试的过程。这种方式使得...
Eclipse远程调试教程 Eclipse 远程调试是指在 Eclipse 中对 Java 应用程序进行远程调试,通过配置 Tomcat 和 Eclipse,可以实现对远程服务器上的 Java 应用程序的调试。下面将详细介绍 Eclipse 远程调试的配置和...
2. **在Eclipse中设置远程调试器** - **新建远程Java应用配置**:在Eclipse中,选择`Run` -> `Debug Configurations`,然后在左侧窗格中选择`Remote Java Application`,点击`New launch Configuration`。 - **...
Eclipse远程调试项目配置 #### 3.1 选择项目右键选择Debug as 在Eclipse中,右键点击需要远程调试的项目,选择Debug as -> Remote Java Application。 #### 3.2 选择Remote Java Application Eclipse会自动尝试...
### Eclipse远程调试Tomcat应用详解 #### 一、前言 在软件开发过程中,调试是不可或缺的一环,尤其是在复杂的分布式系统或服务器端应用中。Eclipse作为一款功能强大的集成开发环境(IDE),提供了丰富的工具来支持...
Eclipse远程Debug功能允许开发者对运行在另一台机器上的应用程序进行调试,这对于分布式系统或者服务器端应用的调试尤其有用。 首先,我们需要确保Eclipse安装了Remote System Explorer (RSE)插件,因为这是远程...
标题 "Eclipse远程调试Tomcat" 指的是在Eclipse集成开发环境中,通过远程调试功能连接并调试在另一台机器上运行的Tomcat服务器。这通常用于在生产环境或测试环境中定位和修复代码问题,而无需直接在该环境中安装IDE...
本文将深入探讨如何在Eclipse集成开发环境中配置Windchill的远程调试环境,以便于高效地定位和解决代码中的问题。 首先,我们需要理解Eclipse作为一款强大的Java开发工具,其内置的调试器功能非常强大,支持多种...
【JVM远程断点调试】 Java虚拟机(JVM)的远程断点调试是一种强大的工具,允许开发者在不中断正常生产环境的情况下,对部署在远程服务器上的...对于Tomcat这样的服务器,通过调整启动参数可以轻松地开启远程调试功能。
### Spring Boot 远程调试(Eclipse篇) #### 背景介绍 Spring Boot 是一个基于 Spring 框架的快速应用开发框架,它简化了 Spring 应用的初始搭建以及开发过程。在开发过程中,远程调试是一项非常重要的功能,尤其...
本篇文章将详细介绍如何使用Eclipse集成开发环境(IDE)来实现远程调试的功能。 #### 二、准备工作 在正式开始远程调试之前,我们需要确保几个先决条件得到满足: 1. **开发环境**:确保Eclipse IDE已安装并且能够...
1. **创建远程调试配置**:在Eclipse中,依次点击“Run” -> “Debug Configurations” -> “Remote Java Application”,然后双击打开“Remote Java Application”配置页面。 2. **配置连接信息**: - **Project**...
标题“Eclipse Linux 远程调试”涉及到的是在Linux环境下使用Eclipse集成开发环境(IDE)进行远程Java应用的调试技术。Eclipse是一款强大的开源IDE,广泛用于Java开发,同时也支持其他编程语言。Linux作为开源操作系统...
Eclipse远程调试的基础是Java Platform Debugger Architecture (JPDA),它由JVM Tool Interface (JVMTI)、Java Debug Interface (JDI)、Java Debug Wire Protocol (JDWP)等组件构成。JPDA定义了一种标准架构,使得...
### Eclipse远程调试WebSphere Application Server (WAS)代码详解 #### 一、远程调试的意义与应用场景 在软件开发过程中,特别是在分布式系统或大型企业级应用的开发中,开发者经常需要在远程服务器上运行和调试...