分析问题:遇到莫名其妙的bug,先冷静思考,仔细检查每一个环节,不要有【以为】【应该】这种态度
决定把这几年遇到的一些问题陆续记录下来,如果有人遇到了类似的问题,可以一起学习,少走弯路
1.HttpServletRequest获取不到Cookie 2014-07-23
(1)domian 跨域导致:比如 cookie是在 a.com下设置的,那么b.com站点就不能获取
(2)path 路径错误:比如 cookie.setPath("/upload") 那么只能在当前站点的 upload 目录下才能获取cookie
(3)security 安全设置:比如 cookie.setSecurity(true) 那么只能在https链接中才能获取之前设置的cookie
(4)其他问题:需要结合项目实际环境来排查,下面介绍一种比较少见,但很实用的案例
而当前在 was 应用里面无法获取cookie。初步排除上述3种情况,那么就要从部署架构入手了。经过排查发现:
直接从was访问,可以获取到cookie
从ihs再到was,仍然可以获取到cookie
这样就能确定:每一次请求是经过varnish之后,请求头里面的cookie才丢失的!
经仔细检查发下 varnish 对get 请求设置了:unset http.req.cookie 意味着每一次get请求,都移除cookie
这句配置的本意是为了提高varnish的命中率,后来经过优化配置使得缓存效率仍然保持较高水平,也能保证需要的cookie不会被移除!
至于 varnish 为什么移除所有cookie能提高命中率,减少回源。请参考文章
2.java.net.UnknowHostException 异常 2014-07-23
A、B两个系统通过http接口交互,中间要经过ESB,结构相当于是
A------请求----->ESB----转发请求----->B
那么系统B处理完毕返回的结果,也要经过 ESB,连接ESB的过程相当于发起一次http请求:ESB提供域名的形式访问,比如 xxx.esb.com/service/
遇到问题就是:A在连接ESB时偶尔会出现 UnknowHostException 异常!
注意:这不是连接超时异常,也不是连接被拒绝,而是明明白白告诉你:压根就是没找到xxx.esb.com这个站点!
这就比较奇怪,因为 A、ESB、B 这3个系统都在内网相同网段,相互能ping通。并且ESB是整个公司的服务总线。之前没听说过类似问题。
不过只能从这个UnknowHost入手了,我们猜测是某些请求在传送过程中丢失了,所以就决定抓包,分析每一次请求。
结果出人意料:每当出现 UnknowHostException 异常,xxx.esb.com域名解析都是以IPV6地址形式产生的
怀疑是公司的dsn服务器解析IPV6地址有问题,经过确认,公司果然不支持IPV6的地址解析!
那么问题需要解决,公司不肯对dns服务器做IPV6的解析,那么可以在hosts文件配置 xxx.esb.com 对应的IPV4地址即可
不过这种不太可取,那么可以在应用服务器配置,tomcat和was都可以配置优先使用IPV4地址
(1)tomcta:在catalina.bat中修改java options
set JAVA_OPTS= %JAVA_OPTS% -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses
(2)was:
应用程序服务器 >
serverXX >
进程定义 >
Java 虚拟机 >
在调试参数中追加 -Djava.net.preferIPv4Stack=true 即可
问题产生的原因:在Java 2 SDK 1.4中,JVM 在获得 HostName 的时候会同时进行 IPv4 和 IPv6 查询。
如果DNS没有配置接受IPv6查询,JVM可能返回Unknown Host异常。并且JVM需要等待IPv6查询返回结果,直到超时。这就引起了JVM挂起或响应慢。
3.background导致页面加载两次 2014-07-30
偶然发现在FireFox和Chrom浏览器下,如果有标签设置内联样式background-image,并且背景图片的地址为空
则会导致当前页面会重复请求一次,这种情况很好模拟,但是不能使用html静态页面模拟,得部署到tomcat上面看效果
background设置为空导致页面重复加载
测试效果可以在FireBug的网络面板很清晰看到:请求了两次。你也可以在后台代码打断点,可以发现会被请求两次!
去掉这个空的background-image属性即可恢复。目前在FireFox和Chrom下发现这个问题。