背景:
嗨,我正在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)
笔记:
可能的解决方案:
更新:
TCP输入endpoint
端口27017直接连接到它们。正如@David所说,我目前无法控制连接到哪个实例。HTTP Input Endpoint
。这是我上面提到的mongo-azure库默认创建的。我不确定我是否应该对此做任何事情。如果所有实例都位于一个负载平衡的Input
endpoint(例如27017)后面,那么每次客户端计算机连接到该endpoint时,它都将连接到replicaset集群中可能不同的节点(并且您无法控制要访问哪个实例)。这可能解释了为什么有时尝试写入非主节点并出错,但所有读取都可以工作(因为您可能将MongoDB集群设置为允许在辅助节点上读取)。
Worker角色还支持InstanceInput
endpoint,允许您设置面向外部的端口范围(例如27017-27019),映射到Worker实例本身(例如27017)上的单个端口。如果您这样做,您的客户端应用程序现在可以直接连接到所有三个实例(270172701827019)。许多驱动程序支持replicaset连接,因此它可以确定哪个节点是主节点,并将所有写入操作定向到该节点。我不知道你在Android上使用的驱动程序是否支持复制集。如果驱动程序不支持ReplicateSet,那么您可能会考虑设置一个API层,该层负责与数据库的所有通信(总之,这是一个通常遵循的良好实践,您可以查看Azure的移动服务,以快速实现这一点)。
因此...如果您的副本集集群的endpoint配置为Input
,这可能解释了您看到的问题,该问题应该可以通过将endpoint类型切换为InstanceInput
来解决。
在构造方法中无法使用返回值,因此遇到错误只能抛出异常,而不应该使用Fatal Error 如果是用户使用方法存在问题,必须要修改程序代码,这类错误可以抛出Fatal Error 非构造方法,只return false,并设置错误码,而不是抛出异常
问题内容: 您认为可以在异常内使用错误代码来指定错误类型吗?请看下面的代码: 我知道在此示例中使用枚举而不是字符串会更好,但是我实际上担心错误代码的概念。您认为在这里异常层次结构会更好吗?我找不到任何权威来源指出异常中的错误代码是反模式的。谢谢。 问题答案: 如果您想根据导致异常(无效名称或无效ID)的原因做出不同的响应(在代码中),那么我建议您使用不同的异常。 如果不是,那么您甚至不需要该方法,
我正在使用SQLiteHelper创建一个数据库,当应用程序尝试运行时,我不断收到异常。 这是我收到的错误消息:引起原因:android.database.sqlite.SQLiteExcture:附近"Trip":语法错误(代码1):,而编译:创建表商务旅行支出(desc文本主键,餐整数不为空,饮料整数不为空,旅行整数不为空,住宿整数不为空,其他整数不为空,Receipt_Retained?Re
本章主要列出 JA 的错误代码,供开发者参考 异常代码 描述 原因 解决方案 2000 Success - - 5000 Failure 多为系统异常,如 JA 本身的 BUG,或者其他原因 请参考控制台异常栈 5001 Not Implemented 方法未实现 ① 针对自定义的 oauth 平台,请检查你的代码,是否存在未实现必要接口的问题; ② 针对 JA 内置的平台,说明该平台的某个方法暂
我坚持这个问题,如果有任何帮助是非常感谢的 请在以上问题上帮助我
目录表 错误 try..except 处理异常 引发异常 如何引发异常 try..finally 使用finally 概括 当你的程序中出现某些 异常的 状况的时候,异常就发生了。例如,当你想要读某个文件的时候,而那个文件不存在。或者在程序运行的时候,你不小心把它删除了。上述这些情况可以使用异常来处理。 假如你的程序中有一些无效的语句,会怎么样呢?Python会引发并告诉你那里有一个错误,从而处理