解惑

解己之惑,解人之惑

标签:Tomcat

Apache2.2和tomcat集成更加简单了

Apache2.2新增加了几个module,和tomcat集成更加的简单了:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_http_module modules/mod_proxy_http.so

ProxyRequests Off

ProxyPass / balancer://myCluster/
<Proxy balancer://myCluster/>
       BalancerMember ajp://localhost:10009 route=tomcat1
       BalancerMember ajp://localhost:20009 route=tomcat2
</Proxy>

The method getXxx() is undefined for the type Yyy

今天遇到这个问题都快崩溃了,那个方法明明定义了,在JSP中用反射拿到类声明的全部方法并打印出来都可以看到的,但是修改回来后就是编译不过。
Google了下,也是很多人遇到,但是没有人解决,有人说是tomcat的问题,不太相信。
突然想到我的工程是hot deploy的,那个class有两份,一份新的一份旧的,jboss的tomcat在编译那个JSP时用的是旧的类,运行时用的是我Hot deploy的新的类定义。
重新编译发布整个工程,问题解决。

Tomcat集群概要

其实已经有很多文档了,不过还是老话,给自己备忘,总结些要注意的要点,给一些范例,以后肯定用得着。

以JK作为Apache和Tomcat的连接器,首先配置的是Apache的httpd.conf,主要是加载JK和配置转发规则:
加载和配置JK:
阅读全文

Pluto的session问题

按照JSR168规范的说明,在Portlet中,我们可以通过PortletSession访问存储在HttpSession中的属性,我看了Pluto的实现,也确实是这样做的:
    // PortletSession Impl: Attributes —————————————–
   
    public Object getAttribute(String name) {
        return getAttribute(name, DEFAULT_SCOPE);
    }
   
    /**
     * Returns the attribute of the specified name under the given scope.
     *
     * @param name  the attribute name.
     * @param scope  the scope under which the attribute object is stored.
     * @return the attribute object.
     */
    public Object getAttribute(String name, int scope) {
        ArgumentUtility.validateNotNull("attributeName", name);
        String key = (scope == PortletSession.APPLICATION_SCOPE)
                ? name : createPortletScopedId(name);
        return httpSession.getAttribute(key);
    }

但是当我把pluto集成到我们的应用里面的时候,问题就来了,用户登录后,访问其它的页面和访问portlet的页面的时候的session id是不同的,历经磨难,找到一些前人的文章:

 
From testing with Jetspeed/Pluto on Tomcat 5.0 and the default configuration of 5.5, servlets accessed directly do not share the portlet session. In Tomcat 5.5 configured with emptySessionPath="true", behaviour is correct as described in the portlet specification.

So, to summarize what I’ve learned, if you need to pass session objects from a portlet to a servlet using Pluto as your servlet container, the following three conditions must all be true:

  1. You must run Tomcat 5.5.x, or later.
  2. You must set crossContext="true" in your web app’s element.
  3. You must set emptySessionPath="true" in the element in Tomcat’s server.xml file.

If you omit any one of these three steps, it won’t work.

所以问题的核心就是emptySessionPath,在我们的环境中使用的是tomcat5.0,crossContext是设置为true的。

2007年3月21日下午更新:
集成中的问题是我犯了一个错误,我在获取HttpSession中的属性的时候忘了应该使用APPLICATION_SCOPE,而不同的session id是因为我的另外的代码导致的(我写了一个Bridge类去获得Struts的Action的执行结果并输出,在Bridge中的请求相当于另外一个客户端)。
从Portlet中,使用RenderRequest..getPortletSession().getAttribute("xxxx", PortletSession.APPLICATION_SCOPE)就可以拿到其它的普通servlet和jsp中设置的值了。

将Pluto1.1发布到Tomcat5.0

上次也已经提到了很难将Pluto1.1发布到Tomcat5.0,经过另外几个小时的艰苦努力,总算是成功了。
第一是因为它使用了一个JDK1.5的API,解决方法是修改org.apache.pluto.core.ContainerInvocation,将CONTAINERS.remove();注释掉。(可能有潜在的问题,猜测可能是会有内存泄漏)
第二是它提供的参考实现的war包的配置使用了testsuite那个应用,必须修改pluto-portal-driver-config.xml,删除其中对testsuite应用的portlet的引用:
<?xml version="1.0" encoding="UTF-8"?>

