当前位置: 首页 > 面试题库 >

MongoDB + Azure + Android:com.mongodb.WriteConcernException err:“非主用户”代码:“ 10058”

淳于昊然
2023-03-14
问题内容

背景

嗨,我正在Azure上运行MongoDB副本集,并已从Android应用程序中远程连接到它。我已使读取在所有实例上都能很好地工作(已更新:因为允许它们在主节点和辅助节点上读取)。但是,对数据库的写入仍然会出现间歇性错误,并出现以下错误,因为写入必须仅在主节点上进行。

另外,如果您可以提供更多具体资源来解决此问题,那么这也将非常有帮助。我已经阅读了大多数文档,并搜索了很多此错误。

问题

如何防止此错误并允许100%的时间写入?

E/AndroidRuntime(): com.mongodb.WriteConcernException: {
        "serverUsed" : "/<my-remote-ip>:27017" , "err" : "not master" , 
        "code" : 10058 , "n" : 0 , "lastOp" : { "$ts" : 0 , "$inc" : 0} , 
        "connectionId" : 1918 , "ok" : 1.0}

堆栈跟踪

E/AndroidRuntime(13731): FATAL EXCEPTION: Thread-7629
E/AndroidRuntime(13731): Process: com.myapplication.examplemongodb, PID: 13731
E/AndroidRuntime(13731): com.mongodb.WriteConcernException: { "serverUsed" : "/<my-remote-ip>:27017" , "err" : "not master" , "code" : 10058 , "n" : 0 , "lastOp" : { "$ts" : 0 , "$inc" : 0} , "connectionId" : 1918 , "ok" : 1.0}
E/AndroidRuntime(13731):    at com.mongodb.CommandResult.getException(CommandResult.java:77)
E/AndroidRuntime(13731):    at com.mongodb.CommandResult.throwOnError(CommandResult.java:110)
E/AndroidRuntime(13731):    at com.mongodb.DBTCPConnector._checkWriteError(DBTCPConnector.java:102)
E/AndroidRuntime(13731):    at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:142)
E/AndroidRuntime(13731):    at com.mongodb.DBTCPConnector.say(DBTCPConnector.java:115)
E/AndroidRuntime(13731):    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:248)
E/AndroidRuntime(13731):    at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:204)
E/AndroidRuntime(13731):    at com.mongodb.DBCollection.insert(DBCollection.java:76)
E/AndroidRuntime(13731):    at com.mongodb.DBCollection.insert(DBCollection.java:60)
E/AndroidRuntime(13731):    at com.mongodb.DBCollection.insert(DBCollection.java:105)
E/AndroidRuntime(13731):    at com.myapplication.examplemongodb.ActivityMain$1.run(ActivityMain.java:83)
E/AndroidRuntime(13731):    at java.lang.Thread.run(Thread.java:841)

注意事项

  • 我正在使用mongo-java-driver v2.11.3。
  • 我使用了mongo-azure库来帮助创建具有两个工作角色的MongoDB副本集。
    • (如果您还有其他资源,那么我很乐意阅读。我已经阅读了GitHub自述文件this,this和其他一些与MongoDB / Azure不相关的内容。但是,这些资源不是更新,也不详细。)

可能的解决方案

  • 我认为这与设置副本集有关。
  • 我不确定这种情况是否会发生,因为我只有两个实例副本集(一个主要副本和一个次要副本),并且他们正在为谁想成为主要副本而进行争夺(阅读:投票)。也许需要仲裁员?但是,我目前不知道该怎么做。

更新

  • 感谢@David Makogon的帮助,我非常确定问题在于如何建立与Azure的连接以及如何访问辅助角色。因此,这是我关于系统配置方式的最新注释:
    • 两个工作角色(MongoDB.WindowsAzure.MongoDBRole),我通过TCP Input EndpointAndroid应用程序通过端口27017 直接连接到这些角色。正如@David所说,我目前无法控制连接到哪个实例。
    • 我不做任何事情的一个Web角色(MongoDB.WindowsAzure.Manager)HTTP Input Endpoint在端口80上有一个。默认情况下,这是我上面提到的mongo-azure库的默认设置。我不确定是否应该对此做任何事情。

