Java技术
文章平均质量分 78
设计模式
菜爷面馆
大家好,
我叫青菜,
原阿里巴巴资资深软件工程师,
原梵帝IT技术总监,
45岁转行学厨师,
你们愿意看我怎么学厨师,
然后一步步走上创业之路吗?
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
Shiro快速入门之三
注:在需要授权的接口加上RequiresPermissions("权限key")来设置,这里我用qingcai18036登录后(初始化数据中qingcai18036账号配置了角色admin,admin角色配置了权限user:view和user:add),然后访问http://localhost:8080/userAdd、或http://localhost:8080/userList?shiro权限有5个注解,如果一个类或方法上有多个注解,按下列次序进行处理,如果通过的会继续检查后面,否则返回。原创 2023-11-14 11:22:44 · 267 阅读 · 0 评论 -
Shiro快速入门之二
用Shiro写认证代码,第一步要先实现Realm的认证方法,将从数据库查出来的密码,salt设置到AuthenticationInfo对象中,在用户登录时会将输入的用户名密码传给SecurityManger,然后进行比对用户名和密码是否正确。介绍了Shiro三大核心组件,四大核心功能,以及一个简单的Test Demo,接下来两篇我会用一个比较完整的例子来讲述Shiro的认证及授权是怎么做的,本篇侧重于介绍认证的过程。自定义的Realm实现,主要实现两个方法一个是认证,一个是授权。注:授权代码下篇再讲。原创 2023-11-14 11:13:37 · 231 阅读 · 0 评论 -
Shiro快速入门之一
Java有两个出名的安全框架,一个是Apache Shiro,另一个是Spring Security ,相对而言Shiro更简单、控制权限的粒度可粗可细,我们项目中使用的是Shiro。原创 2023-11-14 10:17:18 · 345 阅读 · 0 评论 -
Session、Token、Jwt三种登录方案介绍
4、如果应用部署在多台服务器,需要做Session同步,这里一般有两种做法,一种是通过容器(Tomcat)本身进行Session复制,但存在一个问题,当用户量大的时候,每台服务器重复存放大量的Session对象,会占用大量的内存,另外一种做法是写一个拦截器,用户在A机器登录后会在当前服务器生成Session,然后用户下一个请求被路由到机器B,这时需要做Session的恢复,解析出Cookie中用户名查找到用户数据然后放到Session里去,该用户下次请求如果还是路由到该台机器就不用再查数据库了。原创 2023-11-14 10:06:25 · 670 阅读 · 0 评论 -
Quartz之JDBC-JobStoreTX配置
原创 2023-11-06 07:58:53 · 1140 阅读 · 0 评论 -
Quartz介绍
Quartz相对 Linux的Crontab更强大,Crontab是进程调度而Quartz是线程调度,Quartz支持集群,另外Quartz还支持Listener便于进行Job的监控,因为数据可以存在DB便于做Job任务管理的可视化。几乎所有系统都需要定时任务,如果系统中定时任务比较少并且是单机环境的直接使用SpringTask即可,如果定时任务比较多且需要经常维护或者要部署在分布式环境中就要考虑使用Quartz或者xxl-job等开源框架,今天我们来了解一下Quartz的基本使用。原创 2023-11-06 07:47:35 · 361 阅读 · 2 评论 -
JVM参数调优
由于eden区的空间大小为512K,无法容纳每次生成的1MB数组,这种就是大对象,直接分配在老年代,老年代最终占用内存为used 10240K。由于eden区的空间大小为6M有足够的空间,但又并不足以有10M空间,所以发生了一次GC,由于每申请一次空间,同时也废弃上次申请的空间(上次申请的失去引用),做GC时被回收。老年代空间几乎没有被占用。PSYoungGen: 404K->320K(1536K):新生代GC前后空间使用大小,3476K->3400K(5632K)整个堆内存GC前后空间使用大小。原创 2023-11-01 10:27:07 · 214 阅读 · 0 评论 -
JVM堆内存解析
老年代对象比较稳定,当有新生代对象移到老年代,如果空间不够时会触发MajorGC,采用标记清除法,即扫描内存区块后标记出存活的对象,然后将未标记的进行回收,MajorGC耗时比较长(监测两周数据,只有启动的时候执行了4次MajorGC,每次耗时200毫秒)。当Eden区满的时候进行Minor GC,如果对象还存活的,会被移到幸存区,以后每次GC时对象的年龄会加1,当年龄加到一定程度就会被移到老年代,幸存区分成两个区,每次只使用一个区,当一个区块填满了后会将还活着对象复制到另一个区。原创 2023-11-01 09:17:24 · 719 阅读 · 0 评论 -
Java日志组件之三Log4j2漏洞剖析及重现
先搭建一个SpringBoot项目,然后将spring-boot-starter-logging这个依赖移除,自己引用log4j-api-2.13.3.jar、log4j-core-2.13.3.jar这两个包,注(这是我们从自己以前老机器上找到的,现在官方应该是已经修复了,直接maven依赖进来应该是不能重现了)。你调用logger.info(name);注:我这里演示用的是同一台机器,但也可以很明显看得出来是在服务器上去执行远程黑客机器上的代码(那个代码在你的服务器上执行,而不是黑客自己的机器)。原创 2023-11-01 08:37:57 · 385 阅读 · 0 评论 -
Java日志组件介绍之二
SpringBoot默认的日志组件就是logback,只要引入spring-boot-start就会把logback依赖引入,如果没logback配置文件,则会直接使用默认的org.springframework.boot.logging.logback.base.xml,默认日志输出级别为INFO。slf4j-simple、logback都是slf4j的具体实现,log4j并不直接实现slf4j,但是有专门的一层桥接slf4j-log4j12来实现slf4j。原创 2023-10-31 23:33:00 · 523 阅读 · 0 评论 -
Java日志组件介绍之一
前段时间爆出Log4j安全漏洞的事情,XX云因未及时报告漏洞被工信部暂停网络安全威胁和漏洞信息共享平台合作单位(https://www.cstis.cn/),话说Java的日志组件真是多而且也比较乱,后续几篇文章就聊一下各日志组件的使用及区别。common-logging是apache提供的一个通用日志接口,可以让应用程序使用日志不依赖于具体的实现类,提供了对Log4j、jdk内置Log、Avalon LogKit进行简单的包装,在应用程序运行时会动态适配找到对应的日志实现类。注:SPI机制的原理,见。原创 2023-10-31 22:48:16 · 315 阅读 · 0 评论 -
Java访问直接内存
直接内存是在Java堆外的,直接向系统申请内存空间,它不受JVM的内存管理机制控制。直接内存分配、使用和回收是通过java.nio.DirectByteBuffer这个类。原创 2023-10-31 08:22:41 · 294 阅读 · 0 评论 -
gRPC源码剖析-Builder模式
创建一个Person对象,姓名和性别是必须的,年龄和身高等其他属性是可选的,我们有几种方法来创建,第一种是用需要写很多个重载的构造函数,另外一种直接使用JavaBean的set方法但没有办法约束是否必选。关于设计模式的概念对于业务开发人员掌握常用的几种就行(用得最多的是策略模式),但要读懂各底层框架,还是需要对所有设计模式都有所了解,否则很难读得懂源代码,并且好多设计模式加上各种变种容易搞混,似是而非,看似简单掌握起来确不容易,用好更难。当创建复杂对象的算法应独立于该对象的组成部分以及它们的装配方式时。原创 2023-10-31 07:22:03 · 924 阅读 · 0 评论 -
gRPC源码剖析-Server启动流程
SPI 全称Service Provider Interface是一种服务发现机制,它通过在ClassPath路径下提供的META-INF/services目录里查找文件,然后自动加载文件所定义的类,SPI的应用还是比较广泛的,比如加载JDBC驱动,另外业务层架构也有使用SPI机制的,比如淘宝早期交易中心系统,各业务方提供自己的交易扩展类,这样不会影响主交易流程。注:低版本好像是会为每一个监听地址构建一个NettyServr,但grpc-netty1.7.1版本源代码只构建了一个NettyServer。原创 2023-10-31 07:10:05 · 655 阅读 · 3 评论 -
gRPC通信模式
这个文章的例子其实和RESTful在通信模式上没有什么区别,也是一次请求然后一个响应的模式,如果真是这样那gRPC就没啥意思了,今天我们来看一下gRPC四种通信模式。一个请求消息对应一个响应消息,然后关闭连接,请求信息以EOS结尾,响应消息以trailer结尾。Game必须继续,妹子很喜欢你,你要相信凭你的长相和钱包有这样的妹子你不好好把握那是个大傻子。一直在接收消息,但就是不想回你,最后才烦了,回你一句滚,Game Over吧。你:宝,我去输液,输的什么液,想你的夜。妹子:快点和我说,我急死了。原创 2023-10-31 06:56:31 · 187 阅读 · 0 评论 -
gRPC初体验
1、RPC是远程过程调用的简称,在分布式系统中,客户端可以像调用本地对象一样调用远程机器上服务端对象,用于系统的垂直拆分,常见的JAVA RPC框架有JAVA自带的RMI、基于Http的Hessian、阿里基于TCP的Dubbo、淘宝基于TCP的HSF、Spring Cloud等。服务接口的编码依赖于protoc-gen-grpc-java插件,mac下安装protoc-gen-grpc-java,下载protoc-gen-grpc-java配置环境。service:服务端代码。clien:客户端代码。原创 2023-10-30 18:01:17 · 318 阅读 · 0 评论 -
Gateway一个诡异问题处理过程
虽然在日志中没有发现OOM,但观察到gc日志在40分钟左右heap会升到300多M,然后GC也比较频繁(YGC),怀疑是我们网关中一个定时任务(每隔15秒从Redis中注册的权限(路径+权限标识)同步到本地Map)占用了大量资源,这个定时任务在我们应用场景中必要性并不大,属于过度设计了,先摘掉再说,YGC频度降下来了,但问题依旧。但因为我们测试环境,微服务是单机并不是集群部署的,怀疑单机配置了这个负载均衡造成无法访问,移除掉代码,重启服务,一段时间后问题又出现。原创 2023-10-30 16:07:05 · 557 阅读 · 0 评论 -
Class文件简单解析
小版本号(minor_version)、大版本号(major_version)表示当前Class文件由哪个版本的编译器产生,图一major_version 为55表示编译器版本是JDK11, JDK编译器的版本和Class文件的大版本对应关系如下。魔数magic是Class文件的标记,在class文件最开头四个字节,其十六进制值是cafe babe,参见图一,这个标记是用来告诉虚拟机这是Class文件。常量池的作用是:常量池是用来保存常量一个中间场所,在JVM运行时把常量池中的常量加载到内存中。原创 2023-10-27 08:44:45 · 198 阅读 · 0 评论 -
Btrace入门
今天收到客户报的一个Bug,登录系统查看发现没有相关日志输出,方法中相关的请求参数及变量都没有打印出来,给排查问题造成很大不便,我们知道解决Java系统疑难杂症有两大利器,其一是tcpdump用于网络抓包分析 、其二是Btrace用于动态跟踪Java代码,tcpdump在 前面一些文章有介绍它的简单使用(总共4个方法,分别跟踪方法是否被调用,监控方法耗时,打印方法请求参数(可以打印出基本类型参数,也可以打印出业务对象类型参数)、跟踪某一行代码是否被执行。注:上面4个方法基本覆盖了一般跟踪的需求。原创 2023-10-27 08:28:11 · 166 阅读 · 0 评论 -
用Asm生成Class字节码文件
这语法还是很难写的,调了好久才成功输出了HelloWorld,可以在Eclipse或IDEA中安装bytecode可以查一个Class文件的字节码,然后参照字节码文件修改代码,这个对字节码的编码需要特别了解才能写得好,一般我们直接使用。相对于Javassist,Asm是直接生成二进制Class文件,效率会更高,但编写代码特别繁琐,我只做简单了解一下,知道有这个玩意就行。这其实是一个系列,所讲的都是关于如何在执行的时候动态更改代码,从动态代理、到Javaassist,然后到Asm,都是为了做同一件事情。原创 2023-10-23 10:57:22 · 241 阅读 · 0 评论 -
Javassist动态修改Class对象
讲了动态代理,JDK的Proxy动态代理是用反射机制来实现,而CGLIB是通过ASM操作字节码来实现,用ASM操作字节码比较复杂,需要熟悉Class文件结构,用Javassist也可以实现修改类对象,可以在一个已经编译好的类中添加新的方法或者修改已有的方法而不需要你对字节码文件有深入的了解,这个功能还是很强大,不仅服务端在做拦截时会用到,Android做热更新也可以用这个,唉,以前做了2年的Andoid现在差不多忘光了。: 是CtClass对象的容器,makeClass方法创建一个CtClass空类。原创 2023-10-23 09:47:24 · 621 阅读 · 0 评论 -
Java代理
上面类图中有一个订单接口类(OrderService)、一个订单实现类(OrderServiceImpl),订单模块的业务相对复杂和重要,如果这时候要在方法执行前后加上日志,就可以新增一个代理类来实现,而不用改动原来OrderServcieImpl核心业务逻辑代码。代理角色(Proxy):代理对象内部含有对真实对象的引用,与真实对象有相同的接口以便在任何时候都可以代替真实对象,同时它可以在执行真实对象操作时附加其它操作。代理模式定义:为其他对象提供一种代理以控制对这个对象的访问。得到某一对象的代理对象。原创 2023-10-22 21:40:55 · 208 阅读 · 0 评论 -
一次OOM故障分析
吃完中饭正在休息,业务方说POS的后台管理系统进行库存盘点出错,截图过来的报错信息里有:连接POS前台系统的HTTP请求报Readtime Out,第一反应是澳洲的网络出问题了,然后让业务方把条码给我自己操作了一下也不行,紧接着业务方又发信息过来说所有门店POS系统都无法下单,这时候人就紧张起来了,马上登录到机器上执行Top命令查Load状况,机器负载没有什么问题,处于低水位运行,这时候就猜想极有可能是JVM OOM了,不管3721重启应用再说吧,一般重启应用能解决99%的问题,重启后系统恢复正常。原创 2023-10-22 11:32:13 · 207 阅读 · 0 评论 -
限流与下载接口请求数控制
收银台系统相对于互联网应用流量要平稳很多,高峰流量也就平时的三倍,完全是可控的,我们这里用限流主要是控制后台同时下载XLS表格的请求数,因为后台系统要提供大量的导出XLS表格功能,收银员与管理人员需要用我们导出的数据去做各种分析(应该是我们的报表功能还不够完善造成的)。思路:创建LoadCaching对象,设置有效期为1秒,缓存Key为时间戳(当前秒数),值是计数器(调用次数累加),如果查询命中计数器自增,当计数器值大于限定值时不处理,如果没有命中,创建一个新的时间戳缓存并初始化值为0,达到限流的目的。原创 2023-10-16 11:28:30 · 222 阅读 · 0 评论 -
线程池配置介绍
我们收银台项目为了架构简单,一些异步化任务(如下单完成扣减库存、发送邮件等等),没有使用MQ而是直接启动线程来做,但如果随意使用线程对系统性能反而会有影响,当线程数量大到一定的时候会耗尽CPU和内存资源,并且创建和销毁线程也需要时间,大量线程回收会造成GC的压力,所以一般项目中都统一使用一个线程池集中管理所有线程的创建和回收。核心线程即使没有任务执行也会一直存活,当线程数小于核心线程数即使有空闲的线程也会创建新的线程以尽量达到核心线程数。若线程数等于maxPoolSize,则拒绝任务,抛出异常。原创 2023-10-16 10:52:06 · 204 阅读 · 0 评论 -
@SpringBootApplication剖析
定义一个Spring Bean是在类上加上注解@Service、@Controller、@Compent就可以,而Spring是通过扫描@CompoentScan指定包下所有加了注解的类,如果不写它只会加载启动类所在的包及下级包。@SpringBootConfiguration组合了@Configuration,它是用来声明当前类是一个配置类,被注解类的内部包含一个或多个@Bean注解的方法,用于替换xml配置定义,这些方法将被。简单例子:直接使用@Configuration和@Bean来注入容器。原创 2023-10-05 23:02:17 · 364 阅读 · 0 评论 -
面向对象设计原则
面向对象设计原则是一组用于指导良好的软件设计的基本准则。这些原则帮助开发人员创建可维护、可扩展和易于理解的代码,所有的设计模式都会遵循这些基本原则。原创 2023-09-02 17:22:21 · 113 阅读 · 0 评论 -
Java设计模式概述
设计模式为开发人员提供了一系列经过验证的解决方案,能够显著提升代码的可读性和可维护性。这些模式广泛应用于开源基础框架中,如JDK、Spring等,如果你不熟悉设计模式想要理解这些框架的源代码就会非常困难。在业务项目中,设计模式的应用会受到一些限制。特别是以业务为导向的技术团队中,成员的技术背景可能存在差异,如果设计模式应用得不恰当,可能会导致后续维护过程成为一场灾难。原创 2023-08-30 10:58:14 · 103 阅读 · 0 评论
分享