↓ 跳过正文
  1. Posts/

2000年前后:KCBP 与 KCXP 到底是什么?还原金证早期证券中间件架构

2000年前后:KCBP 与 KCXP 到底是什么?
#

——还原金证早期证券中间件架构
#

前面的文章,我们已经从历史角度还原了2000年前后中国证券交易系统的大致结构:

营业部 → 集中交易系统 → 交易主机 → 中间件 → 交易席位 → 交易所。

那么接下来就出现一个非常关键的问题:

KCBP 和 KCXP 到底处在这条链路的什么位置?

更重要的是:

证券公司为什么必须要有 KCBP、KCXP 这一类东西?

如果只看产品名称,很容易把它们理解成某个“交易软件”。

但如果把当时的证券 IT 架构真正拆开,就会发现:

KCBP / KCXP 更应该放到“证券交易基础设施”和“中间件”这个层次来理解。


一、先不要问 KCBP 是什么,先问证券公司遇到了什么问题
#

2000年前后,一家大型证券公司可能已经拥有:

数十个、上百个营业部
        ↓
大量柜台终端
        ↓
大量客户委托

与此同时,这些交易最终又必须进入外部市场:

                    ┌── 上海证券交易所
                    │
证券公司交易系统 ───┼── 深圳证券交易所
                    │
                    ├── 登记结算系统
                    │
                    └── 银行等外部系统

问题马上出现:

证券公司自己的核心交易系统,与外部市场系统,并不是天然使用同一种接口、协议和数据结构。

因此,中间必然需要一层东西。

这就是证券中间件。


二、最简单的架构
#

如果把整个系统极度简化,可以画成:

投资者
  ↓
营业部
  ↓
集中交易系统
  ↓
KCBP / KCXP
  ↓
交易通道
  ↓
交易所

但是这个图还不够准确。

更接近实际工程思维的结构应该是:

                     证券公司
                        │
                        ▼
              ┌──────────────────┐
              │   集中交易系统   │
              └────────┬─────────┘
                       │
                       ▼
              ┌──────────────────┐
              │    中间件层      │
              │                  │
              │ 消息处理         │
              │ 路由             │
              │ 队列             │
              │ 协议转换         │
              │ 会话管理         │
              │ 故障恢复         │
              └────────┬─────────┘
                       │
              ┌────────┴────────┐
              ▼                 ▼
         上交所通道          深交所通道
              │                 │
              ▼                 ▼
             上交所             深交所

KCBP、KCXP 这类产品,真正有意义的地方,就是处在这类架构的中间。


三、首先要分清三个概念
#

理解老证券系统,最容易犯的错误就是把下面三个东西混为一谈:

交易业务系统
       ≠
证券中间件
       ≠
交易所

例如客户下了一笔:

买入
600000
1000股
10.00元

核心交易系统负责的是业务逻辑:

客户是谁?

资金是否足够?

证券是什么?

买还是卖?

数量是多少?

价格是多少?

但是中间件面对的是另外一组问题:

这条消息发给哪里?

使用哪个通道?

使用什么协议?

当前连接是否正常?

有没有收到确认?

如果连接断了怎么办?

消息有没有丢失?

是否发生重复发送?

交易所则负责另一件最核心的事情:

这笔订单能不能和市场上的其他订单撮合?

因此:

核心系统 = 交易业务

中间件 = 交易通信基础设施

交易所 = 集中市场

这是理解 KCBP / KCXP 最重要的第一步。


四、KCBP / KCXP 不应该简单理解成“交易系统”
#

如果直接把:

KCBP = 交易系统

或者:

KCXP = 交易系统

这样理解,实际上已经把架构层级搞混了。

更准确的思路应该是:

证券核心业务系统
        ↓
KCBP / KCXP
        ↓
外部交易基础设施

也就是说:

它们真正解决的问题,是两个系统之间如何可靠地交换金融交易消息。


五、为什么核心交易系统不能直接连接交易所?
#

从今天的软件工程角度看,很容易产生一个疑问:

为什么核心系统不能直接开一个 Socket,然后把订单发送给交易所?

如果只有一个市场,也许看起来没什么问题。

但是现实很快会变成:

核心交易系统
   ├── 上交所
   ├── 深交所
   ├── 席位A
   ├── 席位B
   ├── 席位C
   ├── 主通道
   └── 备用通道

于是核心交易系统开始知道越来越多的外部细节:

上交所协议
深交所协议
席位编号
通道编号
连接状态
登录状态
消息序号
重连逻辑
故障恢复

这就产生了严重的耦合。

任何一个交易所接口发生变化,都可能影响核心交易系统。

