精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Spring Statemachine應用實踐

開發 前端
通常所說的狀態機為有限狀態機(英語:finite-state machine,縮寫:FSM),簡稱狀態機, 是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型。

前言 

在日常開發中經常遇到運營審核經銷商活動、任務等等類似業務需求,大部分需求中狀態穩定且單一無需使用狀態機,但是也會出現大量的if...else前置狀態代碼,也是不夠那么的“優雅”。隨著業務的發展、需求迭代,每一次的業務代碼改動都需要維護使用到狀態的代碼,更讓開發人員頭疼的是這些維護狀態的代碼,像散彈一樣遍布在各個Service的方法中,不僅增加發布的風險,同時也增加了回歸測試的工作量。

1. 什么是狀態機?

通常所說的狀態機為有限狀態機(英語:finite-state machine,縮寫:FSM),簡稱狀態機, 是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型。 

應用FSM模型可以幫助對象生命周期的狀態的順序以及導致狀態變化的事件進行管理。 將狀態和事件控制從不同的業務Service方法的if else中抽離出來。FSM的應用范圍很廣,狀態機 可以描述核心業務規則,核心業務內容. 無限狀態機,顧名思義狀態無限,類似于“π”,暫不做研究。

狀態機可歸納為4個要素,即現態、條件、動作、次態。這樣的歸納,主要是出于對狀態機的內在因果關系的考慮。“現態”和“條件”是因,“動作”和“次態”是果。詳解如下:

現態:是指當前所處的狀態。

條件:又稱為“事件”,當一個條件被滿足,將會觸發一個動作,或者執行一次狀態的遷移。

動作:條件滿足后執行的動作。動作執行完畢后,可以遷移到新的狀態,也可以仍舊保持原狀態。動作不是必需的,當條件滿足后,也可以不 執行任何動作,直接遷移到新狀態。

次態:條件滿足后要遷往的新狀態。“次態”是相對于“現態”而言的,“次態”一旦被激活,就轉變成新的“現態”了。

動作是在給定時刻要進行的活動的描述。有多種類型的動作:

進入動作(entry action):在進入狀態時進行

退出動作(exit action):在退出狀態時進行

輸入動作:依賴于當前狀態和輸入條件進行

轉移動作:在進行特定轉移時進行

其他術語:

Transition: 狀態轉移節點,是組成狀態機引擎的核心。

source/from:現態。

target/to:次態。

event/trigger:觸發節點從現態轉移到次態的動作,這里也可能是一個timer。

guard/when:狀態遷移前的校驗,執行于action前。

action:用于實現當前節點對應的業務邏輯處理。

文字描述比較不容易理解,讓我們舉個栗子:每天上班都需要坐地鐵,從刷卡進站到閘機關閉這個過程,將閘機抽象為一個狀態機模型,如下圖:

圖片

2. 什么場景使用?

以下的場景您可能會需要使用:

您可以將應用程序或其結構的一部分表示為狀態。

您希望將復雜的邏輯拆分為更小的可管理任務。

應用程序已經遇到了并發問題,例如異步執行導致了一些異常情況。

當您執行以下操作時,您已經在嘗試實現狀態機:

使用布爾標志或枚舉來建模情況。

具有僅對應用程序生命周期的某些部分有意義的變量。

在if...else結構(或者更糟糕的是,多個這樣的結構)中循環,檢查是否設置了特定的標志或枚舉,然后在標志和枚舉的某些組合存在或不存在時,做出進一步的異常處理。

3. 為什么要用?有哪些好處?

最初活動模塊功能設計時,并沒有想使用狀態機,僅僅想把狀態的變更和業務剝離開,規范狀態轉換和程序在不同狀態下所能提供的能力,去掉復雜的邏輯判斷也就是if...else,想換一種模式實現思路,此前了解過spring“全家桶”有狀態機就想到了“它”,場景也符合。

從個人使用的經驗,開發階段和迭代維護期總結了以下幾點:

使用狀態機來管理狀態好處更多體現在代碼的可維護性、對于流程復雜易變的業務場景能大大減輕維護和測試的難度。

