【问题标题】:how to make spring boot rest api as stateful如何使spring boot rest api有状态
【发布时间】:2019-05-03 18:41:38
【问题描述】:

我想用 REST 和 Spring Boot 制作 Web 应用程序。 Rest Web 服务是无状态的。我想让它成为有状态的,以便在第一次请求后发送给客户端的信息服务器应该在即将到来的请求中使用。或者在第一个或第二个请求中完成的执行将被进一步使用。 我们可以为此生成一些会话 ID,并且此会话 ID 客户端可以在后续请求中发送到服务器吗?如果是,那么 如果某些对象/bean的状态正在改变(由于某些操作而修改了值)。那么我们如何保存对象/bean的状态顺序以使其具有状态以及这些bean的范围是什么(其值将被修改)以及那些将调用这些bean作为多个客户端或用户的类/bean将是使用这个网络应用程序?

【问题讨论】:

  • 能否请您更明确地回答您的问题?并提供一些你已经采取的例子。
  • nit:如果它是有状态的,那么根据定义它不是 REST。
  • @JonathanJohx - 我还没有写任何代码,我还在做设计。我的问题的第一部分是,我们可以使用 spring-boot 作为有状态的 rest api 吗?可能是通过创建一些会话 ID 或令牌,客户端可以在不同/进一步调用我的 Web api 时使用它们?
  • 没关系,谢谢。所以我同意@Krease。

标签: java rest spring-boot javabeans stateful


【解决方案1】:

Restful API 在设计上不是有状态的,如果您使用服务器端使它们有状态,那么它就不是 REST!

您需要一个相关 ID,它是分布式系统设计中公认的模式。相关 ID 可让您将请求捆绑在一起。

【讨论】:

    【解决方案2】:

    会话通常是一种优化,可在运行多个服务器时提高性能。它们通过确保客户端请求始终发送到缓存了客户端数据的同一服务器来提高性能。

    如果您只想运行单个服务器,则不必担心会话。有两种常见的方法可以解决这个问题。

    1。处于记忆状态

    如果您要维护的状态小到足以放入内存,并且您不介意在服务器崩溃或重新启动时丢失它,则可以将其保存在内存中。您可以创建一个包含数据结构的 spring 服务。然后您可以将该服务注入您的控制器并更改您的 http 处理程序中的状态。

    服务默认是单例的。因此,所有控制器、组件和用户请求都可以访问存储在服务中的状态。下面是一个小的伪示例。

    服务类

    @Service
    public class MyState
    {
      private Map<String, Integer> sums = new HashMap<>();
    
      public synchronized int get(String key) {
        return sums.get(key);
      }
    
      public synchronized void add(String key, int val) {
        int sum = 0;
    
        if (sums.contains(key)) {
          sum = sum.get(key);
        }
    
        sum += val;
    
        sums.put(key, (Integer)sum);
      }
    }
    

    控制器类

    @RestController
    @RequestMapping("/sum")
    public class FactoryController
    {
      @Autowired
      private MyState myState;
    
      @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
      @ResponseStatus(HttpStatus.OK)
      @ResponseBody
      public SuccessResponse saveFactory(@RequestBody KeyVal keyVal)
      {
        myState.add(keyVal.getKey(), keyVal.getValue());
      }
    }
    

    注意:如果您在负载平衡器后面运行多个服务器,则此方法将不起作用,除非您使用更复杂的解决方案,例如分布式缓存。在这种情况下,可以使用会话来优化性能。

    2。数据库

    另一种选择是仅使用数据库来存储您的状态。这样,如果您崩溃或重新启动,您就不会丢失数据。 Spring 支持 hibernate 持久化框架,你可以运行类似 Postgres 的数据库。

    注意:如果您正在运行多个服务器,您将需要一个更复杂的解决方案,因为 hibernate 将数据缓存在内存中。您必须将 hibernate 插入分布式缓存以在多个服务器之间同步内存状态。会话在这里可以用作性能优化。

    重要

    每当您修改状态时,您需要确保以线程安全的方式进行,否则您的状态可能不正确。

    【讨论】:

      猜你喜欢
      • 2023-03-17
      • 2017-02-25
      • 2020-09-12
      • 1970-01-01
      • 2015-12-09
      • 2021-08-28
      • 2019-03-11
      • 1970-01-01
      • 2014-08-09
      相关资源
      最近更新 更多