【问题标题】:Behavior of singletons in task queues on app-engine应用引擎任务队列中单例的行为
【发布时间】:2015-06-02 00:12:01
【问题描述】:

当应用引擎旋转新实例时,我的静态变量会发生什么情况?更具体地说,我正在使用一个可以有 40 个实例/线程的任务队列。在有问题的 Servlet 中,我使用的是单例,如

public class WorkerThread  extends HttpServlet {
    @Override
      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      ..
      MySingleton single = MySingleton.getInstance();
      ..
    }
    ...
}

这是单例的创建方式

public class MySingleton {

  public static I  MySingleton getInstance() {
    return   MySingletonHolder.INSTANCE;
  }

  private static class MySingletonHolder {
    public static final MySingleton INSTANCE = new MySingleton();
  }

  private   MySingleton() {

  }
  ..
}

我有以下问题:

  1. 由于这是一个任务队列,我是否需要担心 App-Engine 会启动新实例以适应高需求扩展?

  2. 单例是 WorkerThread 类的内部类还是 WorkerThread 类正在访问的另一个类有关系吗?

  3. 任务队列实例是否独立? A 相信他们是,但不确定。

我希望问题很清楚。我希望在所有实例中只有一个我的单例实例。如果问题不清楚,请要求澄清。

更新

以下是我的确切用例

public class SingletonProductIndexWriter {

  private static final Logger LOG = Logger.getLogger(SingletonProductIndexWriter.class.getName());

  public static IndexWriter getSingleIndexWriter() {
    return IndexWriterHolder.INDEX_WRITER;
  }

  private static class IndexWriterHolder {

    static PorterAnalyzer analyzer = new PorterAnalyzer();
    static GaeDirectory index = new GaeDirectory(LuceneWorker.PRODUCTS);// create product index
    static IndexWriterConfig config = GaeLuceneUtil.getIndexWriterConfig(LuceneWorker.LUCENE_VERSION, analyzer);
    public static final IndexWriter INDEX_WRITER =  getIndexWriter();


    private static IndexWriter getIndexWriter() {
      try {
        LOG.info("Create single index writer for workers");
        return new IndexWriter(index, config);
      }catch(IOException e){
        return null;
      }
    }
  }
}

称为

IndexWriter writer = SingletonProductIndexWriter.getSingleIndexWriter();

有关详细信息,请参阅堆栈溢出线程:Worker threads cause Lucene LockObtainFailedException

【问题讨论】:

    标签: java multithreading google-app-engine singleton task-queue


    【解决方案1】:

    推送和拉取队列都由标准实例处理(您可以在 queue.xml 中定位模块/前端/后端)。实例将扩展以满足您的正常流量和队列的需求。

    单例(在此处描绘的经典意义上)仅对于加载它们的类加载器是唯一的 - 它们在 appengine 上的应用程序实例之间绝对不是唯一的 - 不会共享任何状态。使用这种模式,每个 appengine 实例将有一个单例。

    如果你需要共享状态,你需要使用datastore/cloud sql/something。

    【讨论】:

    • 我正在使用 Lucene 进行搜索。我使用任务队列写入索引。 Lucene 需要一个 IndexWriter,它本身负责并发调用者(据我所知)。我正在使用的项目是code.google.com/p/lucene-appengine,它声称我可以使用任务队列来扩展。那么在这种情况下我该如何扩展呢?
    • 我已将更新附加到帖子中以获取更多用例详细信息。
    • 我没有在 appengine 上使用过 lucene - 如果我是你,我会考虑使用全文搜索 api(功能有限)或者在 GCE 上使用 lucene 或弹性搜索。在 Auto Scaling 环境中,这样的限制可能是不合理的。话虽如此,拥有单个写入点的最佳方式可能是使用由 cron 作业触发的拉取队列。然后,您可以一次提取数百个任务并将它们一起编写。然后,您可以使用 cron 和队列速率来确保一次只处理一个批次。不过,这并不能保证它们都在同一个实例上运行。
    猜你喜欢
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多