草庐IT

javascript - Node js(getConnection)

coder 2023-10-17 原文

var nodePort = 3030;
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var db = require('mysql');
var dbPool = db.createPool({
    host : 'localhost',
    user : 'root',
    password : '1234',
    database : 'test',
    port : 3306
});


app.use( bodyParser.json() );
app.get('/api/db', function(req, res){
    res.setHeader('content-type', 'application/json');
    dbPool.getConnection(function(objErr, objConn){
        if(objErr){
            sendError(res, 503, 'error', 'connection', objErr); //503 - Service Unavailable
        }else{
            objConn.query("SELECT * FROM person", function(Err, Rows, Fields){
                if(Err){
                    sendError(res, 500, 'error', 'query', Err);
                }else{
                    res.send({
                        results : 'success',
                        err : '',
                        err_type : '',
                        fields : Fields,
                        rows : Rows,
                        length : Rows.length
                    });
                    objConn.release();
                }//else
            });
        }//else
    });
});
/*
app.get('/api/db:id', function(req, res){
    var id = req.params.id;
    res.setHeader('content-type', 'application/json');
    dbPool.getConnection(function(objErr, objConn){
        if(objErr){
            sendError(res, 503, 'error', 'connection', objErr); //503 - Service Unavailable
        }else{
            objConn.query("SELECT * FROM person WHERE id = ? ",[id], function(Err, Rows, Fields){
                if(Err){
                    sendError(res, 500, 'error', 'query', Err);
                }else{
                    res.send({
                        results : 'success',
                        err : '',
                        err_type : '',
                        fields : Fields,
                        rows : Rows,
                        length : Rows.length
                    });
                    objConn.release();
                }//else
            });
        }//else
    });
});
*/
app.post('/api/db', function(req, res){
    if(!req.body.tableName){
        var data = {
            ID : req.body.id,
            Name : req.body.name
        }
        tableName = 'person';
    }else{
        var data = {
            email : req.body.email,
            regid : req.body.regid
        }
        tableName = 'users';
    }//else
    console.log(req.body.regid);
    console.log(req.body.tableName);
    console.log(req.body.email);
    res.setHeader('content-type', 'application/json');
    dbPool.getConnection(function(objErr, objConn){
        if(objErr){
            sendError(res, 503, 'error', 'connection', objErr); //503 - Service Unavailable
        }else{
            objConn.query("INSERT INTO "+tableName+" SET ? ", data, function(Err, Rows, Fields){
                if(Err){
                    sendError(res, 500, 'error', 'query', Err);
                }else{
                    res.send({
                        results : 'success'
                    });
                    objConn.release();
                    if(!req.body.tableName){ gcmSend(); }
                }//else
            });
        }//else
    });
});

app.put('/api/db', function(req, res){
    var id = req.body.id;
    var data = {
        Name : req.body.name
    }
    res.setHeader('content-type', 'application/json');
    dbPool.getConnection(function(objErr, objConn){
        if(objErr){
            sendError(res, 503, 'error', 'connection', objErr); //503 - Service Unavailable
        }else{
            objConn.query("UPDATE person SET ? WHERE ID = ? ", [data,id], function(Err, Rows, Fields){
                if(Err){
                    sendError(res, 500, 'error', 'query', Err);
                }else{
                    res.send({
                        results : 'success'
                    });
                    objConn.release();
                    gcmSend();
                }//else
            });
        }//else
    });
});

app.delete('/api/db/:id', function(req, res){

    var id = req.params.id;
    res.setHeader('content-type', 'application/json');
    dbPool.getConnection(function(objErr, objConn){
        if(objErr){
            sendError(res, 503, 'error', 'connection', objErr); //503 - Service Unavailable
        }else{
            objConn.query("DELETE FROM person WHERE ID = ? ",[id], function(Err, Rows, Fields){
                if(Err){
                    sendError(res, 500, 'error', 'query', Err);
                }else{
                    res.send({
                        results : 'success'
                    });
                    objConn.release();
                    gcmSend();
                }//else
            });
        }//else
    });
});

function gcmSend(){

    message = new gcm.Message({
        collapseKey: 'demo',
        delayWhileIdle: true,
            timeToLive: 3,
            data: {
                title: 'Node.js den mesaj gönderildi'
            }
    });
    sender.send(message, registrationIds, 4, function (err, result) {
        console.log(result);
    });
}

function sendError(res, iStatusCode, strResult, strType, objError){
    res.send({
        results : strResult,
        err : objError.type,
        err_type : strType
    });
}

app.listen(nodePort);
console.log('App listening on port' + nodePort);

你好,

