コード例 #1
0
        // 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配置");
        }
コード例 #2
0
ファイル: RedisNode.cs プロジェクト: staoran/SuperGMS
        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));
            }
        }
コード例 #3
0
ファイル: RedisNode.cs プロジェクト: staoran/SuperGMS
        /// <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);
        }
コード例 #4
0
ファイル: RedisNode.cs プロジェクト: staoran/SuperGMS
        /// <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);
            }
        }