性能相关知识梳理

调用方式

调用方式
同步阻塞方式阻塞影响性能
同步非阻塞方式实际不应用
异步阻塞方式实际不应用
异步非阻塞方式效率最高

保障服务稳定的手段

缓存、限流、熔断降级

缓存

缓存击穿、缓存雪崩、缓存穿透

限流
  • 为什么限流

     对外API服务无法应对突增的请求
    
  • 限流算法

    • 计数器

        1、实现
        	限制1s内允许通过请求数
        2、缺陷
        	若前10ms有100个请求通过,剩余990ms拒绝其他请求
        	产生“突刺现象”,不平滑
      
    • 漏桶

        1、实现
        	准备一个队列保存请求,另外通过一个线程池定期从队列中获取请求并执行,可以一次性获取多个请求并发执行
        2、缺陷
        	无法应对突增流量
      
    • 令牌桶

        1、实现
        	可以准备一个队列,用来保存令牌,另外通过一个线程池定期生成令牌放到队列中,每来一个请求,就从队列中获取一个令牌,并继续执行。
      
熔断降级
  • 熔断

     概念
     	1、应对雪崩效应的一种微服务链路保护机制
     解决问题
     	2、当所依赖的对象不稳定时,能够起到快速失败的目的;
     	3、快速失败后,能够根据一定的算法动态试探所依赖对象是否恢复
    
  • 降级

      概念
      	1、服务降级是从整个系统的负荷情况出发和考虑的,对某些负荷会比较高的情况,为了预防某些功能(业务场景)出现负荷过载或者响应慢的情况
      	2、在其内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个提前准备好的fallback(退路)错误处理信息。这样,虽然提供的是一个有损的服务,但却保证了整个系统的稳定性和可用性。
    
  • 主流框架

      1、Sentinel
      2、Hystrix
      3、Resilience4j
    
  • 熔断、降级相同点

      1、目的很一致,都是从可用性可靠性着想,为防止系统的整体缓慢甚至崩溃,采用的技术手段;
      2、最终表现类似,对于两者来说,最终让用户体验到的是某些功能暂时不可达或不可用; 
      3、粒度一般都是服务级别,当然,业界也有不少更细粒度的做法,比如做到数据持久层(允许查询,不允许增删改); 
      4、自治性要求很高,熔断模式一般都是服务基于策略的自动触发,降级虽说可人工干预,但在微服务架构下,完全靠人显然不可能,开关预置、配置中心都是必要手段;
    
  • 熔断、降级区别

      1、触发原因不太一样,服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;
      2、管理目标的层次不太一样,熔断其实是一个框架级的处理,每个微服务都需要(无层级之分),而降级一般需要对业务有层级之分(比如降级一般是从最外围服务开始) 
      3、实现方式不太一样;服务降级具有代码侵入性(由控制器完成/或自动降级),熔断一般称为自我熔断。
    

内存模型

线程共享数据区、线程私有数据区

  • 线程共享数据区
    随着虚拟机启动而创建,随着虚拟机退出而销毁

    • 堆内存

        新生代
        	eden区(生成区)
        	survivor区(幸存区)
        		Survivor0即FromSpace
        		Survivor1即ToSpace
        	Eden:FromSpace:ToSpace 为 8:1:1
        老年代
        	old区:存储长期活动的对象
      
    • 方法区

        存储类信息、常量、静态变量、即时编译后代码
      
    • 常量池

        编译期生成的class文件的各种字面量和符号引用
      
  • 线程私有数据区
    随着线程开始和结束而创建和销毁

    • PC寄存器

        当前线程所执行的字节码的行号指示器,占内存极小
      
    • 虚拟机栈

        存放栈帧,而栈帧主要包括了:局部变量表、操作数栈、动态链表、方法出又等。
      
    • 本地方法栈

        用于支持native方法的运行
      

GC