<pluto-portal-driver
    xmlns="http://portals.apache.org/pluto/xsd/pluto-portal-driver-config.xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://portals.apache.org/pluto/xsd/pluto-portal-driver-config.xsd
                        http://portals.apache.org/pluto/xsd/pluto-portal-driver-config.xsd"
    version="1.1">

    <portal-name>pluto-portal-driver</portal-name>
    <portal-version>1.1.0</portal-version>
    <container-name>Pluto Portal Driver</container-name>

    <supports>
        <portlet-mode>view</portlet-mode>
        <portlet-mode>edit</portlet-mode>
        <portlet-mode>help</portlet-mode>
        <portlet-mode>config</portlet-mode>

        <window-state>normal</window-state>
        <window-state>maximized</window-state>
        <window-state>minimized</window-state>
    </supports>

    <!– Render configuration which defines the portal pages. –>
    <render-config default="About Pluto">
        <page name="About Pluto"
            uri="/WEB-INF/themes/pluto-default-theme.jsp">
            <portlet context="/pluto" name="AboutPortlet" />
        </page>
        <page name="Pluto Admin"
            uri="/WEB-INF/themes/pluto-default-theme.jsp">
            <portlet context="/pluto" name="PlutoPageAdmin" />
            <portlet context="/pluto" name="AboutPortlet" />
        </page>
    </render-config>

</pluto-portal-driver>

阅读全文

痛苦的Pluto使用经历

项目中要使用到Pluto,今天研究了一下,但是经历着实痛苦。
我们的tomcat使用的是古老的jboss带的版本,我就用我自己安装的tomcat5.0.28做了下试验,结果不成功,后来下载了一个bundle版本,其实就是已经包含了tomcat的版本,但是它带的版本是5.5.20,我就对照了下,把我能看出来的不同都对应的在tomcat5.0.28下做了修改,应用是可以跑起来了,但是登录进首页的时候出了一个NullPointerException,原因不明也没有那么多时间去研究,后来就下载了老版本的1.0.1试验,结果应用都不能起来。没有办法,只能从原代码编译试试,又去下载maven,结果使用JDK1.4无法编译,它的代码中使用了一个JDK1.5才有的方法,手工修改源代码,编译通过了,但是在安装的时候又出了问题,报告pluto的一个plugin不存在。然后又下载pluto的1.0.1版本的原代码,又下载maven1.0.2版本编译,依然不成功,原因是不能解析project.xml文件,彻底无语了。

更新:
回家后又弄了一下,终于在tomcat5.0.28下成功手工发布了pluto1.1,问题是我依然要使用JDK1.5才能看到结果运行正常,使用JDK1.4时会出现编译pluto1.1时遇到的那个问题的运行期版本。步骤为将bundle版本下的文件拷贝到tomcat5.0.28的对应目录:

  • conf\Catalina\localhost\pluto.xml
  • \shared\lib
  • \PlutoDomain\pluto-portal-1.1.0.war
  • 编辑tomcat-users.xml文件,增加pluto用户

要解决JDK版本问题,可能的办法就是修改源代码(pluto-1.1.0-src\pluto-container\src\main\java\org\apache\pluto\core\ContainerInvocation.java,把64行注释掉就行)后在JDK1.4下编译,然后把那个有问题的类替换掉,当然可能会有其他的问题。

优化tomcat

主要是修改http Connector的一些参数,我认为比较主要的有:
maxThreads:可以创建的用来处理请求的最大线程数,这个是在服务器负载没有完全发挥出来时可以调整的最重要的参数,默认是200,建议可以开到500左右。
bufferSize:请求的输入流的缓存大小,默认是2K,建议可以开到10K左右,特别是对于发布大文本内容而言。
connectionTimeout:连接超时的时间,默认是60秒,建议修改为20秒

© 2019 解惑

本主题由Anders Noren提供向上 ↑