我写了一些代码来与nodejs mysql连接,我打开了每个操作的新连接(post,get,put,delete)并发布。这很好吗?还是一种连接更好?一个连接中的所有操作或每个操作一个连接中的所有操作之间有什么区别?

最佳答案

需要说明的是-Node.js是而不是单线程。您的应用程序代码是在一个线程中执行的,但是在后台它会在需要时使用它们-看一看here(答案和下面的注释):

To a Javascript program on node.js, there is only one thread.

If you're looking for technicalities, node.js is free to use threads to solve asynchronous I/O if the underlying operating system requires it.



和:

As far as the user of node.js (ie the Javascript programmer) is involved, the abstraction is that there is only a single thread. In the case of the underlying runtime (v8), it uses threads internally for - for example - profiling, and it may do so freely as long as it doesn't leak that information up to the Javascript.

In other words, if you dive down inside the actual runtime, you will find more than one thread helping to keep the single Javascript thread running smoothly.



如您所见,您使用的mysql模块要求您传递query()方法的回调(可能还有更多)。因此,当您调用它时,将继续执行代码,并在数据库结果到达时调用回调。

至于您的问题-您不是在为每个请求创建新的连接。看一看mysql模块的自述文件Pooling Connections section:

Connections are lazily created by the pool. If you configure the pool to allow up to 100 connections, but only ever use 5 simultaneously, only 5 connections will be made. Connections are also cycled round-robin style, with connections being taken from the top of the pool and returning to the bottom.

When a previous connection is retrieved from the pool, a ping packet is sent to the server to check if the connection is still good.



当您调用dbPool.getConnection()时,仅在池中没有可用连接的情况下才会创建连接-否则,它只会从其顶部抓取一个连接。调用objConn.release()会将连接释放回池-它没有断开连接。此调用使它可以被应用程序的其他部分重用。

