系统优化(安全,限流,数据存储)

这篇具有很好参考价值的文章主要介绍了系统优化(安全,限流,数据存储)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系统优化

1.安全性优化(方法:校验)

  1. 问题:用户上传一个超大的文件怎么办?比如1000G?此时网站很容易崩

  2. 优化方法==>校验:

    • 文件大小
    • 文件后缀
    • 文件内容
    • 文件的合规性(排除敏感内容)(可以用第三发的审核功能)
      • 接入腾讯云的图片万象数据审核(cos对象存储审核功能)
  3. 实现:在后端用户输入内容处,添加校验用户上传文件的逻辑

     //校验文件
            String originalFilename = multipartFile.getName();
            long size = multipartFile.getSize();
            //1.文件大小
            final long ONE_MB = 1024*1024L;
            ThrowUtils.throwIf(size > ONE_MB,ErrorCode.PARAMS_ERROR,"文件超过1M");
            //2.校验文件后缀 aaa.png
            //2.1获取文件名的后缀
            String suffix = FileUtil.getSuffix(originalFilename);
            //2.2定义一个允许传入的文件后缀名列表
            final List<String> vaildFileSuffix = Arrays.asList("png","jpg","webp","jpeg");
            ThrowUtils.throwIf(!vaildFileSuffix.contains(suffix),ErrorCode.PARAMS_ERROR,"文件类型不合法");
    
    

2. 数据存储优化

  1. 问题:数据表中某个字段原始数据量很大,图表数越来越多,查表就会很慢。如果要查询此字段中的某一部分数据,就需要查询整个字段,浪费资源

  2. 优化方法:分库分表(把该字段的数据单独存储到新的数据表中)

    • 存储时:分开存储,互不影响(增加安全性)

    • 查询时:用SQL语句进行高效的数据检索,仅查询需要的列或行;更快、更精确地对数据进行定位和查询,从而提高查询效率和系统的响应速度

  3. 实现方式:

    • 分开存储:存储图表信息时,不把数据存储为字段,而是新建一个chart_{ 图表id } 的数据表通过图表id、数据列名、数据类型等字段,生成以下SQL语句,并且执行即可。

    • mybatis的动态sql实现(更具代码灵活的生成动态sql):

      • 哪部分是需要动态查询的

        select * from chart_{图表id}
        select 指定查询字段 from chart_{图表id}
        
      • 在ChartMapper.xml中定义sql语句

        <select id="queryChartData" resultType="java.util.Map">${queryChartSql}</select>
        
      • 测试类

        @Test
        void queryChartData() {
            String chartId = "1659210482555121666";
            String querySql = String.format("select * from chart_%s", chartId);
            List<Map<String, Object>> resultData = chartMapper.queryChartData(querySql);
            System.out.println(resultData);
        }
        

