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

工作中最常用的五種工作流引擎

開發(fā) 前端
有些小伙伴在工作中,一提到工作流引擎就頭疼,不知道如何選型,更不清楚它們底層的原理。其實(shí),工作流引擎就像我們生活中的交通信號(hào)系統(tǒng),它負(fù)責(zé)協(xié)調(diào)各個(gè)"路口"(業(yè)務(wù)節(jié)點(diǎn))的通行順序,確保整個(gè)"交通"(業(yè)務(wù)流程)有序進(jìn)行。今天我想和大家聊聊工作中最常用的5種工作流引擎,希望對(duì)你會(huì)有所幫助。

前言

有些小伙伴在工作中,一提到工作流引擎就頭疼,不知道如何選型,更不清楚它們底層的原理。

其實(shí),工作流引擎就像我們生活中的交通信號(hào)系統(tǒng),它負(fù)責(zé)協(xié)調(diào)各個(gè)"路口"(業(yè)務(wù)節(jié)點(diǎn))的通行順序,確保整個(gè)"交通"(業(yè)務(wù)流程)有序進(jìn)行。

今天我想和大家聊聊工作中最常用的5種工作流引擎,希望對(duì)你會(huì)有所幫助。

一、工作流引擎是什么?

在深入具體引擎之前,我們先明確一個(gè)基本概念:工作流引擎本質(zhì)上是業(yè)務(wù)流程自動(dòng)化的核心支撐系統(tǒng)

它負(fù)責(zé)將復(fù)雜的業(yè)務(wù)邏輯分解為多個(gè)任務(wù)節(jié)點(diǎn),并控制這些節(jié)點(diǎn)之間的流轉(zhuǎn)邏輯。

舉個(gè)例子,比如一個(gè)請(qǐng)假審批流程:?jiǎn)T工提交申請(qǐng) → 直接主管審批 → 部門經(jīng)理審批 → HR備案 → 結(jié)束。

如果每個(gè)環(huán)節(jié)都用if-else硬編碼,代碼會(huì)變得極其臃腫且難以維護(hù)。

而工作流引擎通過可視化的方式定義流程,讓業(yè)務(wù)邏輯和流程控制徹底解耦。

為了讓大家更直觀地理解工作流引擎的架構(gòu),我畫了一個(gè)整體架構(gòu)圖:

圖片圖片

這張圖展示了工作流引擎的核心組件。接下來,我們看看為什么要用工作流引擎:

  1. 降低復(fù)雜度:將業(yè)務(wù)流程從業(yè)務(wù)代碼中解耦
  2. 提高可維護(hù)性:流程變更只需修改配置,無需改代碼
  3. 增強(qiáng)可視化:大多數(shù)引擎提供流程設(shè)計(jì)器和監(jiān)控界面
  4. 保證一致性:通過狀態(tài)機(jī)保證業(yè)務(wù)流程的標(biāo)準(zhǔn)執(zhí)行

有些小伙伴在工作中可能會(huì)問:"我們系統(tǒng)業(yè)務(wù)邏輯不復(fù)雜,需要用工作流引擎嗎?"

我的經(jīng)驗(yàn)是:當(dāng)你的業(yè)務(wù)有狀態(tài)流轉(zhuǎn)、多人協(xié)作、需要長(zhǎng)時(shí)間運(yùn)行的特征時(shí),就應(yīng)該考慮使用工作流引擎了。

二、Activiti:企業(yè)級(jí)標(biāo)準(zhǔn)工作流引擎

Activiti可以說是Java領(lǐng)域最老牌、最知名的工作流引擎之一,它最初是jBPM的原作者離開JBoss后創(chuàng)建的。

核心原理

Activiti基于BPMN 2.0標(biāo)準(zhǔn),采用狀態(tài)機(jī)+命令模式的設(shè)計(jì)。

它的核心思想是將業(yè)務(wù)流程抽象為一系列的活動(dòng)節(jié)點(diǎn),通過令牌(Token)在節(jié)點(diǎn)間的流動(dòng)來驅(qū)動(dòng)流程執(zhí)行。

架構(gòu)特點(diǎn)

  • 支持完整的BPMN 2.0元素
  • 采用命令模式,所有操作都封裝為命令
  • 基于狀態(tài)機(jī)管理流程實(shí)例狀態(tài)
  • 支持事務(wù)性流程執(zhí)行

開源地址

GitHub: https://github.com/Activiti/Activiti

示例:請(qǐng)假審批流程

首先在Spring Boot項(xiàng)目中引入依賴:

<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring-boot-starter</artifactId>
    <version>7.1.0.M6</version>
</dependency>

定義BPMN 2.0流程文件(leave-approval.bpmn20.xml):

<?xml versinotallow="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">
    <process id="leaveApproval" name="請(qǐng)假審批流程" isExecutable="true">
        <!-- 開始事件 -->
        <startEvent id="startEvent" />
        
        <!-- 用戶提交申請(qǐng) -->
        <userTask id="submitLeave" name="提交請(qǐng)假申請(qǐng)" 
                 activiti:assignee="#{employee}"/>
        
        <!-- 主管審批 -->
        <userTask id="leaderApproval" name="直接主管審批"
                 activiti:assignee="#{leader}"/>
        
        <!-- 排他網(wǎng)關(guān):根據(jù)審批結(jié)果決定流向 -->
        <exclusiveGateway id="decisionGateway"/>
        
        <!-- 條件序列流:審批通過 -->
        <sequenceFlow id="flowApproved" sourceRef="decisionGateway" targetRef="hrRecord">
            <conditionExpression xsi:type="tFormalExpression">
                <![CDATA[${approved == true}]]>
            </conditionExpression>
        </sequenceFlow>
        
        <!-- 條件序列流:審批駁回 -->
        <sequenceFlow id="flowRejected" sourceRef="decisionGateway" targetRef="rejectEnd">
            <conditionExpression xsi:type="tFormalExpression">
                <![CDATA[${approved == false}]]>
            </conditionExpression>
        </sequenceFlow>
        
        <!-- HR備案 -->
        <userTask id="hrRecord" name="HR備案" 
                 activiti:assignee="#{hr}"/>
        
        <!-- 結(jié)束事件 -->
        <endEvent id="endEvent" />
    </process>
</definitions>

