论坛首页 Java企业应用论坛

spring3mvc与struts2比较

浏览 162474 次
该帖已经被评为良好帖
作者 正文
   发表时间:2010-04-29  
现在JavaScript框架这么流行,JSF的地位就更加尴尬了。

SpringMVC的零配置用起来很爽,但到了后期就发现,用配置文件其实还是有用的。。。至少管理起来比较集中

还有,牛的框架不一定能流行的。。Struts1跟webwork就是一个例子
0 请登录后投票
   发表时间:2010-05-08  
wen66 写道
spring3与struts2有很大的区别, 最近我们在struts2.1及spring3.0.2上做过压力测试, 发现struts2.1在默认的配制下存在严重的性能问题. 每秒的点击数不会超过200, 而如果用struts2的dispatchServlet去拦截带有参数的jsp如(http://localhost/myapp/my.jsp?para1=1&para2=2) 这样的url时, 在大并发时, 存在很严重的内存泄漏的问题. 用jprofile可以发现java.util.concurrent.concurrenthashmap占用了大量的内存, 同时java.util.concurrent.locks也占用了大量的内存. 原因估计为struts2里面的参数转化拦截器出了问题(没有得到求证).

而在spring3的mvc下(restful), 会存在一个问题就是, 如果我要直接转向我的 http://localhost/myapp/model1/my.jsp 时如果我不在mvc配制文件下配制下配制, 那它怎么进行转向, 这也是一个问题. 也就是说我增加一个jsp, 还要改配制文件, 这很烦啊. 或者说是我没有发现有别的方法可做, 请大家指教.

总共来说: 在高并发的情况下, strut2慎用, spring3可以大胆使用. spring3在性能和内存使用上都不会存在问题(这点我们是经过压力测试的). spring3 mvc可以达到每秒3000的并发点击. (当然经过的controller是很简单的, 没有业务逻辑在里面), 且内存可以正常回收. 

是不是真的哟,不要吓我撒!
0 请登录后投票
   发表时间:2010-05-08  
小刘而已 写道
wen66 写道
spring3与struts2有很大的区别, 最近我们在struts2.1及spring3.0.2上做过压力测试, 发现struts2.1在默认的配制下存在严重的性能问题. 每秒的点击数不会超过200, 而如果用struts2的dispatchServlet去拦截带有参数的jsp如(http://localhost/myapp/my.jsp?para1=1&para2=2) 这样的url时, 在大并发时, 存在很严重的内存泄漏的问题. 用jprofile可以发现java.util.concurrent.concurrenthashmap占用了大量的内存, 同时java.util.concurrent.locks也占用了大量的内存. 原因估计为struts2里面的参数转化拦截器出了问题(没有得到求证).

而在spring3的mvc下(restful), 会存在一个问题就是, 如果我要直接转向我的 http://localhost/myapp/model1/my.jsp 时如果我不在mvc配制文件下配制下配制, 那它怎么进行转向, 这也是一个问题. 也就是说我增加一个jsp, 还要改配制文件, 这很烦啊. 或者说是我没有发现有别的方法可做, 请大家指教.

总共来说: 在高并发的情况下, strut2慎用, spring3可以大胆使用. spring3在性能和内存使用上都不会存在问题(这点我们是经过压力测试的). spring3 mvc可以达到每秒3000的并发点击. (当然经过的controller是很简单的, 没有业务逻辑在里面), 且内存可以正常回收. 

是不是真的哟,不要吓我撒!

默认拦截器应该精简一下,把不用的拦截器去掉即可。
0 请登录后投票
   发表时间:2010-05-10  
楼主可以提供点资料吗?比如做好的简单项目啊!还有些关于这方面的资料!
0 请登录后投票
   发表时间:2010-06-05  
最近有新项目(企业应用的,非网站运营类),web端在考虑使用struts2还是spring mvc 。以前的项目用过 struts2 和 GWT 。
(1) JSF:肯定是不用. 06年时考察过jsf,一看页面所有组件的对象生命周期都由服务器端维护,一想,老外就是牛逼,服务器配置真高,否则那敢想这方面的事件驱动?而我们的服务器可没有这么好。当时seam还没有成熟版本发布。
(2)GWT: 由于业务操作复杂,一个页面需要处理很多树,就使用了富客户端中的 GWT技术。用了两年。编译打包问题太大,项目业务界面不复杂了,不想继续用了。
(3)Struts2:用了两年了,没有发现什么大问题。
(4)Spring MVC: 既然WEB端Action管理使用了Spring,那就一套,页面流部分也使用 Spring 带的MVC好了。 其实 struts2和spring mvc没有什么差别。要想系统跑得棒,那些拦截器、过滤器、AOP什么之类的,最好少用。否则,又懒写代码,又想性能好,天底下有这么免费的好事?

等我再使用半年 spring mvc ,看看什么情况。

0 请登录后投票
   发表时间:2010-06-10  
拜读spring3的mvc
0 请登录后投票
   发表时间:2010-06-16   最后修改:2010-06-16
wen66 写道
spring3与struts2有很大的区别, 最近我们在struts2.1及spring3.0.2上做过压力测试, 发现struts2.1在默认的配制下存在严重的性能问题. 每秒的点击数不会超过200, 而如果用struts2的dispatchServlet去拦截带有参数的jsp如(http://localhost/myapp/my.jsp?para1=1&para2=2) 这样的url时, 在大并发时, 存在很严重的内存泄漏的问题. 用jprofile可以发现java.util.concurrent.concurrenthashmap占用了大量的内存, 同时java.util.concurrent.locks也占用了大量的内存. 原因估计为struts2里面的参数转化拦截器出了问题(没有得到求证).



你测试的时候有没有加cookie管理器(我假设你用jmeter, 因为你并没有说你是使用什么工具进行测试的)?
如果不加的话, 那么每次请求tomcat(我假设你用tomcat, 因为你没有说你用什么servlet容器)都会创建一个httpsession, tomcat中的实现类为StandardSession,这个对象又会放到StandardManager里的一个叫做sessions的变量里, sessions是一个ConcurrentHashMap, StandardSession里放attribute的又是一个ConcurrentHashMap, 所以如果你没有加cookie就请求30w次, 那么你就产生了30w个StandardSession对象, 每个StandardSession里有一个ConcurrentHashMap, 也就是说会产生30w个ConcurrentHashMap. ConcurrentHashMap使用的是锁分离技术, 一个ConcurrentHashMap里有16个segment(一个segment是一把lock), 那也是什么java.util.concurrent.locks占用了大量的内存的原因.

所以这个并不是struts2.0有问题(为每个cookie中没有sessionid的请求都创建一个httpsession的行为也不能说是一个什么严重的问题), 而是你的测试有问题. 你只要加上cookie来测试(jsessionid在cookie里), 你就不会有这么多StandardSession对象了, 进而也不会有那么多ConcurrentHashMap, 也不会有那么多lock. 也不会占那么多内存.

所以据我推断, 应该是你的测试方法有问题, 而并非是struts2.0有问题, 还有struts2里貌似也没有DispatchServlet这个类.

0 请登录后投票
   发表时间:2010-06-16  
ahuaxuan 写道
wen66 写道
spring3与struts2有很大的区别, 最近我们在struts2.1及spring3.0.2上做过压力测试, 发现struts2.1在默认的配制下存在严重的性能问题. 每秒的点击数不会超过200, 而如果用struts2的dispatchServlet去拦截带有参数的jsp如(http://localhost/myapp/my.jsp?para1=1&para2=2) 这样的url时, 在大并发时, 存在很严重的内存泄漏的问题. 用jprofile可以发现java.util.concurrent.concurrenthashmap占用了大量的内存, 同时java.util.concurrent.locks也占用了大量的内存. 原因估计为struts2里面的参数转化拦截器出了问题(没有得到求证).



你测试的时候有没有加cookie管理器(我假设你用jmeter, 因为你并没有说你是使用什么工具进行测试的)?
如果不加的话, 那么每次请求tomcat(我假设你用tomcat, 因为你没有说你用什么servlet容器)都会创建一个httpsession, tomcat中的实现类为StandardSession,这个对象又会放到StandardManager里的一个叫做sessions的变量里, sessions是一个ConcurrentHashMap, StandardSession里放attribute的又是一个ConcurrentHashMap, 所以如果你没有加cookie就请求30w次, 那么你就产生了30w个StandardSession对象, 每个StandardSession里有一个ConcurrentHashMap, 也就是说会产生30w个ConcurrentHashMap. ConcurrentHashMap使用的是锁分离技术, 一个ConcurrentHashMap里有16个segment(一个segment是一把lock), 那也是什么java.util.concurrent.locks占用了大量的内存的原因.

所以这个并不是struts2.0有问题(为每个cookie中没有sessionid的请求都创建一个httpsession的行为也不能说是一个什么严重的问题), 而是你的测试有问题. 你只要加上cookie来测试(jsessionid在cookie里), 你就不会有这么多StandardSession对象了, 进而也不会有那么多ConcurrentHashMap, 也不会有那么多lock. 也不会占那么多内存.

所以据我推断, 应该是你的测试方法有问题, 而并非是struts2.0有问题, 还有struts2里貌似也没有DispatchServlet这个类.



我用的是loadrunner进行测试的, 应该不会存在你所说的cookie的问题, servlet容量用的是tomcat6. 如果是tomcat对session管理的问题, 那么在spring3的那个例子里, 应该也会占用那么高的内存, 而事实上却没有出现这样的情况. 只在struts2的那个例子里出现了. 对了, 说一下, 我用的strut2的版本是2.0.11
0 请登录后投票
   发表时间:2010-06-16   最后修改:2010-06-16
wen66 写道


我用的是loadrunner进行测试的, 应该不会存在你所说的cookie的问题, servlet容量用的是tomcat6. 如果是tomcat对session管理的问题, 那么在spring3的那个例子里, 应该也会占用那么高的内存, 而事实上却没有出现这样的情况. 只在struts2的那个例子里出现了. 对了, 说一下, 我用的strut2的版本是2.0.11

恰恰我觉得是会, 从你的回复得知你应该没有对loadrunner做什么cookie方面的配置, 只要没有sessionId过去, struts2会为每次请求都调用httpservletrequest.getSession(true);这表示如果请求中不带sessionid,也找不到这个请求的session, 那就为这个请求创建一个session.所以如果你的loadrunner没有做相应的cookie的设置,那么struts2.0+tomcat的时候大量的session就产生了。

而spring mvc之所以没有出现这个问题, 是因为spring mvc应该没有主动在框架里调用httpservletrequest.getSession(true);这个方法, 所以如果你不手动调用这个方法的话, spring+tomcat的环境下, 即使你的请求中不带sessionid, 那么也不回出现大量的session在ConcurrentHashMap中的情况。



11 请登录后投票
   发表时间:2010-06-16  
谢谢ahuaxuan的测试。不过我查看了一下Struts2中的源码,没有显示调用createSession(true)的代码。


    /**
     * Creates a new session map given a http servlet request. Note, ths enumeration of request
     * attributes will occur when the map entries are asked for.
     *
     * @param request the http servlet request object.
     */
    public SessionMap(HttpServletRequest request) {
        // note, holding on to this request and relying on lazy session initalization will not work
        // if you are running your action invocation in a background task, such as using the
        // "execAndWait" interceptor
        this.request = request;
        this.session = request.getSession(false);
    }

    /**
     * Saves an attribute in the session.
     *
     * @param key   the name of the session attribute.
     * @param value the value to set.
     * @return the object that was just set.
     */
    public V put(K key, V value) {
        synchronized (this) {
            if (session == null) {
                session = request.getSession(true);
            }
        }

        synchronized (session) {
            entries = null;
            session.setAttribute(key.toString(), value);

            return get(key);
        }
    }



所以除非Struts2中有显示调用put的代码,否则恐怕不会去调用createSession(true)的代码。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics