架構設計 | 介面冪等性原則,防重複提交Token管理
阿新 • • 發佈:2020-05-23
本文原始碼:[GitHub·點這裡](https://github.com/cicadasmile/data-manage-parent) || [GitEE·點這裡](https://gitee.com/cicadasmile/data-manage-parent)
# 一、冪等性概念
## 1、冪等簡介
程式設計中一個冪等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同。就是說,一次和多次請求某一個資源會產生同樣的作用影響。
## 2、HTTP請求
遵循Http協議的請求,越來越強調Rest請求風格,可以更好的規範和理解介面的設計。
GET:用於獲取資源,不應有副作用,所以是冪等的;
POST:用於建立資源,重複提交POST請求可能產生兩個不同的資源,有副作用不滿足冪等性;
PUT:用於更新操作,重複提交PUT請求只會對其URL中指定的資源有副作用,滿足冪等性;
DELETE:用於刪除資源,有副作用,但它應該滿足冪等性;
HEAD:和GET本質是一樣的,但HEAD不含有呈現資料,僅是HTTP頭資訊,沒有副作用,滿足冪等性;
OPTIONS:用於獲取當前URL所支援的請求方法,滿足冪等性;
# 二、場景業務分析
## 1、訂單支付
![](https://img2020.cnblogs.com/blog/1691717/202005/1691717-20200522212938764-1005309785.png)
實際開發中,經常會面對訂單支付問題,基本流程如下:
- 客戶端發起訂單支付請求 ;
- 支付前系統本地相關業務處理 ;
- 請求第三方支付服務執行扣款;
- 第三方支付返回處理結果;
- 本地服務基於支付結果響應客戶端;
該業務流程中要處理相當複雜的問題,比如事務,分散式事務,介面延遲超時,客戶端重複提交等等,這裡只基於冪等介面角度來看該流程,其他問題後續再聊。
## 2、冪等介面
當上述流程的支付請求有明確結果的時候:失敗或成功,這樣業務流程都好處理,但是例如支付場景如果請求超時,如何判斷服務的結果狀態:客戶端請求超時,本地服務超時,請求支付超時,支付回撥超時,客戶端響應超時等等。
這就需要設計流程化的狀態管理。
## 3、基礎操作案例
模擬管理上述流程,設計冪等介面:
**表結構設計**
```sql
CREATE TABLE `dp_order_state` (
`order_id` BIGINT (20) NOT NULL AUTO_INCREMENT COMMENT '訂單id',
`token_id` VARCHAR (50) DEFAULT NULL COMMENT '防重複提交',
`state` INT (1) DEFAULT '1' COMMENT '1建立訂單,2本地業務,3支付業務',
PRIMARY KEY (`order_id`)
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '訂單狀態表';
CREATE TABLE `dp_state_record` (
`id` INT (11) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`order_id` BIGINT (20) NOT NULL COMMENT '訂單id',
`state_dec` VARCHAR (50) DEFAULT NULL COMMENT '狀態描述',
PRIMARY KEY (`id`)
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '狀態記錄表';
```
**模擬業務流程**
將訂單建立,本地業務,支付業務,分開分段管理提交。分階段測試異常熔斷的業務。
```java
@Service
public class OrderServiceImpl implements OrderService {
@Resource
private OrderStateMapper orderStateMapper ;
@Resource
private StateRecordMapper stateRecordMapper ;
@Override
public OrderState queryOrder(OrderState orderState) {