实习文档背诵

实习内容:

1.定时任务与数据补全:基于 XXL-JOB 实现分布式定时任务调度,补全近半年历史操作日志数据,有效解决因网络异常导致的数据缺失问题。

业务场景;集团的4a日志半年内没有同步,这边需要把日志数据同步到集团上

首先先评估每天的数提量,因为我配照的是开发环境,所有的据量不全,让运维的同事宣询一下每天的数据量是多少?差不多是3.6w日志,那么据总量软是180*3.6=650w号数据知道数据的大概范围认后效开始确认调用天数,循环执行、最终根据实际情况,每15天循环一次,然后添加xx1-job注解。从job平台项用,补全数据朴全过程中断怎么办,可以通过Redis记录处理日期,重启后跳过,同时处理期间增加道暂间隔,减少数据库压大

合井数据库文件

java 复制代码
 //将操作日志数据同步到4A平台上,根据选取的日期,往前推15天,
    @XxlJob("syncLog4AJobNew")
    public void JobHandlerNew() throws IOException {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date curTime = null;
        Date endTime = null;
        try {
            curTime = sdf.parse("2024-12-10 00:00:00");
            endTime = sdf.parse("2025-05-08 22:00:00");
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        // 每次间隔的时间,单位ms
        long interval = 24 * 60 * 60 * 1000;
        int num = 1;
        while (curTime.before(endTime)) {
            Date nextTime = new Date(curTime.getTime() + interval);

            log.info("syncLog4AJobNew-4A日志同步任务:"+nextTime);

            String curFileName = null;
            BufferedWriter bufferedWriter = null;
            try {

                // 读取需要发的日志数据
                //List<OperateLogDto> logs = opLogService.queryOperateLog4ANew();
                List<OperateLogDto> logs = opLogService.queryOperateLog4ANew(nextTime);//填加时间范围
                log.info("syncLog4AJobNew-4A待发送日志查询成功,获取日志信息数为:" + logs.size());
                if (CollectionUtils.isEmpty(logs)) {
                    XxlJobHelper.log("无需要同步数据.");
                    curTime = nextTime;//修改
                    continue;
                }

                // 写入文件流
                int length = 0;
                int startId = 0, endId = 0;
                for (OperateLogDto logDto : logs) {
                    if (StringUtils.isBlank(logDto.getUserCode()))
                        continue;

                    if (curFileName == null)
                        curFileName = logConfig.getResourceCode() + "_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".xml";

                    if (bufferedWriter == null) {
                        bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(ftpConfig.getLocalPath() + curFileName), "UTF-8"));
                        bufferedWriter.write("<?xml version='1.0' encoding='UTF-8' ?><ROOT>");
                    }

                    if (startId == 0)
                        startId = logDto.getOperateLogId();

                    String generateLog = log4AUtil.generateLog(logDto.getToken(), logDto.getOperateLogId().toString(), logDto.getDoneDate(),
                            logDto.getUserCode(), logDto.getOperateTypeName(), logDto.getOperateTypeId(),
                            logDto.getOperateResult(), logDto.getModuleId(), logDto.getModuleName(),
                            logDto.getIp(), logDto.getOperateName());

                    bufferedWriter.write(new String(generateLog.getBytes("UTF-8"), "UTF-8"));
                    endId = logDto.getOperateLogId();
                    // 每个文件控制在5M到10M之间
                    length += generateLog.getBytes(StandardCharsets.UTF_8).length;
                    //当文件长度大于5则传送数据
                    if (length > fileLength) {
                        bufferedWriter.write("</ROOT>");
                        bufferedWriter.flush();

                        // 发送本地文件到4A
                        boolean ss = this.sendSftp(curFileName);
                        if (ss) {
                            opLogService.updateLog4A(startId, endId);
                            log.info("syncLog4AJobNew-4A日志同步任务成功,上传SFTP成功,传输数据范围为:" + startId + "-" + endId);
                        } else {
                            XxlJobHelper.log("4A日志同步任务失败。上传SFTP失败。");
                            XxlJobHelper.handleFail();
                            return;
                        }

                        // 初始化写入
                        curFileName = null;
                        bufferedWriter = null;
                        length = 0;
                        startId = 0;
                    }
                }
                //最后收尾,存在数据没有发送
                if (bufferedWriter != null) {
                    bufferedWriter.write("</ROOT>");
                    bufferedWriter.flush();

                    // 发送本地文件到4A
                    boolean ss = this.sendSftp(curFileName);
                    if (ss) {
                        opLogService.updateLog4A(startId, endId);
                        log.info("syncLog4AJobNew-4A日志同步任务成功,上传SFTP成功,传输数据范围为:" + startId + "-" + endId);
                    } else {
                        XxlJobHelper.log("4A日志同步任务失败。上传SFTP失败。");
                        XxlJobHelper.handleFail();
                    }
                }

                XxlJobHelper.handleSuccess("4A日志同步任务成功");
            } catch (Exception e) {
                log.error("4A日志同步任务失败。" + e);
                XxlJobHelper.log("4A日志同步任务失败。" + e.getMessage());
                XxlJobHelper.handleFail();
            } finally {
                if (bufferedWriter != null)
                    bufferedWriter.close();
            }
            curTime = nextTime;

            log.info("======SyncLog4AJob.JobHandlerNew()," + num + "," + sdf.format(curTime));
            num++;
        }
    }