解耦,業務邏輯與狀態流程隔離,避免業務與狀態“散彈式”維護,且狀態持久化在同一個事務。

狀態流轉越復雜,越能體現狀態流轉的邏輯清晰,減少的“膠水”代碼也越多。

4. 實踐

java語言狀態機框架有很多,目前github star 數比較多的有 spring-statemachine(star 1.3K) 、squirrel-foundation(star1.9K)即“松鼠”狀態機,stateless4j相較前兩個名氣較小,未深入研究。spring-statemachine是spring官方提供的狀態機實現,功能強大,但是相對來說很“重”,加載實例的時間也長于squirrel-foundation,不過好在一直都是有更新(目前官方已更新3.2.0),相信會越來越成熟。

實際生產中使用的是spring statemachine ,版本是2.2.0.RELEASE。線下對比使用的是squirrel-foundation,版本是0.3.10。這里僅供使用對比。

從創建活動到活動下線狀態流轉作為示例,如下圖:

圖片

pom

<?xml versinotallow="1.0" encoding="utf-8" ?>
<!-- spring statemachine -->
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-starter</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<!-- spring statemachine context 序列化 -->
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-kryo</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<!-- squirrel-foundation -->
<dependency>
<groupId>org.squirrelframework</groupId>
<artifactId>squirrel-foundation</artifactId>
<version>0.3.10</version>
</dependency>

狀態&事件定義

public enum State {
INIT("初始化"),
DRAFT("草稿"),
WAIT_VERIFY("待審核"),
PASSED("審核通過"),
REJECTED("已駁回"),
//已發起上線操作,未到上線時間的狀態
WAIT_ONLIE("待上線"),
ONLINED("已上線"),
//過渡狀態無實際意義,無需事件觸發
OFFLINING("下線中"),
OFFLINED("已下線"),
FINISHED("已結束");
private final String desc;
}

public enum Event {
SAVE("保存草稿"),
SUBMIT("提交審核"),
PASS("審核通過"),
REJECT("提交駁回"),
ONLINE("上線"),
OFFLINE("下線"),
FINISH("結束");
private final String desc;
}

狀態流轉定義

@Configuration
@EnableStateMachineFactory
public class ActivitySpringStateMachineAutoConfiguration extends StateMachineConfigurerAdapter<State, Event> {

@Autowired
private ApplicationContext applicationContext;

@Autowired
private StateMachineRuntimePersister<State, Event, String> activityStateMachinePersister;

@Bean
public StateMachineService<State, Event> activityStateMachineService(StateMachineFactory<State, Event> stateMachineFactory) {

return new DefaultStateMachineService<>(stateMachineFactory, activityStateMachinePersister);
}

@Override
public void configure(StateMachineConfigurationConfigurer<State, Event> config) throws Exception {
// @formatter:off
config
.withPersistence()
.runtimePersister(activityStateMachinePersister)
.and().withConfiguration()
.stateDoActionPolicy(StateDoActionPolicy.TIMEOUT_CANCEL)
.stateDoActionPolicyTimeout(300, TimeUnit.SECONDS)
.autoStartup(false);
// @formatter:on
}

@Override
public void configure(StateMachineStateConfigurer<State, Event> states) throws Exception {
states.withStates()
.initial(State.INIT)
.choice(State.OFFLINING)
.states(EnumSet.allOf(State.class));
}

@Override
public void configure(StateMachineTransitionConfigurer<State, Event> transitions) throws Exception {
// 待提交審核 --提交審核--> 待審核
// @formatter:off
// 現態-->事件-->次態
transitions.withExternal()
.source(State.INIT).target(State.DRAFT).event(Event.SAVE)
.and().withExternal()
.source(State.DRAFT).target(State.WAIT_VERIFY).event(Event.SUBMIT)
.guard(applicationContext.getBean(SubmitCondition.class));
transitions.withExternal().source(State.WAIT_VERIFY).target(State.PASSED).event(Event.PASS)
.action(applicationContext.getBean(PassAction.class));
transitions.withExternal().source(State.WAIT_VERIFY).target(State.REJECTED).event(Event.REJECT)
.guard(applicationContext.getBean(RejectCondition.class));
transitions.withExternal()
.source(State.REJECTED)
.target(State.WAIT_VERIFY)
.event(Event.SUBMIT)
.guard(applicationContext.getBean(SubmitCondition.class));

// 審核通過-->上線-->待上線
transitions.withExternal().source(State.PASSED).target(State.WAIT_ONLIE).event(Event.ONLINE);
// 待上線-->上線-->已上線
transitions.withExternal().source(State.WAIT_ONLIE).target(State.ONLINED).event(Event.ONLINE);
// 已上線-->下線-->已下線
transitions.withExternal()
.source(State.ONLINED).target(State.OFFLINING).event(Event.OFFLINE);
// 待上線-->下線-->下線中
transitions.withExternal()
.source(State.WAIT_ONLIE).target(State.OFFLINING).event(Event.OFFLINE)
.and()
// 已下線-->結束-->已結束
.withChoice()
.source(State.OFFLINING)
.first(State.FINISHED, new Guard<State, Event>() {
@Override
public boolean evaluate(StateContext<State, Event> context) {
return true;
}
})
.last(State.OFFLINED);
// @formatter:on
}
}

