【问题标题】:Looking for a better way to do real time stock updates寻找一种更好的方法来进行实时股票更新
【发布时间】:2014-10-21 23:27:40
【问题描述】:

我从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>

【问题讨论】:

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


    【解决方案1】:

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

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

    https://github.com/caolan/async

    特别是'async.each'

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

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

    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

    【讨论】:

      猜你喜欢
      • 2011-03-09
      • 1970-01-01
      • 2020-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多