因爲項目須要MongoDB作爲存儲數據庫,在學習過程碰上疑難雜症,心痛如海,故此終於開始書寫博客之路。html
操做MongoDB類庫版本:mongodb
----------------------------------------------shell
MongoDB.Driver 2.3
MongoDB.Driver.Core 2.3
MongoDB.Bson 2.3
MongoDB 版本 3.2.9
參考相關學習連接(轉載):
---------------------------------------------
https://izk.cloud/437/ 安全認證,權限管理
http://www.cnblogs.com/huangxincheng/archive/2015/10/12/4870557.html 主從熱備集羣
http://blog.csdn.net/luonanqin/article/details/8497860 集羣搭建
鏈接字符串的相關變化:數據庫
-----------------------------------------------安全
沒有安全認證的URL:mongodb://127.0.0.1:27017架構
加上安全認證的URL:mongodb://[userName]:[userPwd]@127.0.0.1:27017/[DataBaseName]dom
重點變化是最後一個指定數據庫,若是不指定,將爲默認數據庫post
因此想固然測試的時候通常使用的是mongodb://[userName]:[userPwd]@127.0.0.1:27017學習
並無加上自定義數據庫名稱,致使初始化報錯。測試
網上參考文章帶安全驗證的鏈接都是:mongodb://[userName]:[userPwd]@127.0.0.1:27017
都沒有在最後補上/[DataBaseName] 致使自定義數據庫的建立失敗。
主副熱備集羣相關代碼處理上的問題:
-------------------------------------------------
感謝國慶,感謝國家,感謝這二篇博文,一直在操做主副集羣C#代碼碰上未知報錯,經過下面連接
深度學習了一下:
雖然依然沒有解決個人問題,可是從中學習到經驗,值得回報。
按照上面代碼(轉載):
MongoClientSettings set = new MongoClientSettings(); List<MongoServerAddress> servers = new List<MongoServerAddress>(); servers.Add(new MongoServerAddress("192.168.129.129", 37017)); servers.Add(new MongoServerAddress("192.168.129.129", 37018)); servers.Add(new MongoServerAddress("192.168.129.129", 37019)); set.Servers = servers; //設置副本集名稱 set.ReplicaSetName = "rs0"; //設置超時時間爲3秒 set.ConnectTimeout = new TimeSpan(0, 0, 0, 3, 0); MongoClient client = new MongoClient(set); MongoServer server = client.GetServer(); MongoDatabase db = server.GetDatabase("test"); MongoCollection coll = db.GetCollection("test"); //插入 BsonDocument bd = new BsonDocument(); bd.Add("name", "zhanjindong"); bd.Add("age", 23); bd.Add("sex", "男D"); coll.Insert(bd); //讀取 QueryDocument qd = new QueryDocument(); qd.Add("name", "zhanjindong"); qd.Add("age", 23); qd.Add("sex", "男D"); BsonDocument rd = coll.FindOneAs<BsonDocument>(qd); Console.WriteLine(rd.ToString()); 默認的C#驅動的ReadPreference是Primary,也就是說讀寫操做都是在主節點上的,那麼當集羣中只剩下一個節點的時候,按照前面所說該節點必定是secondary節點,這樣讀取操做也是無法進行的(經過mongo shell固然是能夠的)。解決方法就是設置驅動的ReadPreferenceMode: set.ReadPreference = new ReadPreference(ReadPreferenceMode.PrimaryPreferred); 狀態說明: primary 主節點,默認模式,讀操做只在主節點,若是主節點不可用,報錯或者拋出異常。 primaryPreferred 首選主節點,大多狀況下讀操做在主節點,若是主節點不可用,如故障轉移,讀操做在從節點。 secondary 從節點,讀操做只在從節點, 若是從節點不可用,報錯或者拋出異常。 secondaryPreferred 首選從節點,大多狀況下讀操做在從節點,特殊狀況(如單主節點架構)讀操做在主節點。 nearest 最鄰近節點,讀操做在最鄰近的成員,多是主節點或者從節點
你覺得上面就複製粘貼一下就解決了?No,實際調用跟參考代碼是二回事,呃?繞回正題,經過上面代碼覺得能夠輕鬆一步了,結果又挖了一個大坑,在招待我。
報錯詳情:
System.TimeoutException」類型的異常在 MongoDB.Driver.Core.dll中發生,但未在用戶代碼中進行處理其餘信息: A timeout occured after 3000ms selecting a server using CompositeServerSelector { Selectors = ReadPreferenceServerSelector { ReadPreference = { Mode = Secondary, TagSets = [] } }, LatencyLimitingServerSelector { AllowedLatencyRange = 00: 00: 00.0150000 } }.Client view of cluster state is { ClusterId: "1", ConnectionMode: "ReplicaSet", Type: "ReplicaSet", State: "Disconnected", Servers: [{ ServerId: "{ ClusterId : 1, EndPoint : " Unspecified / mongodb - 10.localdomain: 27017 " }", EndPoint: "Unspecified/mongodb-10.localdomain:27017", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. ---> System.Net.Sockets.SocketException: 不知道這樣的主機。
我當時就#¥#@¥@#¥,你懂的,一波三折,要命,通過大量時間排查我鎖定問題位置:
EndPoint: "Unspecified/mongodb-10.localdomain:27017",
底氣何來?緣由以下:
![](http://static.javashuo.com/static/loading.gif)
若是你也是本地測試而且副集羣IP地址使用是域名綁定,那麼你在HOSTS沒有配置域名的狀況下,就會出現上面的超時30秒錯誤(一想起無數個F5等30秒就。。。。)
接下來配置HOSTS文件:
而後燒香拜佛,果真不出所料,調用成功,爲此付出很多冤枉路,若是有人碰上相同的問題,能夠參與一下。
最後放上測試單元代碼:
using System; using System.Collections.Generic; using System.Linq; using MongoDB.Driver; using MongoDB.Driver.Linq; using System.Linq.Expressions; public class MongoUnitily { /// <summary> /// MongoDB調用類 /// </summary> private MongoUnitily() { dataBase = new MongoClient(new MongoClientSettings { Credentials = new List<MongoCredential>() { MongoCredential.CreateCredential("avatar","*******","*********") // 數據庫名稱,用戶名,用戶密碼 }, Servers = new string[] { "10.199.*.1", "10.199.*.2", "10.199.*.3" }.Select(x => { return new MongoServerAddress(x); }), // 集羣IP地址 ConnectionMode = ConnectionMode.ReplicaSet, // Replica 模式 ReplicaSetName = "RS01", // Replica名稱 ReadPreference = new ReadPreference(ReadPreferenceMode.SecondaryPreferred), // 讀寫配置,副IP不起做用的狀況下使用主IP ConnectTimeout = new TimeSpan(0, 0, 0, 3, 0), // 3秒報錯測試,當初30秒我是等閒人。。。。 MaxConnectionIdleTime = new TimeSpan(0, 0, 0, 3, 0), // 3秒報錯測試,當初30秒我是等閒人。。。。 MaxConnectionLifeTime = new TimeSpan(0, 0, 0, 3, 0), // 3秒報錯測試,當初30秒我是等閒人。。。。 ServerSelectionTimeout = new TimeSpan(0, 0, 0, 3, 0) // 3秒報錯測試,當初30秒我是等閒人。。。。 }).GetDatabase(database); // 經過數據庫名稱獲取 DbBase } static MongoUnitily() { //初始化單例對象 Instance = new MongoUnitily(); } /// <summary> /// 數據庫名稱 /// </summary> private string database = "avatar";//數據庫名 /// <summary> /// dataBase上下文對象 /// </summary> private IMongoDatabase dataBase = null; public static MongoUnitily Instance { get; private set; } /// <summary> /// 驗證讀取 /// </summary> /// <returns></returns> public bool IsGet() { bool result = true; var coll = dataBase.GetCollection<SysCodes>(nameof(SysCodes)); Expression<Func<SysCodes, bool>> predicate = x => true; try { var count = coll.Find(predicate).Count(); } catch { result = false; } return result; } /// <summary> /// 驗證寫 /// </summary> /// <returns></returns> public bool IsPost() { var result = true; var coll = dataBase.GetCollection<Demo>(nameof(Demo)); try { coll.InsertOne(new Demo { Id = Guid.NewGuid(), Name = "三" }); } catch { result = false; } return result; } /// <summary> /// 測試類 /// </summary> public class Demo { public Guid Id { get; set; } public string Name { get; set; } } }
驗證結果:
本篇文章旨在解決使用新版本MongoDB碰上的集羣、鏈接字符串、安全驗證的相關問題,文章深度不高,提供新手對象相互學習互挽。