3. 限流

  1. 问题:用户在短时间内疯狂使用,导致服务器资源被占满,其他用户无法使用,避免用户频繁使用系统(比如此系统的某些功能需要收费,需要控制成本)

  2. 解决方法:

    1. 限流,比如说单个用户在每秒只能使用多少次(思考限流阈值多大合适,参考正常用户使用多少合适)
  3. 限流的算法(类别)

    1. 固定窗口限流(参考文章https://juejin.cn/post/6967742960540581918)如1小时只允许10个用户操作

      • 优点:最简单
      • 缺点:可出现流量突刺,如前59分钟没有1个操作,第59分钟来了10个操作;第1小时01分钟又来了10个操作。相当于2分钟内执行了20个操作,服务器仍然有高峰危险。
    2. 滑动窗口:流动的一个1小时只允许10个用户操作,解决了固定窗口限流存在的问题

      • 优点:能够解决上述流量突刺的问题,因为第59分钟时,限流窗口是59分~1小时59分,这个时间段内只能接受10次请求,只要还在这个窗口内,更多的操作就会被拒绝。
      • 缺点:实现相对固定窗口来说比较复杂,限流效果和你的滑动单位有关,滑动单位越小,限流效果越好,但往往很难选取到一个特别合适的滑动单位。
    3. 漏桶限流:以固定的速率处理请求(漏水),当请求桶满了后,拒绝请求。如每秒处理10个请求,桶的容量是10,每0.1秒固定处理一次请求,如果1秒内来了10个请求,这10此请求都可以处理完,但如果1秒内来了11个请求,最后那个请求就会溢出桶,被拒绝请求。

      • 优点:能够一定程度上应对流量突刺,能够固定速率处理请求,保证服务器的安全。
      • 缺点:没有固定速率处理一批请求,只能一个一个按顺序来处理(固定速率的缺点)
      • 实现过程:
        1. 初始化漏桶容量和速率;
        2. 不断将请求添加至漏桶;
        3. 如果漏桶已满,则拒绝该请求;
        4. 当漏桶中有请求时,在一定时间间隔内按照速率恒定地处理请求,并从漏桶中移除该请求。
    4. 令牌桶限流:管理员先生成一批令牌,每秒生成10个令牌;当用户要操作前,先去拿到一个令牌,有令牌的人就有资格执行操作、同时执行操作;拿不到令牌的就等着(可以解决漏桶存在的问题)

      • 优点:能够并发处理同时的请求,并发性能会更高

      • 时间单位选取的问题,比如在应对短时间内的高并发请求时,由于令牌数有限,引入过大的并发请求会导致严重的性能问题,也可能会造成请求失败或者拒绝。

      • 实现过程

        1. 初始化令牌桶容量和速率;
        2. 以恒定速率往令牌桶中添加令牌;
        3. 当请求到达时,如令牌桶中仍有令牌,则从桶中移除一个令牌,并处理该请求;
        4. 如果没有足够的令牌,拒绝该请求。
  4. 限流的实现:

    1. 本地限流(单机限流)

      每个服务器单独限流,使用于单体项目,项目只有一个服务器

      可以用Guava RateLimiter库实现

      //导入依赖
      <dependency>
          <groupId>com.google.guava</groupId>
          <artifactId>guava</artifactId>
          <version>30.1-jre</version> <!-- 请检查是否有更新的版本 -->
      </dependency>
      
      import com.google.common.util.concurrent.RateLimiter;
      
      // 创建一个每秒最多处理5个请求的RateLimiter实例
      RateLimiter rateLimiter = RateLimiter.create(5.0); // 5 //requests per second
      public void processRequest(Request request) {
          if (rateLimiter.tryAcquire()) { // 如果当前请求可以获取到许可,就执行处理逻辑
              // 处理请求的代码...
          } else {
              // 处理限流情况,例如返回错误信息或重定向到错误页面等...
          }
      }
      
    2. 分布式限流(多机限流)(Redisson限流实现【操作redis的工具类】实现限流)

      统计用户使用频率这些数据集中的存储统计,比如Redis。在网关集中限流和统计(如Sentinel,Spring Cloud GateWay)有多个服务器,微服务,可以使用分布式限流

      1. Redisson内置了一个限流工具类,可以帮助你利用Redis来存储、来统计。Redisson官网:https://github.com/redisson/redisson

      2. 实现过程

        1. 安装Radis

        2. 引入Redisson包

          <dependency>
             <groupId>org.redisson</groupId>
             <artifactId>redisson</artifactId>
             <version>3.21.3</version>
          </dependency>  
          
        3. 创建RedissonConfig配置类,用于初始化RedissonClient对象单例:

          @Data
          @ConfigurationProperties(prefix = "spring.redis")
          @Configuration
          public class RedissonConfig {
              private Integer database;
              private String host;
              private Integer port;
              private String password;
          
              @Bean
              public RedissonClient redissonClient() {
                  Config config = new Config();
                  config.useSingleServer()
                          .setDatabase(database)
                          .setAddress("redis://" + host + ":" + port)
                          .setPassword(password);
                  RedissonClient redisson = Redisson.create();
                  return redisson;
              }
          }
          
        4. 编写RedisLimiterManager

          什么是Manager??专门提供RedisLimiter限流基础服务的(提供了通用的能力,可以放到任何一个项目里)

          @Service
          public class RedisLimiterManager {
          
              @Resource
              private RedissonClient redissonClient;
          
              /**
               * 限流操作
               *
               * @param key 区分不同的限流器,比如不同的用户 id 应该分别统计
               */
              public void doRateLimit(String key) {
                  // 创建一个限流器
                  RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);
                  // 每秒最多访问 2 次
                  // 参数1 type:限流类型,可以是自定义的任何类型,用于区分不同的限流策略。
                  // 参数2 rate:限流速率,即单位时间内允许通过的请求数量。
                  // 参数3 rateInterval:限流时间间隔,即限流速率的计算周期长度。
                  // 参数4 unit:限流时间间隔单位,可以是秒、毫秒等。
                  rateLimiter.trySetRate(RateType.OVERALL, 2, 1, RateIntervalUnit.SECONDS);
                  // 每当一个操作来了后,请求一个令牌
                  boolean canOp = rateLimiter.tryAcquire(1);
                  ThrowUtils.throwIf(!canOp,ErrorCode.TOO_MANY_REQUEST);
              }
          }
          
        5. 单元测试

          @SpringBootTest
          class RedisLimiterManagerTest {
              @Resource
              private RedisLimiterManager redisLimiterManager;
          
              @Test
              void doRateLimit() throws InterruptedException {
                  String userId = "1";
                  for (int i = 0; i < 2; i++) {
                      redisLimiterManager.doRateLimit(userId);
                      System.out.println("成功");
                  }
                  Thread.sleep(1000);
                  for (int i = 0; i < 5; i++) {
                      redisLimiterManager.doRateLimit(userId);
                      System.out.println("成功");
                  }
              }
          }
          
        6. 应用到要限流的方法中,比如智能分析接口

