0

情况

我们正在开发项目的后端,该项目由用 Django 和 FastAPI 编写的两个服务组成。两种服务都使用 MongoDB 作为其数据库系统。

在 Django 中,我们使用djongo==1.3.0ORM 兼容性。

在 FastAPI 中,我们使用odmantic==0.3.4.

这两个库都pymongo==3.11.3在下面使用。

自从我们创建 Django 服务以来,这个 MongoDB SRV 错误一直是一个问题,但我们设法通过不使用最新的包以某种方式解决它,例如:

Django==2.2.20
djongo==1.3.0
pymongo==3.11.3

最近由于安全风险我们不得不升级:

  • urllib3 from 1.25.8 to 1.26.5
  • pydantic from 1.8.1 to 1.8.2
  • Django from 2.2.20 to 2.2.22

这些是 GitHub 的dependabot建议的。

问题

当我们现在在本地运行任何这些服务时,它们会因以下基本异常而中断:

dns.resolver.NoAnswer: The DNS response does not contain an answer to the question: _mongodb._tcp.cluster0.k1eh0.mongodb.net. IN SRV

Django 的完整日志:

> python manage.py test
Creating test database for alias 'default'...
Traceback (most recent call last):
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/djongo/database.py", line 10, in connect
    return clients[db]
KeyError: 'djongo_test'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/dns/resolver.py", line 212, in __init__
    rrset = response.find_rrset(response.answer, qname,
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/dns/message.py", line 341, in find_rrset
    raise KeyError
KeyError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/dns/resolver.py", line 220, in __init__
    crrset = response.find_rrset(response.answer,
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/dns/message.py", line 341, in find_rrset
    raise KeyError
KeyError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/pymongo/srv_resolver.py", line 72, in _resolve_uri
    results = resolver.query('_mongodb._tcp.' + self.__fqdn, 'SRV',
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/dns/resolver.py", line 1100, in query
    return get_default_resolver().query(qname, rdtype, rdclass, tcp, source,
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/dns/resolver.py", line 1003, in query
    answer = Answer(_qname, rdtype, rdclass, response,
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/dns/resolver.py", line 232, in __init__
    raise NoAnswer(response=response)
dns.resolver.NoAnswer: The DNS response does not contain an answer to the question: _mongodb._tcp.database-test.avxhw.mongodb.net. IN SRV

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "manage.py", line 21, in <module>
    main()
  File "manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/core/management/commands/test.py", line 23, in run_from_argv
    super().run_from_argv(argv)
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/core/management/base.py", line 323, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/core/management/base.py", line 364, in execute
    output = self.handle(*args, **options)
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/core/management/commands/test.py", line 53, in handle
    failures = test_runner.run_tests(test_labels)
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/test/runner.py", line 629, in run_tests
    old_config = self.setup_databases(aliases=databases)
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/test/runner.py", line 552, in setup_databases
    return _setup_databases(
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/test/utils.py", line 170, in setup_databases
    connection.creation.create_test_db(
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/db/backends/base/creation.py", line 58, in create_test_db
    self._create_test_db(verbosity, autoclobber, keepdb)
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/db/backends/base/creation.py", line 168, in _create_test_db
    with self._nodb_connection.cursor() as cursor:
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 256, in cursor
    return self._cursor()
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 233, in _cursor
    self.ensure_connection()
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 217, in ensure_connection
    self.connect()
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/django/db/backends/base/base.py", line 195, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/djongo/base.py", line 185, in get_new_connection
    self.client_connection = Database.connect(db=name, **connection_params)
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/djongo/database.py", line 13, in connect
    clients[db] = MongoClient(**kwargs, connect=False)
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/pymongo/mongo_client.py", line 639, in __init__
    res = uri_parser.parse_uri(
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/pymongo/uri_parser.py", line 500, in parse_uri
    nodes = dns_resolver.get_hosts()
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/pymongo/srv_resolver.py", line 102, in get_hosts
    _, nodes = self._get_srv_response_and_hosts(True)
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/pymongo/srv_resolver.py", line 83, in _get_srv_response_and_hosts
    results = self._resolve_uri(encapsulate_errors)
  File "/home/bk/inz/backend/authservice/venv/lib/python3.8/site-packages/pymongo/srv_resolver.py", line 79, in _resolve_uri
    raise ConfigurationError(str(exc))
pymongo.errors.ConfigurationError: The DNS response does not contain an answer to the question: _mongodb._tcp.database-test.avxhw.mongodb.net. IN SRV

FastAPI 的完整日志:

> python -m src.main                                       
Traceback (most recent call last):
  File "/home/bk/inz/backend/testservice/venv/lib/python3.8/site-packages/pymongo/srv_resolver.py", line 72, in _resolve_uri
    results = resolver.query('_mongodb._tcp.' + self.__fqdn, 'SRV',
  File "/home/bk/inz/backend/testservice/venv/lib/python3.8/site-packages/dns/resolver.py", line 1321, in query
    return resolve(qname, rdtype, rdclass, tcp, source,
  File "/home/bk/inz/backend/testservice/venv/lib/python3.8/site-packages/dns/resolver.py", line 1305, in resolve
    return get_default_resolver().resolve(qname, rdtype, rdclass, tcp, source,
  File "/home/bk/inz/backend/testservice/venv/lib/python3.8/site-packages/dns/resolver.py", line 1202, in resolve
    (answer, done) = resolution.query_result(response, None)
  File "/home/bk/inz/backend/testservice/venv/lib/python3.8/site-packages/dns/resolver.py", line 674, in query_result
    raise NoAnswer(response=answer.response)
dns.resolver.NoAnswer: The DNS response does not contain an answer to the question: _mongodb._tcp.cluster0.k1eh0.mongodb.net. IN SRV

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/bk/inz/backend/testservice/src/main.py", line 20, in <module>
    client = AsyncIOMotorClient(MONGODB_URL)
  File "/home/bk/inz/backend/testservice/venv/lib/python3.8/site-packages/motor/core.py", line 156, in __init__
    delegate = self.__delegate_class__(*args, **kwargs)
  File "/home/bk/inz/backend/testservice/venv/lib/python3.8/site-packages/pymongo/mongo_client.py", line 639, in __init__
    res = uri_parser.parse_uri(
  File "/home/bk/inz/backend/testservice/venv/lib/python3.8/site-packages/pymongo/uri_parser.py", line 500, in parse_uri
    nodes = dns_resolver.get_hosts()
  File "/home/bk/inz/backend/testservice/venv/lib/python3.8/site-packages/pymongo/srv_resolver.py", line 102, in get_hosts
    _, nodes = self._get_srv_response_and_hosts(True)
  File "/home/bk/inz/backend/testservice/venv/lib/python3.8/site-packages/pymongo/srv_resolver.py", line 83, in _get_srv_response_and_hosts
    results = self._resolve_uri(encapsulate_errors)
  File "/home/bk/inz/backend/testservice/venv/lib/python3.8/site-packages/pymongo/srv_resolver.py", line 79, in _resolve_uri
    raise ConfigurationError(str(exc))
pymongo.errors.ConfigurationError: The DNS response does not contain an answer to the question: _mongodb._tcp.cluster0.k1eh0.mongodb.net. IN SRV

在我们在 GitHub Actions 上的 CI 设置中,Django 服务测试仍然成功运行。很明显,问题出在 DNS 方面。

问题

  • 是否有任何不支持 MongoDB 的特定 DNS 服务器?我8.8.8.8在它坏掉之前和之后都在使用谷歌。
  • 为什么升级列出的依赖项会导致问题?仅urllib针对两种服务进行了升级。
  • 有什么解决方法吗?
4

1 回答 1

0

查看https://github.com/mongodb/specifications/blob/master/source/initial-dns-seedlist-discovery/initial-dns-seedlist-discovery.rst了解 SRV URI 的工作原理,然后使用手动发出相关 DNS 查询dig用于验证您的环境是否具有有效 DNS的工具。

于 2021-06-10T18:05:14.343 回答