这是非常糟糕的架构。


六、中间件解决的第一个问题:隔离
#

因此系统开始变成:

                 核心交易系统
                       │
                       ▼
                ┌────────────┐
                │   中间件   │
                └──────┬─────┘
                       │
          ┌────────────┼────────────┐
          ▼            ▼            ▼
         上交所       深交所        其他系统

核心系统只需要知道:

我要发送一笔订单。

至于:

发送到哪里?

通过哪个席位?

走哪个连接?

采用什么协议?

消息如何编码?

交给中间件处理。


七、因此可以把中间件理解成“翻译层”
#

假设核心系统内部使用自己的订单结构:

ORDER
{
    account
    security
    side
    price
    quantity
}

交易所却要求另外一种格式。

那么中间件负责:

内部订单
   ↓
协议适配
   ↓
交易所订单

反过来也一样:

交易所成交消息
   ↓
协议解析
   ↓
内部成交消息
   ↓
核心交易系统

所以中间件最重要的能力之一就是:

把证券公司内部的数据模型,与外部交易系统的数据模型隔离开。


八、为什么“消息”是理解 KCBP / KCXP 的关键
#

不要把整个系统理解成:

程序调用程序

更好的理解方式是:

消息 → 消息 → 消息 → 消息

例如一笔订单可能经历:

ORDER
  ↓
ACK
  ↓
EXECUTION

或者:

ORDER
  ↓
REJECT

或者:

ORDER
  ↓
CANCEL
  ↓
CANCEL_ACK

这就是一个典型的金融交易消息生命周期。


九、一笔订单在中间件里到底经历了什么?
#

可以抽象成:

订单进入
   ↓
接收
   ↓
检查
   ↓
进入队列
   ↓
路由
   ↓
协议转换
   ↓
发送
   ↓
等待确认
   ↓
接收成交
   ↓
反向路由
   ↓
通知核心系统

看起来只是几个步骤。

但每一步实际上都是一个工程问题。


十、第一步:Receive——接收订单
#

核心交易系统把订单交给中间件:

核心系统
    ↓
中间件

消息可能包含:

订单号
客户号
证券代码
买卖方向
价格
数量
市场
时间

中间件首先必须把这条消息正确接收下来。


十一、第二步:Validate——检查消息
#

中间件需要知道:

消息格式正确吗?

当前连接正常吗?

目标通道存在吗?

会话是否有效?

消息序号正确吗?

是不是重复消息?

这里特别需要注意:

通信层面的检查,与交易业务层面的检查不是一回事。

例如:

核心交易系统可能负责:

客户资金够不够?

而中间件更关心:

这是不是一条合法的通信消息?

两者属于不同层次。


十二、第三步:Queue——消息队列
#

为什么要有队列?

因为生产者和消费者的速度不一定相同。

例如:

核心交易系统
      ↓
   消息队列
      ↓
交易所通道

假设某一瞬间:

核心系统产生速度 = 很快
交易所通道处理速度 = 暂时较慢

那么订单可以暂存在队列中:

生产者
  ↓
[1001][1002][1003][1004][1005]
                          ↓
                        消费者

这样可以吸收短时间的流量突发。

对于证券交易系统来说,这一点非常重要。


十三、第四步:Routing——路由
#

例如:

600000

属于上海市场,那么:

订单
 ↓
上海市场路由
 ↓
上交所

而另外一笔:

000001

可能走:

订单
 ↓
深圳市场路由
 ↓
深交所

因此中间件实际上形成了:

                 中间件
                /      \
               /        \
           上交所       深交所

路由规则成为系统非常重要的一部分。


十四、第五步:Protocol Adapter——协议转换
#

这是中间件存在的另一个核心原因。

内部可能是:

BUY_ORDER

外部交易系统却有自己的通信格式。

于是:

内部消息
   ↓
协议适配器
   ↓
外部交易协议

返回时反过来:

外部交易协议
   ↓
协议适配器
   ↓
内部成交消息

因此可以把它想象成:

证券公司内部语言
       ↕
     中间件
       ↕
交易所通信语言

十五、第六个问题:Session——会话管理
#

交易所连接并不是简单的:

打开 Socket
     ↓
一直发送

一个真正的交易通信连接通常需要经历:

CONNECT
   ↓
LOGIN
   ↓
ESTABLISHED
   ↓
MESSAGE EXCHANGE
   ↓
LOGOUT

如果网络断开:

ESTABLISHED
      ↓
DISCONNECTED
      ↓
RECONNECT
      ↓
RECOVER
      ↓
ESTABLISHED

