簡體   English   中英

如何使Spring Boot Rest API具有狀態

[英]how to make spring boot rest api as stateful

我想使用REST和Spring Boot來制作Web應用程序。 其余Web服務是無狀態的。 我想使其狀態化,以便在即將到來的請求中使用第一個請求后信息服務器發送給客戶端。 否則將在第一個或第二個請求中完成執行。 我們可以為此生成一些會話ID,並且該會話ID客戶端可以在后續請求中將其發送給服務器嗎? 如果是,則某些對象/ bean的狀態正在更改(值由於某些操作而被修改)。 因此,我們如何保存對象/ bean的狀態順序以使其成為有狀態的,這些bean的范圍是什么(將修改其值),以及將作為多個客戶端或用戶調用這些bean的類/ bean將成為對象?使用此Web應用程序?

會話通常是一種優化,可以在運行多台服務器時提高性能。 它們通過確保始終將客戶端請求發送到已緩存客戶端數據的同一服務器來提高性能。

如果您只想運行一台服務器,則不必擔心會話。 解決此問題有兩種常用方法。

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支持休眠持久性框架,您可以運行Postgres之類的數據庫。

注意:如果您正在運行多個服務器,則由於休眠模式會將數據緩存在內存中,因此您將需要一個更復雜的解決方案。 您將必須將hibernate插入分布式緩存中,以在多個服務器之間同步內存狀態。 會話可以在此處用作性能優化。

重要

每當您修改狀態時,都需要確保以線程安全的方式進行操作,否則狀態可能不正確。

Restful API在設計上不是有狀態的,如果您使用服務器端將它們設為有狀態,則它不是REST!

您需要什么相關性ID,它是分布式系統設計中公認的模式。 關聯ID可讓您將請求捆綁在一起。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM