Quickfix的线程和latency

Discussion in 'FIX Protocol' started by tom_sh, Dec 21, 2009.

  1. 根据以下的讨论(http://old.nabble.com/Re:-Two-more-questions-about-QuickFix-td15538709.html),quickfix的收发都由队列技术控制,即使是单线程的socketinitiator。可以在程序中写进时间戳来计算延迟。

    1. On sending, you should log when you are actually calling the SendToTarget method and determine how long the delay is between calls within your code. Once you call SendToTarget, quickfix will take over and manage the socket connection to the broker. Depending on your line bandwidth and latency, as well as their ability to process things, this could be a bottleneck. If however you are seeing delays between successive calls to SendToTarget, the delay is in your code. QuickFix will manage any line delays by handling its own queue internally, so it won't cause any noticeable delays between successive calls to SendToTarget. You could also consider logging a millisecond timestamp both before you call SendToTarget and immediately after the method returns, in order to get a sense of the time quickfix is taking to release your thread.

    2. When your broker is sending messages to you, quickfix ought to handle any delays in your code by transparently creating and managing an inbound queue on your side. You clear the queue by handling each onMessage event. If your code is the bottleneck, you won't react to the onMessage event until your code has finished processing the previous message. One way to get around this problem (if that is indeed what you are experiencing) is to create your own managed queue. Essentially you limit your code in the onMessage event to grabbing the message and putting it onto your own managed queue. Then, on a separate thread, you have a queue processor which clears the queue. This gives you the flexibility to easily monitor any queue length in your managed queue.

    If however your broker is in fact seeing a bottleneck on their side in their ability to send you messages, it is likely a problem with your network connection to the broker. You might want to investigate the TCP traffic and determine if there is a problem between you and the broker. Incorrect net card drivers or router configuration can cause the TCP protocol to progressively reduce the frame size in an attempt to determine an optimal sending packet size. If this shrinks enough, it will manifest itself in seemingly slow network connectivity as the protocol takes each of your messages and breaks them into tiny chunks and then has to reassemble them on the other side before passing them up to your application.

    If it helps you to get a benchmark for what to expect, on our systems we typically see about a 1,000 max message per second throughput using the single threaded socket initiator and socket acceptor object, configured for file (not DB) logging and with the .body files turned on. This is on a system using high speed dedicated lines between us and the exchanges/brokers in question. We have not gone further in our attempts to maximize throughput yet, as we only do a few hundred thousand orders per day. On a 4xCPU, 4GB RAM server running right now, I see CPU load at about 2% on our engine and its running about 20 messages per second right now.

    根据另一篇讨论(http://osdir.com/ml/finance.quickfix.devel/2006-05/msg00037.html),单线程的socketiniator没有把socket的读写放到不同的线程上处理,如果连接的两端都是这样,可能会发生线程阻塞,所以建议只采用threadedsocketinitiator编程。

    The non-threaded SocketInitiator can actually get into a deadlock situation whereby your application will block forever. I would recommend against anyone ever using it.

    This deadlock will happen if your application fills up a socket's sending buffer while the other side is doing the same (e.g. two non-threaded QuickFIX apps generating heavy traffic). Neither side will end up reading from its side of the socket, being blocked in a send() call, and both sides will deadlock.
     
  2. 可以用队列实现线程异步操作