@Atry: 硬盘满了

我们用的持续集成服务器是一台虚拟机内的虚拟机。虚拟机内的虚拟机的虚拟硬盘文件内的分区还是LVM的虚拟分区。最后虚拟分区内再划分了一块ext4分区。

本周,这块ext4分区满了。这层层虚拟下来,要想扩大分区,真的挺费劲。大概需要这么多步骤:

  1. 备份。
  2. 扩大虚拟硬盘文件。
  3. 把虚拟硬盘文件挂到别的虚拟机上。
  4. 用别的虚拟机上给新增的虚拟硬盘空间划分新的LVM分区。可以使用命令行工具fdisk和parted,也可以用GUI工具gparted。注意:千万不要扩大原有LVM分区,因为扩大后的分区空间识别不了。
  5. 把分完LVM分区后的硬盘文件挂回原有虚拟机。
  6. 用vgextend注册LVM分区。
  7. 用lvextend扩大LVM内的ext4分区。

如果下次需要扩大分区,我可能会选择直接增加一块新的虚拟硬盘,直接在原有虚拟机内给新硬盘分区,就不需要把原有虚拟硬盘挂到别的虚拟机上了。

@Atry: 为什么Java程序员要写又臭又长的public int getXxx() { return xxx; }

前两天和 @zxiy 聊天时,提到Java程序中往往会充满高深莫测的getXxx、setXxx、addXxxListener。为什么呢?请见Java bean 是个什么概念?

@Atry: 删删删

代码评审时,最常见的意见是什么?当然是删!删!删!

@zxiy: 变量起名

在编写武将装备穿戴相关的代码时,有把一个穿戴在一个武将身上的装备来装备到另外一个武将身上的业务逻辑。

于是在这个业务逻辑中,出现了“要装备的装备”、“要装备装备的武将”、“正在装备这个装备的武将”、“要装备装备的武将装备位置现有的装备”这些东西。

然后我就写出了可能比代码还要晦涩的TODO注释。

幸好我早就把装备的英文equipment加入了术语表,有了英语词性变化之后变量名比上述中文表述清晰多了。

这也是我们在程序中尽量使用英文的原因吧,不过因为三国背景题材游戏中很多东西实在没有相应英语单词,有些东西只好用拼音了。

@zxiy: MongoDB 的升级和鉴权

因为我们的paraiso服务器端在持续集成服务器的2.4版本MongoDb下总是出现一些诡异错误,所以就把MongoDb版本升级到了2.6。

之后发现其设定鉴权方式出现了变化。目前并没有什么MongoDb2.6鉴权设置相关的中文文章,于是最好的办法就是看官方文档了。

一定要注意!在用mongo shell给用户设置单独某个数据库权限时,一定要use 数据库名之后在设置这个数据库的权限。在官方的文档的示例中虽然有写到这个,但是没有用文字说明其必要性。

createUser语法中,也可以设置这个用户是属于哪个数据库的,但是!如果没有use 数据库名直接在createUser中指定数据库名,MongoDb不会报错,只是这个账户就不知道设给哪个数据库了,因为哪个数据库都不能用这个账户来访问。

顺便说,升级鉴权方式带来的一系列问题全部搞好之后的几小时内,服务器硬盘就满了:)

@chank: 客户端数量在高压下计数错误

客户端数量在高压下计数会出现错误,因为之前使用定时器和stm出了问题,所以刚开始查该问题时还是把重点放在了定时器和stm的使用上,后来在写stateless-future-util的单元测试用例时才发现定时器没有问题。问题在于在启动一个clien并把该client加到clients中时clients忘了加锁导致的。

使用防御式编程是很有必要的,即在编码时多使用assert。因为这次在性能评测查bug时通过多用assert发现了一些没有暴露出来但也很难会暴露出来的问题。例如在结束链接时竟然检查了两次链接可不可以被清理掉,而其中有一次是没有必要的

ps:在stm中使用定时器好麻烦,如果没有模板照着写的话很容易出错

@tice9982: 单元测试异常处理

什么也不说,先上代码

try {
      ……
    } catch {
      case e: Throwable => Assert.assertFalse(e.isInstanceof[XXXXXXX])
    }
try {
      ……
    } catch {
      case e: XXXXXXX => //正常应该抛出的异常
    }

本身Assert就是抛出异常,然后被自己写的第一段代码先截获 然后再抛出新的异常,这不但是多余的,而且还改变了原来的异常,如果提示的信息不正确,将给调试带来麻烦。

反省反省

(注:catcher处理也一样,把catcher声明成员函数也是以后要注意的)

@tice9982: 单元测试 注入

new Session(id) with ParaisoSession with TextSession {
      ……
      final def outgoingService[ServiceInterface]( implicit entry: RpcSession.OutgoingProxyEntry[ServiceInterface]): ServiceInterface = {
        //网络处理
      }
    }
new ParaisoSession{
        ……
      final def outgoingService[Service](implicit entry: com.qifun.bcp.rpc.RpcSession.OutgoingProxyEntry[Service]): Service = {
        assertEquals(XXXXXXX,XXXXXXXXX)
        }
      }

注入框架很方便实现接口的替换,从而跳过网络模块直接调用测试代码,一个单元测试思路


小报

岂凡技术小报