【问题标题】:Reduction of CPU utilization on a nodejs server降低 nodejs 服务器上的 CPU 利用率
【发布时间】:2012-12-15 17:34:15
【问题描述】:

我正在研究降低 CPU 利用率的有趣方法 在 NodeJS 服务器上。

在我的研究过程中,我发现了以下文章: http://engineering.linkedin.com/nodejs/blazing-fast-nodejs-10-performance-tips-linkedin-mobile

这些都是很好的提示,但我有一个关于 提示#4。

这是否真的意味着用户正在请求“JavaScriptTemplate.html” 然后随后请求所有的 JSON(这里没有实现)?

假设所有动态内容都应该在没有用户的情况下可用 交互(例如,在按钮单击事件上请求 JSON)什么是 实现这一目标的最佳方法是什么?我可以考虑加载额外的 JS 依赖项 (requirejs) 执行函数以请求 JSON 内容。

因为我从没见过大网站调用静态 html 文件,但是 而是请求到他们的应用程序服务器的路由有多常见 是上面链接建议的解决方案吗?他们真的 使用服务器端模板来浪费 CPU 利用率 大部分是静态文本内容???

对于 Node (expressJS),这必须是一种次优方式,尤其是 如果要生成的 HTML 相当复杂......理想情况下 Node 应该只是作为提供 JSON 数据的 API 服务器运行。

你有什么想法要分享吗?

