【Azkaban优化】防止IP变化导致频繁登录

现状

Azkaban的 session 会根据IP地址判断,如果session的IP发生变化,则会遇到session错误。

如果session正确,而ip不正确,则会如下错误:

{
  "error": "session"
}

如果正常写业务逻辑,可能要重新登录。那么分布式场景下,多台服务器请求一台Azkaban-Web-server,
会导致什么?如果没有正确缓存session,则会导致反复重复登录。

原因

直接原因,这里发现IP和Session里面的IP不一致,则返回null。

//azkaban.webapp.servlet.LoginAbstractAzkabanServlet#getSessionFromRequest
  private Session getSessionFromSessionId(String sessionId, String remoteIp) {
    if (sessionId == null) {
      return null;
    }

    Session session = getApplication().getSessionCache().getSession(sessionId);
    // Check if the IP's are equal. If not, we invalidate the sesson.
    if (session == null || !remoteIp.equals(session.getIp())) {
      return null;
    }

    return session;
  }

在上层逻辑中:

//azkaban.webapp.servlet.LoginAbstractAzkabanServlet#doGet
    if (session != null) {
      //session正常 
    } else {
      if (hasParam(req, "ajax")) {
        HashMap<String, String> retVal = new HashMap<String, String>();
        retVal.put("error", "session");
        this.writeJSON(resp, retVal);
      } else {
        handleLogin(req, resp);
      }
    }

解决方案

有如下三种方案:

  • 优化代码,每台机器存储自己的session,不要以Azkaban的IP为key存储Azkaban Session
  • 在请求Azkaban的Header中加入X-Forwarded-For 伪装成反向代理,填入固定的IP。
  • 在Azkaban中间加入一层nginx反向代理,配置Azkaban的证书,以及固定上述Header。
proxy_set_header X-Real-IP $remote_addr; # 隐藏客户端时修改为 固定IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 隐藏客户端修改 固定IP

修复效果


Azkaban使用了Guava的缓存,只要24小时以内,访问超过一次,有效期就会延续,因此,理论上业务只要不停止,不需要再登录。
进一步说,如果Redis存储了Session,并且在有效期内、没有过期,那么服务重启也不会影响。

posted @ 2022-01-20 15:17  一杯半盏  阅读(218)  评论(0编辑  收藏  举报