Java代碼中啟動(dòng)和執(zhí)行流程:

@Service
@Transactional
publicclass LeaveProcessService {
    
    @Autowired
    private RuntimeService runtimeService;
    
    @Autowired
    private TaskService taskService;
    
    @Autowired
    private RepositoryService repositoryService;
    
    // 部署流程定義
    public void deployProcess() {
        repositoryService.createDeployment()
            .addClasspathResource("processes/leave-approval.bpmn20.xml")
            .name("請(qǐng)假審批流程")
            .deploy();
    }
    
    // 啟動(dòng)請(qǐng)假流程
    public void startLeaveProcess(String employee, String leader, int leaveDays) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("employee", employee);
        variables.put("leader", leader);
        variables.put("hr", "hr_department");
        variables.put("leaveDays", leaveDays);
        // 啟動(dòng)時(shí)尚未有審批結(jié)果,approved變量稍后設(shè)置
        variables.put("approved", null);
        
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
            "leaveApproval", variables);
        
        System.out.println("流程啟動(dòng)成功,實(shí)例ID:" + processInstance.getId());
    }
    
    // 查詢用戶待辦任務(wù)
    public List<Task> getPendingTasks(String assignee) {
        return taskService.createTaskQuery()
            .taskAssignee(assignee)
            .orderByTaskCreateTime().desc()
            .list();
    }
    
    // 完成任務(wù)并傳遞審批結(jié)果
    public void completeTask(String taskId, boolean approved, String comment) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("approved", approved);
        
        // 添加審批意見
        if (comment != null && !comment.trim().isEmpty()) {
            taskService.addComment(taskId, null, comment);
        }
        
        taskService.complete(taskId, variables);
        System.out.println("任務(wù)完成,審批結(jié)果:" + (approved ? "通過" : "駁回"));
    }
}

代碼邏輯深度解析

  1. 流程定義:BPMN文件定義了節(jié)點(diǎn)拓?fù)浣Y(jié)構(gòu),userTask表示人工任務(wù),exclusiveGateway是決策點(diǎn)
  2. 變量傳遞:通過variables映射表在流程實(shí)例中傳遞業(yè)務(wù)數(shù)據(jù)
  3. 任務(wù)查詢:Activiti自動(dòng)維護(hù)任務(wù)狀態(tài),通過TaskQueryAPI查詢待辦
  4. 狀態(tài)持久化:所有流程狀態(tài)自動(dòng)持久化到數(shù)據(jù)庫(kù),保證一致性

有些小伙伴在工作中可能會(huì)遇到Activiti表太多的問題,其實(shí)這是因?yàn)樗捎?/span>分表設(shè)計(jì)ACT_RE_*存儲(chǔ)靜態(tài)定義,ACT_RU_*存儲(chǔ)運(yùn)行時(shí)數(shù)據(jù),ACT_HI_*存儲(chǔ)歷史數(shù)據(jù)。

這種設(shè)計(jì)既保證了運(yùn)行時(shí)性能,又支持歷史追溯。

三、Flowable:Activiti的性能優(yōu)化版

Flowable是Activiti的原班人馬創(chuàng)建的分支項(xiàng)目,在性能和云原生支持方面有顯著改進(jìn)。

它完全兼容Activiti的API,但內(nèi)部進(jìn)行了大量?jī)?yōu)化。

核心原理

Flowable在Activiti的基礎(chǔ)上引入了異步執(zhí)行器執(zhí)行樹優(yōu)化。

它通過更精細(xì)的鎖管理和批量處理來提升高并發(fā)下的性能。

架構(gòu)改進(jìn)

  • 增強(qiáng)的異步執(zhí)行器,支持批量操作
  • 優(yōu)化的執(zhí)行樹結(jié)構(gòu),減少數(shù)據(jù)庫(kù)訪問
  • 更好的緩存管理和懶加載策略
  • 原生支持Spring Boot Starter

開源地址

GitHub: https://github.com/flowable/flowable-engine

示例:訂單處理流程(含服務(wù)任務(wù))

Flowable特別擅長(zhǎng)處理自動(dòng)化業(yè)務(wù)流程,下面是一個(gè)訂單處理示例:

@Service
publicclass OrderProcessService {
    
    @Autowired
    private RuntimeService runtimeService;
    
    @Autowired
    private RepositoryService repositoryService;
    
    // 部署訂單流程
    public void deployOrderProcess() {
        repositoryService.createDeployment()
            .addClasspathResource("processes/order-process.bpmn20.xml")
            .addClasspathResource("processes/order-discount.dmn") // DMN決策表
            .deploy();
    }
    
    // 啟動(dòng)訂單流程
    public void startOrderProcess(Order order) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("order", order);
        variables.put("customerService", "cs_team");
        variables.put("warehouse", "wh_team");
        
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
            "orderProcess", order.getOrderNo(), variables);
        
        logger.info("訂單流程啟動(dòng): {}", processInstance.getId());
    }
}

// 服務(wù)任務(wù)處理器 - 庫(kù)存檢查
@Component
publicclass InventoryCheckDelegate implements JavaDelegate {
    
    @Autowired
    private InventoryService inventoryService;
    
    @Override
    public void execute(DelegateExecution execution) {
        Order order = (Order) execution.getVariable("order");
        
        // 調(diào)用庫(kù)存服務(wù)檢查庫(kù)存
        boolean inStock = inventoryService.checkInventory(
            order.getProductId(), order.getQuantity());
        
        execution.setVariable("inStock", inStock);
        
        if (!inStock) {
            execution.setVariable("needBackorder", true);
            logger.warn("產(chǎn)品{}庫(kù)存不足,需要備貨", order.getProductId());
        }
    }
}

// 服務(wù)任務(wù)處理器 - 支付處理
@Component
publicclass PaymentProcessDelegate implements JavaDelegate {
    
    @Autowired
    private PaymentService paymentService;
    
    @Override
    public void execute(DelegateExecution execution) {
        Order order = (Order) execution.getVariable("order");
        
        try {
            // 調(diào)用支付網(wǎng)關(guān)
            PaymentResult result = paymentService.processPayment(order);
            execution.setVariable("paymentSuccess", result.isSuccess());
            execution.setVariable("paymentId", result.getPaymentId());
            
        } catch (Exception e) {
            execution.setVariable("paymentSuccess", false);
            execution.setVariable("paymentError", e.getMessage());
            thrownew RuntimeException("支付處理失敗", e);
        }
    }
}

