【商城实战(91)】安全审计与日志管理:为电商平台筑牢安全防线

news2025/3/31 19:40:41

【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配,乃至运营推广策略,102 章内容层层递进。无论是想深入钻研技术细节,还是探寻商城运营之道,本专栏都能提供从 0 到 1 的系统讲解,助力你打造独具竞争力的电商平台,开启电商实战之旅。

目录

  • 一、建立安全审计机制
    • 1.1 审计内容与范围
    • 1.2 Spring Boot 实现审计
    • 1.3 MyBatis-Plus 在审计中的作用
  • 二、开发日志管理系统
    • 2.1 日志收集
    • 2.2 日志存储
    • 2.3 日志查询
  • 三、分析审计与日志数据
    • 3.1 潜在风险分析
    • 3.2 防范措施
  • 四、总结


一、建立安全审计机制

1.1 审计内容与范围

在商城系统中,安全审计机制需要记录的信息广泛。对于用户操作,涵盖登录、注册、密码修改、商品浏览、添加购物车、下单、支付、评论等。例如,用户登录时,记录登录时间、登录 IP、登录账号等信息,有助于追踪用户的登录行为,及时发现异常登录情况,如异地登录、频繁登录失败等。下单操作则记录下单时间、订单金额、购买商品列表、用户 ID 等,方便后续对订单相关操作的追溯。

系统事件方面,包括服务器错误(如 500 内部服务器错误、404 页面未找到等)、资源访问(如对数据库、文件系统的访问)、系统配置变更等。当服务器出现 500 错误时,记录错误发生时间、错误堆栈信息、触发错误的请求等,能够帮助开发人员快速定位问题。资源访问记录可以监控对关键数据的读取和修改操作,确保数据的安全性和完整性。

1.2 Spring Boot 实现审计

基于 Spring AOP 实现审计功能,首先需要添加相关依赖。在pom.xml文件中添加spring-boot-starter-aop依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

接着定义一个自定义注解,用于标识需要审计的方法。例如:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AuditAnnotation {
    String value() default "";
}

然后创建切面类,在切面类中定义切点和增强逻辑。示例代码如下:

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AuditAspect {
    private static final Logger logger = LoggerFactory.getLogger(AuditAspect.class);

    @Pointcut("@annotation(com.example.demo.AuditAnnotation)")
    public void auditPointCut() {}

    @Before("auditPointCut()")
    public void before(JoinPoint joinPoint) {
        logger.info("Before method {} execution", joinPoint.getSignature().getName());
    }

    @AfterReturning(pointcut = "auditPointCut()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        logger.info("After method {} execution, result: {}", joinPoint.getSignature().getName(), result);
    }

    @AfterThrowing(pointcut = "auditPointCut()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Exception e) {
        logger.error("Method {} threw an exception: {}", joinPoint.getSignature().getName(), e.getMessage());
    }

    @Around("auditPointCut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        logger.info("Around method {} execution, start", proceedingJoinPoint.getSignature().getName());
        Object result = proceedingJoinPoint.proceed();
        logger.info("Around method {} execution, end", proceedingJoinPoint.getSignature().getName());
        return result;
    }
}

在上述代码中,@Pointcut定义了切点,即被@AuditAnnotation注解标注的方法。@Before、@AfterReturning、@AfterThrowing和@Around分别表示在方法执行前、执行成功后、抛出异常后和环绕方法执行时的增强逻辑。

1.3 MyBatis-Plus 在审计中的作用

MyBatis-Plus 与 Spring Boot 配合,可以方便地记录数据库操作相关的审计信息。在实体类中,可以通过自定义字段和注解来记录审计信息。例如,创建一个AuditEntity基类,包含创建时间、创建人、修改时间、修改人等字段:

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;

import java.util.Date;

@Data
public class AuditEntity {
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    @TableField(fill = FieldFill.INSERT)
    private String createUser;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private String updateUser;
}

