简体   繁体   English

Spring MVC和Ajax请求在同一个控制器中

[英]Spring MVC and Ajax requests in the same controller

I have the following controller setup in Spring 3.0.5. 我在Spring 3.0.5中设置了以下控制器。 Tomcat Webserver 7.0.14 with Windows 7 host. 带有Windows 7主机的Tomcat Webserver 7.0.14。

    @Controller
    @RequestMapping (value="myForm")
    public class SubmitClassController {


    //Status object with getters and setters
    Status myStatus= newStatus();

   @RequestMapping (method=RequestMethod.GET)
    public String getMyForm (Model getModel){
    //setup form
   //very simple adds one attribute to the model and returns view
    }

    @RequestMapping (value="/myFormStatus",method=RequestMethod.POST)
    public @ResponseBody Status getStatus(){
    //Ajax responder handles a null (empty) request and responds with results of status obj
    //Has System.out.println prior to return that shows variables when processed correctly
    System.out.printlin ("vars are: "+myStatus.getStatus()+" "+myStatus.getCurStep()+" "+myStatus.getTotSteps());
     return myStatus;
     }

    @RequestMapping (method=RequestMethod.POST)
    public String create (@Valid MyFormText submitText ...){
   // processes the form submitted and sets status object variables while doing so .
   //many steps each one is bascily query a remote DB wait for response, add response to the set  repeat. After each query myStatus has its status,curStap and totstep set.
   }


  }

I perform the ajax request as follows from firefox or IE the result is the same 我从firefox或IE执行如下的ajax请求,结果是一样的

   Ext.Ajax.request({
    url: './myForm/myFormStatus',
    method: 'POST',
    success: function(result, request) {
        var json = Ext.decode(result.responseText);
        pbar.updateProgress(json.step / json.steps, 'Working on ' + json.status + ' Step ' + json.step + ' of ' + json.steps + '...');

    },
    failure: function(result, request) {
        Ext.MessageBox.alert('Failed runner', result.responseText);
    }

});

The Ajax responder works correctly except when called during the "create" POST method. 除了在“创建”POST方法期间调用时,Ajax响应器才能正常工作。 So I run the ajax query in a loop while the create method ( which handles the POST) is not running it returns fine . 所以我在循环中运行ajax查询,而create方法(处理POST)没有运行它返回正常。 However while the create is running Ajax responses are intermittent and Ajax requests are often not responded to. 但是,当create正在运行时,Ajax响应是间歇性的,并且Ajax请求通常不会响应。 The server does not lock up and freeze rather it just stop responding to the status method while the create method is actually doing something. 服务器没有锁定和冻结而只是在create方法实际执行某些操作时停止响应状态方法。

I tried replacing the bulk of the create with loops that fill arrays . 我尝试用填充数组的循环替换大量的创建。 I got more ajax responses but no where near one for one , at best a got 20-30 responses out of 100. I also tested changing the values for the status object to confirm that the values would return valid JSON. 我得到了更多的ajax响应,但没有一个接近一个,最多得到20个响应中的100个。我还测试了更改状态对象的值以确认值将返回有效的JSON。 They all worked. 他们都工作了。 While running the test where I just filled treemaps and arrays I also watched Jconsole and the task manager for signs of a resource constraint. 在我刚刚填充树形图和数组的测试运行时,我还看了Jconsole和任务管理器以查看资源约束的迹象。 HTe JVM never used more then 50% of its available memory and the niether I/O,RAM or CPU were anywhere close to loaded. HTe JVM从未使用过50%以上的可用内存,而且其他I / O,RAM或CPU都是接近加载的。

Clearly something is wrong here . 显然这里有些不对劲。 I tried attaching the @Async annotation to both the Ajax controller and to the POST handler but this did not seem to make any changes. 我尝试将@Async注释附加到Ajax控制器和POST处理程序,但这似乎没有做任何更改。 I also tried putting timeouts and auto aborts on the request. 我还尝试在请求中设置超时和自动中止。

