
分布式项目调优
文章平均质量分 65
ADRU
这个作者很懒,什么都没留下…
展开
-
项目开发中用户数据脱敏如何实现?
利用 CONCAT()、LEFT()和RIGHT() 字符串函数组合使用,请看下面具体实现。-- RIGHT(str,len):从字符串str 开始,返回最右len 字符。-- CONCAT(str1,str2,…):返回结果为连接参数产生的字符串。-- LEFT(str,len):返回从字符串str 开始的len 最左字符。2.自定义工具类 实现统一管理进行数据处理。提供两种方式:正则表达式和长度判定形式。3.定义枚举类 获取脱敏信息的类型。举个栗子:对用户姓名进行脱敏。通过自定义注解的形式实现。原创 2024-04-06 16:55:33 · 446 阅读 · 0 评论 -
深入理解Netty以及为什么项目中要使用?(七)Netty中ByteBuf详解
在Netty中,还有另外一个比较常见的对象ByteBuf,它其实等同于Java Nio中的ByteBuffer,但是ByteBuf对Nio中的ByteBuffer的功能做了很作增强,下面我们来简单了解一下ByteBuf。下面这段代码演示了ByteBuf的创建以及内容的打印,这里显示出了和普通ByteBuffer最大的区别之一,就是ByteBuf可以自动扩容,默认长度是256,如果内容长度超过阈值时,会自动触发扩容第一种,创建基于堆内存的ByteBuf第二种,创建基于直接内存(堆外内存)的ByteBuf(原创 2024-03-23 21:41:24 · 1045 阅读 · 0 评论 -
深入理解Netty以及为什么项目中要使用?(六)Netty核心组件实例
前面我们讲过NIO多路复用的设计模式之Reactor模型,Reactor模型的主要思想就是把网络连接、事件分发、任务处理的职责进行分离,并且通过引入多线程来提高Reactor模型中的吞吐量。其中包括三种Reactor模型单线程单Reactor模型多线程单Reactor模型多线程多Reactor模型在Netty中,可以非常轻松的实现上述三种线程模型,并且Netty推荐使用主从多线程模型,这样就可以轻松的实现成千上万的客户端连接的处理。原创 2024-03-23 21:23:57 · 1071 阅读 · 0 评论 -
深入理解Netty以及为什么项目中要使用?(五)Netty核心组件
服务端启动初始化Boss和Worker线程组,Boss线程组负责监听网络连接事件,当有新的连接建立时,Boss线程会把该连接Channel注册绑定到Worker线程Worker线程组会分配一个EventLoop负责处理该Channel的读写事件,每个EventLoop相当于一个线程。通过Selector进行事件循环监听。当客户端发起I/O事件时,服务端的EventLoop将就绪的Channel分发给Pipeline,进行数据的处理。原创 2024-03-18 17:05:55 · 982 阅读 · 0 评论 -
深入理解Netty以及为什么项目中要使用?(四)Netty详解
Netty的整体工作机制如下,整体设计就是前面我们讲过的多线程Reactor模型,分离请求监听和请求处理,通过多线程分别执行具体的handler。原创 2024-03-18 14:45:14 · 421 阅读 · 0 评论 -
深入理解Netty以及为什么项目中要使用?(二)Reactor模型
了解了NIO多路复用后,就有必要再和大家说一下Reactor多路复用高性能I/O设计模式,Reactor本质上就是基于NIO多路复用机制提出的一个高性能IO设计模式,它的核心思想是把响应IO事件和业务处理进行分离,通过一个或者多个线程来处理IO事件,然后将就绪得到事件分发到业务处理handlers线程去异步非阻塞处理将I/O事件发派给对应的Handler处理客户端连接请求执行非阻塞读/写这是最基本的单Reactor单线程模型。原创 2024-03-18 08:54:22 · 982 阅读 · 0 评论 -
深入理解Netty以及为什么项目中要使用?(一) IO模型
在linux中,内核把所有的外部设备都当成是一个文件来操作,对一个文件的读写会调用内核提供的系统命令,返回一个fd(文件描述符)。而对于一个socket的读写也会有相应的文件描述符,称为socketfd。常见的IO多路复用方式有。原创 2024-03-14 21:26:47 · 914 阅读 · 0 评论 -
分布式架构下 网络通信的底层实现原理(三)
阻塞是指进程在等待某个事件发生之前的等待状态,它是属于操作系统层面的调度,我们通过下面操作来追踪Java程序中有多少程序,每一个线程对内核产生了哪些操作。这个时候通过tail -f out.33321这个文件,发现被阻塞的poll()方法,被POLLIN事件唤醒了,表示监听到了一次连接。5.打开out.33321这个文件(主线程后面的一个文件),shift+g到该文件的尾部,可以看到如下内容。从这个代码中可以看到,Socket的accept方法最终是调用系统的poll函数来实现线程阻塞的。原创 2024-03-11 16:39:46 · 823 阅读 · 0 评论 -
分布式架构下 网络通信的底层实现原理(二)
mac地址就好像个人的身份证号,人的身份证号和人户口所在的城市,出生的日期有关,但是和人所在的位置没有关系,人是会移动的,知道一个人的身份证号,并不能找到它这个人,mac地址类似,它是和设备的生产者,批次,日期之类的关联起来,知道一个设备的mac,并不能在网络中将数据发送给它,除非它和发送方的在同一个网络内。操作系统知道了目标IP地址后,就开始根据这个IP来寻找目标机器,而目标服务器一定是部署在不同的地方,这种跨网络节点的访问,需要经过网关(所谓网关就是一个网络到另外一个网络的关口)。原创 2024-03-08 13:34:25 · 967 阅读 · 0 评论 -
分布式架构下 网络通信的底层实现原理(一)
当我们通过浏览器访问一个网址时,一段时间后该网址会渲染出访问的内容,这个过程是怎么实现的呢?这种通信方式是基于http协议实现的,那么什么是协议?像一个中国人和一个外国人交流时,一个讲英语另一个讲解中文,肯定是无法正常交流。因此两个计算机之间要实现数据通信,必须遵循同一种协议协议的组成组成一个协议,需要具备三个要素:语法,就是这一段内容要符合一定的规则和格式。例如,括号要成对,结束要使用分号等。语义,就是这一段内容要代表某种意义。例如数字减去数字是有意义的,数字减去文本一般来说就没有意义。原创 2024-03-08 12:44:30 · 452 阅读 · 0 评论 -
springboot开启mybatis二级缓存
首先选一个缓存框架(EhCache )EhCache 是一个广泛使用的开源 Java 分布式缓存库,主要用于提高应用程序的性能,减少数据库访问次数,通过缓存频繁读取的数据来实现。它可以作为 Hibernate、Spring、MyBatis 等框架的缓存提供者,用于提升这些框架在数据处理方面的性能。可以缓存来自数据库的数据,当应用程序需要这些数据时,可以直接从缓存中读取,而不是每次都查询数据库。这减少了数据库的访问压力和响应时间。的 EhCache 配置文件。对于 Mapper 接口,可以通过在接口上添加。原创 2024-02-14 13:43:56 · 732 阅读 · 0 评论 -
MySQL 中有关 NULL
原因是:MySQL 中 sum 函数没统计到任何记录时,会返回 null 而不是 0,可以使用 IFNULL 函数把 null 转换为 0;MySQL 中使用诸如 =、、> 这样的算数比较操作符比较 NULL 的结果总是 NULL,这种比较就显得没有任何意 义,需要使用 IS NULL、IS NOT NULL 或 ISNULL() 函数来比较。显然,这三条 SQL 语句的执行结果和我们的期望不同:虽然记录的 score 都是 NULL,但 sum 的结果应该是 0 才对;原创 2024-02-02 17:36:53 · 575 阅读 · 0 评论 -
项目中的空指针处理
• 对于 rightMethod 返回的 List,由于不能确认其是否为 null,所以在调用 size 方法获得列表大小之前,同样可以使用 Optional.ofNullable 包装一下返回 值,然后通过.orElse(Collections.emptyList()) 实现在 List 为 null 的时候获得一个空的 List,最后再调用 size 方法。• 对于 String 和字面量的比较,可以把字面量放在前面,比如"OK".equals(s),这样即使 s 是 null 也不会出现空指针异常;原创 2024-02-02 17:30:23 · 424 阅读 · 0 评论 -
项目安全-----加密算法实现
是使用相同的密钥进行加密和解密。使用对称加密算法来加密双方的通信的话,双方需要先约定一个密钥,加密方才能加密,接收方才能 解密。常用的加密算法,有 DES、3DES 和 AES,国密算法包括SM1,SM4和SM7。目前,使用 DES 来加密数据非常不安全。因此,在业务代码中要避免使用 DES 加密。而 3DES 算法,是使用不同的密钥进行三次 DES 串联调用,虽然解决 了 DES 不够安全的问题,但是比 AES 慢,也不太推荐。原创 2024-02-02 17:19:03 · 2178 阅读 · 0 评论 -
项目安全问题及解决方法------使用合适的算法
我们的密码保存方式: "password": "$2a$10$wPWdQwfQO2lMxqSIb6iCROXv7lKnQq5XdMO96iCYCj7boK9pk6QPC" //格式为:$$$ 第一个$后的 2a 代表算法版本,第二个$后的 10 是代价因子(默认是 10,代表 2 的 10 次方次哈希),第三个$后的 22 个字符是盐,再后面是摘要。制作 8 位密码长度的 MD5 彩虹表需要 5 个月,那么对于 BCrypt 来说,可能就需要几十年,大部分黑客应该都没有这个耐心。原创 2024-02-02 17:08:13 · 446 阅读 · 0 评论 -
项目安全问题及解决方法------用户密码处理
我们一般来说是不保存原始密码,这样即使被拖库也不会造成用户数据损失,一般来说我们通常会使用 MD5 加密后保存,但是大家对于MD5是使用是否 是正确的呢?所谓加密算法,是可以使用密钥把明文加密为密文,随后还可以使用密钥解密出明文,是双向的。不管多长的数据,使用 MD5 运算后得到的都是固定长度的摘要信息或指纹信息,无法再解密为原始数据。此时,黑客可以自己注册一个账号,使用一个简单的密码,比如 1,生成的密码是 "password": "55f312f84e7785aa1efa552acbf251db"原创 2024-02-02 17:03:28 · 402 阅读 · 0 评论 -
项目安全问题及解决方法-----xss处理
XSS 问题的根源在于,原本是让用户传入或输入正常数据的地方,被黑客替换为了 JavaScript 脚本,页面没有经过转义直接显示了这个数据,然后脚本就被 执行了。更严重的是,脚本没有经过转义就保存到了数据库中,随后页面加载数据的时候,数据中混入的脚本又当做代码执行了。黑客可以利用这个漏洞 来盗取敏感数据,诱骗用户访问钓鱼网站等。原创 2024-02-02 16:50:44 · 1452 阅读 · 0 评论 -
项目中的安全问题及解决方法-----动态脚本注入
但是假如我们传入的name参数是 haha';java.lang.System.exit(0);' 就可以达到关闭整个程序的目的。原因是,我们直接把代码和数据拼接在了一起。外部如 果构造了一个特殊的用户名先闭合字符串的单引号,再执行一条 System.exit 命令的话,就可以满足脚本不出错,命令被执行原创 2024-02-02 16:38:12 · 812 阅读 · 0 评论 -
项目开发中安全问题及解决方案------sql注入
所谓盲注,指的是注入后并不能从服务器得到任何执行结果(甚至是错误信息),只能寄希望服务器对于 SQL 中的真假条件表现出不同的状态。也就是说,通过在真假条件中加入 SLEEP,来实现通过判断接口的响应时间,知道条件的结果是真还是假。基于时间的盲注原理就是,虽然 不能直接查询出 password 字段的值,但可以按字符逐一来查,判断第一个字符是否是 a、是否是 b……在代码中,我们可以引入p6spy工具打印出所有执行的 SQL,观察 sqlmap 构造的一些 SQL,来分析 其中原理。原创 2024-01-19 15:50:02 · 712 阅读 · 0 评论 -
项目开发中安全问题及解决方法-----资金处理一定要幂等
一般而言,这些接口都会有商户订单号的概念,对于相同的商户订单号,无 法进行重复的资金处理,所以三方公司的接口可以实现唯一订单号的幂等处理。最终虽然商品订单是一个,但支付订单是多个,相同的商品订单因为 产生多个支付订单导致多次支付。这,就是全链路的意义,从一开始就需要先有业务订单产生,然后使用相同的业务订单号一直贯穿到最后的资金通路,才能真正 避免重复资金操作。任何资金操作都需要在平台侧生成业务属性的订单,可以是优惠券发放订单,可以是返现订单,也可以是借款订单,一定是先有订单再去做资金操作。原创 2024-01-18 19:46:13 · 417 阅读 · 0 评论 -
项目开发中安全问题及解决方法-----平台资源需要考虑防刷机制
好的防刷逻辑是,对正常使用的用户毫无影响,只有疑似异常使用的用户才会感受到。对于短信验证码,有如下 4 种可行的方式来防刷。如果不加任何限制的话,某些用户大量请求就会导致系统出现问题。下面的例子中,直接调用方法获取短信验证码。• 控制相同手机号的发送次数和发送频次;• 只有先到过注册页面才能发送验证码;• 只有固定的请求头才能发送验证码;• 增加前置图形验证码。原创 2024-01-18 19:40:25 · 397 阅读 · 0 评论 -
项目开发中安全问题及解决方法-----用户标识不能从客户端获取
如果接口面向内部服务,由服务调用方传入用户 ID 没什么不合理,但是这样的接口不能直接开放给客户 端或 H5 使用。在测试阶段为了方便测试调试,我们通常会实现一些无需登录即可使用的接口,直接使用客户端传过来的用户标识,却在上线之前忘记删 除类似的超级接口。关于登陆的逻辑,其实我们没有必要在每一个方法内都复制粘贴相同的获取用户身份的逻辑,可以定义一个自定义注解 @LoginRequired 到 userId 参数上, 然后通过 HandlerMethodArgumentResolver 自动实现参数的组装。原创 2024-01-18 19:34:39 · 496 阅读 · 0 评论 -
项目开发中安全问题及解决方法----请求头中信息仅供参考
通常我们的应用之前都部署了反向代理或负载均衡器,remoteAddr 获得的只 能是代理的 IP 地址,而不是访问用户实际的 IP。这种过于依赖 X-Forwarded-For 请求头来判断用户唯一性的实现方式,是有问题的。我们是完全可以更改它的请求头的,比如我们可以通过模拟发送下面的请求头信息来影响业务: curl http://localhost:45678/trustclientip/test -H "X-Forwarded-For:183.84.18.71, 10.253.15.1"原创 2024-01-18 19:04:58 · 384 阅读 · 0 评论 -
项目开发中安全问题以及解决办法——客户请求需要校验
客户端提交的参数需要校验的问题,可以引申出一个更容易忽略的点是,我们可能会把一些服务端的数据暂存在网页的隐藏域中,这样下次页面提交的时 候可以把相关数据再传给服务端。虽然用户通过网页界面的操作无法修改这些数据,但这些数据对于 HTTP 请求来说就是普通数据,完全可以随时修改为 任意值。所以,服务端在使用这些数据的时候,也同样要特别小心。比如上面的情况,我们从数据库存储的国家中选择其中三个作为白名单进行展示,选择条件是id原创 2024-01-18 18:46:29 · 359 阅读 · 0 评论 -
项目开发中安全问题以及解决办法——客户传进来的数据不可信
一种可行的做法是,让客户端仅传入需要的数据给服务端,像这样重新定义一个 POJO CreateOrderRequest 作为接口入参,比直接使用领域模型 Order 更合 理。在设计接口时,我们会思考哪些数据需要客户端提供,而不是把一个大而全的对象作为参数提供给服务端,以避免因为忘记在服务端重置客户端数据 而导致的安全问题。如果我们直接利用客户端传过来的数据就很可能导致出现问题,服务端也一定要重新从数据库来初始化商品的价格,重新计算最终的订单价格。原创 2024-01-18 18:31:37 · 430 阅读 · 0 评论 -
秒杀系统的业务流程以及优化方案(实现异步秒杀)
确定了我们可以将判断库存和检验一人一单业务抽取出来之后,我们在想一下 还能不能优化,这个时候我们会发现,这两个操作还是在数据库进行的,那么mysql的并发本身也是不高的,现在我们就要通过另一个性能更好的数据库进行实现,就是。首先我们要思考怎么对业务进行拆分,可以想象一个我们去饭店点餐,会有前台接待,询问订单,之后将小票传给后厨去做饭,这样就会快很多,也可以接待更多的客人。如果有下单资格就可以将用户id,优惠券id,和订单id存入一个阻塞队列里面,之后异步进行写入数据库操作。原创 2023-08-25 18:10:31 · 1561 阅读 · 0 评论 -
使用乐观锁解决超卖问题
举个例子:订单系统中,用户在执行下单操作时,可能同一时间有无数个用户同时下单,当a用户的请求查询当前商品库存时,发现当前的商品剩余5件,在执行生成订单并减少库存时,线程切换了,此时b用户执行了查询操作,发现还是剩余5件,并进行了下单操作,这样就导致了这件商品被卖掉了两次正常的情况如下:认为线程安全问题一定会发生,因此在操作数据之前先获取锁,确保线程串行执行。例如SynchronizedLock都属于悲观锁。原创 2023-08-10 17:43:17 · 693 阅读 · 0 评论 -
SpringBoot配置线程池,实现多线程
当任务提交到线程池中,但核心线程数已满并且任务队列也已满时,会继续创建新的线程,直到达到最大线程数。实例分析:比如我想要开多线程进行插入数据,这个时候可以按照下面的方式去写,这种写法呢是创建了一个任务丢给了操作系统,它会被放进任务队列中,等待线程去拿取任务并执行,但是我们这样只是放了一个任务进去,也只会有一个线程进行调用。当任务队列满了并且正在运行的线程数少于最大线程数时,会创建新的线程来执行任务。keepAliveTime(线程空闲时间):当线程池中的线程数大于核心线程数时,空闲线程的存活时间。原创 2023-08-10 14:19:58 · 1284 阅读 · 0 评论 -
详解线程池的作用和实际应用以及拒绝策略
优化系统架构通常包括在时间和空间之间进行权衡。对于线程池的创建,采用线程池预先创建并维护一定数量的线程,以空间换取时间的方式,可以有效减少每次任务执行时创建线程所带来的开销。通过预先创建一定数量的线程并将其放入线程池中,可以避免在任务到来时动态创建线程的开销。相反,任务可以直接从线程池中获取可用的线程并执行,这样可以显著降低任务处理的延迟时间。这种池化思想利用了空间来存储预先创建的线程,以提高整体系统性能。通过将线程池用作线程的缓存,可以避免重复创建和销毁线程的开销,提高系统的吞吐量和响应性能。原创 2023-06-29 20:53:17 · 700 阅读 · 0 评论