其他需要审计的实体类继承AuditEntity,MyBatis-Plus 在执行插入和更新操作时,会自动填充这些字段。同时,可以通过自定义插件,在 SQL 执行前后记录审计信息。例如,创建一个自定义插件类:

import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
        // 获取当前用户,这里假设通过工具类获取
        String currentUser = "admin";
        this.setFieldValByName("createUser", currentUser, metaObject);
        this.setFieldValByName("updateUser", currentUser, metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime", new Date(), metaObject);
        // 获取当前用户,这里假设通过工具类获取
        String currentUser = "admin";
        this.setFieldValByName("updateUser", currentUser, metaObject);
    }
}

在上述代码中,MyMetaObjectHandler实现了MetaObjectHandler接口,重写了insertFill和updateFill方法,在插入和更新操作时自动填充审计字段。这样,通过 MyBatis-Plus 与 Spring Boot 的结合,能够有效地记录数据库操作相关的审计信息,为商城系统的安全审计提供有力支持。

二、开发日志管理系统

2.1 日志收集

在前端,无论是 uniapp(用于移动前端)还是 Element plus(用于 PC 前端),都可以通过自定义日志收集函数来捕获用户操作相关的日志。以 uniapp 为例,在utils目录下创建log.js文件,代码如下:

export function log(message) {
  const logData = {
    timestamp: new Date().getTime(),
    message: message,
    // 可以添加更多信息,如当前页面路径等
    pagePath: getCurrentPages().pop().route
  };
  // 这里可以使用uni.request将日志发送到后端
  uni.request({
    url: 'http://your-backend-url/log',
    method: 'POST',
    data: logData,
    success: (res) => {
      console.log('Log sent successfully', res);
    },
    fail: (err) => {
      console.error('Failed to send log', err);
    }
  });
}

在需要记录日志的页面,引入该函数并调用。例如:

import { log } from '@/utils/log.js';

export default {
  methods: {
    addToCart() {
      // 模拟添加购物车操作
      log('User added item to cart');
    }
  }
};

在 Element plus 前端项目中,类似地可以在src/utils目录下创建log.js文件,实现日志收集和发送功能:

import axios from 'axios';

export function log(message) {
  const logData = {
    timestamp: new Date().getTime(),
    message: message,
    // 可以添加更多信息,如当前路由等
    route: this.$router.currentRoute.path
  };
  axios.post('http://your-backend-url/log', logData)
   .then((res) => {
      console.log('Log sent successfully', res);
    })
   .catch((err) => {
      console.error('Failed to send log', err);
    });
}

在后端 Spring Boot 中,创建一个日志接收的 Controller。在src/main/java/com/example/demo/controller目录下创建LogController.java文件:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LogController {

    @PostMapping("/log")
    public String receiveLog(@RequestBody LogData logData) {
        // 这里可以将日志数据传递给服务层进行进一步处理
        System.out.println("Received log: " + logData);
        return "Log received successfully";
    }
}

class LogData {
    private long timestamp;
    private String message;
    private String pagePath; // 移动端日志包含的页面路径

    // 省略getter和setter方法
}

2.2 日志存储

使用 MyBatis-Plus 将日志存储到数据库。首先,创建日志实体类LogEntity。在src/main/java/com/example/demo/entity目录下创建LogEntity.java文件:

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.Date;

@Data
@TableName("log")
public class LogEntity {
    private Long id;
    private long timestamp;
    private String message;
    private String pagePath; // 移动端日志包含的页面路径
    private Date createTime;
}

然后,创建日志服务层接口LogService和实现类LogServiceImpl。在src/main/java/com/example/demo/service目录下创建LogService.java文件:

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.entity.LogEntity;

public interface LogService extends IService<LogEntity> {
}

在src/main/java/com/example/demo/service/impl目录下创建LogServiceImpl.java文件:

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.LogEntity;
import com.example.demo.mapper.LogMapper;
import com.example.demo.service.LogService;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class LogServiceImpl extends ServiceImpl<LogMapper, LogEntity> implements LogService {
    @Override
    public boolean saveLog(LogEntity logEntity) {
        logEntity.setCreateTime(new Date());
        return save(logEntity);
    }
}