對(duì)應(yīng)的BPMN流程包含服務(wù)任務(wù):

<process id="orderProcess" name="訂單處理流程">
    <startEvent id="start" />
    
    <!-- 庫(kù)存檢查服務(wù)任務(wù) -->
    <serviceTask id="inventoryCheck" name="庫(kù)存檢查"
                 activiti:class="com.example.InventoryCheckDelegate"/>
    
    <!-- 庫(kù)存決策網(wǎng)關(guān) -->
    <exclusiveGateway id="inventoryDecision" />
    
    <!-- 有庫(kù)存流程 -->
    <sequenceFlow id="inStockFlow" sourceRef="inventoryDecision" targetRef="paymentProcess">
        <conditionExpression>${inStock == true}</conditionExpression>
    </sequenceFlow>
    
    <!-- 無庫(kù)存流程 -->
    <sequenceFlow id="outOfStockFlow" sourceRef="inventoryDecision" targetRef="backorderTask">
        <conditionExpression>${inStock == false}</conditionExpression>
    </sequenceFlow>
    
    <!-- 支付處理 -->
    <serviceTask id="paymentProcess" name="支付處理"
                 activiti:class="com.example.PaymentProcessDelegate"/>
    
    <!-- 備貨任務(wù) -->
    <userTask id="backorderTask" name="備貨處理" 
              activiti:assignee="#{warehouse}"/>
    
    <endEvent id="end" />
</process>

深度原理剖析

  1. 服務(wù)任務(wù)異步執(zhí)行:Flowable的JavaDelegate默認(rèn)支持異步執(zhí)行,避免阻塞主線程
  2. 執(zhí)行樹優(yōu)化:Flowable將流程執(zhí)行建模為執(zhí)行樹,減少狀態(tài)同步開銷
  3. 批量事件處理:多個(gè)流程實(shí)例的事件可以批量處理,提升吞吐量
  4. DMN集成:內(nèi)置DMN決策引擎,支持復(fù)雜業(yè)務(wù)規(guī)則

有些小伙伴在工作中處理高并發(fā)場(chǎng)景時(shí),F(xiàn)lowable的異步執(zhí)行器特別有用。

它能夠?qū)⒑臅r(shí)的服務(wù)任務(wù)放入消息隊(duì)列異步處理,避免數(shù)據(jù)庫(kù)長(zhǎng)事務(wù)。

四、Camunda:微服務(wù)架構(gòu)的首選

Camunda是另一個(gè)流行的Activiti分支,特別強(qiáng)調(diào)運(yùn)維監(jiān)控微服務(wù)集成能力。

它提供了完整的操作工具鏈。

核心原理

Camunda采用外部任務(wù)模式樂觀鎖并發(fā)控制。它的核心思想是將工作流引擎與業(yè)務(wù)服務(wù)解耦,通過外部任務(wù)隊(duì)列實(shí)現(xiàn)松耦合集成。

架構(gòu)特色

  • 外部任務(wù)模式,支持多語(yǔ)言客戶端
  • 完整的監(jiān)控工具Cockpit和Tasklist
  • 基于樂觀鎖的高并發(fā)控制
  • 原生支持微服務(wù)架構(gòu)模式

開源地址

GitHub: https://github.com/camunda/camunda-bpm-platform

示例:貸款審批流程(外部任務(wù)模式)

Camunda的外部任務(wù)模式特別適合微服務(wù)架構(gòu):

// 貸款申請(qǐng)DTO
@Data
publicclass LoanApplication {
    private String applicationId;
    private String applicantName;
    privatedouble amount;
    privateint duration;
    privatedouble income;
    privateint creditScore;
}

// 貸款流程啟動(dòng)服務(wù)
@Service
@Transactional
publicclass LoanProcessService {
    
    @Autowired
    private RuntimeService runtimeService;
    
    public void startLoanProcess(LoanApplication application) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("application", application);
        variables.put("creditCheckRequired", application.getAmount() > 100000);
        variables.put("autoApprovalLimit", 50000.0);
        
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
            "loanApprovalProcess", application.getApplicationId(), variables);
        
        logger.info("貸款流程啟動(dòng): {}", processInstance.getId());
    }
}

// 征信檢查外部任務(wù)工作者
@Component
publicclass CreditCheckWorker {
    
    @Autowired
    private ExternalTaskService externalTaskService;
    
    @Autowired
    private CreditService creditService;
    
    @PostConstruct
    public void startCreditCheckWorker() {
        new Thread(() -> {
            while (true) {
                try {
                    // 獲取外部任務(wù)
                    List<LockedExternalTask> tasks = externalTaskService
                        .fetchAndLock(10, "credit-check-worker")
                        .topic("credit-check", 60000L)
                        .execute();
                    
                    for (LockedExternalTask task : tasks) {
                        processCreditCheck(task);
                    }
                    
                    Thread.sleep(5000); // 5秒輪詢
                    
                } catch (Exception e) {
                    logger.error("征信檢查工作者異常", e);
                }
            }
        }).start();
    }
    
    private void processCreditCheck(LockedExternalTask task) {
        try {
            LoanApplication application = (LoanApplication) 
                task.getVariable("application");
            
            // 調(diào)用外部征信系統(tǒng)
            CreditReport report = creditService.getCreditReport(
                application.getApplicantName(), application.getApplicantId());
            
            Map<String, Object> variables = new HashMap<>();
            variables.put("creditReport", report);
            variables.put("creditScore", report.getScore());
            variables.put("creditCheckPassed", report.getScore() > 600);
            
            // 完成任務(wù)
            externalTaskService.complete(task.getId(), "credit-check-worker", variables);
            
            logger.info("征信檢查完成: {}", application.getApplicationId());
            
        } catch (Exception e) {
            // 處理失敗,解鎖任務(wù)以便重試
            externalTaskService.handleFailure(task.getId(), "credit-check-worker", 
                e.getMessage(), 3, 30000L);
        }
    }
}

// 風(fēng)險(xiǎn)評(píng)估外部任務(wù)工作者
@Component
publicclass RiskAssessmentWorker {
    
    @Autowired
    private RiskService riskService;
    
    public void startRiskAssessmentWorker() {
        // 類似的實(shí)現(xiàn)模式
        // 訂閱"risk-assessment"主題
    }
}