堆内存分代理由:提高GC性能

  • GC算法
    • 引用计数

        应用
        	python、微软的com
        缺点
        	每次对对象赋值时,均要维护引用计数器,且本身计数器也有一定消耗
      
    • 可达分析(跟踪)

      • 复制

          原理
          	从根集合开始,通过跟踪从fromSpace中找到存活的对象,copy到toSpace中
          	from、to交换身份,下次内存分配从to开始
          优点
          	没有标记-清除过程,效率高
          	没有内存碎片,可以利用bump-the-pointer实现快速分配内存
          缺点
          	需要双倍空间
          应用
          	eden、幸存区
        
      • 标记-清除

          原理
          	标记:从跟集合开始扫描,对存活的对象进行标记
          	清除:扫描整个内存空间,回收未被标记的对象,使用free-list记录可用区域
          优点
          	不需要额外空间
          缺点
          	两次扫描,损耗严重
          	产生内存碎片
        
      • 标记-压缩

          原理
          	标记:从跟集合开始扫描,对存活的对象进行标记
          	压缩:再次扫描,并往一端滑动存活的对象
          优点
          	没有内存碎片,可以利用bump-the-pointer
          缺点
          	需要移动对象的成本
        
      • 标记-清除-压缩

          原理
          	标记-清除、标记-压缩结合
          	当进行多次GC(标记、清除)后,才压缩
          优点
          	减少了移动对象的成本
          应用
          	老年代
        
      • 直接内存

          直接内存适合申请次数较少,访问较频繁的场合
          直接内存跳过了java堆,使java程序可以直接访问原⽣内存空间,因此,直接内存访问速度会快于堆内存
          直接内存常⽤于使⽤NIO的场景,例如:mina,netty框架;参考DirectBuffer、ByteBuffer
        

类加载(classloader)

  • 类加载时机
    • 类的生命周期

        加载
        验证
        准备
        解析
        初始化
        使用
        卸载
        连接
      
    • 类立即初始化五种场景
      主动引用、被动引用

        主动引用
        1、遇到如下字节码指令
        	new
        	getstatic
        	putstatic
        	invokestatic
        2、使用java.lang.reflect包对类进行反射调用
        3、初始化某个类,其父类未初始化,先触发父类初始化
        4、虚拟机启动,用户指定一个要执行的类包含main()方法,优先初始化该主类
        5、当使用 JDK 1.7 的动态语言支持时,如果一个 java.lang.invoke.MethodHandle 实例最后的解析结果 REF_getStatic、REF_putStatic、REF_invodeStatic 的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化
        被动引用
        除上面五种主动引用之外,其他引用类的方式都不会触发类的初始化,称为类的被动引用
      
    • 类加载过程

        1、加载
        	将字节码文件装载入内存中,生成一个java.lang.Class对象
        2、验证
        	文件格式验证
        	元数据验证
        	字节码验证
        	符号引用验证
        3、准备
        	为类变量分配内存,并赋初值
        4、解析
        	将常量池内符号引用替换为直接引用
        5、初始化
        	真正开始执行类中定义的java程序代码
      
    • 类加载器

      • 类加载器的定义

          虚拟机把描述类的数据从class字节码文件加载到内存,并对数据进行检验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。
        
      • 类加载器的分类

          1、从jvm的角度
          	启动类加载器
          	所有其他的类加载器
          2、从开发者的角度
          	启动类加载器(Bootstrap ClassLoader)
          	扩展类加载器(Extension ClassLoader)
          	应用程序类加载器(Application ClassLoader)
        
      • 双亲委派模型

          1、定义
          	启动类加载器《-扩展类加载器《-应用程序类加载器《-自定义类加载器
          2、优点
          	有一个很明显的好处,就是Java类随着它的类加载器(说白了,就是它所在的目录)一起具备了一种带有优先级的层次关系,这对于保证Java程序的稳定运作很重要
        
      • 应用

          1、依赖冲突
          	包冲突通过pandora(潘多拉),自定义类加载器为每个中间价自定义一个加载器
          2、热加载
          	spring boot devtools
          	RestartClassLoader为自定义的类加载器,其核心是loadClass的加载方式,我们发现其通过修改了双亲委托机制,默认优先从自己加载,如果自己没有加载到,从从parent进行加载。这样保证了业务代码可以优先被RestartClassLoader加载。进而通过重新加载RestartClassLoader即可完成应用代码部分的重新加载。
          3、热部署
          	指在线上环境使用classloader的加载机制完成业务的部署
          	热部署除了与热加载具有发布更快之外,还有更多的更大的优势就是具有更细的发布粒度
          4、加密保护
          	jar包反编译即可获得代码
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值