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

这个项目在我处理一两只股票时效果很好,但当我想同时更新数百只股票的价格时就不行了。我想知道我是否以正确的方式这样做。现在我在服务器上的 for 循环中获取所有股票的数据,但价格更新非常缓慢。我想知道如何改进这一点。

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

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

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

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

我的服务器端代码:

////
// 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>

最佳答案

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

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

https://github.com/caolan/async

特别是“async.each”

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

把你的 ID 数组分成 5 个。然后错开每个的间隔。

var arr1 = [...]
var arr2 = [...]
var arr3 = [...]
var arr4 = [...]
var arr5 = [...]

setTimeout(doWorkOnArray(arr1), 4000)
setTimeout(doWorkOnArray(arr2), 3000)
setTimeout(doWorkOnArray(arr3), 2000)
setTimeout(doWorkOnArray(arr4), 1000)
setTimeout(doWorkOnArray(arr5), 0)

function doWorkOnArray(arr) {
setInterval(getData(arr), 5000)
}

或者,您可以考虑使用 Redis 之类的东西设置 Master/Worker 以将工作排队。我认为这将是最好的表现。查看:

https://github.com/Automattic/kue

关于node.js - 寻找一种更好的方式来进行实时股票更新,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25543069/

10-10 11:28