所以中间件需要保存:

连接状态
登录状态
会话状态
消息序号

十六、为什么消息序号非常重要
#

假设系统发送:

1001
1002
1003
1004

返回确认却是:

1001
1002
1004

那么:

1003

去哪了?

可能是:

丢失

也可能是:

网络延迟

或者:

处理异常

所以系统必须能够识别:

缺失消息
重复消息
乱序消息

这也是金融消息系统与普通业务系统的重要区别之一。


十七、最危险的问题:重复订单
#

假设:

订单100001

发送出去以后,迟迟没有收到 ACK。

那么系统不知道:

交易所没收到?

还是:

交易所收到了,但 ACK 在网络中丢了?

如果简单重发:

订单100001

就可能产生:

重复订单

这就是金融交易系统中非常经典的问题。

因为:

发送方无法仅凭网络状态判断接收方究竟有没有处理成功。

所以证券中间件必须考虑:

消息唯一性
序列号
确认
超时
恢复
对账

十八、因此 Recovery——恢复机制非常重要
#

假设:

正常运行
    ↓
网络故障
    ↓
连接断开

系统不能简单地:

重新连接

然后继续发送。

它必须知道:

最后发送到哪里?

最后确认到哪里?

哪些消息已经处理?

哪些消息可能丢失?

哪些消息不能重新发送?

因此恢复流程可以抽象成:

故障
 ↓
重新连接
 ↓
确定双方最后状态
 ↓
恢复缺失消息
 ↓
重新同步
 ↓
继续交易

这也是金融中间件真正复杂的地方。


十九、成交消息也必须可靠地回来
#

订单不是单向的。

正向:

核心系统
   ↓
中间件
   ↓
交易所

反向:

交易所
   ↓
中间件
   ↓
核心系统

例如:

ORDER 100001

交易所可能返回:

ACK 100001

然后:

EXECUTION
成交500股

之后:

EXECUTION
再成交500股

核心系统最终需要得到:

成交数量 = 1000
剩余数量 = 0

所以中间件不仅仅负责“把订单发出去”。

它还负责:

把市场产生的结果可靠地带回来。


二十、订单实际上就是一个状态机
#

例如:

NEW
 ↓
SENT
 ↓
ACKNOWLEDGED
 ↓
PARTIALLY_FILLED
 ↓
FILLED

也可能:

NEW
 ↓
SENT
 ↓
REJECTED

或者:

NEW
 ↓
SENT
 ↓
CANCEL_REQUESTED
 ↓
CANCELLED

因此:

证券交易系统实际上是在维护大量订单状态机。

KCBP、KCXP 这样的中间件,就必须参与这个状态流转中的通信部分。


二十一、为什么日志在证券中间件里极其重要
#

假设客户投诉:

“我10点15分32秒下了一笔订单,为什么没有成交?”

证券公司必须能够追踪:

营业部什么时候收到?

核心系统什么时候接收?

中间件什么时候收到?

什么时候进入队列?

什么时候发往交易所?

什么时候交易所确认?

什么时候成交?

成交结果什么时候返回?

因此系统必须保存完整的交易链路日志。

概念上可能类似:

10:15:32.001 RECEIVE
10:15:32.003 VALIDATE
10:15:32.004 QUEUE
10:15:32.005 SEND
10:15:32.008 ACK
10:15:32.120 EXEC

具体实现会随着产品和年代变化,但原则不会变化:

金融交易必须可追踪、可审计、可恢复。


二十二、所以理解 KCBP / KCXP,不能只看产品界面
#

如果研究一套老证券软件,最容易陷入一个误区:

“这个软件有什么菜单?”

但真正应该问的是:

它处理什么消息?

连接什么系统?

如何路由?

如何排队?

如何维护会话?

如何转换协议?

如何处理 ACK?

如何处理成交?

如何重连?

如何恢复?

如何记录日志?

这才是真正的技术问题。


二十三、KCBP / KCXP 的边界不能简单粗暴地下结论
#

这里尤其需要谨慎。

研究历史软件时,很容易直接得出:

KCBP = 某一层

KCXP = 另一层

然后认为所有版本、所有证券公司部署都是如此。

实际上这很可能过于简单。

更可靠的研究方式应该是:

金证证券软件体系
       │
       ├── 核心交易系统
       │
       ├── 通信 / 中间件
       │
       ├── 交易所接入
       │
       └── 配套基础设施

然后再根据:

  • 产品版本;
  • 部署文档;
  • 系统架构图;
  • 安装文件;
  • 配置文件;
  • 服务器清单;
  • 招聘资料;
  • 客户案例;
  • 历史技术资料;

