提问者:小点点

Node. js MySQL:程序拒绝使用“ECONNREFUSED”连接到远程数据库


我想出了下面的解决方案。我留下了第二次更新以获得更多澄清。

我有一个用JavaScript编写的Discord机器人,使用discord. js库,我自己已经研究了将近两年。一年多前,我开始使用MySQL进行数据库查询等。这是在我本地的Windows 10机器上。由于当时这是一个小型爱好项目,我并不太担心只有一个MySQL实例用于开发和生产。最后,大约9个月前,我能够在运行Ubuntu 18.04的Linode服务器上启动并运行该机器人,以及运行在那里的MySQL数据库的副本。

到目前为止,通过这种设置,事情进展顺利。我使用WindowsPC上的本地数据库进行开发和测试,然后将更新推送到Linode上的Ubuntu 18.04服务器,其中包含生产数据库。此外,为了以防万一,我在开发时确实在PC本地运行机器人。有两个具有两个唯一令牌(一个用于生产,一个用于开发)的Disord机器人,因此我可以在更新时保持生产机器人运行。我没有像生产机器人那样全天候在服务器上运行开发机器人。

然而,最近,我的一个朋友(自称“for循环非凡”)开始帮助我进行开发。因此,我们认为现在是让开发数据库24/7全天候活跃的好时机,这样无论我是否在身边,他都可以在机器人上工作。这就是我们解决问题的地方。

我在下面留下了更新,因为我已经切换到mysql2包以尝试找到解决方案。

所以,如果不是很明显的话,我的目标很简单:我希望我的机器人(当在我或我朋友的Windows机器上使用node. js本地运行时)连接到托管在我的Ubuntu 18.04服务器上的远程数据库,该服务器位于云中,而不是我的本地网络中。我不怕承认我离一个好的Web开发人员还很远,所以我不知道这些东西是如何工作的。我能走到这一步真是个奇迹。但我以为它会像连接到本地MySQL实例一样简单。然而,当我运行代码时,控制台向我吐出了这个错误。

Error: connect ECONNREFUSED LINODE.IP.ADDRESS.HERE:3306
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)
    --------------------
    at Protocol._enqueue (D:\Users\path\node_modules\mysql\lib\protocol\Protocol.js:144:48)
    at Protocol.handshake (D:\Users\path\node_modules\mysql\lib\protocol\Protocol.js:51:23)
    at Connection.connect (D:\Users\path\node_modules\mysql\lib\Connection.js:119:18)
    at Object.<anonymous> (D:\Users\path\bot\index.js:118:5)
    at Module._compile (internal/modules/cjs/loader.js:1138:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
    at Module.load (internal/modules/cjs/loader.js:986:32)
    at Function.Module._load (internal/modules/cjs/loader.js:879:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  errno: 'ECONNREFUSED',
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: 'LINODE.IP.ADDRESS.HERE',
  port: 3306,
  fatal: true
}

以下是我的代码当前的设置方式:

const mysql = require("mysql")
//CONNECT TO MYSQL
var con = mysql.createConnection({
    host: 'example.com',
    port: 3306,
    user: 'user',
    password: 'pass',
    database: 'botDB',
    charset: "utf8mb4"
});

//CONNECTED TO DATABASE
con.connect(err => {
    if (err) { throw err };
    console.log("My database is up and running!")
})

hostlocalhost时,这种方法可以完美地工作,但是当尝试远程连接到Linode上的服务器时,它就是拒绝。我尝试了LinodeURL(example.com)以及IP(LINODE.IP.ADDRESS.HERE)地址,都给我同样的错误。我也知道Node的mysql2包存在,我只是还没有切换。如果切换实际上有助于解决这个问题,请告诉我。

我已经尝试了这个网站上多个类似问题的多个答案,比如这个和这个,但是没有一个解决方案有效(包括添加socket ketPath或更改port等)

我尝试将mysqld. cnf文件中的bind地址更改为0.0.0.0*,这两个文件都允许机器人连接到数据库,但是访问仍然被拒绝以实际读取数据库本身。我只知道它至少连接了(尽管这次再次尝试给我留下了错误消息)

  code: 'ER_NOT_SUPPORTED_AUTH_MODE',
  errno: 1251,
  sqlMessage: 'Client does not support authentication protocol requested by server; consider upgrading MySQL client',
  sqlState: '08004',
  fatal: true

MySQL是最新的,所以这是否与我不使用mysql2有关?无论如何,我不喜欢这个选项,但我想我至少会尝试一下。

我最后的手段是创建一个连接到数据库的SSH隧道。同样,我仍然是一个Web开发新手,所以我不完全知道我在做什么,但是我在这里遵循了这个指南,但是替换了我需要的代码,最终导致了一个完全独立的SSH连接错误。如果SSH绝对需要完成我想要的,那么请告诉我,我会就此提出一个新的问题。我只想在这里提到它,以表明我至少尝试过。

我已经切换到使用mysql2,虽然错误消息更干净,但它仍然存在。

我尝试了Archil的解决方案,虽然现在我已经切换到mysql2,但它确实让我更好地了解了MySQL的身份验证系统,这让我首先进行了切换。不幸的是,Archil的答案和mysql2升级都给我同样的错误:

{
  code: 'ER_ACCESS_DENIED_ERROR',
  errno: 1045,
  sqlState: '28000',
  sqlMessage: "Access denied for user 'root'@'MY.LOCAL.IP.ADDRESS' (using password: YES)"
}

…尽管我已经授予'root'@'%'所有权限。

无论如何,这不是我喜欢的方法。如果有更安全的解决方案,我很乐意接受。既然我已经安装了mysql2,我将继续尝试不同的解决方案。

经过进一步研究,我发现权限没有像我想象的那样为我试图连接到服务器的用户设置。一旦我修复了这个问题,它确实连接了,但是机器人启动时查询的一个表显示为空。原来它不存在!

我已经制作了一个生产数据库的副本作为新开发数据库的基础。问题是,它缺少本地(旧)开发数据库中的一个表。这让我相信机器人正在连接MySQL,但没有从数据库中读取任何内容。我添加了正确的表,它工作得很好!我在下面留下了一个更具体的步骤的解决方案,以防像我这样的新手Web开发人员找到此页面。感谢您的帮助!


共3个答案

匿名用户

我已经离开了第二次更新,我如何得到这个解决方案。

简而言之,将bind-address设置为0.0.0.0确实有效。如果您使用的是原始mysql包,则需要遵循Archil的解决方案。如果您使用的是mysql2并且仍然存在错误(或者Archil的答案不适用于mysql),请确保您仔细检查您尝试使用以下方法连接的用户的权限:

SHOW GRANTS FOR 'user'@'%';

假设您尝试像我一样远程连接,如果没有,则需要创建一个带有“%”通配符的用户。

此时它应该连接,就像我一样,如果之后有任何错误,它可能与数据库本身中的表有关。

匿名用户

我已经回答https://stackoverflow.com/a/50547109/4089212

请检查。您需要更改mySQL的身份验证模式。

匿名用户

在我的例子中(mariadb),我已经设法将绑定地址更改为文件中的0.0.0.0:

sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

重新启动后,我设法连接到数据库:

service mysql restart

您可能需要在文件夹/etc/mysql/mariadb. conf.d/中搜索要编辑的正确文件

只是寻找绑定地址(可能有一个IP地址,如127.0.0.1)