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

使用BookSleeve维护开放的Redis连接

邢焱
2023-03-14
问题内容

是否有人可以通过BookSleeve库获取Redis的固定html" target="_blank">模式?

我的意思是:

BookSleeve的作者@MarcGravell
建议不要每次都打开和关闭连接,而是在整个应用程序中保持一个连接。但是如何处理网络中断?也就是说,连接可能首先成功打开,但是当某些代码尝试对Redis进行读/写操作时,连接可能已断开,您必须重新打开它(如果连接无法打开,则正常失败-
但是完全可以满足您的设计需求。)

我寻求覆盖常规Redis连接打开的代码段,以及将在每次读/写之前使用的常规“活动”检查(如果未激活,则可选地唤醒)。

这个问题有很好的态度,但是它只是局部的(例如,它不能恢复丢失的连接),并且对该问题的公认答案画出了正确的方法,但是没有展示具体的代码。

我希望该线程能够得到可靠的答案,并最终成为.Net应用程序中有关BookSleeve的一种Wiki。

-----------------------------

重要更新(21/3/2014):

-----------------------------

马克Gravell(@MarcGravell)/堆栈交易所已经最近发布的StackExchange.Redis库,最终取代Booksleeve。这个新的库除其他外,在内部处理重新连接并使我的问题变得多余(也就是说,对于Bookleeve或下面的答案来说,这不是多余的,但我认为最好的方法是开始使用新的StackExchange.Redis库)。


问题答案:

由于我没有任何好的答案,所以我想出了这个解决方案(顺便说一句,感谢@Simon和@Alex的回答!)。

我想与所有社区分享作为参考。当然,任何更正将不胜感激。

using System;
using System.Net.Sockets;
using BookSleeve;

namespace Redis
{
    public sealed class RedisConnectionGateway
    {
        private const string RedisConnectionFailed = "Redis connection failed.";
        private RedisConnection _connection;
        private static volatile RedisConnectionGateway _instance;

        private static object syncLock = new object();
        private static object syncConnectionLock = new object();

        public static RedisConnectionGateway Current
        {
            get
            {
                if (_instance == null)
                {
                    lock (syncLock)
                    {
                        if (_instance == null)
                        {
                            _instance = new RedisConnectionGateway();
                        }
                    }
                }

                return _instance;
            }
        }

        private RedisConnectionGateway()
        {
            _connection = getNewConnection();
        }

        private static RedisConnection getNewConnection()
        {
            return new RedisConnection("127.0.0.1" /* change with config value of course */, syncTimeout: 5000, ioTimeout: 5000);
        }

        public RedisConnection GetConnection()
        {
            lock (syncConnectionLock)
            {
                if (_connection == null)
                    _connection = getNewConnection();

                if (_connection.State == RedisConnectionBase.ConnectionState.Opening)
                    return _connection;

                if (_connection.State == RedisConnectionBase.ConnectionState.Closing || _connection.State == RedisConnectionBase.ConnectionState.Closed)
                {
                    try
                    {
                        _connection = getNewConnection();
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(RedisConnectionFailed, ex);
                    }
                }

                if (_connection.State == RedisConnectionBase.ConnectionState.Shiny)
                {
                    try
                    {
                        var openAsync = _connection.Open();
                        _connection.Wait(openAsync);
                    }
                    catch (SocketException ex)
                    {
                        throw new Exception(RedisConnectionFailed, ex);
                    }
                }

                return _connection;
            }
        }
    }
}


 类似资料:
  • 问题内容: 我最近开始在新的Azure VM上托管我的一个副项目。该应用程序将Redis用作内存缓存。在本地环境中一切正常,但是现在我已将代码移至Azure,我发现Bookleeve中出现了一些奇怪的异常。 当应用首次启动时,一切正常。但是,在闲置约5-10分钟后,对应用程序的下一个请求遇到了网络异常(我现在正在工作,并且没有确切的错误消息,因此我回到家时会张贴这些消息,如果人们认为他们与讨论密切

  • supervisorctl -c /redis/conf/redis-supervisord.conf start redis supervisorctl -c /redis/conf/redis-supervisord.conf stop redis supervisorctl -c /redis/conf/redis-supervisord.conf restart redis

  • 问题内容: 我不知道最好的方法是使用BookSleeve发布和订阅频道。目前,我实现了几种静态方法(请参见下文),这些方法可以将内容发布到特定的频道,而新创建的频道则存储在中。 考虑到我想发布到通道并订阅同一应用程序中的通道,这是正确的方法吗(注意:我的包装器是一个静态类)。即使我想发布和订阅,创建一个频道就足够了吗?显然,我不会在同一应用程序中发布相同的频道。但是我对其进行了测试,并且效果很好:

  • 如何在restasured中设置会话属性?在我的应用程序代码中,我们有如下内容 String userId = request.getSession().getAttribute(“userid”) 如何在此处将 userId 设置为会话属性(在重新保证的测试用例中)? 如何为所有请求(多个后续请求)维护同一会话? 当我发送多个请求时,它认为每个请求都是新的,会话从服务器端失效,我想在后续调用之间

  • Navicat 为维护 Oracle 用户提供完整的解决方案。 在对象选项卡中选择用户。 右击已选择的用户。 选择“维护”,然后从弹出式菜单中选择一个维护选项。 选项 描述 密码过期 设置用户的密码为过期。 锁定帐号 锁定用户的帐号和禁用访问。 解除锁定帐号 解除锁定用户的帐号和启用访问。

  • Navicat 为维护 Oracle 用户提供完整的解决方案。 在对象选项卡中选择用户。 按住 Control 键并点按已选择的用户。 选择“维护”,然后从弹出式菜单中选择一个维护选项。 选项 描述 锁定用户 锁定用户的帐号和禁用访问。 解除锁定用户 解除锁定用户的帐号和启用访问。 过期用户 设置用户的密码为过期。