說明:

  • 多個狀態節點配置可用.and()串聯。
  • withExternal是當現態和次態不相同時使用。
  • withChoice是當執行一個動作,當前狀態(瞬時狀態)可能遷移不同的的狀態,此時可以使用Choice和Guard組合使用,且無需事件觸發。相當于if...else的分支狀態功能。
  • StateMachineService 這個類是spring statemachine自帶的接口,用于獲取和釋放一個狀態機的輔助service,依賴狀態機工廠和持久化 實例, 但由于默認實現 StateMachinePersist< S, E, String> 規定了StateMachineContext的泛型為String 類型,故而持久層的參數contextObj 為string 類型,實際是狀態機的id。
  • 持久化 spring-statemachine官方支持MongoDB和Redis持久化存儲,開發無需關心狀態持久化,但是存在業務數據存儲和狀態存儲事務的問題, 這里需要自己實現(StateMachineRuntimePersister)持久化以存儲狀態。
  • 上下文傳遞時都使用的StateMachineContext,其內部包含StateMachine實例,可以通過增加StateMachine實例擴展參數傳遞參數。

Guard與Action

@Component
public class SaveGuard implements Guard<State, Event> {
@Override
public boolean evaluate(StateContext<State, Event> context) {
log.info("[execute save guard]");
return true;
}
}

@Component
public class SaveAction implements Action<State, Event> {

@Override
public void execute(StateContext<State, Event> context) {
try {
log.info("[execute saveAction]");
} catch (Exception e) {
context.getExtendedState().getVariables().put("ERROR", e.getMessage());
}
}
}

說明:

  1. Guard 門衛,條件判斷返回true時再執行狀態轉移,可以做業務前置校驗。

持久化配置

@Component
public class ActivityStateMachinePersister extends AbstractStateMachineRuntimePersister<State, Event, String> {

@Autowired
private ActivityStateService activityStateService;

@Override
public void write(StateMachineContext<State, Event> context, String id) {
Activity state = new Activity();
state.setMachineId(id);
state.setState(context.getState());
activityStateService.save(state);
}

@Override
public StateMachineContext<State, Event> read(String id) {
return deserialize(activityStateService.getContextById(id));
}
}

說明:

  • AbstractStateMachineRuntimePersister 繼承AbstractPersistingStateMachineInterceptor 并實現了StateMachineRuntimePersister接口, AbstractPersistingStateMachineInterceptor主要攔截狀態變更時的狀態監聽。不同于StateMachineListener被動監聽,interceptor擁有可以改變狀態變化鏈的能力。
  • 序列化存儲實現參考了spring-statemachine-data-redis的實現。

狀態服務調用

@Service
public class StateTransitService {

@Autowired
private StateMachineService<State, Event> stateMachineService;

@Transactional
public void transimit(String machineId, Message<Event> message) {
StateMachine<State, Event> stateMachine = stateMachineService.acquireStateMachine(machineId);
stateMachine.addStateListener(new DefaultStateMachineListener<>(stateMachine));
stateMachine.sendEvent(message);
if (stateMachine.hasStateMachineError()) {
String errorMessage = stateMachine.getExtendedState().get("message", String.class);
stateMachineService.releaseStateMachine(machineId);
throw new ResponseException(errorMessage);
}
}
}