2.数据安全与合规控制:通过 SpringAOP 自动脱敏敏感字段,结合 SpringSecurily+ 数据权限注解 实现细粒度访问控制,确保数据隔离与合规性。

aop切面

java 复制代码
package com.asiainfo.osm.aop;

import com.asiainfo.osm.common.result.ResultObject;
import com.asiainfo.osm.common.result.ResultPage;
import com.asiainfo.osm.common.user.dto.UserDTO;
import com.asiainfo.osm.system.dto.UserExtDTO;
import com.asiainfo.osm.system.dto.UserInfoDTO;
import com.asiainfo.osm.utils.DesensitizationUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 脱敏切面
 *
 * @author renhx
 * @createDate 2025/5/9 19:29
 **/
@Aspect
@Component
public class SensitiveDataAspect {

    @Around("execution(* com.asiainfo.osm.system.web.UserController.getUsers(..)) || " +
            "execution(* com.asiainfo.osm.system.web.UserController.getUserInfo(Integer)) ||" +
            "execution(* com.asiainfo.osm.system.web.UserController.queryUserInfo(Integer))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = joinPoint.proceed();
        return processSensitiveData(result);
    }

    private Object processSensitiveData(Object obj) {
        if (obj == null) {
            return null;
        }

        // 人员信息下拉列表出参
        if (obj instanceof UserInfoDTO) {
            UserInfoDTO user = (UserInfoDTO) obj;
            user.setUserName(DesensitizationUtils.chineseName(user.getUserName()));
            user.setEmail(DesensitizationUtils.email(user.getEmail()));
            return user;
        }

        // 用户详情出参
        if (obj instanceof UserDTO) {
            UserDTO user = (UserDTO) obj;
            user.setUserName(DesensitizationUtils.chineseName(user.getUserName()));
            user.setPhone(DesensitizationUtils.mobilePhone(user.getPhone()));
            user.setEmail(DesensitizationUtils.email(user.getEmail()));
            return user;
        }

        // 用户列表出参
        if (obj instanceof UserExtDTO) {
            UserExtDTO user = (UserExtDTO) obj;
            user.setUserName(DesensitizationUtils.chineseName(user.getUserName()));
            user.setPhone(DesensitizationUtils.mobilePhone(user.getPhone()));
            user.setEmail(DesensitizationUtils.email(user.getEmail()));
            return user;
        }

        if (obj instanceof List) {
            List<?> list = (List<?>) obj;
            return list.stream()
                    .map(this::processSensitiveData)
                    .collect(Collectors.toList());
        }

        if (obj instanceof ResultPage) {
            ResultPage<?> resultPage = (ResultPage<?>) obj;
            List<?> pageData = resultPage.getPageData().stream()
                    .map(this::processSensitiveData)
                    .collect(Collectors.toList());
            return ResultPage.instance(resultPage.getTotal(),pageData);
        }

        if (obj instanceof ResultObject) {
            ResultObject<?> resultObject = (ResultObject<?>) obj;
            Object data = processSensitiveData(resultObject.getData());
            ResultObject<Object> resultObjectNew = new ResultObject<>();
            resultObjectNew.setCode(resultObject.getCode());
            resultObjectNew.setName(resultObject.getName());
            resultObjectNew.setMessage(resultObject.getMessage());
            resultObjectNew.setData(data);
            return resultObjectNew;
        }

        return obj;
    }
}