总结一下:
  • 为每个请求创建新连接不是一个好主意,因为它将在您的应用程序和数据库计算机上使用更多资源(CPU,RAM)。
  • 对所有请求使用一个连接也是错误的,因为如果任何操作花费很长时间才能完成您的连接,将挂起,从而使所有其他请求等待连接。
  • 使用连接池是一个好主意,它使您可以同时对数据库执行多个操作,即使其中一个操作需要很长时间才能完成。

  • 更新:
    要回答评论中的问题:

    当您对每个请求使用一个连接时,mysql模块必须打开一个新的套接字,连接数据库并在进行查询之前进行身份验证-这会花费时间并占用一些资源。因此,这是一个不好的方法。

    另一方面,当仅使用一个连接(而不是连接池)时,运行需要很长时间才能完成的查询将阻塞该连接上的所有其他查询,直到连接完成为止-这意味着任何其他请求都必须等待。这也是一个不好的方法。

    为每个请求创建一个新的连接池几乎就像使用新的连接一样,除非您多次调用pool.getConnection(),否则甚至更糟(获取创建新连接所用的资源,并乘以pool.getConnection()调用的次数)。

    为了进一步阐明每个操作的一个连接与一个连接问题中的所有操作:

    每个连接中的每个操作都在上一个操作完成之后开始(它是同步的,但不是在客户端),因此,如果您的表有几十亿行并发出SELECT * FROM yourtable,将需要一些时间来完成,从而阻塞了此连接直到完成。

    如果您需要并行执行的每个操作都具有一个连接(例如,对于每个请求),问题将消失。但是如前所述,打开新连接需要时间和资源,这就是引入连接池概念的原因。

    因此答案是:对所有请求使用一个连接池(就像您在示例代码中所做的一样)-连接的数量将根据应用程序的流量进行相应调整。

    更新#2:

    基于这些评论,我看到我也应该解释连接池背后的概念。它的工作方式是在连接池为空的情况下启动应用程序,并初始化为最多创建n个连接(默认情况下,mysql模块的连接数为10)。

    每当您调用dbPool.getConnection()时,它都会检查池中是否有任何可用的连接。如果有,它会捕获一个(使其不可用),否则,它将创建一个新的。如果达到连接限制并且没有可用的连接,则会引发某种异常。

    调用connection.release()会将连接释放回池,以便再次可用。

    使用池仅为整个应用程序获得一个全局连接是完全错误的,并且违反了概念本身(您可以通过手动创建连接来完成相同的操作),因此使用连接池意味着将连接池用作它应该被使用-当您需要它们时从它获取连接

    关于javascript - Node js(getConnection),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26118700/

    有关javascript - Node js(getConnection)的更多相关文章

    1. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

      我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

    2. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

      我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

    3. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

      我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

    4. ruby-on-rails - 我将 Rails3 与 tinymce 一起使用。如何呈现用户关闭浏览器javascript然后输入xss? - 2

      我有一个用Rails3编写的站点。我的帖子模型有一个名为“内容”的文本列。在帖子面板中,html表单使用tinymce将“content”列设置为textarea字段。在首页,因为使用了tinymce,post.html.erb的代码需要用这样的原始方法来实现。.好的,现在如果我关闭浏览器javascript,这个文本区域可以在没有tinymce的情况下输入,也许用户会输入任何xss,比如alert('xss');.我的前台会显示那个警告框。我尝试sanitize(@post.content)在posts_controller中,但sanitize方法将相互过滤tinymce样式。例如

    5. ruby - 使用 Selenium WebDriver 启用/禁用 javascript - 2

      出于某种原因,我必须为Firefox禁用javascript(手动,我们按照提到的步骤执行http://support.mozilla.org/en-US/kb/javascript-settings-for-interactive-web-pages#w_enabling-and-disabling-javascript)。使用Ruby的SeleniumWebDriver如何实现这一点? 最佳答案 是的,这是可能的。而是另一种方式。您首先需要查看链接Selenium::WebDriver::Firefox::Profile#[]=

    6. ruby - Watir-Webdriver 是否支持点击目标为 javascript 的链接? - 2

      我是Ruby和Watir-Webdriver的新手。我有一套用VBScript编写的站点自动化程序,我想将其转换为Ruby/Watir,因为我现在必须支持Firefox。我发现我真的很喜欢Ruby,而且我正在研究Watir,但我已经花了一周时间试图让Webdriver显示我的登录屏幕。该站点以带有“我同意”区域的“警告屏幕”开头。用户点击我同意并显示登录屏幕。我需要单击该区域以显示登录屏幕(这是同一页面,实际上是一个表单,只是隐藏了)。我整天都在用VBScript这样做:objExplorer.Document.GetElementsByTagName("area")(0).click

    7. 网页设计期末作业,基于HTML+CSS+JavaScript超酷超炫的汽车类企业网站(6页) - 2

      🎉精彩专栏推荐💭文末获取联系✍️作者简介:一个热爱把逻辑思维转变为代码的技术博主💂作者主页:【主页——🚀获取更多优质源码】🎓web前端期末大作业:【📚毕设项目精品实战案例(1000套)】🧡程序员有趣的告白方式:【💌HTML七夕情人节表白网页制作(110套)】🌎超炫酷的Echarts大屏可视化源码:【🔰Echarts大屏展示大数据平台可视化(150套)】🔖HTML+CSS+JS实例代码:【🗂️5000套HTML+CSS+JS实例代码(炫酷代码)继续更新中…】🎁免费且实用的WEB前端学习指南:【📂web前端零基础到高级学习视频教程120G干货分享】🥇关于作者:💬历任研发工程师,技术组长,教学总监;

    8. ruby-on-rails - 在页面的最底部包含 javascript 文件 - 2

      我有一个Rails应用程序。还有一个javascript(javascript1.js)文件必须包含在每个View的最底部。我把它放在/assets/javascripts文件夹中。Application.js包含以下代码//=requirejquery//=requirejquery_ujs//=someotherfiles//=require_directory.即使Application.js中不包含javascript1.js,它也会自动包含,不是吗?那么我怎样才能做我想做的事呢? 最佳答案 单独定义、包含和执行您的java

    9. ruby-on-rails - 为 rails 中的 javascript 生成完整的 url(类似于 javascript_path,但是是 url) - 2

      如何生成指向javascript文件的绝对链接。我想应该有类似下面的东西(不幸的是它似乎不可用):javascript_url'main'#->'http://localhost:3000/javascripts/main.js'代替:javascript_path'main'#->'/javascripts/main.js'我需要绝对URL,因为该javascript文件将用于书签。另外我需要相同的css文件。谢谢,德米特里。 最佳答案 javascript和css文件的绝对URL现在在Rails4中可用ActionView::H

    10. ruby - 处理在 keyup 事件上发生的 javascript 弹出窗口 - 2

      我在HTML页面上有一个文本字段,用于检查您是否输入了1到365之间的值。如果用户输入了无效值,如非数字字符或不在范围内的值,它显示一个弹出窗口。我在watirwiki上看到有一个select_no_wait方法,用于在您从列表中选择无效值时关闭弹出窗口。处理键盘事件时出现的弹出窗口的好方法是什么?我是否需要按照select_no_wait方法的实现方式进行操作,或者我们是否可以启动一个不同的进程来消除调用set方法时可能出现的弹出窗口。带有Javascript验证函数的HTML文件示例如下:varnum=0functionvalidate(e){varcharPressed=Stri

    随机推荐