其中,LogMapper由 MyBatis-Plus 自动生成,无需手动编写。在LogController中修改receiveLog方法,调用服务层保存日志:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LogController {

    private final LogService logService;

    public LogController(LogService logService) {
        this.logService = logService;
    }

    @PostMapping("/log")
    public String receiveLog(@RequestBody LogData logData) {
        LogEntity logEntity = new LogEntity();
        logEntity.setTimestamp(logData.getTimestamp());
        logEntity.setMessage(logData.getMessage());
        logEntity.setPagePath(logData.getPagePath());

        if (logService.saveLog(logEntity)) {
            return "Log saved successfully";
        } else {
            return "Failed to save log";
        }
    }
}

2.3 日志查询

在前端,通过界面组件触发日志查询请求。以 Element plus 为例,创建一个日志查询页面LogQuery.vue:

<template>
  <div>
    <el-input v-model="queryParams.message" placeholder="Search by message"></el-input>
    <el-button @click="queryLogs">Query</el-button>
    <el-table :data="logs">
      <el-table-column prop="id" label="ID"></el-table-column>
      <el-table-column prop="timestamp" label="Timestamp"></el-table-column>
      <el-table-column prop="message" label="Message"></el-table-column>
      <el-table-column prop="pagePath" label="Page Path"></el-table-column>
      <el-table-column prop="createTime" label="Create Time"></el-table-column>
    </el-table>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      queryParams: {
        message: ''
      },
      logs: []
    };
  },
  methods: {
    async queryLogs() {
      try {
        const response = await axios.post('http://your-backend-url/log/query', this.queryParams);
        this.logs = response.data;
      } catch (error) {
        console.error('Failed to query logs', error);
      }
    }
  }
};
</script>

在后端 Spring Boot 中,创建日志查询的 Controller 方法。在LogController中添加如下方法:

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class LogController {

    private final LogService logService;

    public LogController(LogService logService) {
        this.logService = logService;
    }

    @PostMapping("/log/query")
    public List<LogEntity> queryLogs(@RequestBody LogQueryParams queryParams) {
        QueryWrapper<LogEntity> wrapper = new QueryWrapper<>();
        if (queryParams.getMessage() != null &&!queryParams.getMessage().isEmpty()) {
            wrapper.like("message", queryParams.getMessage());
        }
        return logService.list(wrapper);
    }
}

class LogQueryParams {
    private String message;

    // 省略getter和setter方法
}

通过上述步骤,实现了日志管理系统的日志收集、存储和查询功能,能够有效地记录和管理商城系统中的日志信息。

三、分析审计与日志数据

3.1 潜在风险分析

通过对审计与日志数据的深入分析,可以发现多种潜在安全风险。例如,在用户登录方面,如果在一段时间内某个账号出现大量的登录失败记录,且这些失败记录来自不同的 IP 地址,这可能表明该账号正在遭受暴力破解攻击。假设通过日志查询发现,在某一小时内,用户 “user123” 的登录失败次数达到 50 次,且登录 IP 地址有 10 个不同的地址,这就明显超出了正常的登录行为范围,存在极大的安全风险。

在订单操作方面,若出现异常的订单修改或取消操作,也需要重点关注。比如,一个订单在短时间内被多次修改收货地址,且修改后的地址毫无规律,或者突然出现大量的订单在支付成功后立即被取消,这些都可能是恶意行为。例如,在某一天的订单日志中,发现有 100 个订单在支付成功后的 1 分钟内被取消,进一步调查发现这些订单的操作 IP 地址相同,这就很可能是有人在进行恶意刷单或其他欺诈行为。

3.2 防范措施