【问题讨论】:

    标签: javascript node.js web-applications linkedin express


    【解决方案1】:

    感谢分享这篇文章 - 这是一篇很棒的文章(对我来说非常及时)。

    您实际上是在问两个问题 - 1)如何加载数据以在没有客户端交互的情况下呈现 html 客户端,以及 2)如何在用户实际请求路由时将静态文件发送到浏览器。

    在没有用户交互和客户端 MVC 上的我的 ¢2 的情况下呈现页面

    1) 您需要在页面加载后运行所有初始化/数据加载/渲染代码来渲染页面。如果您在客户端使用 jQuery(就像大多数 Web 应用程序一样):

    $(document).ready(function(){
        // Your code here
    });
    

    只是从jQuery docs复制过来的。

    大多数人使用主干/下划线在客户端构建 MVC 层。尽管有很多更高级(而且看起来更强大)的客户端框架可以做到这一点,但这对夫妇为您提供了足够的功能,而不会限制您的选择或降低您在某些时候肯定需要的灵活性。下划线(无论如何都是骨干依赖)除了许多非常有用的功能(如果你花一个小时阅读整个一页手册,你会惊讶于 JavaScript 的可能)有自己的模板,这些模板看似简单,同时time 非常强大,因为它们只是在模板中运行所有 javascript。

    虽然在模板中包含应用程序逻辑通常是一件坏事(因为下划线允许,而大多数更高级和“更强大”的模板引擎却没有),但能够添加一些通常非常方便且更好当您发现自己处于某个狭窄的角落(通常会这样)时,模板中的逻辑而不是重新设计大量应用程序逻辑或添加额外的模板。

    另外,我的意见是避免使用 require.js 或任何其他模块加载器(直到你真的必须使用它们),因为我写了here

    为任何路由提供静态 html,为 node-as-api 提供 nginx 配置

    2) 您需要重写对所有路由的请求,以使用相同的静态 html 文件(或多个依赖于路由的 html 文件)进行响应。根据您的偏好或应用程序要求,它可以是具有空正文的文件(在这种情况下,用户将看到一个空白页面,直到您的数据被加载并且页面在正文中呈现/插入),一些欢迎页面甚至一些模板页面,其中显示的是纺车而不是数据。

    重写请求的方式取决于用于提供静态内容和代理请求的 Web 服务器。如果您使用 Apache(Node 不太可能选择,因为它是同步的),您需要使用 .htaccess 文件。如果您像大多数使用 node 的人一样使用 Nginx,则需要在配置文件中的 server 块内使用 rewrite 指令,如下例所示:

    server {
        listen       80;
        server_name  example.com;
        root         html/example;
    
        access_log   logs/example.log;
    
        # location block below sends specific static assets from inside your app's
        # public directory when routes /img, /js, /css, /views are requested
        location ~ /(img|js|css|views)/ {
            rewrite ^(.*)$ /public/$1 break;
        }
    
        # location block below proxies all data requests (/api route) to your node app
        location /api {
            proxy_pass             http://localhost:3000/;
            proxy_redirect         http://localhost:3000/ http://example.com;
            proxy_connect_timeout  30s;
            proxy_read_timeout     30s;
            proxy_cookie_domain    localhost example.com;
            #proxy_http_version     1.1;
        }
    
        # location block below rewrites all other routes to a specific html file
        # that is sent to the client and that is supposed to load all JS and
        # static assets to render a page
        location / {
            rewrite ^(.*)$ /public/app.html;
        }
    }
    

    您在客户端中呈现页面的方式(以及您从服务器请求的数据)将取决于用户请求的路由(您可以在 javascript 中访问/更改,也可以设置/访问/更改cookies)。应用程序内部的所有导航(当用户单击任何按钮或内部链接时 - 您需要捕获所有单击事件)都会发生,而不需要对已加载的页面或静态资产的额外请求,只会将数据请求发送到服务器。

    希望对你有帮助。

    SEO 更新

    nginx 的建议配置仅适用于您不需要任何被机器人索引的页面并且对其他需要静态 html 的 Web 应用程序可见的页面,例如 facebook,例如对于要被索引的页面,您需要添加条件以不同方式路由来自机器人的请求(基于 $http_user_agent),并为这些路由呈现一些静态 html。但它可以是不同的纯语义 html(更小,没有设计图像、布局 div/类、UI 元素和 javascript 以减少来自爬行机器人和网络应用程序的请求)。

    【讨论】:

    • 感谢您的辛勤工作。真棒答案! 1:jquery 的 ready() 很棒,但现在所有这些像 angular 这样的漂亮框架都出现了,我打算使用其中一个来处理这些东西。 2:这里有个小误会。我真正担心的是,很多页面在他们的应用服务器上使用服务器端模板来生成大部分是静态的 html 页面(因此没有真正的缓存可能)。使用 nginx(正如你提到的)似乎好多了......对我来说似乎“有趣”的事情是直接通过 URL 请求这些 html 文件(请参阅下面的其他答案)......
    • 1. 1)使用大多数框架和jquery.ready()没有矛盾。 2) 我在 Angular.js 上花了一些时间,它在他们的why backbone 部分中完全做到了骨干创建者所说的“通过做出让你更有能力做出自己的决定来把你画到一个角落”,而且它比你期望。不幸的是,大多数其他“不错”的框架似乎都在做同样的事情。骨干虽然看起来不太好,但非常有用且非常容易学习。
    • 2. 1)在服务器端生成页面既是历史的又是传统的,虽然很常见,但并非总是如此。直到最近,浏览器才变得足够强大,可以以令人满意的性能呈现页面。 2)您可以让您的用户请求(或有类似的链接)example.com/app.html,但这不是很传统。建议的配置使用 /public/app.html 响应几乎所有请求的路由(例如 example.com/catalog/product/33),并让您在客户端中实现所有应用程序逻辑。
    • 2. 3)您可以在服务器端渲染页面并使它们也可缓存,尽管管理它是一个额外的麻烦,所以最好避免它。在服务器中呈现页面的缺点是 a) 它使用的服务器资源比仅发送数据多得多,b) 您至少无法避免一些重复的开发工作。在服务器端呈现页面的唯一原因是让您的网站可抓取。只向无头机器人提供静态内容是有意义的(所以我要去搜索是否可以配置 nginx 以对不同的用户代理做出不同的响应:)...
    • 太棒了 - 你在这里做得非常好。感谢您分享所有细节。我一定会调查骨干 - 感谢您的出色专业知识。现在真的很兴奋。您的第二个答案非常好,并且很高兴了解给定的路由示例。现在这样做很有意义。我完全同意可抓取的问题......荣誉!
    【解决方案2】:

    这不是最常见的方法,但现在仍然很常见。有许多 Web 框架(angularjs by google、knockoutmoustache 等)可以很好地与客户端中的这种模板理念配合使用。

    模型被请求到服务器(即 json)并映射到静态视图(模板)。

    我认为它非常适合提供 JSON 数据的 API 服务器。这样您就可以开发另一个 API 客户端,在本例中为 Web 客户端 (RIA)。但我认为这种方法背后的主要原因并不是为了节省 CPU。

    【讨论】:

    • 谢谢!我希望 angularjs 提供一种方法来帮助在初始页面加载时请求 JSON 数据。真正让我困惑/担心的是调用静态 html 页面——就像 10 年前所做的那样。但我认为这是一种公认​​的方式,因为我想不出任何其他有效的方式来更好地缓存。在 webapp 上调用某个路由总是意味着与节点服务器交谈(我只想在与数据库交谈时做这件事)。如果我错了或者你有其他想法,请告诉我... PS:有没有办法查看大玩家的顶级域名背后?
    • 取决于框架。从服务器端获取模板不是强制性的(例如,您可以将它们定义为页面中的“div”),并且它们可以在任何情况下本地缓存。如果您正在寻找使用它们的网站示例,请查看builtwith.angularjs.org(角度)。您可以使用淘汰/主干找到更多网站,因为它们在市场上的时间更长。
    • 谢谢。我肯定会看看 buildwith.angular.org。很高兴了解所有这些页面如何使用客户端方法(在初始加载时超出 index.html)以及它们如何受到大玩家的启发。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多