业务架构设计---硬件设备监控指标数据上报业务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);
                }
            }
        });
    }

}
相关推荐
李豆豆喵1 分钟前
第42天:WEB攻防-PHP应用&MYSQL架构&SQL注入&跨库查询&文件读写&权限操作
sql·mysql·架构
Seven972 分钟前
【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
java·后端·设计模式
梦醒沉醉20 分钟前
Scala的初步使用
开发语言·后端·scala
重庆穿山甲23 分钟前
建造者模式实战指南:场景案例+实战代码,新手也能快速上手
后端
小安同学iter1 小时前
Spring(七)AOP-代理模式
java·后端·spring
Goboy1 小时前
老婆问我:“大模型的 Token 究竟是个啥?”
后端·程序员·架构
前期后期1 小时前
Android Compose是如何使用什么架构,多个Activity?还是Fragment?compose的ui又是如何卸载和挂载的呢?
android·ui·架构·kotlin
子洋2 小时前
Chroma+LangChain:让AI联网回答更精准
前端·人工智能·后端
追逐时光者2 小时前
基于 .NET Blazor 开源、低代码、易扩展的插件开发框架
后端·.net
MZWeiei5 小时前
Scala:解构声明(用例子通俗易懂)
开发语言·后端·scala