Camunda還提供強(qiáng)大的運(yùn)維監(jiān)控能力:

// 流程實(shí)例監(jiān)控
@Service
publicclass ProcessMonitorService {
    
    @Autowired
    private HistoryService historyService;
    
    @Autowired
    private ManagementService managementService;
    
    // 獲取流程實(shí)例統(tǒng)計(jì)
    public Map<String, Object> getProcessStats(String processDefinitionKey) {
        Map<String, Object> stats = new HashMap<>();
        
        // 運(yùn)行中實(shí)例數(shù)量
        long runningInstances = historyService.createHistoricProcessInstanceQuery()
            .processDefinitionKey(processDefinitionKey)
            .unfinished()
            .count();
        
        // 今日完成數(shù)量
        long todayCompleted = historyService.createHistoricProcessInstanceQuery()
            .processDefinitionKey(processDefinitionKey)
            .finishedAfter(TemporalUtil.todayStart())
            .count();
        
        // 平均處理時(shí)間
        HistoricProcessInstanceQuery query = historyService
            .createHistoricProcessInstanceQuery()
            .processDefinitionKey(processDefinitionKey)
            .finished();
        
        stats.put("runningInstances", runningInstances);
        stats.put("todayCompleted", todayCompleted);
        stats.put("avgDuration", calculateAverageDuration(query));
        
        return stats;
    }
}

架構(gòu)深度解析

  1. 外部任務(wù)模式:業(yè)務(wù)邏輯在引擎外部執(zhí)行,支持多語(yǔ)言和技術(shù)棧
  2. 主題訂閱機(jī)制:工作者訂閱特定主題的任務(wù),實(shí)現(xiàn)關(guān)注點(diǎn)分離
  3. 樂觀鎖控制:通過版本號(hào)避免并發(fā)沖突,提高吞吐量
  4. 完整的運(yùn)維體系:Cockpit提供實(shí)時(shí)監(jiān)控,Optimize提供流程分析

Camunda的這種設(shè)計(jì)特別適合微服務(wù)架構(gòu),每個(gè)微服務(wù)可以獨(dú)立開發(fā)部署,通過外部任務(wù)與工作流引擎交互。

五、jBPM:規(guī)則集成的最佳選擇

jBPM是紅帽旗下的開源BPM套件,基于KIE(Knowledge Is Everything)平臺(tái),與Drools規(guī)則引擎深度集成。

核心原理

jBPM采用知識(shí)會(huì)話模式,將流程引擎和規(guī)則引擎統(tǒng)一在同一個(gè)會(huì)話中。

這種設(shè)計(jì)使得業(yè)務(wù)流程和業(yè)務(wù)規(guī)則能夠無縫協(xié)作。

架構(gòu)特色

  • 與Drools規(guī)則引擎深度集成
  • 基于知識(shí)會(huì)話的統(tǒng)一執(zhí)行環(huán)境
  • 支持BPMN 2.0和CMN(案例管理)
  • 完整的生命周期管理

開源地址

GitHub: https://github.com/kiegroup/jbpm

示例:保險(xiǎn)理賠流程(規(guī)則集成)

jBPM最大的優(yōu)勢(shì)在于規(guī)則和流程的集成:

// 保險(xiǎn)理賠DTO
@Data
publicclass InsuranceClaim {
    private String claimId;
    private String policyNumber;
    private String claimType; // AUTO, HEALTH, PROPERTY
    privatedouble claimAmount;
    private Date incidentDate;
    private String description;
    privateboolean fraudulent = false;
    privatedouble approvedAmount = 0.0;
}

// 理賠流程服務(wù)
@Service
publicclass ClaimProcessService {
    
    @Autowired
    private RuntimeEngine runtimeEngine;
    
    @Autowired
    private KieContainer kieContainer;
    
    public void startClaimProcess(InsuranceClaim claim) {
        // 創(chuàng)建KIE會(huì)話
        KieSession kieSession = kieContainer.newKieSession();
        
        try {
            // 插入事實(shí)對(duì)象到規(guī)則引擎
            kieSession.insert(claim);
            kieSession.insert(new Date());
            
            // 啟動(dòng)流程實(shí)例
            ProcessInstance processInstance = runtimeEngine.getKieSession()
                .startProcess("claimApprovalProcess", 
                    createProcessVariables(claim));
            
            logger.info("理賠流程啟動(dòng): {}", processInstance.getId());
            
        } finally {
            kieSession.dispose();
        }
    }
    
    private Map<String, Object> createProcessVariables(InsuranceClaim claim) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("claim", claim);
        variables.put("claimAmount", claim.getClaimAmount());
        variables.put("claimType", claim.getClaimType());
        variables.put("autoApprovalLimit", 5000.0);
        variables.put("requiresManagerApproval", claim.getClaimAmount() > 10000);
        return variables;
    }
}

// 欺詐檢測(cè)規(guī)則(DRL文件)
rule "High Amount Fraud Detection"
    when
        $claim : InsuranceClaim(claimAmount > 50000)
        Date() // 當(dāng)前日期
    then
        $claim.setFraudulent(true);
        modify($claim);
        System.out.println("檢測(cè)到大額理賠,標(biāo)記為可疑欺詐: " + $claim.getClaimId());
end

rule "Quick Claim Fraud Detection"
    when
        $claim : InsuranceClaim(incidentDate after [30d] )
        // 事故日期在30天內(nèi)的快速理賠
    then
        $claim.setFraudulent(true);
        modify($claim);
        System.out.println("快速理賠標(biāo)記為可疑: " + $claim.getClaimId());
end

rule "Auto Approval for Small Claims"
    when
        $claim : InsuranceClaim(claimAmount <= 5000, fraudulent == false)
    then
        $claim.setApprovedAmount($claim.getClaimAmount());
        modify($claim);
        System.out.println("小額理賠自動(dòng)批準(zhǔn): " + $claim.getClaimId());
end

流程定義中集成規(guī)則任務(wù):

