HAProxy正在ping tomcat并请求一个非常小的页面,导致Tomcat每2秒创建一个新会话。有没有办法以编程方式(或通过配置)告诉Tomcat不为特定页面创建新会话?
答案 0 :(得分:12)
你不需要实现任何东西,它已经存在;)!
Tomcat容器提供 Crawler会话管理器阀(阀门就像HttpServletFilter,但在Tomcat容器内(下层)。 您可以在http://tomcat.apache.org/tomcat-7.0-doc/config/valve.html#Crawler_Session_Manager_Valve
找到更多详细信息您只需使用正确的配置将< Valve> 标记添加到tomcat的 server.xml 。请记住为bot用户代理提供正则表达式。
例如
<Valve className="org.apache.catalina.valves.CrawlerSessionManagerValve"
crawlerUserAgents=".*googlebot.\*|.*yahoo.*" sessionInactiveInterval="600"/>
答案 1 :(得分:4)
是的,有。这有点复杂,但对我们来说效果很好。
基本上,我们更改会话的过滤器链。我们为机器人(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;
}
}
如果这两个类在给定的时间限制内使用相同的IP再次连接,则这两个类重新使用机器人之前的会话。我们并不是百分之百确定它对机器人收到的数据有何影响,但是由于此代码现在运行了很多个月并且解决了我们的问题(每个IP每秒多个连接/会话)。
在有人试图提供帮助之前:问题已通过网站管理员界面多次提交给Google。爬行间隔已降低到可能的最低设置,问题在相应的论坛上产生了3x回复线程,没有任何暗示为什么存在此问题。
答案 2 :(得分:3)
请勿将其指向您的申请页面。如果httpchk正在拉动JSP页面,它将创建一个会话。
您可以将HAProxy指向httpchk的静态HTML页面吗?
Aiternatively,创建一个servlet,检查您需要验证的健康状况,但不创建会话。 (àlaHttpServletRequest.getSession(false)
)
答案 3 :(得分:2)
只需在JSP中添加session=false
指令即可。
<%@ page session="false"%>
答案 4 :(得分:1)
此页面是常规网络应用程序还是独立网络应用程序的一部分?
如果页面是独立Web应用程序的一部分,即该应用程序中只存在该页面,则可以在该应用程序的web.xml中设置低会话超时。列克2分钟甚至更低。
否则,Tomcat端的问题无法解决。如果没有与请求一起发送较早的会话ID,Tomcat将创建一个新会话。