// private static readonly string localConfig = "<RedisConfig><Node NodeName=\"default\" IsMasterSlave=\"false\"><Item pool = \"0\" IsMaster=\"false\" server=\"{0}\" port=\"{1}\" allowadmin=\"true\" connectTimeout=\"0\" ssl=\"false\" pwd=\"\" /></Node></RedisConfig>"; /// <summary> /// 初始化服务器配置 /// </summary> /// <returns>服务器配置列表</returns> // public static Dictionary<string,RedisNode> InitlizeServerList(XElement root) // { // if (root != null && root.Element("RedisConfig") != null && // root.Element("RedisConfig").Elements("Node") != null) // { // IEnumerable nodes = // from em in root.Element("RedisConfig").Elements("Node") // select em; // foreach (XElement it in nodes) // { // if (it.Elements("Item") == null) // { // continue; // } // RedisNode node = new RedisNode() // { // NodeName = it.Attribute("NodeName").Value.ToLower(), // IsMasterSlave = it.Attribute("IsMasterSlave").Value == "true" ? true : false, // }; // if (redisNodes.ContainsKey(node.NodeName)) // { // Log.GrantLogTextWriter.Write(new Exception(string.Format("不能配置业务节点同名的redis服务器,{0}节点的配置将被忽略", node.NodeName))); // continue; // } // redisNodes[node.NodeName] = node; // IEnumerable srvs = from sr in it.Elements("Item") // select sr; // var servers = new List<RedisServer>(); // foreach (XElement s in srvs) // { // var srv = new RedisServer // { // Node = node, // IsMaster = s.Attribute("IsMaster").Value == "true" ? true : false, // Pool = int.Parse(s.Attribute("pool").Value), // ConnectTimeout = int.Parse(s.Attribute("connectTimeout").Value), // Server = s.Attribute("server").Value, // Port = int.Parse(s.Attribute("port").Value), // AllowAdmin = s.Attribute("allowadmin").Value == "true" ? true : false, // Ssl = s.Attribute("ssl").Value == "true" ? true : false, // Pwd = s.Attribute("pwd").Value, // }; // if (node.IsMasterSlave && srv.IsMaster) // { // RedisConnectionManager.GetConnection(srv); // 提前预初始化 // node.MasterServer = srv; // 如果配置了多个主,这里只会把最后一个做为主 // } // else // { // servers.Add(srv); // 如果是非主从模式,将所有的都加到从上,没有主次 // RedisConnectionManager.GetConnection(srv); // } // } // node.SlaveServers = servers.ToArray(); // } // return redisNodes; // } // throw new Exception("无法解析RedisConfig配置"); // // else // // Log.LogEx.LogError("redis clinet config is null"); // } public static Dictionary <string, RedisNode> InitlizeServerList(Config.RedisConfig config) { if (config != null && config.Nodes != null && config.Nodes.Count > 0) { foreach (Config.RedisNode it in config.Nodes) { RedisNode node = new RedisNode() { NodeName = it.NodeName.ToLower(), IsMasterSlave = it.IsMasterSlave, }; // 这里的初始化方法需要满足 重复调用. 所以注释掉这句, 覆盖原来的配置 //if (redisNodes.ContainsKey(node.NodeName)) //{ // Log.GrantLogTextWriter.Write(new Exception(string.Format("不能配置业务节点同名的redis服务器,{0}节点的配置将被忽略", node.NodeName))); // continue; //} redisNodes[node.NodeName] = node; var servers = new List <RedisServer>(); foreach (Config.RedisItem sItem in it.Items) { var srv = new RedisServer { Node = node, IsMaster = sItem.IsMaster, Pool = sItem.Pool, ConnectTimeout = sItem.ConnectTimeout, Server = sItem.Server, Port = sItem.Port, AllowAdmin = sItem.AllowAdmin, Ssl = sItem.Ssl, Ssl2 = sItem.Ssl2, Pwd = sItem.Pwd, DbIndex = sItem.DbIndex, }; if (node.IsMasterSlave && srv.IsMaster) { RedisConnectionManager.GetConnection(srv); // 提前预初始化 node.MasterServer = srv; // 如果配置了多个主,这里只会把最后一个做为主 } else { servers.Add(srv); // 如果是非主从模式,将所有的都加到从上,没有主次 RedisConnectionManager.GetConnection(srv); } } node.SlaveServers = servers.ToArray(); } return(redisNodes); } throw new Exception("无法解析RedisConfig配置"); }
private T GetSlave <T>(Func <IDatabase, T> fn) { int error = 0; gotoHere: ConnectionMultiplexer conn = null; int idx = DateTime.Now.Millisecond % SlaveServers.Length; // 如果读从库,随机取 try { conn = RedisConnectionManager.GetConnection(SlaveServers[idx]); if (conn == null) { return(default(T)); } IDatabase db = conn.GetDatabase(this.SlaveServers[idx].DbIndex); try { return(fn(db)); // 回调异常和连接异常分开处理,回调异常是业务处理异常,连接异常底层做重试 } catch (Exception e) { logger.LogError(e, $"RedisNode.GetSlave<T>类型{typeof(T).FullName}转换异常"); return(default(T)); } } catch (Exception ex) { if (error < 2) { if (conn != null) { // 释放掉坏连接 RedisConnectionManager.Dispose(SlaveServers[idx], conn); } error += 1; System.Threading.Thread.Sleep(1000); goto gotoHere; } logger.LogError(ex, "RedisNode.GetSlave<T>.Error"); return(default(T)); } }
/// <summary> /// 操作从库,一般是不分主从的set,不能乱了 /// </summary> /// <param name="fn">fn</param> /// <returns>bool</returns> private bool setSlave(Func <IDatabase, bool> fn) { int error = 0; gotHere: if (this.SlaveServers == null || this.SlaveServers.Length < 1) { return(false); } int num = 0; ConnectionMultiplexer conn = null; for (int i = 0; i < this.SlaveServers.Length; i++) { try { conn = RedisConnectionManager.GetConnection(this.SlaveServers[i]); if (conn == null) { continue; } IDatabase db = conn.GetDatabase(this.SlaveServers[i].DbIndex); num += fn(db) ? 1 : 0; } catch (Exception ex) { if (error < 2) { if (conn != null) { RedisConnectionManager.Dispose(this.SlaveServers[i], conn); // conn = null; } error += 1; System.Threading.Thread.Sleep(1000); goto gotHere; } logger.LogError(ex, "RedisNode.SetSlave.Error"); } } return(num == this.SlaveServers.Length); }
/// <summary> /// 操作主库,一般都是set操作 /// </summary> /// <param name="fn">fn</param> /// <returns>bool</returns> private bool setMaster(Func <IDatabase, bool> fn) { int error = 0; gotoHere: ConnectionMultiplexer conn = null; try { conn = RedisConnectionManager.GetConnection(this.MasterServer); if (conn == null) { return(false); } IDatabase db = conn.GetDatabase(this.MasterServer.DbIndex); return(fn(db)); } catch (Exception ex) { if (error < 2)//出错可以重试两次 { if (conn != null) { RedisConnectionManager.Dispose(this.MasterServer, conn); // conn = null;//把这个链接设置为空,防止第二次还是被取出来 } error += 1; System.Threading.Thread.Sleep(1000); goto gotoHere; } logger.LogError(ex, "RedisNode.setMaster.Error"); return(false); } }