@AllArgsConstructor
public class DefaultStateMachineListener<S, E> extends StateMachineListenerAdapter<S, E> {

private final StateMachine<S, E> stateMachine;

@Override
public void eventNotAccepted(Message<E> event) {
stateMachine.getExtendedState().getVariables().put("message", "當前狀態不滿足執行條件");
stateMachine.setStateMachineError(new ResponseException(500, "Event not accepted"));
}

@Override
public void transitionEnded(Transition<S, E> transition) {
log.info("source {} to {}", transition.getSource().getId(), transition.getTarget().getId());
}
}

說明:

  • Message為發送事件的載體,其內部封裝了消息體、事件等上下文擴展參數。
  • StateMachineListenerAdapter為默認監聽接口的空實現,依據業務需要重寫監聽的方法。
  • eventNotAccepted此為事件未正確執行時的監聽器。

集成單元測試

@SpringBootTest
@RunWith(SpringRunner.class)
public class StateMachineITest {

@Autowired
private StateTransitService transmitService;

@Autowired
private ActivityStateService activityStateService;

@Test
public void test() {
String machineId = "test";//業務主鍵ID
transmitService.transimit(machineId, MessageBuilder.withPayload(Event.SAVE).build());
transmitService.transimit(machineId, MessageBuilder.withPayload(Event.SUBMIT).build());
transmitService.transimit(machineId, MessageBuilder.withPayload(Event.PASS).build());
transmitService.transimit(machineId, MessageBuilder.withPayload(Event.ONLINE).build());
transmitService.transimit(machineId, MessageBuilder.withPayload(Event.ONLINE).build());
transmitService.transimit(machineId, MessageBuilder.withPayload(Event.OFFLINE).build());
assert activityStateService.getStateById(machineId).equals(State.FINISHED);
}

}

注意事項

  • 由于框架中每次都是加載一個狀態機內存實例,所以在執行狀態轉移相關代碼時一定要加分布式鎖!!!建議狀態維護提供統一調用service, 開啟事務、處理異常。
  • spring-statemachine異常包裝比較另類,如guard、action以及listener中發生異常,狀態機會捕獲并把異常信息捕獲為警告,狀態也能夠成功轉移到次態,這顯然不符合 我們的需求,所以調用后需要手動判斷是否發生異常stateMachine.hasStateMachineError(),但statemachine并沒有給提供獲取異常信息的接口,所以在guard 和action中將異常信息用變量的方式解決此問題,stateMachine.getExtendedState().getVariables().put("message", "當前狀態不滿足執行條件");
  • @EnableStateMachineFactory開啟工廠模式,然后通過StateMachineService從持久化層加載一個狀態機實例。
  • 當一個project中有多個業務狀態機時,@EnableStateMachineFactory(name = "xxx")為工廠配置名稱以區別不同的業務狀態機。
  • 當使用withChoice()時,一定要在配置StateMachineStateConfigurer.choice()配置分支狀態,否則將不生效。

擴展-與squirrel-foundation異同

@Component
public class ActivityMachine extends SquirrelStateMachine<ActivityMachine, State, Event, TransmitCmd> {

private final ActivityStateService activityStateService;

public ActivityMachine(ApplicationContext applicationContext) {
super(applicationContext);
activityStateService = applicationContext.getBean(ActivityStateService.class);
}

@Override
public void buildStateMachine(StateMachineBuilder<ActivityMachine, State, Event, TransmitCmd> stateMachineBuilder) {
stateMachineBuilder.externalTransition().from(State.INIT).to(State.DRAFT).on(Event.SAVE).when(applicationContext.getBean(SubmitCondition.class));
//以下省略,大致與spring-statemachine相同
}

@Override
public ActivityMachine createStateMachine(State stateId) {
ActivityMachine activityMachine = super.createStateMachine(stateId);
activityMachine.addStartListener(new StartListener<ActivityMachine, State, Event, TransmitCmd>() {

});
return activityMachine;
}

@Override
protected void afterTransitionDeclined(S fromState, E event, C context) {
//轉移狀態未執行
}

@Override
protected void afterTransitionCausedException(S fromState, S toState, E event, C context) {
// 轉移狀態時發生異常
}

@Override
protected void afterTransitionCompleted(State fromState, State toState, Event event, TransmitCmd context) {
log.info("from {} to {} on {}, {}", fromState.getDesc(), toState.getDesc(), event.getDesc(), context);
}

}

