elasticsearch - 创建TransportClient单例实例

时间:2014-04-09 08:27:40

标签: elasticsearch

我试图使用单个客户端实例来创建多个索引。下面是相同的代码。但每次我将实例作为null并且它创建一个新实例。请让我知道我做错了什么

单身实例:

public class ESClientSingleton {

    public static Client instance ;

    private ESClientSingleton()
    {}

    public static Client getInstance()
    {
        if (instance == null)
          {
            System.out.println("the instance is null...");
            ImmutableSettings.Builder settings = ImmutableSettings.settingsBuilder(); 
                    settings.put("node.client", true); 
                    settings.put("node.data", false); 
                    settings.put("node.name", "node-client");
                    settings.put("cluster.name", "elasticsearch");
                    settings.build(); 
            instance = new TransportClient(settings)
                            .addTransportAddress(new InetSocketTransportAddress("10.203.251.142", 9300));
            //instance = client;
            System.out.println("return the client");
            return instance;
          }
        return instance;
    }       
}

调用方法:

public static IndexResponse insertESDocument(String nodeName, String json) throws MasterNotDiscoveredException, SocketException
  {  
      Client client = ESClientSingleton.getInstance();
      logger.debug("calling the es client");
      logger.debug("the json received as == "+json);
      IndexResponse response = client.prepareIndex("aricloud-nodes","node-entry",nodeName )
                               .setSource(json)
                               .execute()
                               .actionGet();
      logger.debug("the document is successfully indexed...");
              System.out.println("the document is indexed...");
              //client.close();
      return response;  
  } 

3 个答案:

答案 0 :(得分:1)

要实现Singleton模式,请使用 enum 而不是类。 enum具有许多内置优势,这有助于我们简化单例实现。 有关更多信息,请参阅joshua bloch的Effective Java。

答案 1 :(得分:0)

这确实是为elasticsearch集群调用单例客户端对象实例的正确方法。我在webapp上遇到了一些问题,现在也在使用。

然而,这可以成为寻找类似答案的人的一个例子。

答案 2 :(得分:0)

在多线程环境中,检查实例是否为null可能还不够。

您可以拥有一个竞速条件,其中有2个或更多个线程并行执行此检查,第二个尝试也尝试实例化该对象,因为第一个没有完成分配。 有很多方法可以解决这个问题,最常见的方法是将实例声明为 volatile ,并将if放在 synchronized块中:

public class SingletonDemo {
    private static volatile SingletonDemo instance;
    private SingletonDemo() { }
    public static SingletonDemo getInstance() {
        if (instance == null ) {
            synchronized (SingletonDemo.class) {
                if (instance == null) {
                    instance = new SingletonDemo();
                }
            }
        }

        return instance;
    }
}

或者由Jayan K提出的枚举解决方案。 更多详情:https://en.wikipedia.org/wiki/Singleton_pattern