首页 > 解决方案 > 从 Azure Cloud Function 调用 CosmosDB 服务器

问题描述

我正在开发一个 Azure 云函数(在节点 js 上运行),它应该从我的 Azure Cosmos DB for MongoDB API 帐户返回一组文档。

当我在本地构建和启动函数时一切正常,但当我将它部署到 Azure 时失败。这是错误:MongoNetworkError: failed to connect to server [++++.mongo.cosmos.azure.com:++++] on first connect ...

我是 CosmosDB 和 Azure Cloud Functions 的新手,所以我是努力寻找问题。我查看了门户中的防火墙和虚拟网络设置,并尝试了连接字符串的不同变体。

由于它似乎在本地工作,我认为它可能是门户中的配置设置。
有人可以帮我吗?

1.设置连接
我使用了门户提供的主要连接字符串。

import * as mongoClient from 'mongodb';
import { cosmosConnectionStrings } from './credentials';
import { Context } from '@azure/functions';

// The MongoDB Node.js 3.0 driver requires encoding special characters in the Cosmos DB password. 
const config = {
  url: cosmosConnectionStrings.primary_connection_string_v1,
  dbName: "****"
};

export async function createConnection(context: Context): Promise<any> {

  let db: mongoClient.Db;
  let connection: any;

  try {
    connection = await mongoClient.connect(config.url, {
      useNewUrlParser: true,
      ssl: true
    }); 

    context.log('Do we have a connection? ', connection.isConnected());

    if (connection.isConnected()) {
      db = connection.db(config.dbName);
      context.log('Connected to: ', db.databaseName);
    }

  } catch (error) {
    context.log(error);
    context.log('Something went wrong');
  }

  return {
    connection,
    db
  };
}



2. 主
函数 执行查询并返回集合的主函数。

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    context.log('Get all projects function processed a request.');

            try {

                const { db, connection } = await createConnection(context);

                if (db) {
                    const projects = db.collection('projects')
                    const res = await projects.find({})
                    const body = await res.toArray()
                    context.log('Response projects: ', body);

                    connection.close()

                    context.res = {
                        status: 200,
                        body
                    }
                } else {
                    context.res = {
                        status: 400,
                        body: 'Could not connect to database'
                    }; 
                }

            } catch (error) {
                context.log(error); 
                context.res = {
                    status: 400,
                    body: 'Internal server error'
                }; 
    }  
};

标签: azureazure-functionsazure-cosmosdbazure-cosmosdb-mongoapi

解决方案


我又查看了防火墙和专用网络设置,并阅读了有关配置 IP 防火墙的官方文档。默认情况下,本地计算机的当前 IP 地址会添加到 IP 白名单中。这就是该功能在本地工作的原因。

根据文档,我尝试了下面描述的所有选项。他们都为我工作。但是,仍然不清楚为什么我必须手动执行操作才能使其工作。我也不确定哪个选项是最好的。

  • 设置允许访问所有网络
    所有网络(包括互联网)都可以访问数据库(显然不建议)

  • 将云功能项目的入站和出站 IP 地址添加到白名单
    如果 IP 地址随时间变化,这可能会很有挑战性。如果您在消费计划中,这可能会发生。

  • 检查“例外”部分中的“接受来自公共 Azure 数据中心内的连接”选项

    如果您从不提供静态 IP 的服务(例如,Azure 流分析和 Azure Functions)访问您的 Azure Cosmos DB 帐户,您仍然可以使用 IP 防火墙来限制访问。您可以通过选择从 Azure 数据中心内接受连接选项来启用从 Azure 内其他来源的访问。

    This option configures the firewall to allow all requests from Azure, including requests from the subscriptions of other customers deployed in Azure. The list of IPs allowed by this option is wide, so it limits the effectiveness of a firewall policy. Use this option only if your requests don’t originate from static IPs or subnets in virtual networks. Choosing this option automatically allows access from the Azure portal because the Azure portal is deployed in Azure.


推荐阅读