HAProxy は tomcat に ping を実行し、非常に小さなページを要求しているため、Tomcat は 2 秒ごとに新しいセッションを作成します。特定のページに対して新しいセッションを作成しないように Tomcat にプログラムで (または構成を介して) 指示する方法はありますか?
5 に答える
何も実装する必要はありません。既に存在しています ;)!
Tomcat コンテナーはCrawler Session Manager Valveを提供します(valve は HttpServletFilter と同じですが、Tomcat コンテナー (下位レベル) 内にあります)。詳細については、http://tomcat.apache.org/tomcat-7.0-doc/config/valve.htmlを参照してください。 #Crawler_Session_Manager_Valve
<Valve>タグを tomcat の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
はいあります。少し複雑ですが、私たちにとってはうまくいきます。
基本的に、セッションのフィルター チェーンを変更します。これは、ボット (Google、Pear、Yahoo) に対して行います。
新しい Filter を作成して登録し、次のソースを 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;
}
}
これら 2 つのクラスは、ボットが指定された制限時間内に同じ IP を使用して再び接続した場合、ボットが以前に持っていたセッションを再利用します。これがボットが受信するデータに何をもたらすかは 100% わかりませんが、このコードは現在何ヶ月も実行されており、問題 (Google からの IP ごとに 1 秒あたり複数の接続/セッション) を解決しているためです。
誰かが助けようとする前に: 問題はウェブマスター インターフェースを介して Google に何度も送信されています。クロール間隔は可能な限り低い設定に下げられ、この問題が存在する理由についてのヒントなしに、適切なフォーラムで 3x 返信スレッドが生成されました。
アプリケーションページに向けないでください。httpchk が JSP ページをプルしている場合、セッションが作成されます。
httpchk の静的 HTML ページで HAProxy を指定できますか?
または、検証する必要があるヘルスをチェックするサーブレットを作成しますが、セッションは作成しません。(アラHttpServletRequest.getSession(false)
)
session=false
JSP にディレクティブを追加するだけです。
<%@ page session="false"%>
このページは通常のWebアプリの一部ですか、それともスタンドアロンのWebアプリの一部ですか?
ページがスタンドアロンのWebアプリの一部である場合、つまりそのページのみがそのアプリに存在する場合は、そのアプリのweb.xmlで低いセッションタイムアウトを設定できます。Liek2分以下。
それ以外の場合、Tomcat側の問題に対する解決策はありません。以前のセッションIDがリクエストと一緒に送信されない場合、Tomcatは新しいセッションを作成します。