业务架构设计---硬件设备监控指标数据上报业务Java企业级架构

策略模式企业级实践------硬件设备监控指标数据上报

业务背景

河水水环境业务监测指标数据上报, 核心业务需求:

  • 多设备指标差异化处理:各设备,指标上报参数格式、加密方式、回调协议不同
  • 监测指标类型扩展:支持 水温,悬浮物,pH值,化学需氧量(COD),大肠菌群 等等30+业务指标类型
  • 高并发处理:日均处理百万级事件,峰值QPS 1000
  • 数据一致性:保证不同设备上报不同指标数据完整性

业务例子:比如设备A上报(该设备sn 时间 A指标 监测结果)数据,就会触发对应的URL(我们这边提供)

通过采用策略模式和事件驱动的设计,实现了对不同指标的灵活处理和扩展。

请求处理流程图

相似场景代码demo

策略容器

java 复制代码
package com.shsc.wms.biz;

import com.shsc.wms.common.annotation.PlatformHandler;
import com.shsc.wms.common.enums.TaskTypeEnum;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class TaskEtlContext {

    private final Map<TaskTypeEnum, TaskEtlTemplateService> handlerMap = new HashMap<>();

    public TaskEtlContext(Map<String, TaskEtlTemplateService> map) {
        map.forEach((k, v) -> {
            PlatformHandler annotation = v.getClass().getAnnotation(PlatformHandler.class);
            this.handlerMap.put(annotation.value(), v);
        });
    }

    public TaskEtlTemplateService getHandler(String code) {
        return handlerMap.get(code);
    }

}

策略标识注解

java 复制代码
package com.shsc.wms.common.annotation;

import com.shsc.wms.common.enums.TaskTypeEnum;
import org.springframework.stereotype.Component;

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface PlatformHandler {

    TaskTypeEnum value();

}

策略枚举类型

java 复制代码
package com.shsc.wms.common.enums;

/**
 * @desc 指标对照关系
 **/
public enum TaskTypeEnum {

    TASK_A("WarehouseReq", "AAAA");

    //入参类全路径
    private String req;
    //实体类全路径
    private String entity;

    TaskTypeEnum(String req, String entity) {
        this.req = req;
        this.entity = entity;
    }

    public String getReq() {
        return req;
    }

    public String getEntity() {
        return entity;
    }

}

策略抽象模版方法

java 复制代码
package com.shsc.wms.biz;

import com.shsc.wms.common.enums.EtlTaskStatusEnum;
import com.shsc.wms.entity.EtlTaskEntity;
import com.shsc.wms.mapper.etl.EtlTaskEntityMapper;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.List;

public abstract class TaskEtlTemplateService<T> {

    @Autowired
    private EtlTaskEntityMapper etlTaskEntityMapper;

    public final void handle(EtlTaskEntity taskEntity) {

        // 1 抓取数据
        List<T> items = extract(taskEntity);

        // 2 保存或者更新 指标结果
        saveOrUpdateResult(items);

        // 3 更新 task
        updateTask(taskEntity);

    }

    /**
     * 抓取数据
     */
    protected abstract List<T> extract(EtlTaskEntity taskEntity);

    /**
     * 保存或者更新 指标结果
     */
    protected abstract void saveOrUpdateResult(List<T> items);

    /**
     * 更新 task
     */
    public void updateTask(EtlTaskEntity taskEntity) {
        taskEntity.setStatus(EtlTaskStatusEnum.FINISH.getCode());
        taskEntity.setActualTime(new Date());
        etlTaskEntityMapper.updateById(taskEntity);
    }

}

具体策略实现Demo

java 复制代码
package com.shsc.wms.service;

import com.shsc.wms.biz.TaskEtlTemplateService;
import com.shsc.wms.common.annotation.PlatformHandler;
import com.shsc.wms.common.enums.TaskTypeEnum;
import com.shsc.wms.common.model.request.StoredLocationBatchReq;
import com.shsc.wms.entity.EtlTaskEntity;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.List;

@PlatformHandler(value = TaskTypeEnum.TASK_A)
@Slf4j
public class TaskAService extends TaskEtlTemplateService<StoredLocationBatchReq> {

    @Override
    protected List<StoredLocationBatchReq> extract(EtlTaskEntity taskEntity) {
        log.info("TaskAService TaskA 抓取数据");
        return Collections.emptyList();
    }

    @Override
    protected void saveOrUpdateResult(List<StoredLocationBatchReq> items) {
        log.info("TaskAService TaskA 保存数据");
    }


}

策略调用

java 复制代码
package com.shsc.wms.biz;

import com.shsc.wms.common.constant.CommonConstant;
import com.shsc.wms.common.core.ThreadUtil;
import com.shsc.wms.common.core.UserInfoEntity;
import com.shsc.wms.entity.EtlTaskEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

@Component
@Slf4j
public class EtlTask {

    @Autowired
    private TaskEtlContext taskEtlContext;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Async(value = CommonConstant.wmsEtlExecutor)
    public void runTask(EtlTaskEntity taskEntity, UserInfoEntity userHolder) {
        ThreadUtil.resetCurrentUserInfo(userHolder);

        // 获取任务处理器
        TaskEtlTemplateService handler = taskEtlContext.getHandler(taskEntity.getTaskType());

        if (handler == null) {
            log.error("未找到对应的任务处理器,任务类型:{}", taskEntity.getTaskType());
            return;
        }

        // 使用编程式事务
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                try {
                    // 处理任务
                    handler.handle(taskEntity);
                } catch (Exception e) {
                    // 发生异常时回滚事务
                    status.setRollbackOnly();
                    log.error("执行任务时发生异常,事务已回滚", e);
                }
            }
        });
    }

}
相关推荐
米粉0305几秒前
深入剖析Nginx:从入门到高并发架构实战
java·运维·nginx·架构
什么都想学的阿超15 分钟前
【Redis系列 04】Redis高可用架构实战:主从复制与哨兵模式从零到生产
数据库·redis·架构
JohnYan44 分钟前
Bun技术评估 - 03 HTTP Server
javascript·后端·bun
周末程序猿1 小时前
Linux高性能网络编程十谈|C++11实现22种高并发模型
后端·面试
ZHOU_WUYI1 小时前
Flask与Celery 项目应用(shared_task使用)
后端·python·flask
冒泡的肥皂2 小时前
强大的ANTLR4语法解析器入门demo
后端·搜索引擎·编程语言
IT_陈寒2 小时前
Element Plus 2.10.0 重磅发布!新增Splitter组件
前端·人工智能·后端
有梦想的攻城狮2 小时前
spring中的@RabbitListener注解详解
java·后端·spring·rabbitlistener
Java水解3 小时前
MySQL DQL全面解析:从入门到精通
后端·mysql
Aurora_NeAr3 小时前
Apache Spark详解
大数据·后端·spark