<process id="claimApprovalProcess" name="保險(xiǎn)理賠審批流程">
    
    <startEvent id="start" />
    
    <!-- 規(guī)則任務(wù):欺詐檢測(cè) -->
    <businessRuleTask id="fraudDetection" name="欺詐檢測(cè)"
                      g:ruleFlowGroup="fraud-detection" />
    
    <!-- 網(wǎng)關(guān):基于欺詐檢測(cè)結(jié)果路由 -->
    <exclusiveGateway id="fraudDecision" />
    
    <!-- 檢測(cè)到欺詐 -->
    <sequenceFlow id="fraudDetected" sourceRef="fraudDecision" targetRef="investigateFraud">
        <conditionExpression>${claim.fraudulent == true}</conditionExpression>
    </sequenceFlow>
    
    <!-- 無欺詐 -->
    <sequenceFlow id="noFraud" sourceRef="fraudDecision" targetRef="approvalDecision">
        <conditionExpression>${claim.fraudulent == false}</conditionExpression>
    </sequenceFlow>
    
    <!-- 規(guī)則任務(wù):自動(dòng)理賠決策 -->
    <businessRuleTask id="approvalDecision" name="理賠決策"
                      g:ruleFlowGroup="claim-approval" />
    
    <!-- 欺詐調(diào)查人工任務(wù) -->
    <userTask id="investigateFraud" name="欺詐調(diào)查"
              g:assignee="fraud_investigator" />
    
    <endEvent id="end" />
</process>

深度集成原理

  1. 統(tǒng)一知識(shí)會(huì)話:流程實(shí)例和規(guī)則引擎共享同一個(gè)KIE會(huì)話
  2. 事實(shí)對(duì)象同步:流程變量自動(dòng)作為事實(shí)插入規(guī)則引擎
  3. 規(guī)則流組:通過規(guī)則流組控制規(guī)則執(zhí)行順序
  4. 動(dòng)態(tài)規(guī)則更新:支持運(yùn)行時(shí)更新業(yè)務(wù)規(guī)則而不影響流程實(shí)例

有些小伙伴在處理復(fù)雜業(yè)務(wù)規(guī)則時(shí),jBPM的這種集成模式特別有價(jià)值。

比如在風(fēng)控場(chǎng)景中,反欺詐規(guī)則經(jīng)常變化,使用jBPM可以獨(dú)立更新規(guī)則而不需要修改流程定義。

六、JDEasyFlow:輕量級(jí)流程編排新星

JDEasyFlow是京東自研的輕量級(jí)流程編排組件,特點(diǎn)是簡(jiǎn)單、靈活、易擴(kuò)展。

它適用于不需要完整BPMN功能的簡(jiǎn)單場(chǎng)景。

核心原理

JDEasyFlow采用基于JSON的流程定義狀態(tài)機(jī)引擎。

它的設(shè)計(jì)理念是"約定優(yōu)于配置",通過簡(jiǎn)單的節(jié)點(diǎn)定義實(shí)現(xiàn)靈活的流程編排。

架構(gòu)特色

  • 基于JSON的聲明式流程定義
  • 無數(shù)據(jù)庫(kù)依賴,純內(nèi)存執(zhí)行
  • 支持BPMN元素子集
  • 極低的學(xué)習(xí)成本

開源地址

GitHub: https://github.com/JDEasyFlow/jd-easyflow

示例:簡(jiǎn)單訂單狀態(tài)流轉(zhuǎn)

JDEasyFlow特別適合簡(jiǎn)單的狀態(tài)機(jī)場(chǎng)景:

首先引入依賴:

<dependency>
    <groupId>com.jd.easyflow</groupId>
    <artifactId>easyflow-flow</artifactId>
    <version>1.2.0</version>
</dependency>

定義訂單狀態(tài)流程JSON:

{
  "id": "order_flow",
"name": "訂單狀態(tài)流程",
"nodes": [
    {
      "id": "created",
      "name": "訂單創(chuàng)建",
      "start": true,
      "post": {
        "to": "paid"
      }
    },
    {
      "id": "paid",
      "name": "已支付",
      "action": {
        "createExp": "new com.example.order.PaymentAction()"
      },
      "post": {
        "to": "shipped"
      }
    },
    {
      "id": "shipped",
      "name": "已發(fā)貨",
      "action": {
        "createExp": "new com.example.order.ShipmentAction()"
      },
      "post": {
        "to": "received"
      }
    },
    {
      "id": "received",
      "name": "已收貨",
      "action": {
        "createExp": "new com.example.order.ReceiveAction()"
      },
      "post": {
        "to": "completed"
      }
    },
    {
      "id": "completed",
      "name": "已完成"
    },
    {
      "id": "cancelled",
      "name": "已取消"
    }
  ]
}

Java節(jié)點(diǎn)動(dòng)作實(shí)現(xiàn):

// 支付節(jié)點(diǎn)動(dòng)作
@Component
publicclass PaymentAction implements FlowNodeAction {
    
    @Autowired
    private PaymentService paymentService;
    
    @Override
    public Object execute(FlowRequest request, FlowContext context) {
        String orderId = (String) request.getParam("orderId");
        
        // 執(zhí)行支付邏輯
        PaymentResult result = paymentService.confirmPayment(orderId);
        
        // 設(shè)置節(jié)點(diǎn)輸出
        Map<String, Object> resultData = new HashMap<>();
        resultData.put("paymentId", result.getPaymentId());
        resultData.put("paymentTime", result.getPaymentTime());
        resultData.put("success", result.isSuccess());
        
        logger.info("訂單{}支付處理完成", orderId);
        
        return resultData;
    }
}

// 發(fā)貨節(jié)點(diǎn)動(dòng)作
@Component
publicclass ShipmentAction implements FlowNodeAction {
    
    @Autowired
    private LogisticsService logisticsService;
    
    @Override
    public Object execute(FlowRequest request, FlowContext context) {
        String orderId = (String) request.getParam("orderId");
        
        // 調(diào)用物流服務(wù)發(fā)貨
        ShipmentInfo shipment = logisticsService.createShipment(orderId);
        
        Map<String, Object> resultData = new HashMap<>();
        resultData.put("shipmentId", shipment.getShipmentId());
        resultData.put("shipmentTime", shipment.getShipmentTime());
        resultData.put("logisticsCompany", shipment.getCompany());
        
        logger.info("訂單{}發(fā)貨完成,物流單號(hào): {}", orderId, shipment.getShipmentId());
        
        return resultData;
    }
}

流程引擎配置和使用:

@Configuration
publicclass EasyFlowConfig {
    
    @Bean
    public FlowEngine flowEngine() {
        FlowEngineImpl flowEngine = new FlowEngineImpl();
        flowEngine.setFlowPath("classpath:flows/order_flow.json");
        flowEngine.init();
        return flowEngine;
    }
}

@Service
publicclass OrderFlowService {
    
    @Autowired
    private FlowEngine flowEngine;
    
    // 執(zhí)行訂單流程
    public void processOrder(String orderId, String action) {
        Map<String, Object> params = new HashMap<>();
        params.put("orderId", orderId);
        params.put("action", action);
        
        FlowParam flowParam = new FlowParam("order_flow", params);
        
        // 執(zhí)行流程
        FlowResult result = flowEngine.execute(flowParam);
        
        if (result.isSuccess()) {
            logger.info("訂單流程執(zhí)行成功: {}", result.getNodeIds());
        } else {
            logger.error("訂單流程執(zhí)行失敗: {}", result.getMessage());
            thrownew RuntimeException("流程執(zhí)行失敗: " + result.getMessage());
        }
    }
    
    // 獲取下一個(gè)可用節(jié)點(diǎn)
    public List<String> getNextNodes(String orderId, String currentNode) {
        Map<String, Object> params = new HashMap<>();
        params.put("orderId", orderId);
        
        FlowParam flowParam = new FlowParam("order_flow", params);
        
        // 解析流程定義,獲取后續(xù)節(jié)點(diǎn)
        return flowEngine.getNextNodes(flowParam, currentNode);
    }
}

輕量級(jí)架構(gòu)解析

  1. JSON定義:通過簡(jiǎn)單的JSON結(jié)構(gòu)定義節(jié)點(diǎn)和流轉(zhuǎn)
  2. 無持久化:純內(nèi)存執(zhí)行,性能極高
  3. 插件化動(dòng)作:通過接口實(shí)現(xiàn)業(yè)務(wù)邏輯
  4. 條件支持:支持簡(jiǎn)單的條件表達(dá)式路由

JDEasyFlow的這種設(shè)計(jì)特別適合服務(wù)編排簡(jiǎn)單狀態(tài)機(jī)場(chǎng)景。

有些小伙伴在微服務(wù)架構(gòu)中需要編排多個(gè)服務(wù)調(diào)用,但又不想引入沉重的BPMN引擎,JDEasyFlow是完美選擇。

七、五種工作流引擎全面對(duì)比

為了幫助大家更好地進(jìn)行技術(shù)選型,我整理了這五種工作流引擎的詳細(xì)對(duì)比:

特性維度

Activiti

Flowable

Camunda

jBPM

JDEasyFlow

學(xué)習(xí)曲線

中等

中等

較陡

較陡

簡(jiǎn)單

性能

良好

優(yōu)秀

優(yōu)秀

良好

極佳

功能完備性

很高

中等

監(jiān)控運(yùn)維

基礎(chǔ)

良好

優(yōu)秀

良好

簡(jiǎn)單

社區(qū)生態(tài)

活躍

活躍

活躍

活躍

一般

云原生支持

基礎(chǔ)

良好

優(yōu)秀

良好

良好

規(guī)則集成

基礎(chǔ)

基礎(chǔ)

良好

優(yōu)秀

適用場(chǎng)景

傳統(tǒng)企業(yè)應(yīng)用

高性能業(yè)務(wù)

微服務(wù)架構(gòu)

規(guī)則密集型

輕量級(jí)編排

為了更直觀地展示選型邏輯,我畫了一個(gè)決策流程圖:

圖片圖片

八、總結(jié)

下面我們來總結(jié)一下工作流引擎選型的一些建議:

  1. 傳統(tǒng)企業(yè)級(jí)應(yīng)用:選擇Activiti,生態(tài)成熟,文檔豐富,遇到問題容易找到解決方案
  2. 高性能高并發(fā)場(chǎng)景:選擇Flowable,它在Activiti基礎(chǔ)上做了大量性能優(yōu)化
  3. 微服務(wù)架構(gòu):選擇Camunda,外部任務(wù)模式完美契合微服務(wù)理念,運(yùn)維監(jiān)控工具完善
  4. 規(guī)則密集型業(yè)務(wù):選擇jBPM,與Drools規(guī)則引擎深度集成,適合風(fēng)控、保險(xiǎn)等場(chǎng)景
  5. 輕量級(jí)服務(wù)編排:選擇JDEasyFlow,簡(jiǎn)單靈活,學(xué)習(xí)成本低,無外部依賴

有些小伙伴在工作中可能會(huì)想:"能不能一個(gè)項(xiàng)目用多種工作流引擎?"

我的經(jīng)驗(yàn)是:可以,但要明確邊界。

比如用Camunda管理核心業(yè)務(wù)流程,用JDEasyFlow做微服務(wù)內(nèi)部編排。

最后記?。?/span>沒有最好的工作流引擎,只有最合適的。

選型時(shí)要綜合考慮團(tuán)隊(duì)技術(shù)棧、業(yè)務(wù)場(chǎng)景、性能要求和運(yùn)維能力。

責(zé)任編輯:武曉燕 來源: 蘇三說技術(shù)
相關(guān)推薦

2025-11-10 02:11:00

2024-12-11 08:20:57

設(shè)計(jì)模式源碼

2025-11-18 08:22:56

2025-08-12 08:22:29

2024-03-18 08:22:15

OOM問題java線上問題

2021-10-14 11:34:05

技術(shù)工作流引擎

2024-04-28 11:22:18

2024-05-09 08:19:09

OOMJVM內(nèi)存

2015-07-14 09:26:28

微型工作流引擎設(shè)計(jì)

2023-01-04 08:02:16

工作流架構(gòu)設(shè)計(jì)

2023-07-05 09:48:44

Activiti部署

2011-12-14 09:58:58

JavajBPM

2023-08-02 18:48:23

Flowable工作流引擎

2009-06-11 14:43:34

jbpm工作流引擎jBPM搭建

2009-09-01 18:26:23

C#工作流引擎

2024-10-17 08:39:32

2021-09-16 11:02:49

Python線程

2021-03-12 06:44:09

Argo Workfl開源項(xiàng)目

