首页 > 解决方案 > Spring Boot 微服务中如何维护 Session

问题描述

我是 Spring MicroService 的新手,我知道如何在 Springboot 单体应用程序中处理会话,但是当我们从一个微服务与另一个微服务通信时,你能告诉我如何处理微服务中的会话,以及如果一个微服务的多个实例正在运行,如何处理会话.

标签: springmicroservices

解决方案


这是一个复杂的问题,需要编写一些额外的逻辑。所以,所有可能从一个服务调用到另一个服务的方法都应该被参数化,看起来像这样:

public int externalCall(Session session)
{
    if(sessionManager.isAliveSession(session)
    {
        sessionManager.touch(session);
        //do some actions
    } 
    else
    {
       throw new UnknownSessionException();
    }   
}

然后你应该有更多的服务或模块来处理会话。在我的代码中,我称之为 sessionManager。它可能有这样的方法:

public interface SessionManager
{
   /**
   * to create session object in database, for example, 
   * with expiration date, create date etc.
   */
   public void createSession(); 

   /**
   * to set the fact, that this session is 
   * still used and update its expiration time
   */
   public void touch(Session session); 

   /**
   * checks if session with this
   * id is not expired.
   */
   public boolean isAliveSession(Session session);  
}

这是一个如何从其他服务调用 externalCall 的示例。您将需要创建这样的类来执行基于会话的调用:

public class SessionTemplate
{
    private SessionManager sessionManager;
    private AtomicReference<SessionTO> session = new AtomicReference();

    public <T> T execute(Callback<T> callback) {
        Session session = this.getSession();

        try {
            return callback.doInSeance(session);
        } catch (UnknownSessionException e) {
            // exception may happen in externalCall method
            session = this.createSession(session);
            return callback.doInSeance(session);
        }
    }

    private Session getSession() {
        if (this.session.get() == null) {
            synchronized(this) {
                if (this.session.get() == null) {
                    this.session.set(this.createSession());
                }
            }
        }

        return (Session)this.session.get();
    }

    private Session createSession() 
    {
        // create session in your DB
        return sessionManager.createSession();
    }
}

现在您的远程调用将像这样执行:

    public int getSmthFromRemote()
    {
        return sessionTemplate.execute(session -> microService.externalCall(session));
    }

推荐阅读