Out of 100 Ajax requests I get one response...the rest appear to be blocked. 在100个Ajax请求中,我得到一个响应......其余的似乎被阻止了。 Either before the create block is called or after, responses are instant. 在调用创建块之前或之后,响应是即时的。 I should not be overloading the browser. 我不应该重载浏览器。 The ajax request in question is set to fire once every quarter second ( progress bar updater ). 有问题的ajax请求设置为每四分之一秒触发一次(进度条更新程序)。 Even if I throttle the ajax request back to 1 per second (or even 1 per 2 secs) the result is the same. 即使我将ajax请求限制为每秒1次(甚至每2秒1次),结果也是一样的。 The ajax calls are made on time so JS side is working as expected. ajax调用是按时完成的,所以JS方面按预期工作。

I used wireshark so i can see the ajax request coming in. I can account the the majority of the ajax requests in that i can see them reaching the server. 我使用wireshark所以我可以看到ajax请求进来。我可以考虑大多数ajax请求,因为我可以看到它们到达服务器。 I can see them hit the handler but troubleshooting (System.out.println) messages only appear when the "create" method is not "busy". 我可以看到它们命中处理程序,但只有当“create”方法不“忙”时才会出现故障排除(System.out.println)消息。 To be clear "busy" means processing the results of the queries it makes, "not busy" seems to be mean waiting for a response.No latches or semaphores are being used. 要清楚“忙”意味着处理它所做查询的结果,“不忙”似乎意味着等待响应。没有使用锁存器或信号量。 Adding the Spring @Async annotation did not make any difference. 添加Spring @Async注释没有任何区别。

Anyone know whats going on here ? 有谁知道这里发生了什么? Its seems something is getting locked and preventing a response? 它似乎被锁定并阻止响应? Is a controller locked to a single thread ? 控制器是否锁定到单个线程?

Remember browser only has 2-4 threads per domain (depending on browser) so it won't make more than 2-4 requests at a time, so your web server has to send those responses back in time for them to not timeout. 请记住浏览器每个域只有2-4个线程(取决于浏览器),因此一次不会超过2-4个请求,因此您的Web服务器必须及时发送这些响应,以使它们不会超时。 Sending 100 requests all at once would probably just get dropped if you didn't get those back in ~10ms. 如果你在大约10毫秒内没有得到这些请求,那么一次发送100个请求可能会被丢弃。

When you send out 100 request do you see all of those 100 request in the create method? 当您发出100个请求时,您是否在create方法中看到了所有这100个请求? Are you logging some data when it starts and when it finishes so you can correlate they all got there? 您是否在启动时记录了一些数据并在完成时记录了所有数据? I'd make sure your getting all 100 requests from the browser in the server and generated a response for each 100 requests. 我确保您从服务器中的浏览器获取所有100个请求,并为每100个请求生成响应。 Use log4j so you can see the thread name servicing each request. 使用log4j,您可以看到为每个请求提供服务的线程名称。 Those thread names will help you identify each individual request so you can match up messages logged at the start and end. 这些线程名称将帮助您识别每个单独的请求,以便您可以匹配在开始和结束时记录的消息。 System.out you don't get that out of the box. System.out你没有开箱即用。

For more testing try this. 如需更多测试,请试试这个 What happens if you only send 10 requests per browser? 如果您每个浏览器只发送10个请求,会发生什么? Do you get all of those? 你得到了所有这些吗? If so then multiply by 2 and see if you get all of those, etc until you start to see them drop off. 如果是这样,那么乘以2,看看你是否得到所有这些,等等,直到你开始看到它们下降。

I hope you're just testing performance by trying to send 100 requests per browser session otherwise you'll destroy your server when you goto production and 30,000 browsers x 100 = 3 Million requests hit that page. 我希望您只是通过尝试每个浏览器会话发送100个请求来测试性能,否则当您转到生产时会破坏您的服务器,并且30,000个浏览器x 100 = 3百万个请求命中该页面。 If you are not just testing stuff I'd seriously consider redesigning what you're doing. 如果你不只是测试东西,我会认真考虑重新设计你正在做的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM