【问题标题】:Is a Singleton pattern a good use case for RedissonClient?单例模式是 RedissonClient 的一个很好的用例吗?
【发布时间】:2016-06-15 18:31:50
【问题描述】:

我正在通过 Jetty/CometD 运行一个长时间运行的 Web 服务,并且我正在使用 Redisson 库来连接到 redis。我正在使用单例模式来获取我的 RedissonClient/连接,但我不确定这是否是最好的方法。

类看起来像这样:

public class RedisClient {
    // singleton instance of our RedisonClient/connection
    private static RedissonClient _redissonInstance;
    public static String REDIS_HOST = "my.redishost.com:6379";


    private static RedissonClient setupRedis() {
        org.redisson.Config config = new org.redisson.Config();

        config.useSingleServer()
                .setAddress(REDIS_HOST)
                .setConnectionPoolSize(200);

        return Redisson.create(config);
    }

    public static RedissonClient getRedis() {
        if (_redissonInstance == null) {
            _redissonInstance = setupRedis();
        }
        return _redissonInstance;
    }

    public static void setRedisHost(String redisHost) {
        _logger.warn("Setting REDIS_HOST to: " + redisHost);
        REDIS_HOST = redisHost;
    }
}

【问题讨论】:

  • 我想不出任何单例是个好主意的用例。
  • 为什么单例在 Java 中是个坏主意?似乎我读的越多,似乎越不推荐它们(仍在学习Java btw)
  • 在任何语言中它们都是一个坏主意。这就是不推荐它们的原因。谷歌已经编写了检测它们以消除它们的工具:googlecode.blogspot.com/2007/07/…
  • 总体上同意@nikdeapen 的观点,即public static final 对于拥有如此多资源(TCP 连接、线程等)的实例来说是一个糟糕的选择。任何主要保存在static final 中的实例都无法以合理的方式进行管理。 Spring、CDI 或 EJB 中的单例更好,因为您可以通过 bean 管理来初始化和销毁​​实例。使用 static final 需要您自己关闭实例或添加关闭挂钩。
  • @mp911de 我明白你的意思,谢谢!您是否知道如何在 Jetty Servlet 中进行设置?我已将 MySql 数据源设置为 JDNI 资源,但似乎找不到为 redis 设置资源的方法

标签: java redis redisson


【解决方案1】:

我会说这是个坏主意。我不认为单身人士一般来说是一个好主意,但即便如此这也不是一个好方法。您的代码不是线程安全的,似乎您想支持多个主机。

如果你真的不想将你的 redis 客户端传递给每个组件,并且你的主机不会改变并且想要快速而肮脏的东西,试试这个:

public class Redis {
    public static final RedissonClient CLIENT;
    static {
        Config config = new Config();
        config.useSingleServer()
            .setAddress("my.redishost.com:6379")
            .setConnectionPoolSize(200);
        CLIENT = Redisson.create(config);
    }
}

这具有线程安全的好处,在获取引用时无需任何同步。

【讨论】:

  • 并不是我想支持多个主机,而是我从一个 maven 配置文件属性设置主机 -> web.xml init-param,我在 servlet 被初始化并且是基于此设置redis的主机。我有两台redis主机,一台用于开发,一台用于生产,我不想在测试时使用生产redis主机。不确定最好的解决方法,但感谢您的回复并指出线程安全问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-13
  • 1970-01-01
  • 2012-06-27
  • 2015-10-30
  • 2016-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多