寻找更好的方式来进行实时库存更新

时间:2014-08-28 07:27:08

标签: node.js performance express websocket socket.io

我从this project开始了解我的实时股价更新项目。

当我使用一两只股票时,这个项目运作良好,但当我想同时更新数百只股票的价格时,这个项目并不适用。我想知道我是否以正确的方式这样做。现在我在服务器的for循环中获取所有股票的数据,但价格更新非常慢。我想知道如何改善这一点。

我想知道如何在不影响服务器性能的情况下每秒更新数百个股票价格。

我不知道我是否应该从客户端向服务器发送我需要的股票列表,例如:var ids = [ '', '', '', ... ],或者我是否可以从服务器本身运行这些ID。

哪个最好:股票请求从客户端到服务器,或从服务器到客户端?

注意:我将使用不同的网址来获取股票价格。

我的服务器端代码:

////
// CONFIGURATION SETTINGS
///
var PORT = 4000;
var FETCH_INTERVAL = 5000;
var PRETTY_PRINT_JSON = true;

///
// START OF APPLICATION
///
var express = require('express');
var http = require('http');
var io = require('socket.io');

var app = express();
var server = http.createServer(app);
var io = io.listen(server);
io.set('log level', 1);

server.listen(PORT);

var ticker = "";
app.get('/:ticker', function(req, res) {
    ticker = req.params.ticker;
    res.sendfile(__dirname + '/index.html');
});

io.sockets.on('connection', function(socket) {
    var local_ticker = ticker;
    ticker = "";

    //Run the first time immediately
    get_quote(socket, local_ticker);

    //Every N seconds   
    var timer = setInterval(function() {
        var ids = ['AAPL', '' , ..........100 stocks];

        var l = ids.length;
        for(var i=0; i<l; i++){
            get_quote(socket, ids[i])
        }
    }, FETCH_INTERVAL);

    socket.on('disconnect', function () {
        clearInterval(timer);
    });
});

function get_quote(p_socket, p_ticker) {
    http.get({
        host: 'www.google.com',
        port: 80,
        path: '/finance/info?client=ig&q=' + p_ticker
    }, function(response) {
        response.setEncoding('utf8');
        var data = "";

        response.on('data', function(chunk) {
            data += chunk;
        });

        response.on('end', function() {
            if(data.length > 0) {
                try {
                    var data_object = JSON.parse(data.substring(3));
                } catch(e) {
                    return;
                }

                var quote = {};
                quote.ticker = data_object[0].t;
                quote.exchange = data_object[0].e;
                quote.price = data_object[0].l_cur;
                quote.change = data_object[0].c;
                quote.change_percent = data_object[0].cp;
                quote.last_trade_time = data_object[0].lt;
                quote.dividend = data_object[0].div;
                quote.yield = data_object[0].yld;

                p_socket.emit('quote', PRETTY_PRINT_JSON ? JSON.stringify(quote, true, '\t') : JSON.stringify(quote));
            }
        });
    });
}

我的客户端代码:

    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>

    <script type="text/javascript" src="http://localhost:4000/socket.io/socket.io.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
        var socket = io.connect("http://localhost:4000");
          socket.on('quote', function(data) {
              var data = $("<pre>" + data + "</pre><hr />");
              $("#quotes").append(data);
              $("html, body").animate({ scrollTop: $(document).height() }, 100);
              $(data).show("slide", { direction: "up" }, 250);
              $(data).effect("highlight", {}, 1500); 
          });
    });
</script>
<body>
    <div id="quotes"></div>
</body>

1 个答案:

答案 0 :(得分:1)

我认为从客户端发送所需的ID会使您的应用程序更灵活,更易于使用。您仍然可以以高效的方式编写服务器。

'For loops'将阻止Node的事件循环。对于需要迭代数组的异步操作,我建议:

https://github.com/caolan/async

特别是'async.each'

我没有运行你的代码,但我的直觉告诉我,我的浏览器不会同时享受那么多的DOM操作。我认为将小组分成小块会有所帮助。例如:

获取你的ID数组并将其分解为5.然后错开每个ID的间隔。

$sql     = "SELECT list FROM order";
$result  = $conn->query($sql);
$getList = $result->fetchAll(PDO::FETCH_ASSOC);

foreach($getOrder as $order) {
  $products = $order['theorder'] . ', ';
  $sql      = "INSERT INTO confirmation (theorder) VALUES ('$products')";
  $result   = $conn->query($sql);
}

或者,您可以查看使用Redis等设置Master / Worker来排队工作。我认为这将是最好的表现。退房:

https://github.com/Automattic/kue