微服务下的各个服务都是无状态的,所以这个时候tomcat的session管理功能是多余的,即时不用,也会消耗性能,关闭后tomcat的性能会有提升,但是springboot提供的tomcat没有配置选项可以直接关闭,研究了一下,tomcat默认的session管理器名字叫:StandardManager,查看tomcat加载源码发现,如果context中没有Manager的时候,直接new StandardManager(),源码片段如下:
Manager contextManager = null;
Manager manager = getManager();
if (manager == null) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("standardContext.cluster.noManager",
Boolean.valueOf((getCluster() != null)),
Boolean.valueOf(distributable)));
}
if ((getCluster() != null) && distributable) {
try {
contextManager = getCluster().createManager(getName());
} catch (Exception ex) {
log.error(sm.getString("standardContext.cluster.managerError"), ex);
ok = false;
}
} else {
contextManager = new StandardManager();
}
}
// Configure default manager if none was specified
if (contextManager != null) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("standardContext.manager",
contextManager.getClass().getName()));
}
setManager(contextManager);
}
为了不让tomcat去new自己的管理器,必须让第二行的getManager()获取到对象,所以就可以从这里入手解决,我的解决办法如下:自定义一个tomcat工厂,继承原来的工厂,context中加入自己写的manager
@Component
public class TomcatServletWebServerFactorySelf extends TomcatServletWebServerFactory {
protected void postProcessContext(Context context) {
context.setManager(new NoSessionManager());
}
}
public class NoSessionManager extends ManagerBase implements Lifecycle {
@Override
protected synchronized void startInternal() throws LifecycleException {
super.startInternal();
try {
load();
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
t.printStackTrace();
}
setState(LifecycleState.STARTING);
}
@Override
protected synchronized void stopInternal() throws LifecycleException {
setState(LifecycleState.STOPPING);
try {
unload();
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
t.printStackTrace();
}
super.stopInternal();
}
@Override
public void load() throws ClassNotFoundException, IOException {
log.info("HttpSession 已经关闭,若开启请配置:seeyon.tomcat.disableSession=false");
}
@Override
public void unload() throws IOException {}
@Override
public Session createSession(String sessionId) {
return null;
}
@Override
public Session createEmptySession() {
return null;
}
@Override
public void add(Session session) {}
@Override
public Session findSession(String id) throws IOException {
return null;
}
@Override
public Session[] findSessions(){
return null;
}
@Override
public void processExpires() {}
}
两个类解决问题,这样通过request获取session就是空了,tomcat摆脱session这层处理性能有所提升。