针对上述潜在风险,需要采取相应的防范措施。对于频繁登录失败的情况,可以限制登录次数。在 Spring Boot 中,可以通过配置过滤器来实现。在src/main/java/com/example/demo/config目录下创建LoginLimitFilter.java文件:

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@WebFilter(filterName = "loginLimitFilter", urlPatterns = "/login")
public class LoginLimitFilter implements Filter {
    private static final int MAX_LOGIN_ATTEMPTS = 5;
    private static final Map<String, Integer> loginAttempts = new HashMap<>();

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String username = request.getParameter("username");
        if (username != null) {
            Integer attempts = loginAttempts.getOrDefault(username, 0);
            if (attempts >= MAX_LOGIN_ATTEMPTS) {
                response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                response.getWriter().println("Too many login attempts, please try again later.");
                return;
            }
            loginAttempts.put(username, attempts + 1);
        }
        filterChain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化操作
    }

    @Override
    public void destroy() {
        // 销毁操作
    }
}

同时,在src/main/java/com/example/demo/DemoApplication.java中添加过滤器注册:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean
    public FilterRegistrationBean<LoginLimitFilter> loginLimitFilterRegistrationBean() {
        FilterRegistrationBean<LoginLimitFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new LoginLimitFilter());
        registrationBean.addUrlPatterns("/login");
        return registrationBean;
    }
}

对于异常订单操作,加强订单验证是关键。在订单处理的 Service 层方法中添加验证逻辑。例如,在src/main/java/com/example/demo/service/impl/OrderServiceImpl.java中:

import com.example.demo.entity.Order;
import com.example.demo.mapper.OrderMapper;
import com.example.demo.service.OrderService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class OrderServiceImpl implements OrderService {

    private final OrderMapper orderMapper;

    public OrderServiceImpl(OrderMapper orderMapper) {
        this.orderMapper = orderMapper;
    }

    @Override
    @Transactional
    public boolean updateOrder(Order order) {
        // 验证订单修改的合法性
        Order originalOrder = orderMapper.selectById(order.getId());
        if (originalOrder == null) {
            return false;
        }
        // 检查收货地址是否合理,这里假设合理地址的判断逻辑
        if (!isValidAddress(order.getShippingAddress())) {
            return false;
        }
        // 其他验证逻辑
        return orderMapper.updateById(order) > 0;
    }

    private boolean isValidAddress(String address) {
        // 简单示例,实际应根据业务需求实现更复杂的验证
        return address != null &&!address.isEmpty();
    }
}

通过上述限制登录次数和加强订单验证等防范措施,可以有效地降低商城系统的安全风险,保障系统的稳定运行和用户数据的安全。

四、总结

安全审计与日志管理是商城系统中至关重要的环节,它们就像系统的 “安全卫士” 和 “记录员”。通过建立完善的安全审计机制,能够全面记录用户操作和系统事件,为系统的安全运行提供了有力的监控和追溯依据。而开发功能完备的日志管理系统,实现了日志的收集、存储和查询,使得系统运行过程中的各种信息能够被有效地管理和利用。通过对审计与日志数据的深入分析,能够及时发现潜在的安全风险,并采取针对性的防范措施,保障了商城系统的稳定运行和用户数据的安全。

未来,随着技术的不断发展和业务的日益复杂,安全审计与日志管理还需要不断优化和完善。在技术方面,可以引入人工智能和机器学习技术,实现对审计与日志数据的自动化分析和智能预警,提高发现潜在安全风险的效率和准确性。同时,进一步加强日志管理系统的性能优化,确保在高并发场景下也能稳定运行。在业务方面,要紧密结合商城的业务特点和发展需求,不断调整和完善审计内容和范围,使安全审计与日志管理更好地服务于商城的运营和发展。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2323713.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

kotlin,jetpack compose 最简导航(navigation)案例学习

// 添加导航组件依赖&#xff0c;用于支持Compose中的导航功能 implementation ("androidx.navigation:navigation-compose:2.8.9") // 定义包名 package com.example.mynavigation// 导入所需的Android和Compose库 import android.os.Bundle import androidx.activ…

