【问题标题】:HtppServlet and MongoClientHtppServlet 和 MongoClient
【发布时间】:2016-10-08 02:40:13
【问题描述】:

我正在尝试使用 Jetty 和 HttpServlets 创建一个简单的 API 后端。我已经阅读了 herehere 关于 HttpServlets 线程安全的详细信息。普遍的共识似乎是这是在 HttpServlerts 中处理变量访问的正确方法:

public class MyServlet extends HttpServlet {
    private static Object thisIsNotThreadsafe;
    private Object thisIsAlsoNotThreadsafe;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Object thisIsThreadsafe;

        thisIsNotThreadsafe = request.getParameter("foo"); // BAD! Shared among all requests.
        thisIsAlsoNotThreadsafe = request.getParameter("foo"); // BAD! Shared among all requests.
        thisIsThreadsafe = request.getParameter("foo"); // Good.
    }
}

我想做的是创建一个新的MongoClient

MongoClient mongoClient = new MongoClient("localhost", 27017);

我可以将其设为“全局变量”,但这不是线程安全的。每次调用 doGetdoPost 时,我都可以创建一个新实例。但 MongoDB 的 Java 驱动程序文档似乎也反对这样做:

具有内部连接池的 MongoDB 客户端。对于大多数应用程序,您应该为整个 JVM 提供一个 MongoClient 实例。

最好的方法是什么?

【问题讨论】:

    标签: java mongodb servlets


    【解决方案1】:

    如果MongoClient 实例是线程安全的并且可以由多个线程共享而不会成为并发瓶颈,那么您可以为共享的MongoClient 实例实现一个单例包装器。

    根据 Mongo 文档的说法,这将是“最正确”的方法,特别是如果您有/可能有多个 servlet 类。

    如果MongoClient 实例不是线程安全的,等等,那么您需要为MongoClient 实例实现某种(线程安全)连接池。


    如果您使用的框架支持依赖注入 (DI),那么还有其他解决方案可以避免显式单例和池的一些问题。

    【讨论】:

    • 那么我可以只创建一个属于扩展 HttpServlet 的类的静态 MongoClient 对象吗?这会是安全且良好的做法吗?
    • 安全吗?是的。好习惯?嗯……我提到过单身人士吗?
    • 哦,我不知道这是不好的做法,你能指导我看一些关于这方面的阅读材料吗?
    • 嗯,这是一个好主意还是坏主意取决于上下文。在您的情况下,这取决于是否存在,或将来,可能需要 MongoDB 的任何其他 servlet。以及他们是否可能需要共享客户端对象。 “好的做法”和“坏的做法”这两个词都是懒惰的术语。您应该真正做的是了解问题并在具体情况下做出自己的判断。
    猜你喜欢
    • 2016-05-10
    • 2018-03-08
    • 1970-01-01
    • 2017-04-28
    • 2019-09-20
    • 1970-01-01
    • 2018-12-10
    • 2021-09-06
    • 1970-01-01
    相关资源
    最近更新 更多