去判断 KCBP 和 KCXP 在具体年代、具体版本中的实际边界。


二十四、为什么同一个产品名字,内部架构可能发生变化?
#

这是研究90年代末、2000年前后软件非常重要的一点。

证券市场变化速度非常快。

一个产品可能最初只是:

通信组件

后来逐渐增加:

消息队列
路由
协议转换
监控
故障恢复

另一个产品则可能反过来:

大型综合系统
      ↓
逐渐拆成多个模块

因此:

不能因为一个产品在某个年份承担了某项功能,就认为它从诞生开始一直都是这个功能。

历史软件研究一定要带版本和时间轴。


二十五、那么一台证券公司的服务器可能怎么部署?
#

从架构上,可以想象一种典型模式:

                    营业部
                 /    |    \
                /     |     \
               ↓      ↓      ↓

          ┌────────────────────┐
          │   集中交易系统     │
          └─────────┬──────────┘
                    │
                    ▼
          ┌────────────────────┐
          │    中间件服务器    │
          │                    │
          │ 消息处理           │
          │ 路由               │
          │ 协议转换           │
          │ 会话管理           │
          │ 恢复               │
          └─────────┬──────────┘
                    │
             ┌──────┴──────┐
             ↓             ↓
          上交所          深交所

还可能进一步存在:

主中间件
   │
   └── 备用中间件

以及:

主通道
   │
   └── 备用通道

实际部署当然会因为证券公司规模、交易所接入方式和具体产品版本不同而变化。


二十六、为什么中间件需要独立服务器?
#

如果所有东西全部放在一起:

核心交易
+
数据库
+
交易所通信
+
消息队列
+
监控

那么任何通信程序的问题,都可能影响核心交易。

例如:

交易所通信进程异常
        ↓
核心交易系统受到影响

而如果拆开:

核心交易服务器
       │
       ▼
中间件服务器
       │
       ▼
交易所

故障隔离能力就更强。

这也是后来证券系统不断走向:

多层架构
分布式架构
高可用架构
灾备架构

的重要基础。


二十七、从这里可以看到“交易网关”是怎么产生的
#

后来越来越常见的概念就是:

核心交易系统
       ↓
交易网关
       ↓
交易所

网关成为:

证券公司内部网络
        │
        │
        ▼
      Gateway
        │
        │
        ▼
证券市场外部网络

中间可能承担:

连接
认证
协议
路由
消息转换
会话
监控
故障恢复

今天我们经常听到:

API Gateway
Message Gateway
Protocol Gateway
Trading Gateway

虽然底层技术已经完全不同,但架构思想其实非常接近。


二十八、这与1990年代初的证券系统有什么不同?
#

把两个时代放在一起就很清楚。

早期1990年代
#

投资者
   ↓
营业部
   ↓
交易员
   ↓
交易所

人是整个交易链路的重要组成部分。


2000年前后
#

投资者
   ↓
营业部
   ↓
集中交易系统
   ↓
中间件
   ↓
交易通道
   ↓
交易所

人的角色开始退出订单实际传输路径。

网络和软件成为新的中间人。


二十九、真正发生的技术革命:从“人”变成“消息”
#

这是理解中国证券 IT 发展史最重要的变化之一。

早期:

投资者
 ↓
柜员
 ↓
交易员
 ↓
交易所

后来:

投资者
 ↓
客户端
 ↓
交易系统
 ↓
消息
 ↓
中间件
 ↓
交易所

也就是说:

证券交易从“人和人之间传递交易指令”,逐渐变成“机器和机器之间传递金融消息”。

这就是为什么中间件越来越重要。


三十、为什么中间件最终变成交易基础设施?
#

普通软件中:

界面坏了

可能只是用户暂时不能操作。

但是证券中间件如果出现故障:

中间件故障
      ↓
订单无法发送
      +
成交无法返回
      +
撤单无法处理

甚至可能影响:

大量营业部
大量客户
整个交易时段

所以:

中间件并不是一个普通的辅助程序,而是证券交易基础设施的一部分。


三十一、把 KCBP / KCXP 放进完整架构
#

现在我们可以画出一个更加完整的概念图:

                         投资者
                            │
                            ▼
                         营业部
                            │
                            ▼
                    集中交易系统
                            │
                            ▼
                  ┌─────────────────┐
                  │  KCBP / KCXP    │
                  │                 │
                  │ 消息处理        │
                  │ 消息队列        │
                  │ 路由            │
                  │ 协议适配        │
                  │ 会话管理        │
                  │ 故障恢复        │
                  └────────┬────────┘
                           │
                  ┌────────┴────────┐
                  ▼                 ▼
               交易席位          交易席位
                  │                 │
                  ▼                 ▼
                 上交所             深交所