centos 7 LVM管理命令

物理卷&#xff08;PV&#xff09;管理命令 pvcreate&#xff1a;用于将物理磁盘分区或整个磁盘创建为物理卷。 示例&#xff1a;sudo pvcreate /dev/sdb1 解释&#xff1a;将 /dev/sdb1 分区创建为物理卷。 pvdisplay&#xff1a;显示物理卷的详细信息&#xff0c;如大小、所属…

鸿蒙前后端项目源码-点餐v3.0-原创!原创!原创!

鸿蒙前后端点餐项目源码含文档ArkTS语言. 原创作品.我半个月写的原创作品&#xff0c;请尊重原创。 原创作品&#xff0c;盗版必究&#xff01;&#xff01;&#xff01;&#xff01; 原创作品&#xff0c;盗版必究&#xff01;&#xff01;&#xff01;&#xff01; 原创作…

Unity打包崩溃SRP-URP-管线的问题:Shader::SRPBatcherInfoSetup()

URP build always crash when Use SPR Batcher is ON by default - Bug Reports - Niantic SDK for Unity Community 有点类似这个情况&#xff0c;暂时没有解决方法 *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Build fingerprint: google/bluejay/blu…

不落因果与不昧因果

在佛教浩瀚的哲学体系中&#xff0c;“因果”是贯穿修行始终的核心命题。而“不落因果”与“不昧因果”这对看似矛盾的概念&#xff0c;恰似明镜的两面&#xff0c;映照出修行者对因果法则的不同认知层次。二者虽仅一字之差&#xff0c;却如天堑般分隔了迷悟两岸&#xff0c;其…

<tauri><rust><GUI>基于rust和tauri,实现一个大寰电爪PGHL(串口设备)定制化控制程序

前言 本文是基于rust和tauri,由于tauri是前、后端结合的GUI框架,既可以直接生成包含前端代码的文件,也可以在已有的前端项目上集成tauri框架,将前端页面化为桌面GUI。 环境配置 系统:windows 10平台:visual studio code语言:rust、javascript库:tauri2.0概述 本文是…

浅谈工商企业用电管理的分布式储能设计

摘要&#xff1a;文章设计了一种新的用于工商业用电管理的分布式储能系统。由于储能系统硬件置换成本高&#xff0c;选择在传统储能系统的硬件框架基础上&#xff0c;对控制软件进行优化设计&#xff0c;建立分布式储能系统模型&#xff0c;分析发电量、储电量及损失电量三者之…

项目代码第10讲【数据库运维知识——如何优化数据库查询效率?】:各种日志查看;主从复制;分库分表(MyCat);读写分离;区别数据分区、分表、分库

01. 运维-课程介绍_哔哩哔哩_bilibili 一、各种日志查看 二、主从复制 三、分库分表&#xff08;MyCat&#xff09; 四、读写分离 五、区别数据分区、分表、分库 1、数据库分区 上图中的ibd文件&#xff0c;是分区表的数据文件&#xff0c;可以分布在不同的物理设备上&…

H5DS编辑器教程——H5页面触发动画实战指南

在 H5 页面设计中&#xff0c;触发动画通过动态交互提升用户体验&#xff0c;成为吸引注意力的关键手段。H5DS 编辑器作为一款高效的可视化工具&#xff0c;提供了丰富的动画制作功能&#xff0c;即使是零基础用户也能轻松实现专业级效果。 使用工具&#xff1a;H5DS编辑器 触…

小程序语音识别功能 wx.createInnerAudioContext

页面样式htmlcss <view class"recorder_content"><view class"result_content"><view class"r_title">语音识别结果显示:</view><view class"r_h_input"><text wx:if"{{resultDetails.result}…

Web网页内嵌福昕OFD版式办公套件实现在线预览编辑PDF、OFD文档