问题答案:

如果所有实例都位于单个负载均衡Input端点(例如27017)后面,那么每次您的客户端计算机连接到该端点时,它将连接到副本集群集中可能不同的节点上(并且您无法控制您去过哪个实例)。这可能可以解释为什么您有时会尝试向非主节点写入并得到错误,但所有读取仍然有效(因为您可能将MongoDB集群设置为允许在辅助节点上进行读取)。

辅助角色还支持InstanceInput端点,这些端点使您可以设置一个面向外部的端口范围(例如27017-27019),映射到辅助实例自身上的单个端口(例如27017)。如果执行此操作,您的客户端应用程序现在可以直接连接到所有三个实例(27017、27018、27019)。许多驱动程序支持副本集连接,因此它将能够确定哪个节点是主节点,并将所有写入均定向到该节点。
我不知道您在Android上使用的驱动程序是否支持副本集。
如果驱动程序不支持副本集,则您可能需要考虑建立一个API层,该层随后将所有通信传递给数据库(无论如何,通常遵循的一种良好做法是,您可以查看Azure的移动服务一种快速的实现方法)。

因此…如果将副本集群集的端点配置为Input,则可能解释了您所看到的问题,可以通过将端点类型切换为来解决该问题InstanceInput



 类似资料:
  • 有没有办法在AWS CodeBuild上删除用户?我们正在构建一个Yocto项目,如果我们是root(Bitbake健全性检查),它在代码构建上会失败。 我们不顾一切的方法也不起作用: 在以下情况下失败: 你知道我们怎么把它变成非根的吗?

  • 背景: 嗨,我正在Azure上运行MongoDB副本集,并已从Android应用程序中远程连接到它。我已经让所有实例的读取工作得很好(更新:因为它们允许在主节点和辅助节点上读取)。但是,写入数据库仍然会出现间歇性错误,错误如下,因为写入必须仅在主节点上完成。 另外,如果您能提供更多具体的资源来处理这个问题,那也会很有帮助。我已经浏览了大部分文档并搜索了很多这个错误。 问题: 如何防止此错误并允许1

  • 本文向大家介绍mongodb driver使用代码详解,包括了mongodb driver使用代码详解的使用技巧和注意事项,需要的朋友参考一下 MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。 MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。 0 前言 全是

  • 我正在尝试用JMeter学习负载测试(非常新)。使用该教程在JMeter网站和另一个youtube教程上构建一个Web测试计划,我创建了一个HTTP GET请求来访问www.google.com/,但是我得到了以下结果: 这是我的要求:链接到图像,因为我还没有10个声誉 环顾四周,其他人正在遇到此问题,但他们的问题是在 250 个用户之后: 响应代码: 非 HTTP 响应代码: java.net.

  • TLDR;如何使用Spring在正文中发送文本消息以及304状态代码? 背景 我正在使用Spring Boot编写一个REST API。在某些endpoint中,我想返回: 任一状态 ,身体, 或状态 未修改,正文 我的endpoint使用(在kotlin中)的方式如下: 问题 每当我用状态代码创建< code>ResponseEntity时!= 200,正文不发(空正文)。将< code>Htt

  • JAVA语言及其标准API(应用程序编程接口)应付应用程序的编写已绰绰有余。但在某些情况下,还是必须使用非JAVA编码。例如,我们有时要访问操作系统的专用特性,与特殊的硬件设备打交道,重复使用现有的非Java接口,或者要使用“对时间敏感”的代码段,等等。与非Java代码的沟通要求获得编译器和“虚拟机”的专门支持,并需附加的工具将Java代码映射成非Java代码(也有一个简单方法:在第15章的“一个