如何解决'错误:连接ECONNREFUSED 127.0.0.1:9200'将ElasticSearch与Firebase一起使用?

时间:2018-01-23 00:20:49

标签: javascript firebase elasticsearch google-cloud-functions

我知道这个问题已被问过几次,但解决方案并不适用于我的情况。我使用以下两个命令启动了ElasticSearchKibana

bin/elasticsearch
bin/kibana

服务器运行良好,使用浏览器转到http://localhost:9200时,我得到以下结果:

{
    "name" : "vg7RnLh",
    "cluster_name" : "elasticsearch",
    "cluster_uuid" : "gqDf0H67TxGZGYigAlu2mQ",
    "version" : {
        "number" : "6.1.2",
        "build_hash" : "5b1fea5",
        "build_date" : "2018-01-10T02:35:59.208Z",
        "build_snapshot" : false,
        "lucene_version" : "7.1.0",
        "minimum_wire_compatibility_version" : "5.6.0",
        "minimum_index_compatibility_version" : "5.0.0"
    },
    "tagline" : "You Know, for Search"
}

使用kibana时,一切正常。这是我写的firebase云功能,如果有什么不对的话,我认为它在这里:

exports.downloadUserInfo = functions.https.onRequest((req, res) => {
    const { uid } = req.query;

    const searchConfig = {
        uri: 'http://localhost:9200/users/user/' + uid,
        method: 'GET'
    };

    request(searchConfig)
        .then((result) => {
           console.log(result);
           return res.status(200).send(result);
       })
           .catch((error) => {
               console.log(error);
               return res.status(400).send(error);
           });
});

request是由yarn add request request-promise安装的模块。然后,当使用Postman来测试我的API时,我收到此错误:

enter image description here

如何解决此问题?

更新

我还使用命令flashlight运行node app.js。将新用户插入数据库时​​,新用户也会自动插入ElasticSearch服务器(localhost),但是,当我尝试读取时,会抛出请求错误

第二次更新

这是创建用户的API:

exports.register = functions.https.onRequest((req, res) => {
    const { firstName, lastName } = req.body;

    admin.database().ref('users').push({ firstName, lastName })
        .then(() => res.status(201).send())
        .catch(() => res.status(400).send());
});

当此API创建新用户时,此用户会自动插入我的localhost ElasticSearch服务器,因为我使用的是flashlight插件。我不明白为什么当我尝试从同一台服务器上读取时,会出现请求错误。

3 个答案:

答案 0 :(得分:2)

您的代码正在尝试访问本地主机:

-pubnub.com

这不起作用:您不能只访问运行Cloud Functions的容器上的“随机”端口。

我的猜测是你在本地机器上运行ElasticSearch,这就是uri: 'http://localhost:9200/users/user/' + uid, 所指的内容。但是要在云功能环境中运行代码,您需要在可公开访问的系统上运行ElasticSearch,并在localhost中指定该计算机的IP。

答案 1 :(得分:2)

云功能在Google控制的服务器上运行。它们不能在您的计算机上运行(除非您使用本地仿真进行测试)。

您的功能是访问“localhost”的网址:

const searchConfig = {
    uri: 'http://localhost:9200/users/user/' + uid,
    method: 'GET'
};

request(searchConfig).then(...)

在几乎每个上下文中,localhost表示IP地址127.0.0.1 - 运行代码的机器。当您的代码在云功能中运行时,这意味着localhost是运行代码的Google服务器实例。这肯定不是您想要的,不幸的是,您将无法访问在您的个人计算机上运行的服务。

答案 2 :(得分:1)

这是答案。正如Frank van PuffelenDoug Stevenson指出的那样,无论如何,我都无法从已部署的firebase函数向localhost服务器执行任何请求。

但是在flashlight插件的帮助下,我可以让我的localhost服务器知道我现在要执行搜索操作。我所做的是config.js文件夹flashlight文件夹中的文件:

exports.FB_REQ = 'search/request';
exports.FB_RES = 'search/response';

这两行的作用是告诉我的数据库在数据库中创建一个名为search的表,该表有2个子表,一个名为request,另一个名为responseflashlight将监视您的firebase数据库并更新ES服务器中的任何数据,除了您写入search/request表的内容。当您写入此表时,flashlight会检测到它,并且它知道您现在要执行搜索操作,它将运行您在ES服务器上放置的查询,然后将结果存储在search/response表,您只需要听取该表中的更新,这将是您的搜索结果。

新的downloadUserInfo API应该是这样的:

exports.downloadUserInfo = functions.https.onRequest((req, res) => {
    const { uid } = req.query;

    const key = admin.database().ref('search/request')
        .push({ index: 'users', type: 'user', q: uid }).key;

    admin.database().ref(`search/response/${key}`).once('value')
        .then((snapshot) => {
            return res.status(200).send(snapshot.val());
        })
        .catch((error) => {
            return res.status(400).send(error);
        });
});