最近在项目上遇到了一个奇怪的问题:某个 XPages 页面偶发性报错,对数据库进行签名后问题消失,但过些时间就又会出现。

由于签名后问题消失,最开始排查时就认为是代码签名的问题,可能是服务器上有对应的模板,设计不定时的被 Design 任务刷新回来导致问题。但是通过各种方法找了很多遍,都确认库的设计没有被刷新过。

最终通过检查代码的错误行发现,是一处 session.getDatabase 调用时数据库路径的大小写有问题,修改成与文件系统一致后问题消失。问题虽然解决了,但为什么同样的代码大部分情况下没问题,只有偶发性的报错呢?同样的代码在同为 Linux 平台的产品测试环境上,为什么就一切正常呢?

带着这些疑问继续探索,终于找到了一些端倪。在这个技术文档中提到如下内容:

DB on server names AgentRunner.nsf. Notes the upper/lowercase.

Steps to Reproduce:

After a server restart or a “dbcache flush”:

> lo fixup agentrunner
> 25.06.2002 09:58:00   Database fixup process started
25.06.2002 09:58:00   Unable to fixup database agentrunner: File
does not exist
25.06.2002 09:58:00   Database fixup process shutdown
–> does not work, because db is not in server cache

lo fixup AgentRunner
> 25.06.2002 09:58:07   Database fixup process started
25.06.2002 09:58:07   Performing consistency check on
AgentRunner.nsf…
25.06.2002 09:58:08   Completed consistency check on
AgentRunner.nsf
25.06.2002 09:58:08   Database fixup process shutdown
–> works – it`s exact-case

> lo fixup agentrunner
> 25.06.2002 09:58:12   Database fixup process started
25.06.2002 09:58:12   Database fixup process shutdown
–> works now with lowercase, cause db is in cache

dbcache flush
> lo fixup agentrunner
> 25.06.2002 09:58:21   Database fixup process started
25.06.2002 09:58:21   Unable to fixup database agentrunner: File
does not exist
25.06.2002 09:58:21   Database fixup process shutdown
–> db removed from cache –> doesn`t work

整个过程总结如下:

  • 首先用大小写错误的文件名访问,报错
  • 再用大小写正确的文件名访问,正常
  • 再次用大小写错误的文件名访问,正常(因为上一条命令已经将数据库加入了 dbcache)
  • 清空 dbcache 后,再次用大小写错误的文件名访问,报错

导致这个现象的根本原因就是:

  • 当数据库不在 dbcache 中时,Domino 使用数据库文件名通过文件系统获取数据库对象,此时是区分大小写的
  • 当数据库在 dbcache 中时,Domino 使用数据库文件名在 dbcache 中查找,找到后直接返回数据库对象,此过程无需访问文件系统,所以就不区分大小写

分析到这里,最初的所有现象就能说通了:

  • 错误偶发,是因为大部分情况下此库都在 dbcache 中,可能只有服务器刚刚启动/缓存超限将此库移除时,才会报错
  • 签名后错误消失,是因为签名的过程肯定会把此库加入到 dbcache

吃一堑长一智,既然这个问题让我纠结了这么久,那么如何才能避免此类问题发生呢?建议如下:

  • 数据库名始终使用全小写,代码中获取数据库时也用全小写
  • *nux 测试环境下建议通过 NSF_DbCache_Disable=1 禁用缓存。虽然性能会差一些,但是能尽早的发现问题(千万别在生产服务器上这样做)

今天同事报告一个问题:Linux 平台下的 Domino 服务器运行一段时间之后,Notes 客户机无法连接,但 HTTP 服务器却是好的。同时在服务器控制台上出现以下错误:

WARNING: the maximum number of file handles (ulimit -n) allowed for Domino is 1024. See Release Notes and set the allowable maximum to 20000.

经查明其原因是在 Linux 默认设置下,每个进程能够使用的 file handles 为 1024,达到这个限制之后就无法再打开任何文件了。修改此设定分为两种情况:

  • 用户登录系统手工启动 Domino(修改 /etc/security/limits.conf 文件)
  • 通过 /etc/init.d 脚本自动启动(在启动脚本中增加 ulimit -n 20000 命令)

具体方法请参考 IBM 技术支持文档

由于我的显示器比较特殊,所以启动的 kernel 参数中一直加上了 vga=791,来指定分辨率为 1024×768。前些天升级到 7.10 之后,开机过程以及 tty[1-6] 就都是黑屏。昨天终于找到了解决方法:

  1. 修改 /etc/initramfs-tools/modules,加入了 fbcon,vesafb,nvidiafb 三行
  2. 修改 /etc/modprobe.d/blacklist-framebuffer,把 nvidiafb,vesafb,vga16fb 三行注释掉
  3. 运行sudo update-initramfs -u,重启机器

其中的 nvidiafb 可以按照自己的显卡类型,换成相应的模块。

参考链接:Ubuntu 中文论坛

现象:做字符串比较、包含相关的操作无法得到正确的结果。

解决方法:

  • 检查当前操作系统的语言设置
    • 使用locale命令来查询当前的语言环境
  • 设置Language Pack的语言环境。
    • 前面安装Domino的过程我就不说了。安装完Domino之后,还需要安装Language Pack。在LP的readme.txt文件中,注明了各种操作系统下面需要使用的语言和字符集,以Linux为例,需要设置为zh_CN.GB2312。
    • 操作如下:

LANG=zh_CN.GB2312
LC_ALL=zh_CN.GB2312
export LANG
export LC_ALL

  • 安装Language Pack
    • 运行install来进行安装,在安装过程中注意选择中文。
  • 设置notes用户的语言环境
    • Domino不能用root账号来启动,必须使用notes(安装Domino时候设置的账号)来进行启动。由于我们设置了当前的语言为中文,采用GB2312的字符集。所以该notes用户的语言环境也需要设置为zh_CN.GB2312
  • 修改profile文件
    • 到domino运行账号(notes)的home目录下去(/home/notes),然后编辑.bash_profile文件,添加如下行

LANG=zh_CN.GB2312
LC_ALL=zh_CN.GB2312
export LANG
export LC_ALL
然后重新使用该账号登录系统,启动domino即可!

我们一般使用“date -s”命令来修改系统时间。比如将系统时间设定成1996年6月10日的命令如下。

#date -s 06/10/96
将系统时间设定成下午1点12分0秒的命令如下。
#date -s 13:12:00

注意,这里说的是系统时间,是linux由操作系统维护的。
在系统启动时,Linux操作系统将时间从CMOS中读到系统时间变量中,以后修改时间通过修改系统时间实现。为了保持系统时间与CMOS时间的一致性,Linux每隔一段时间会将系统时间写入CMOS。由于该同步是每隔一段时间(大约是11分钟)进行的,在我们执行date -s后,如果马上重起机器,修改时间就有可能没有被写入CMOS,这就是问题的原因。如果要确保修改生效可以执行如下命令。

#clock -w

这个命令强制把系统时间写入CMOS