2022-10-26 08:00:43

Activiti工作流BPM

2021-12-17 08:39:39

SpringbootActiviti網(wǎng)關(guān)路由
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

日韩mv欧美mv国产网站| 狠狠人妻久久久久久综合麻豆| 国产免费久久| 日韩一区二区免费在线电影| 日韩伦理在线免费观看| 欧美一区激情视频在线观看| 伊人免费在线| 伊人精品在线| 国产一区二区三区欧美| 亚洲女人在线观看| www.色在线| 中文字幕日韩av资源站| 狠狠色综合一区二区| 在线观看免费视频a| 亚洲精选成人| 久久影视电视剧免费网站| 老鸭窝一区二区| 婷婷视频一区二区三区| 欧美日韩一级黄| 日本韩国欧美在线观看| 国产视频中文字幕在线观看| 久久精品夜色噜噜亚洲a∨ | 国产一区二区三区影视| 亚洲国产视频网站| 欧美日韩视频免费在线观看| 精品视频一二三| 成人黄色大片在线观看| 91久久久国产精品| 国语对白做受69按摩| 99精品欧美| 在线成人激情| 亚洲一区二区中文在线| 亚洲国产精品久久久久久女王| 亚洲奶汁xxxx哺乳期| 久久国产麻豆精品| 国产成人精品视| 看片网址国产福利av中文字幕| 欧美先锋影音| 久久久精品国产| 欧美另类69xxxx| 蜜臀久久99精品久久一区二区| 精品久久久久一区| 亚洲熟女乱综合一区二区| 小说区图片区亚洲| 欧美视频第二页| 黄色av免费在线播放| 一本大道色婷婷在线| 亚洲6080在线| 免费看国产曰批40分钟| 俺来也官网欧美久久精品| 一区二区三区中文在线观看| 天天操天天干天天玩| 巨大荫蒂视频欧美另类大| 中文av字幕一区| 亚洲免费视频一区| 在线激情网站| 国产精品福利在线播放| 伊人久久大香线蕉精品| 麻豆影院在线| 亚洲激情自拍视频| 国产黄色激情视频| 丁香花电影在线观看完整版| 午夜av一区二区| 欧美牲交a欧美牲交aⅴ免费下载| 小早川怜子影音先锋在线观看| 欧美日韩精品在线| 日韩亚洲在线视频| 久久久久久久性潮| 91精选在线观看| 岛国精品一区二区三区| 日韩高清成人在线| 亚洲欧美激情一区| 国产又粗又长又硬| 欧美视频二区| 青草青草久热精品视频在线网站| 久国产精品视频| 97人妻精品一区二区三区免| www一区二区三区| 欧美一区二区三区四区五区| 久久人妻少妇嫩草av蜜桃| 国产精东传媒成人av电影| 亚洲国产日韩欧美综合久久 | 99精品视频中文字幕| 欧美高清一区二区| 在线免费观看黄色av| 依依成人综合视频| 日本久久久精品视频| 免费视频成人| 精品免费视频.| 强伦人妻一区二区三区| 欧美大人香蕉在线| 国外视频精品毛片| 中文有码在线播放| 国产成人精品免费视频网站| 欧美xxxx黑人又粗又长密月| 色网站免费在线观看| 亚洲国产日韩a在线播放| 欧美视频在线播放一区| 欧美一级在线| 亚洲精品美女免费| 色偷偷男人天堂| 亚洲激情视频| 91精品久久久久久久久久另类| 国产 日韩 欧美 综合| 国产亚洲精品aa午夜观看| 日韩精品手机在线观看| 欧美激情喷水| 日韩免费一区二区| 国产熟女一区二区| 伊人天天综合| 成人在线精品视频| 九色在线播放| 亚洲大片精品永久免费| 一区二区三区四区毛片| 在线日韩网站| 久久全球大尺度高清视频| 国产精品美女一区| 国产日韩视频一区二区三区| 国产aaa免费视频| 中文成人激情娱乐网| 亚洲男人av在线| 日本少妇性高潮| 国产一本一道久久香蕉| 久久中文娱乐网| 91精品视频免费观看| 精品美女视频在线观看免费软件 | 久久免费视频2| 欧美大片免费观看网址| 亚洲国产又黄又爽女人高潮的| 午夜精品一区二区三级视频| 日韩电影在线免费看| 久久精品国产美女| 国产三级伦理在线| 欧美一区二区三区电影| 羞羞在线观看视频| 日本视频中文字幕一区二区三区| 久久精品aaaaaa毛片| 福利在线导航136| 欧美一区欧美二区| 国精产品久拍自产在线网站| 日韩在线观看一区二区| 欧美日本亚洲| 中老年在线免费视频| 日韩精品中文字幕久久臀| 欧美三级一区二区三区| 不卡的av电影| www.爱色av.com| 日本一区福利在线| 欧美综合在线观看| 久香视频在线观看| 91豆麻精品91久久久久久| 37p粉嫩大胆色噜噜噜| 午夜在线一区| 日产中文字幕在线精品一区| 台湾成人免费视频| 中文在线资源观看视频网站免费不卡| 中文字幕 国产精品| 欧美激情一区二区三区在线| 韩国一区二区av| 欧美久久综合网| 91精品久久久久久久久青青| 中文在线观看免费| 欧美成人vr18sexvr| 久久精品免费av| 久久综合九色综合97_久久久| 99色精品视频| 欧美一级精品| 91亚洲一区精品| 91在线三级| 国产视频精品免费播放| 中文亚洲av片在线观看| 亚洲日本丝袜连裤袜办公室| 久久久精品人妻一区二区三区| 成人自拍av| 精品一二三区| 日本一本a高清免费不卡| 高清日韩av电影| 欧美一级国产精品| 日本熟妇一区二区| 国产亚洲人成网站| 亚洲网中文字幕| 日韩亚洲国产欧美| 日韩中文一区二区三区| 国产一区二区三区免费观看在线 | 亚洲精品在线视频观看| 国产精品一区二区三区www| 久久久久久久久久久免费精品| 亚洲 美腿 欧美 偷拍| 欧美日韩一本到| 久久久国产精品黄毛片| 久久久亚洲综合| www.偷拍.com| 丝瓜av网站精品一区二区| 亚洲欧美一二三| 网曝91综合精品门事件在线| 国产日韩精品综合网站| 狠狠操一区二区三区| 色偷偷9999www| 天堂中文在线资源| 欧美精品vⅰdeose4hd| 日韩精品一区二区在线播放| 中文字幕亚洲一区二区va在线| 国产婷婷在线观看| 九色|91porny| 日本精品www| 一区二区三区在线| 手机成人在线| 日韩欧美四区| 99在线视频免费观看| 欧美日韩亚洲国产| 91精品国产91久久久久久久久| 久草中文在线| 亚洲欧美日韩成人| 秋霞视频一区二区| 4438x成人网最大色成网站| 欧美成人精品| 98精品在线视频| 老司机精品影院| 精品调教chinesegay| 国产农村老头老太视频| 日本高清不卡aⅴ免费网站| 国产一级视频在线观看| 亚洲欧洲成人精品av97| 中文字幕第4页| 成人免费观看av| 日韩av加勒比| 麻豆专区一区二区三区四区五区| 欧美一区二区在线播放| 波多野结衣家庭教师视频| 欧美搞黄网站| 正在播放一区| 成人激情开心网| 日本一区二区三区四区在线观看| 国产精品15p| 国产精品美女久久久久av福利| 91麻豆精品| 国产一区视频在线| jizz久久久久久| 国产精品日韩在线一区| 99re66热这里只有精品4| 91精品国产乱码久久久久久蜜臀 | 亚洲精品第一国产综合野| 国产大屁股喷水视频在线观看| 国产亚洲一区字幕| 蜜桃精品成人影片| 成人av片在线观看| 李丽珍裸体午夜理伦片| 成人一区二区三区视频在线观看| 无码国产精品一区二区高潮| 国产资源在线一区| 伊人国产精品视频| 国产精品资源网站| 岛国精品一区二区三区| caoporn国产精品| 亚洲国产果冻传媒av在线观看| 99免费精品在线| 免费观看av网站| 亚洲国产精品ⅴa在线观看| 国产成人精品视频免费| 综合久久综合久久| 印度午夜性春猛xxx交| 国产 日韩 欧美 精品| 日韩av在线播放中文字幕| 丝袜亚洲另类欧美重口| 亚洲欧洲国产综合| 亚洲人成电影网站色www| 国产高清免费av在线| 深夜精品寂寞黄网站在线观看| 秋霞成人影院| 欧美日本亚洲视频| 爱啪啪综合导航| 国产成人在线视频| 99精品视频在线免费播放| 91精品免费| 人人网欧美视频| 日韩欧美视频第二区| 亚洲人体av| 热99这里只有精品| 免费在线观看成人| 北条麻妃亚洲一区| 972aa.com艺术欧美| 一级黄色录像毛片| 一区二区三区精品| 欧美精品韩国精品| 在线观看91精品国产麻豆| 亚洲欧美另类综合| 国产亚洲精品久久久| 国产视频在线播放| 456国产精品| 91成人福利社区| 久久精品综合一区| 99久久久久国产精品| 日日碰狠狠添天天爽超碰97| 国产欧美一区二区| 最新国产露脸在线观看| 国内自拍欧美激情| 成人高清一区| 国产九区一区在线| 日韩欧美一区二区三区免费看| 国产专区在线视频| 日韩精品亚洲一区| 国产精品久久久久野外| 国产日韩欧美精品一区| 久久综合色综合| 在线精品观看国产| 日本免费一区视频| 久久精品免费播放| 欧美大电影免费观看| 国产91精品一区二区绿帽| 日韩在线看片| 日本中文字幕片| av不卡在线播放| 欧美黑人猛猛猛| 欧美日韩和欧美的一区二区| 色哟哟在线观看| 久久青草福利网站| 亚洲精品在线播放| 天堂v在线视频| 日本亚洲天堂网| 精品国产av无码| 婷婷成人激情在线网| 成人黄色免费视频| 久久精品色欧美aⅴ一区二区| 日本精品另类| 欧美激情专区| 国产精品五区| 国产美女视频免费观看下载软件| 亚洲免费观看高清完整版在线 | 久久丁香综合五月国产三级网站| 人妻丰满熟妇aⅴ无码| 亚洲va欧美va人人爽| 亚洲乱熟女一区二区| 欧美理论片在线观看| 999精品嫩草久久久久久99| 亚洲成人一区二区三区| 久久久久欧美精品| 性色av蜜臀av色欲av| 午夜电影久久久| 午夜在线视频观看| 91精品国产乱码久久久久久久久 | 亚洲欧美成人一区| 日韩**一区毛片| 国产午夜精品福利视频| 欧洲视频一区二区| 懂色av中文在线| 国产精品美女主播| 日韩综合网站| 小明看看成人免费视频| 国产精品第一页第二页第三页| 亚洲无码精品国产| 久久久精品久久| 一区二区在线免费播放| 97干在线视频| 99r精品视频| 三级网站在线播放| 在线观看欧美日韩| 天堂久久一区| 日本一道在线观看| 成人精品鲁一区一区二区| 日本少妇性生活| 亚洲嫩模很污视频| www.成人在线视频| 自拍另类欧美| 国产sm精品调教视频网站| 亚洲欧洲一区二区在线播放| 免费在线观看av的网站| 国产午夜精品视频免费不卡69堂| 在线一区视频观看| 一区在线电影| 懂色av一区二区三区免费看| 国产无遮挡又黄又爽又色| 精品一区二区三区电影| 成人1区2区| 伊人再见免费在线观看高清版 | 欧美日韩三级在线| 蜜桃视频在线观看www社区| 亚洲最大的成人网| 亚洲国产美女| 色婷婷久久综合| 特黄视频在线观看| 国产999在线观看| 午夜激情久久| 亚洲の无码国产の无码步美| 色老头久久综合| 怡红院在线观看| 欧美成ee人免费视频| 韩国视频一区二区| 久久久国产高清| 久久综合伊人77777尤物| 美女av一区| 日韩在线不卡一区| 欧美日韩国产中字| a免费在线观看| 欧美主播一区二区三区美女 久久精品人 | 中文字幕免费不卡| 性欧美8khd高清极品| 国产激情视频一区| 亚洲视频中文| 熟女少妇a性色生活片毛片| 日韩成人在线视频|