Tomcat: Как остановить Tomcat, создавая сеанс для всех запросов? - PullRequest
3 голосов
/ 10 октября 2011

HAProxy пингует tomcat и запрашивает очень маленькую страницу, заставляющую Tomcat создавать новый сеанс каждые 2 секунды.Есть ли способ программно (или через конфиг) сказать Tomcat не создавать новый сеанс для конкретной страницы?

Ответы [ 5 ]

12 голосов
/ 21 ноября 2012

Вам не нужно ничего реализовывать, это уже есть;)!

Контейнер Tomcat предоставляет Клапан диспетчера сеансов Crawler (клапан похож на HttpServletFilter, но внутри контейнера Tomcat (нижний уровень). Вы можете найти более подробную информацию здесь http://tomcat.apache.org/tomcat-7.0-doc/config/valve.html#Crawler_Session_Manager_Valve

Вы просто добавляете тег в server.xml вашего кота с правильной конфигурацией. Не забудьте предоставить регулярные выражения для агентов пользователей ботов.

Например

<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

4 голосов
/ 10 октября 2011

Да, есть.Это немного сложно, но у нас хорошо работает.

По сути, мы меняем цепочку фильтров для сессий.Мы делаем это для ботов (Google, Pear, Yahoo).

Создайте новый фильтр и зарегистрируйте его, затем используйте этот источник для класса Filter:

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%, что это делает с данными, которые получает бот, но этот код работает уже много месяцев и решил нашу проблему (несколько соединений / сессий в секунду на IP от Google).

И прежде чем кто-то попытается помочь: проблема была отправлена ​​в Google несколько раз через интерфейс веб-мастера.Интервал сканирования был уменьшен до минимально возможного значения, и проблема породила 3-х кратную ветку ответов на соответствующем форуме без каких-либо подсказок о том, почему существует эта проблема.

3 голосов
/ 10 октября 2011

Не указывайте это на страницах вашего приложения. Если httpchk тянет страницу JSP, он создаст сеанс.

Можете ли вы указать HAProxy на статическую HTML-страницу для вашего httpchk?

С другой стороны, создайте сервлет, который проверяет любое состояние здоровья, которое необходимо проверить, но не создает сеанс. (à la HttpServletRequest.getSession(false))

2 голосов
/ 19 апреля 2013

Просто добавьте директиву session=false в JSP.

<%@ page session="false"%>
1 голос
/ 10 октября 2011

Является ли эта страница частью обычного веб-приложения или автономного веб-приложения?

Если страница является частью автономного веб-приложения, то есть в этом приложении существует только та страница, вы можете установить малое время ожидания сеансав web.xml для этого приложения.Подожди 2 минуты или даже меньше.

В противном случае, у вас не будет решения вашей проблемы на стороне Tomcat.Tomcat создаст новый сеанс, если более ранний идентификатор сеанса не будет отправлен вместе с запросом.

...