首先我同意软件解藕的方法很多,按进程拆分不过是其中一种,但不必然是最好的一种。事实上要提高开发效率和降低维护难度,是一项需要根据团队成员的技术特点不断摸索的艺术,不必预先把自己的思维模式限制死了,尝试一下其他方法(比如 OO ,Functional )也许有更好的效果。

根据我(多年打杂)的经验来看,交易系统也是特别符合《人月神话》中推荐的外科手术团队的开发模式。开发这种高精密系统人多了其实有负面作用,最好的办法是以一两个高水平程序员为主力设计和开发,再加几个杂兵跑堂就可以了。所以解决这个问题有一个四海一家的终极大法:让老板涨工资高薪聘请一流的技术专家。当你有一个一流高手坐镇主攻的时候,解藕就从多人协作变成一项个人品味的问题了,只要根据主攻手的口味选择方案就好。

当然我明白人在江湖,身不由己。以上建议对于已经有很多历史遗留或者起了一半的项目来说显然是远水解不了近渴。所以下面尝试给点实际的建议。

首先进程间通信(IPC)有很多种方法,端口通讯(Socket)绝对不是最快的那种。Named pipe 和共享内存都可以做的更好,事实上最快的办法是共享内存+独占 CPU core,可以参考 Java-Chronicle 的实现。这种方法做到几十钠秒的通信延迟是没问题的,见:fastest (low latency) method for Inter Process Communication between Java and C/C++

关于端口通讯为什么慢,只要看这篇文章就可以理解:Know your TCP system call sequences,见下图:

高频交易系统怎样在多线程和端口通讯之间取舍?插图

即便你用的是本地接口(localhost),一样要经过系统调用(system call)切换进 kernel space,中间经过无数内存拷贝,协议检查之类浪费时间的事情。这些问题在共享内存方案下都不存在。所以一个简单的做法是重写你们的通信模块,采用这些更快的通信方法。

如果你的摊子实在太烂以至于修改通信代码也是不能承受之重,那么还有一手秘籍叫做替换系统调用。简言之就是用修改函数指针的方式把系统调用入口换成自己的程序,比如用共享内存来实现端口通讯的 API。这样你可以在不改动现有程序的基础上改变通信方式来提高通信速度。具体怎么做可以参考流行的开源实现 OpenOnload,虽然它主要是替换 TCP/IP 协议栈,但思路是一样的。

其实这个时候是最能体现 Java 等基于虚拟机字节码的语言的优势的。如果你用 Java,那么替换系统调用就很容易,对 JVM 上 instrumentation 即可,嫌麻烦可以直接用 JMockit 之类的库,用法很简单(请允许我对于深陷 C++ 囹圄中苦苦挣扎的同学们表示一下同情)。

— 完 —

本文作者:董可人

【知乎日报】
你都看到这啦,快来点我嘛 Σ(▼□▼メ)

此问题还有 8 个回答,查看全部。
延伸阅读:
什么是高频交易系统?
程序化交易、算法交易、量化投资、高频交易、统计套利,这些名词之间的关系是怎么样的?

分享到