播放框架和jdbc阻止io调用是否存在主要的扩展限制 [英] Are there major scaling limits with play framework and jdbc blocking io calls

查看:115
本文介绍了播放框架和jdbc阻止io调用是否存在主要的扩展限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用playframework(2.4)for Java并将其连接到Postgres。 play框架被用作一个宁静的服务,它所做的就是使用JDBC进行插入,更新,读取和删除。在此播放页面上 https://www.playframework.com/documentation/2.3.x/ JavaAsync 它明确指出JDBC是阻塞的,并且该游戏几乎没有线程。对于那些了解这一点的人来说,这是多么有限,是否有某种方法可以解决这个问题?我的特定应用程序每秒可以有几百个数据库调用。我将拥有所有硬件和额外的服务器,但不知道播放如何处理这个或扩展以在代码中处理这个。我的游戏代码如下所示:

I am using the playframework (2.4) for Java and connecting it to Postgres. The play framework is being used as a restful service and all it is doing is insert,updates,reads and deletes using JDBC. On this play page https://www.playframework.com/documentation/2.3.x/JavaAsync it states clearly that JDBC is blocking and that play has few threads. For the people who know about this, how limiting could this be and is there some way I can work around this? My specific app can have a few hundred database calls per second. I will have all the hardware and extra servers but do not know how play can handle this or scale to handle this in the code. My code in play looks like this:

public static Result myprofile() {
        DynamicForm requestData = Form.form().bindFromRequest();
        Integer id = Integer.parseInt(requestData.get("id"));

        try {
            JSONObject jo = null;
            Connection conn = DB.getConnection();
            ResultSet rs;
            JSONArray ja = new JSONArray();
            PreparedStatement ps = conn.prepareStatement("SELECT p.fullname as fullname, s.post as post,to_char(s.created_on, 'MON DD,YYYY') as created_on,s.last_reply as last_reply,s.id as id,s.comments as comments,s.state as state,s.city as city,s.id as id FROM profiles as p INNER JOIN streams as s ON (s.profile_id=p.id) WHERE s.profile_id=? order by created_on desc");
            ps.setInt(1, id);
            rs = ps.executeQuery();

            while (rs.next()) {
                jo = new JSONObject();
                jo.put("fullname", rs.getString("fullname"));
                jo.put("post", rs.getString("post"));
                jo.put("city", rs.getString("city"));
                jo.put("state", rs.getString("state"));
                jo.put("comments", rs.getInt("comments"));
                jo.put("id", rs.getInt("id"));
                jo.put("last_reply", difference(rs.getInt("last_reply"), rs.getString("created_on")));
                ja.put(jo);
            }
            JSONObject mainObj = new JSONObject();
            mainObj.put("myprofile", ja);


            String total = mainObj.toString();
            System.err.println(total);
            conn.close();
            return ok(total);
        } catch (Exception e) {
            e.getMessage();
        }
        return ok();
    }

我也知道我可以尝试将其包含在期货承诺中但是阻塞仍然发生。如前所述,我将处理所有服务器和其他内容,但是播放框架是否能够使用jdbc扩展到每秒数百个请求?我现在正在学习和学习以避免以后出现严重错误。

I also know that I can try to wrap that in a futures promise however the blocking still occurs. As stated before I will have all the servers and the other stuff taken care of, but would the play framework be able to scale to hundreds of requests per second using jdbc? I am asking and learning now to avoid serious mistakes later on.

推荐答案

播放绝对可以处理此负载。

Play can absolutely handle this load.

文档指出应该在控制器方法中避免阻塞代码 - 调整默认配置以使它们具有异步执行。如果你在那里粘贴了一些阻塞调用,你的控制器现在将等待该调用完成,然后才能处理另一个传入请求 - 这很糟糕。

The documentation states that blocking code should be avoided inside controller methods - the default configuration is tuned for them to have asynchronous execution. If you stick some blocking calls in there, your controller will now be waiting for that call to finish before it can process another incoming request - this is bad.


通过将
包装在Promise中,你无法神奇地将同步IO变为异步。如果您无法将应用程序的体系结构更改为
,请避免阻塞操作,在某些时候操作将必须执行
,并且该线程将阻止。所以除了
将操作包含在Promise中之外,还需要配置
以在单独的执行上下文中运行,该上下文已经配置了
足够的线程来处理预期并发
即可。有关详细信息,请参阅
了解Play线程池。
https://www.playframework.com/documentation /2.4.x/JavaAsync#Make-controllers-asynchronous

You can’t magically turn synchronous IO into asynchronous by wrapping it in a Promise. If you can’t change the application’s architecture to avoid blocking operations, at some point that operation will have to be executed, and that thread is going to block. So in addition to enclosing the operation in a Promise, it’s necessary to configure it to run in a separate execution context that has been configured with enough threads to deal with the expected concurrency. See Understanding Play thread pools for more information. https://www.playframework.com/documentation/2.4.x/JavaAsync#Make-controllers-asynchronous

我相信你知道这一点但我想指出粗体部分。您的数据库具有可供应用程序调用的有限数量的线程 - 跟踪此数字可能会有所帮助,为这些线程创建新的执行上下文,并将新的执行上下文分配给承诺包装你的数据库调用。

I believe you are aware of this but I wanted to point out the bolded section. Your database has a limited number of threads that are available for applications to make calls on - it may be helpful to track this number down, create a new execution context that is turned for these threads, and assign that new execution context to a promise that wraps your database call.

查看这篇关于应用程序转向Play的帖子,它应该让你知道这是什么样的。我相信他正在使用Akka Actors,这可能超出你的范围,但线程调整的想法是一样的:

Check out this post about application turning for Play, it should give you an idea of what this looks like. I believe he is using Akka Actors, something that might be out of scope for you, but the idea for thread tuning is the same:


对于没有
包含阻塞调用(即异步)的HTTP请求,Play 2已经开箱即用。 Java中大多数数据库驱动的应用程序
都使用JDBC进行同步调用,因此Play 2需要一些额外的
配置来为这些类型的请求调整Akka。
http:// www .jamesward.com / 2012/06/25 / optimize-play-2-for-database-driven-apps

如果您尝试在不转动线程的情况下在数据库上执行大量请求,则存在使线程应用程序的其余部分挨饿的风险,这将使您的应用程序停止运行。对于你期望的负载,默认调整可能没问题,但值得进行一些额外的调查。

If you try to execute a massive number of requests on the database without turning the threads, you run the risk of starving the rest of your application of threads, which will halt your application. For the load you are expecting, the default tuning might be ok, but it is worth performing some additional investigating.

线程调优入门:
https://www.playframework.com/documentation/2.4.x/ThreadPools

您应该更新控制器以返回Promise,并且没有理由让Play 2.4再次保持静态。 https://www.playframework.com/documentation/2.4.x/Migration24#Routing

You should update your controller to return Promise and there is also no reason to make it static anymore with Play 2.4. https://www.playframework.com/documentation/2.4.x/Migration24#Routing

在application.conf中定义一个名为jdbc-execution-context的执行上下文

Define an execution context in the application.conf with name "jdbc-execution-context"

//reference to context
ExecutionContext jdbcExecutionContext = Akka.system().dispatchers()
     .lookup("jdbc-execution-context");

return promise(() -> {
    //db call
}, jdbcExecutionContext)
.map(callResult -> ok(callResult));

这篇关于播放框架和jdbc阻止io调用是否存在主要的扩展限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