2011-10-10 77 views

回答

10

你不需要執行任何操作,它已經存在了;)!

Tomcat容器提供履帶式會話管理器閥(閥就像HttpServletFilter,但Tomcat容器(下級)。 裏面你可以在這裏找到更多的細節http://tomcat.apache.org/tomcat-7.0-doc/config/valve.html#Crawler_Session_Manager_Valve

你只需要添加<閥門>標記到您的tomcat的server.xml,並且正確配置。請記住爲bot用戶代理提供正則表達式。

例如

<Valve className="org.apache.catalina.valves.CrawlerSessionManagerValve" 
crawlerUserAgents=".*googlebot.\*|.*yahoo.*" sessionInactiveInterval="600"/> 

你可以看一下閥門的源代碼:http://grepcode.com/file/repo1.maven.org/maven2/org.apache.tomcat/tomcat-catalina/7.0.11/org/apache/catalina/valves/CrawlerSessionManagerValve.java

3

不要將它指向您的應用程序頁面。如果httpchk正在拉一個JSP頁面,它將創建一個會話。

您可以將HAProxy指向您的httpchk的靜態HTML頁面嗎?

另外,創建一個servlet來檢查您需要驗證的任何健康狀況,但不會創建會話。 (àla HttpServletRequest.getSession(false)

1

此頁面是普通網頁應用程序還是獨立網頁應用程序的一部分?

如果頁面是獨立Web應用程序的一部分,即只有該頁面存在於該應用程序中,則可以在該應用程序的web.xml中設置較低的會話超時。列克2分鐘甚至更低。

否則,在Tomcat結束時沒有解決您的問題的方法。如果先前的會話ID未與請求一起發送,Tomcat將創建一個新的會話。

4

是的,有。這有點複雜,但適合我們。

基本上,我們更改會話的過濾器鏈。我們爲機器人(谷歌,梨,雅虎)做到這一點。

創建一個新的過濾器,並進行註冊,然後使用此源過濾器類:

public class BotFilter implements javax.servlet.Filter { 
    private int inactive_seconds = 5*60; 
    private String[] bots = new String[] { "googlebot", //google 
    "msnbot", //msn 
    "slurp", //yahoo 
    "libcurl", //curl, sometimes used with bigbrother 
    "bigbrother", //bigbrother availability check 
    "whatsup", //whatsup availability check 
    "surveybot", //unknown 
    "wget", // nocomment 
    "speedyspider", //http://www.entireweb.com/about/search_tech/speedyspider/ 
    "nagios-plugins", //Alle Nagios-Abfragen 
    "pear.php.net", //Irgendwelcher PHP-Scheiß 
    "mj12bot", //http://www.majestic12.co.uk/projects/dsearch/mj12bot.php 
    "bingbot", //M$ Bing 
    "dotbot", //We are just a few Seattle based guys trying to figure out how to make internet data as open as possible. 
    "aggregator:spinn3r", //http://spinn3r.com/robot 
    "baiduspider" //http://www.baidu.com/search/spider.htm 
    }; 
    private HashMap<String, HttpSession> botsessions; 

    public BotFilter() { 
    this.botsessions = new HashMap<String, HttpSession>(); 
    } 

    public void init(FilterConfig config) throws ServletException { 

    } 

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain next) throws IOException, ServletException { 
    if (request instanceof HttpServletRequest) { 
     HttpServletRequest httprequest = (HttpServletRequest) request; 
     try { 
     String useragent = ((HttpServletRequest) request).getHeader("User-Agent"); 
     if (useragent == null) { 
      ((HttpServletResponse) response).sendRedirect("http://www.google.com"); 
     } 
     useragent = useragent.toLowerCase(); 
     if (httprequest.getSession(false) == null) { 
     } 
     for (int i = 0; i < this.bots.length; i++) { 
      if (useragent.indexOf(this.bots[i]) > -1) { 
      String key = httprequest.getRemoteAddr() + useragent; 
      boolean SessionIsInvalid=false; 
      synchronized(this.botsessions) { 
       try { 
       if(this.botsessions.get(key)!=null) 
        this.botsessions.get(key).getAttributeNames(); 
       } catch (java.lang.IllegalStateException ise) { 
       SessionIsInvalid = true; 
       } 
       if(this.botsessions.get(key)==null||SessionIsInvalid) { 
       httprequest.getSession().setMaxInactiveInterval(this.inactive_seconds); 
       if(SessionIsInvalid) 
        this.botsessions.remove(key); //Remove first, if in there 
       this.botsessions.put(key, httprequest.getSession()); //Then add a little spice 
       } else { 
       next.doFilter(new BotFucker(httprequest, this.botsessions.get(key)), response); 
       return; 
       } 
      } 
      }; 
     } 
     } catch (Exception e) { 
     //Error handling code 
     } 
    } 
    next.doFilter(request, response); 
    } 

    public void destroy() { 

    } 
} 

而這個小傢伙對重定向類:

public class BotFucker extends HttpServletRequestWrapper { 

    HttpSession session; 

    public BotFucker(HttpServletRequest request, HttpSession session) { 
    super(request); 
    this.session = session; 
    } 
    @Override 
    public HttpSession getSession(boolean create) { 
    return this.session; 
    } 
    @Override 
    public HttpSession getSession() { 
    return this.session; 
    } 
} 

這兩個類再利用如果它們在給定的時間限制內使用相同的IP再次連接,那麼這些機器人之前的會話。我們並不是100%確定這對bot收到的數據有什麼影響,但是因爲此代碼現在運行了好幾個月,並且解決了我們的問題(每個來自Google的每秒IP連接數/會話數)。

而之前有人試圖幫助:該問題已多次提交給谷歌通過網站管理員界面。抓取時間間隔已降至最低可能的設置,並且問題在相應的論壇上產生了3次回覆帖,沒有提示存在這個問題的原因。

2

只是在JSP中添加session=false指令。

<%@ page session="false"%> 
+0

本來是很高興知道當時....我通常使用playframework代替相比,Tomcat的200M左右,它飛......多得更快的佔用僅20MB左右或更低。 –