PDF&#xff0c;即Portable Document Format&#xff0c;用于以一种独立于应用程序、硬件、操作系统的方式共享和查看文档&#xff1b;OFD&#xff0c;即Office Open Document Format for Document&#xff0c;是一种在政府公文和法律文件等领域广泛应用的电子文件格式&#xf…

ADZS-ICE-2000和AD-ICE2000仿真器在线升级固件

作者的话 近期发现有些兄弟的ICE-2000仿真器链接DSP报错&#xff0c;然后test第四步不通过&#xff0c;我就拿我的仿真器也试了一下&#xff0c;发现ADI悄咪咪的在线升级仿真器固件&#xff0c;有些兄弟不会操作&#xff0c;就会导致仿真器升级失败&#xff0c;连不上目标板&a…

第十一章:Python PIL库-图像处理

一、PIL库简介 PIL&#xff08;Python Imaging Library&#xff09;是一个功能强大的图像处理库&#xff0c;它提供了丰富的图像处理功能&#xff0c;包括图像的打开、处理和保存等操作。PIL支持多种图像文件格式&#xff0c;如JPEG、PNG、BMP等&#xff0c;并且可以完成对图像…

python项目整体文件和依赖打包

python项目整体文件和依赖打包 python项目整体文件和依赖打包 python项目整体文件和依赖打包 准备工作&#xff1a;扫描项目中必要的依赖包 pip install pipreqs pipreqs . 会有一些警告包&#xff0c;需要pip list进行版本修正,这里是三个包第一步&#xff1a;在虚拟环境中安…

logstash收集数据

防止ES的的I/O的压力过大&#xff0c;使用redis/kafka进行缓冲。 对redis的要求 Redis input plugin | Logstash Reference [8.17] | Elastic 一般企业要求的架构 我实现的架构 filebeat把数据传给logstash 配置好filebeat把收集到的数据输入到redis 然后执行命令&#xff0…

智能运维时代的网络拓扑管理:乐维监控的架构可视化实践

在数字化转型的浪潮中&#xff0c;企业IT基础设施正经历着前所未有的复杂化进程。当数以千计的网络设备、服务器、存储系统构成庞大网络体系时&#xff0c;如何实现全局可视化管理已成为企业数字化转型的关键命题。乐维监控网络拓扑系统作为新一代智能运维平台的核心组件&#…

CentOS 7 安装 EMQX (MQTT)

CentOS 7 安装 EMQX 通过 Yum 源安装 EMQX 支持通过 Yum 源安装&#xff0c;您可通过以下 Yum 命令从中自动下载和安装 EMQX。 通过以下命令配置 EMQX Yum 源&#xff1a; curl -s https://assets.emqx.com/scripts/install-emqx-rpm.sh | sudo bash安装以下依赖项&#xff…

人工智能:officeAI软件,如何调整AI对话界面的字体?

1、首先&#xff0c;随便打开一个excel&#xff08;使用wps&#xff09; 依次点击上方的【OfficeAI】—【右侧面板】 2、在弹出的面板中&#xff0c;输入&#xff1a;助手设置 &#xff0c; 然后按【回车】发送出去 3、之后会弹出界面&#xff0c;在【样式设定】中&#xff…

Qt之共享内存类QSharedMemory的使用及实现原理(全)

目录 1.简介 2.使用 3.实现原理 3.1.Windows内存映射 3.2.POSIX 共享内存 3.3.System V 共享内存 3.4.QSharedMemory的实现原理 4.总结 1.简介 QSharedMemory 是 Qt 框架提供的一个类&#xff0c;用于在不同进程或线程之间实现共享内存的管理。借助共享内存&#xff0c…

Problem A: 接口使用

1.题目问题 2.样例 3.代码实现 补充&#xff1a;注意空格 // 定义Vehicle接口 interface Vehicle {void start();void stop(); }// 实现Vehicle接口的Bike类 class Bike implements Vehicle {Overridepublic void start() {System.out.println("i am bike,i am running&…