这里需要再次强调:

这是一种架构层面的历史还原模型,不意味着每一个 KCBP / KCXP 安装实例都严格按照这个进程图部署。

研究历史系统时,必须区分:

产品概念

和:

具体版本的实际部署

三十二、那么为什么金证需要两个产品?
#

这才是接下来真正值得研究的问题。

如果 KCBP 和 KCXP 都属于证券通信、交易基础设施这一大领域:

为什么不是一个产品?

为什么会出现两个名字?

可能涉及:

不同功能
不同产品代际
不同部署场景
不同协议层次
不同性能要求
不同客户架构

但是不能简单写成:

KCBP = 老版本
KCXP = 新版本

也不能在没有版本资料的情况下直接断言:

KCBP = 交易所适配器
KCXP = 消息队列

真正严谨的做法,是继续寻找具体历史版本的架构资料。


三十三、为什么恒生也出现类似产品?
#

这就能够解释为什么同一时期恒生也发展出了自己的相关产品体系。

例如:

金证
KCBP / KCXP

与:

恒生
AS / AR

虽然产品名称不同,但它们背后的市场问题非常相似:

证券集中交易
       ↓
全国营业部联网
       ↓
集中交易主机
       ↓
多个交易市场
       ↓
多个交易席位
       ↓
可靠通信
       ↓
高可用
       ↓
高吞吐

所以真正的竞争并不是简单的:

产品A vs 产品B

而是:

金证和恒生分别如何解决中国证券公司集中交易时代的基础设施问题。


三十四、真正的竞争力并不在界面
#

如果今天看一个软件,我们往往首先看:

界面
功能
菜单

但是证券中间件真正重要的东西往往完全看不见:

网络断了能不能恢复?

消息顺序能不能保证?

会不会重复?

能不能处理高峰?

能不能多席位?

能不能主备切换?

能不能完整记录?

能不能对账?

能不能恢复?

用户甚至可能从来没有直接看到这些功能。

但是这些能力决定了:

交易日高峰时系统究竟能不能活下来。


三十五、为什么2000年前后是一个关键时间点?
#

把中国证券 IT 的发展压缩成一条时间线,大致可以看到:

1980年代
纸质股票 + 柜台交易
        ↓
1990年前后
交易所成立 + 交易电子化
        ↓
1990年代中期
营业部联网
        ↓
1990年代后期
集中交易
        ↓
2000年前后
中间件 + 网关 + 交易席位
        ↓
2000年代
分布式 + 多层架构 + 高可用 + 灾备

KCBP、KCXP 正好处在这个重要的转折阶段。

它们背后的意义,并不只是两个软件产品。

而是说明:

证券 IT 已经从“营业部软件”,逐渐变成“全国性金融网络基础设施”。


三十六、最值得记住的一张图
#

如果整篇文章只记住一张图,可以记住:

                 客户
                  │
                  ▼
                 营业部
                  │
                  ▼
              核心交易系统
                  │
                  ▼
             交易主机 / 核心
                  │
                  ▼
          ┌────────────────┐
          │    中间件      │
          │                │
          │ 消息           │
          │ 路由           │
          │ 队列           │
          │ 协议           │
          │ 会话           │
          │ 恢复           │
          └───────┬────────┘
                  │
           ┌──────┴──────┐
           ▼             ▼
        上交所席位     深交所席位
           │             │
           ▼             ▼
          上交所          深交所

最重要的四句话就是:

核心系统 = 交易业务

中间件 = 消息与通信

席位 = 进入交易所市场的接入边界

交易所 = 集中撮合市场

三十七、下一步:真正进入 KCBP / KCXP 内部
#

到了这里,我们已经回答了:

KCBP / KCXP 为什么存在?

但是还没有真正进入最有意思的部分:

一笔订单进入 KCBP 以后,究竟发生了什么?

接下来可以进一步把一个2000年前后的证券中间件拆到进程级别:

订单进入
   ↓
哪个进程接收?
   ↓
哪个线程处理?
   ↓
消息进入哪个队列?
   ↓
如何选择交易席位?
   ↓
如何生成交易所协议?
   ↓
哪个 Socket 发出去?
   ↓
ACK 到哪里?
   ↓
成交消息由谁接收?
   ↓
如何回传核心系统?
   ↓
连接断开怎么办?
   ↓
主通道故障怎么办?
   ↓
如何恢复?
   ↓
如何最终对账?

相关文章