說明:

  • squirrel-foundation直接可繼承AbstractStateMachine實例化狀態機,配置上大體相同只是使用的是from、to、on、when詞不同,框架builder的約束太強。
  • 不支持choice分支狀態。
  • 狀態機異常處理afterTransitionCausedException相比spring-statemachine更加方便、易用。
  • 狀態的持久化通過重寫afterTransitionCompleted方法即可。

5.使用后的效果如何?

以下是在開發和迭代維護期間,真切體會到狀態機帶來好處的兩個小場景。

  • 由于新項目中涉及到跨部門卡券業務,在開發初期審核活動通過時同步創建卡券批次,卻忽略了異步生成券碼的時間,隨著開發的深入才意識到此問題。此時只需要在狀態審核通過時加一個過渡狀態并啟動一個任務去輪詢券碼是否創建完成即可,絲毫不影響已開發的代碼。
  • 最初的需求設計時,活動下線后是不能再次上線的,在需求迭代期內又增加了再次上線的功能,狀態機流轉邏輯清晰,只需要再增加個狀態配置流轉事件就行,就為狀態機賦予了再次上線的能力。

6.總結 

在實踐的過程中,在spring-statemachine官方文檔結合Google摸索使用的過程中,遇到持久化存儲StateMachineContext、異常處理,以及狀態分支等問題。目前回頭看來也不復雜,如今寫出來總結一下,希望對小伙伴們有所幫助。

最后建議在狀態流程不是很復雜的情況,如果您也厭煩了if...else,那么不妨嘗試一下squirrel-foundation,相信也是不錯的選擇。

參考文獻

  1. ??https://baike.baidu.com/item/%E7%8A%B6%E6%80%81%E6%9C%BA/6548513?fr=aladdin??
  2. ??https://zh.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E7%8A%B6%E6%80%81%E6%9C%BA??
  3. ??https://spring.io/projects/spring-statemachine#learn??
  4. ??http://hekailiang.github.io/squirrel/??

作者簡介

圖片

姜強強

■ 經銷商技術部-商業資源團隊。

■ 2016年加入汽車之家,目前主要負責經銷商事業部內創新商業項目的研發工作,熱衷于業內新技術的探索與實踐。

責任編輯:武曉燕 來源: 之家技術
相關推薦

2025-06-19 09:53:30

Spring性能優化服務器

2025-02-27 08:00:00

熔斷機制微服務Spring

2022-08-22 13:29:42

微服務應用Java

2013-11-20 10:21:30

閃存

2017-03-24 09:44:33

Java反射機制

2017-05-17 15:28:15

Java反射機制

2022-08-04 10:12:49

桌面技術

2017-09-05 14:05:11

微服務spring clou路由

2025-04-14 02:25:00

2024-12-24 14:01:10

2012-05-28 09:10:18

云計算應用

2010-03-02 11:12:33

Android應用開發

2020-12-03 10:05:07

鴻蒙OS

2024-07-10 08:58:22

2020-12-18 10:42:14

鴻蒙開發應用

2022-07-15 12:58:02

鴻蒙攜程華為

2022-04-08 09:01:56

腳本Go應用單元

2020-12-08 09:45:33

鴻蒙OS應用開發

2009-10-28 10:26:36

2020-12-04 09:52:22

鴻蒙OS
點贊
收藏

51CTO技術棧公眾號