4. 零散知识点记录

  1. 文件分片上传!100M以上

  2. 水平分表,垂直分库

    • 水平分表:水平分表是将同一张表中的数据按一定的规侧划分到不同的物理存储位置上,以达到分难单张表的数据及访问压力的目的。对于SQL分为两类:id-based分表和range-based分表。

    • 垂直分库:指的是根据业务模块的不同,将不同的字段或表分到不同的数据库中。垂直分库基于数据库内核支持,对应用透明,无需额外的开发代码,易于维护升级。

  3. sql注入:

    • 是什么:SQL注入是一种常见的网络攻击手段,攻击者通过在Web表单中输入恶意SQL代码,并将其作为输入参数提交给应用程序,从而绕过预期的SQL查询,执行恶意SQL语句,并可能窃取敏感数据或破坏数据库结构。
    • 危害:SQL注入通常会导致数据泄露、数据篡改、数据库损坏等问题。
    • 解决方法:正确地验证和转义用户输入的数据,使其能够影响实际的SQL查询。应用程序需要正确验证和转义用户输入的数据,并使用参数化查询或绑定变量来执行SQL语句
  4. 创建测试的快捷键:在类名中上按alt+enter文章来源地址https://www.toymoban.com/news/detail-752689.html

到了这里,关于系统优化(安全,限流,数据存储)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据库系统-数据物理存储

    1.1.1 磁盘的结构特性 1.1.2 DBMS数据存储查询原理 记录:磁盘块 。OS的文件存储记录表(FAT)记录 数据 在哪些磁盘块当中block 数据先加载到内存缓冲区中,有一个内存页page block的对应表 磁盘块Block已经装载进了磁盘页Page,有一个 记录Record 记录所在内存位置Point的映射 记录:

    2023年04月20日
    浏览(37)
  • Redis缓存设计与性能优化【缓存和数据库不一致问题,解决方案:1.加过期时间这样可以一段时间后自动刷新 2.分布式的读写锁】

    在大并发下,同时操作数据库与缓存会存在数据不一致性问题 1、双写不一致情况 2、读写并发不一致 解决方案: 1、对于并发几率很小的数据(如个人维度的订单数据、用户数据等),这种几乎不用考虑这个问题,很少会发生缓存不一致, 可以给缓存数据加上过期时间,每隔一

    2024年04月13日
    浏览(54)
  • 分布式系统中数据库和缓存双写一致性的实现技术

    标题:分布式系统中数据库和缓存双写一致性的实现技术 在分布式系统中,为了确保数据库和缓存之间的数据一致性,双写一致性成为了一个关键的挑战。本文将深入探讨如何利用一些常见的技术手段来保证数据库和缓存的双写一致性,以及通过举例说明这些技术是如何在实

    2024年01月16日
    浏览(57)
  • 数据库原理及应用课程设计--药品存储信息管理系统

    1.1项目提出 1.2.调查使用该药品存储信息数据库的用户的实际需求 1.3 功能需求 1.供应商基本信息模块,完成对供应商基本信息的输入、修改和查询; 2.员工基本信息模块,完成对员工基本情况的输入、修改和查询; 3.药品基本信息模块,完成对药品基本信息的输入、修改

    2024年02月08日
    浏览(43)
  • 数据库实验六:数据库系统安全

    实验目的: 掌握混合模式下数据库用户帐号的建立与取消方法; 掌握数据库用户权限的设置方法; 掌握服务器角色的用法; 掌握SQL-Server中数据库备份和恢复的方法。   1、 数据安全性。以系统管理员身份登录到SQL Server服务器,在SQL Server界面中实现以下操作,并写出相应程

    2024年02月06日
    浏览(46)
  • MySQL数据库——存储过程-变量(系统变量、用户定义变量、局部变量)

    目录 系统变量  1.查看系统变量  2.设置系统变量 演示示例 用户定义变量 1.赋值  2.使用 演示示例 局部变量 声明  赋值 演示示例 变量 在MySQL中变量分为三种类型: 系统变量、用户定义变量、局部变量。 系统变量是MySQL服务器提供,不是用户定义的,属于服务器层面。分为全

    2024年02月05日
    浏览(53)
  • 数据库优化案例—某市中心医院HIS系统

    记得在自己学习数据库知识的时候特别喜欢看案例,因为优化的手段是容易掌握的,但是整体的优化思想是很难学会的。这也是为什么自己特别喜欢看案例,今天也开始分享自己做的优化案例。 最近一直很忙,博客产出也少的可怜,今天整理了一下自己做过优化或各种方案的

    2024年02月05日
    浏览(48)
  • 了解您的数据库管理系统及其优化器

    模式 物品具有唯一标识符、唯一图像标识符、名称和价格。 仓库具有唯一标识符、名称以及由街道、城市和国家定义的位置。 对于每个可用的物品,我们记录每个仓库中的库存数量。如果某个物品在仓库中不可用,则这对没有记录。数量总是等于或大于1。 PostgreSQL 内部 在

    2024年02月21日
    浏览(41)
  • 数据库系统原理及MySQL应用教程实验七存储过程与函数的创建管理

    1. 理解存储过程和函数的概念。 2. 掌握创建存储过程和函数的方法。 3. 掌握执行存储过程和函数的方法。 4. 掌握游标的定义、使用方法。 1.验证性实验:某超市的食品管理的数据库的Food表对其操作。 2.设计性试验:学校教师管理数据库中的teacherInfo表对其操作。 三、实验步

    2024年02月03日
    浏览(55)
  • 数据库系统头歌实验八 数据库完整性、安全设计

    第1关:执行 CREATE USER 创建以2022100904为用户名的用户,同时设置其密码为root1234 第2关:给予创建的用户2022100904在mydata数据库中授予\\\"J\\\" 表 SELECT 权限(注意创建权限时的用户名为\\\'用户名\\\'@\\\'localhost\\\'),不允许转授此权限给其它用户。 第3关:给予创建的用户2022100904、2022100908在

    2024年02月05日
    浏览(103)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包