脱敏规则

java 复制代码
package com.asiainfo.osm.utils;

import org.apache.commons.lang.StringUtils;

/**
 * 脱敏工具
 *
 * @author renhx
 * @createDate 2025/5/10 8:19
 **/
public class DesensitizationUtils {

    // 姓名脱敏 (两字: 张* | 三字: 张*三 | 多字: 张**...三)
    public static String chineseName(String fullName) {
        if (StringUtils.isBlank(fullName)) {
            return "";
        }

        int length = fullName.length();
        if (length == 1) {
            return fullName; // 单字名不做处理
        }

        if (length == 2) {
            // 两字名: 张*
            return fullName.charAt(0) + "*";
        }

        if (length == 3) {
            // 三字名: 张*三
            return fullName.charAt(0) + "*" + fullName.charAt(2);
        }

        // 多字名: 张**...三
        return fullName.charAt(0) +
                StringUtils.repeat("*", length - 2) +
                fullName.charAt(length - 1);
    }


    // 手机号脱敏 (保留前3后4)
    public static String mobilePhone(String phone) {
        if (StringUtils.isBlank(phone)) {
            return "";
        }
        return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
    }

    // 邮箱脱敏 (保留@前3位和域名)
    public static String email(String email) {
        if (StringUtils.isBlank(email)) {
            return "";
        }
        int index = email.indexOf("@");
        if (index <= 1) {
            return email;
        }
        String head = "";
        if (index <= 3) {
            head = email.substring(0,index);
        } else {
            head = email.substring(0,3);
        }
        return head + "*********" + email.substring(index);
    }
}

越权规则

3.数据库性能优化:定位高负载场景下的慢 SOL 问题,通过重构索引和优化子查询,将关键 SOL 执行时间从 703、秒降至毫秒级,显著提升系统响应速度。

4.JVM 性能调优: 利用 ArthaS+MAT 分析定位内存问题,优化年轻代内存配置,使 YGC耗时从 20s 降至 3s,任务执行效率提升 12%,系统卡顿减少33%。

相关推荐
橘颂TA42 分钟前
【Linux】特效爆满的Vim的配置方法 and make/Makefile原理
linux·运维·服务器·vim
AI大法师1 小时前
企业级Linux服务器安全:防火墙规则配置与Web/SSH服务优化指南
linux·服务器·安全
花小璇学linux2 小时前
imx6ull-驱动开发篇10——pinctrl 子系统
linux·驱动开发·imx6ull·嵌入式软件
Hat_man_2 小时前
如何在虚拟机(Linux)安装Qt5.15.2
linux·运维·服务器
LLLLYYYRRRRRTT2 小时前
12. SELinux 加固 Linux 安全
linux·运维·安全
爱学习的小熊猫_3 小时前
在Linux上部署RabbitMQ、Redis、ElasticSearch
linux·redis·elasticsearch·中间件·rabbitmq
我是小bā吖3 小时前
使用阿里云服务器部署dify实战
服务器·阿里云·dify
拾心213 小时前
【运维进阶】DHCP服务配置和DNS域名解析
linux·运维·服务器
代码改变世界ctw4 小时前
TrustZone技术详解————这篇是AI写的包括图
linux