久久男人的天堂| 欧美电影精品一区二区| 亚洲国产欧美一区二区三区不卡| 中文字字幕在线中文乱码| 91精品国产调教在线观看| 欧美videos大乳护士334| 成年网站在线免费观看| 欧美性猛交xxx乱大交3蜜桃| 福利视频网站一区二区三区| 国产精品久久久久77777| 久久久久久视频| 日韩动漫一区| 欧美一级片在线看| 红桃av在线播放| 性xxxfreexxxx性欧美| 久久嫩草精品久久久精品| 91免费福利视频| 波多野结衣视频网站| 久久久久国产精品| 亚洲系列中文字幕| 亚洲图片欧美另类| 久久精品嫩草影院| 精品国产乱码久久久久久虫虫漫画 | 国产亚洲精品自在久久| 一级片在线免费观看视频| 伊人激情综合| 日韩一区av在线| 自拍偷拍视频亚洲| 欧美日韩一区二区三区不卡视频| 欧美日韩和欧美的一区二区| 日韩中文字幕三区| 日本片在线观看| 国产精品成人免费在线| 欧美日韩系列| 色久视频在线播放| 床上的激情91.| 91在线观看网站| 一区二区国产欧美| 日本成人中文字幕在线视频| 欧洲日本亚洲国产区| www.av视频在线观看| 亚洲一区二区三区| 日韩亚洲精品视频| 大吊一区二区三区| 国产欧美日韩在线观看视频| 国产视频自拍一区| 国产三级视频网站| 秋霞综合在线视频| 日韩成人av在线播放| 亚洲少妇18p| 福利电影一区| 亚洲国产成人精品电影| 玖玖爱在线精品视频| 国产欧美自拍一区| 亚洲国产天堂久久综合网| 日韩成人av影院| 加勒比久久高清| 亚洲精品久久久久久下一站| 成年人网站免费看| 亚洲小说图片视频| 亚洲一区二区精品| 国产一二三av| 一区二区中文字| 精品中文字幕在线2019| 国产一国产二国产三| 亚洲精品美女91| 欧美在线视频观看| 特级西西444www大胆免费看| 另类成人小视频在线| 国产日韩欧美中文在线播放| 国产又爽又黄又嫩又猛又粗| 国产成人午夜精品影院观看视频 | 999精品一区| 久久天天躁狠狠躁老女人| 深夜福利影院在线观看| 亚洲国产裸拍裸体视频在线观看乱了中文| 韩国精品久久久999| 欧美男人亚洲天堂| 九九国产精品视频| 成人羞羞视频免费| 看电影就来5566av视频在线播放| 亚洲国产成人在线| 日本福利视频网站| 都市激情亚洲一区| 91麻豆精品国产91久久久久| 久久精品无码专区| 国产亚洲一区二区三区啪| 日韩视频精品在线| 日本三级片在线观看| 首页国产欧美日韩丝袜| 91在线视频免费| 外国精品视频在线观看 | 91成人福利社区| 精品不卡在线视频| 日韩av片在线| 激情视频一区| 国产欧美日韩最新| 免费av网站在线播放| 国产欧美久久久精品影院| 天堂av在线中文| 成人性教育av免费网址| 日韩欧美视频一区| 国产传媒在线看| 极品裸体白嫩激情啪啪国产精品| 国产福利成人在线| 免费观看国产视频| 最新高清无码专区| 动漫av免费观看| 成人在线视频你懂的| 中文字幕亚洲字幕| 91视频免费网址| 国产激情一区二区三区四区 | 国产一区二区三区av在线| av网站在线免费观看| 亚洲成人精品影院| 一二三级黄色片| 免费视频国产一区| 欧美激情一区二区久久久| 免费又黄又爽又猛大片午夜| 国产91在线观看丝袜| 亚洲色图自拍| 欧洲一级精品| 精品小视频在线| 国产在线拍揄自揄拍| 国产一区欧美二区| 亚洲高清在线播放| 精品欧美一区二区三区在线观看| 亚洲高清在线观看| 久草福利资源在线观看| 国产综合成人久久大片91| 日日夜夜精品网站| 中文字幕在线视频久| 亚洲国产成人一区| 久热这里只有精品在线| 国产精选一区二区三区| 午夜精品短视频| 精品欧美一区二区三区在线观看| 亚洲男人天天操| 男女视频免费看| 不卡一二三区首页| 日韩一区二区高清视频| 嫩呦国产一区二区三区av| 精品国产欧美一区二区五十路 | 欧美va亚洲va国产综合| 免费又黄又爽又色的视频| 国产一区二区三区不卡在线观看 | 国产一区二区三区av在线| 波多野结衣在线高清| 精品av久久707| 日韩av电影网址| 99r国产精品| 丝袜老师办公室里做好紧好爽| 美女视频亚洲色图| 97色在线视频| 久久精品a一级国产免视看成人 | 久久av中文| 国产999精品视频| 国产黄色在线| 欧美日韩国产电影| 可以直接看的黄色网址| 国产传媒日韩欧美成人| 国产真人做爰毛片视频直播| 欧美a级网站| 日韩美女在线看| 欧美jizz18hd性欧美| 日韩一区二区三区电影在线观看 | www.自拍偷拍| 日韩福利视频网| 成人短视频在线看| 91精品短视频| 日本91av在线播放| 在线观看免费高清完整| 欧美一区二区三区男人的天堂| 欧美日韩中文字幕在线观看| 不卡免费追剧大全电视剧网站| 苍井空浴缸大战猛男120分钟| 日韩一区二区中文| 国产a一区二区| 欧美一区 二区 三区| 精品久久国产精品| 熟妇人妻系列aⅴ无码专区友真希| 色综合久久久久久久| 2014亚洲天堂| www.99精品| av污在线观看| 欧美一区精品| 秋霞在线观看一区二区三区| 成人97精品毛片免费看| 91精品国产免费久久久久久| 亚乱亚乱亚洲乱妇| 亚洲国产高清福利视频| 中文字幕观看视频| 亚洲成人高清在线| 亚洲色图27p| 91首页免费视频| 中文字幕视频三区| 裸体素人女欧美日韩| 天堂а√在线中文在线| 欧美禁忌电影| 国产精品福利视频| 免费一级欧美在线观看视频| 欧美性受xxxx白人性爽| 影音先锋中文在线视频| 亚洲最新中文字幕| 污视频网站免费观看| 91精品国产福利在线观看| 日韩综合在线观看| 亚洲一区二区欧美| 2025国产精品自拍| 国产欧美日本一区视频| 在线观看国产三级| 国产精品一区二区久久不卡| 午夜免费福利在线| 国产精品嫩草99av在线| 国产精品三级一区二区| 日韩欧美1区| 日韩欧美第二区在线观看| 久久久伦理片| 99免费在线视频观看| 欧洲午夜精品| 国产精品免费网站| 在线天堂资源| 2023亚洲男人天堂| 丁香影院在线| 久久久久久美女| 在线电影福利片| 久久国产精品电影| 麻豆视频免费在线观看| 日韩在线国产精品| av福利精品| 亚洲色图美腿丝袜| 日本五码在线| 精品亚洲男同gayvideo网站| 天堂8在线视频| 精品国产一区二区三区不卡| 精品人妻无码一区二区| 91精品蜜臀在线一区尤物| 国产一区二区麻豆| 欧美人与z0zoxxxx视频| 国产又爽又黄免费软件| 欧美一区二区在线看| 国产乱码精品一区二区三区精东| 欧美日韩电影在线| 91无套直看片红桃| 欧美一区二区福利在线| 999av视频| 日韩女优av电影| 亚洲毛片欧洲毛片国产一品色| 日韩免费电影网站| 亚洲国产精品久久人人爱潘金莲 | 亚洲国产精品成人综合久久久| 成人国产免费视频| 中文字幕第3页| 91在线看国产| 精品国产无码在线观看| 国产视频一区二区三区在线观看| 三上悠亚影音先锋| 亚洲国产精品精华液2区45| 在线观看日本黄色| 亚洲欧美偷拍另类a∨色屁股| 欧美丰满艳妇bbwbbw| 亚洲成人一区在线| 黄色在线观看国产| 日本精品视频一区二区| 一级黄色片视频| 欧美精品在线视频| 亚洲第一视频在线| 精品一区二区电影| 成人精品一区二区三区校园激情| 丝袜美腿亚洲一区二区| 菠萝蜜视频国产在线播放| 久久免费视频在线观看| 日韩不卡在线| 亚洲va国产va天堂va久久| 久久久亚洲欧洲日产| 欧美一区二区三区电影在线观看 | 国产亚洲精品网站| 蜜臀av性久久久久蜜臀aⅴ流畅| 手机免费看av网站| 99re热视频精品| 国产1区2区在线观看| 亚洲精品免费在线观看| 精品在线视频观看| 在线免费精品视频| 亚洲av无码国产精品久久不卡 | 免费在线观看av片| 欧美精品videosex牲欧美| 欧美日韩亚洲国产| 岛国视频一区免费观看| 黄色不卡一区| cao在线观看| 看国产成人h片视频| 亚洲成av人片在线观看无| 国产精品美女久久久久久久久 | 蜜臀久久99精品久久久久宅男| 日本少妇xxx| 国产欧美一区二区在线| 久久久久久蜜桃| 欧美日韩视频在线一区二区| 香蕉视频网站在线| 理论片在线不卡免费观看| 午夜欧美巨大性欧美巨大 | 亚洲一级片在线观看| 成人免费一级片| 亚洲成色777777在线观看影院| aⅴ在线视频男人的天堂| 992tv成人免费视频| 精品国产乱码一区二区三区| 亚洲成人自拍| 亚洲制服av| 岛国精品一区二区三区| 中文字幕中文乱码欧美一区二区| 国产精品一区二区三区四| 日韩欧美电影一二三| 秋霞午夜在线观看| 国产精品九九九| 亚州av一区| 男人添女人下部高潮视频在观看| 国产一区二区三区不卡在线观看| 美国黑人一级大黄| 一本高清dvd不卡在线观看| 性xxxx视频| 韩国三级日本三级少妇99| 一区中文字幕电影| 亚洲天堂第一区| 极品尤物av久久免费看| 懂色av蜜臀av粉嫩av永久| 欧美亚洲国产一区二区三区va | 久久av.com| 亚州精品国产| 一区二区不卡在线| 免费成人美女在线观看| 9.1片黄在线观看| 欧美在线观看你懂的| 国产区视频在线| 国产精品av免费在线观看| 欧洲美女日日| 国产嫩草在线观看| 国产人成亚洲第一网站在线播放 | 777xxx欧美| 免费黄色网页在线观看| 国产在线精品成人一区二区三区| 日韩国产一区| 奇米视频7777| 亚洲欧美日韩一区二区三区在线观看| ,亚洲人成毛片在线播放| 色yeye香蕉凹凸一区二区av| 全球中文成人在线| 五月天av影院| 国产精品伊人色| 国产一级理论片| 亚洲激情在线视频| 伊人色综合一区二区三区影院视频| 久久伊人一区二区| 老**午夜毛片一区二区三区 | 亚洲成人精品影院| 涩涩视频在线观看免费| 日本91av在线播放| 色喇叭免费久久综合| 一二三av在线| 亚洲永久精品国产| 香蕉久久一区二区三区| 热久久这里只有精品| 日韩一区二区在线免费| 四川一级毛毛片| 图片区日韩欧美亚洲| 国产福利片在线| 91视频国产一区| 99国产精品| 国产黄色录像视频| 日韩欧美一级特黄在线播放| √天堂8资源中文在线| 日本一区免费在线观看| 美女爽到高潮91| 久久老司机精品视频| 亚洲人成啪啪网站| 国产精品一区二区美女视频免费看 | 久做在线视频免费观看| 动漫精品视频| 久久在线精品| 日韩女优一区二区| 亚洲美女动态图120秒| 亚洲色图图片| 缅甸午夜性猛交xxxx| 国产精品三级在线观看| 亚洲xxx在线| 国产精品极品在线| 在线欧美视频| 91无套直看片红桃在线观看| 亚洲第一区中文99精品| 成人精品动漫| 激情深爱综合网| 亚洲欧美成aⅴ人在线观看| 日本福利在线观看| 999视频在线免费观看| 日韩影院在线观看| 男人天堂中文字幕| 久久色精品视频| 国产成人1区| 中文字幕一区二区人妻电影丶|