作者:shajc220 | 来源:互联网 | 2023-06-26 13:47
文章目录《4.5.1单机限流(限流算法及隔离策略》《4.5.2低入侵限流框架设计与实现》《【技术分享】OOM问题解决与优化》old《3.2.4内存爆炸、CPU100%问题分析、定位
文章目录 《4.5.1 单机限流(限流算法及隔离策略》 《4.5.2 低入侵限流框架设计与实现》 《【技术分享】OOM问题解决与优化》 old《3.2.4 内存爆炸、CPU100%问题分析、定位、解决》 old《3.2.5 网易真实性能调优案例分享》 《4.5.3 编写限流框架中的核心模块》 《【技术分享】CPU100%问题解决与优化》
《4.5.1 单机限流(限流算法及隔离策略》 此缺点真的存在?《4.5.3 编写限流框架中的核心模块》118:50+有解释,但我认为解释不正确。 Guava RateLimiter原理是令牌桶
隔离策略:线程池、信号量Semaphore 《4.5.2 低入侵限流框架设计与实现》 使用Guava RateLimiter实现限流
7分 DateTimeFormatter与LocalDateTime,是jdk1.8以后线程安全的时间处理类
《【技术分享】OOM问题解决与优化》
29:30: 逃逸分析 & 栈上分配 & 标量替换 默认开启>=1.6u23 逃逸分析默认开启,关闭 -XX:-DoEscapeAnalysis 对象有动态调整大小的集合时,不会进行栈上分配
55:30+ 防止full GC: 运用Btrace的强大定位功能,发现system.gc被调用
83分 分步骤分析瓶颈
136分- 一些OOM场景:
146分 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/temp/202006.hprof 用MemoryAnalyzer工具分析dump文件:
166:45+: 对堆内内存溢出的问题,在测试环境下用gperftools工具:
old《3.2.4 内存爆炸、CPU100%问题分析、定位、解决》 垃圾回收器一般用 CMS+ParNewGC?
36:50 监控系统:大众点评的CAT, Zabbix
60:23 禁止显式调用gc方法:
jcmd jmap输出内存快照
104:30 没有分页(或者前端参数不严谨)导致10w+的超长arraylist, OOM
old《3.2.5 网易真实性能调优案例分享》 28:15 某案例中,cpu占用不高但接口访问依然慢,用jstack输出进程堆栈信息后,发现一个sleep的线程: 然后在对应代码中发现了问题:是调用了sleep命令 54:35 本机不能直连生产环境的机器,必须通过中转机(或称堡垒机) 87:50 jstack输出信息中的线程的nid,为os中线程pid的16进制形式。通过这种办法来定位那些cpu占用率特别高的线程的代码 《4.5.3 编写限流框架中的核心模块》 使用aop的环绕通知来拦截自定义注解,在切面类中使用Guava的令牌桶限流算法: Controller中的方法:
@GetMapping ( "sdh" ) @SdhRateLimiter ( permitsPerSecond = 1 , timeout = 500 , errorMsg = "有错误" ) public String sdhLimiter ( ) { return "sdh success" ; }
自定义注解:
@Retention ( RetentionPolicy. RUNTIME) @Target ( { ElementType. METHOD} ) public @interface SdhRateLimiter { double permitsPerSecond ( ) default 1 ; long timeout ( ) default 500 ; TimeUnit timeUnit ( ) default TimeUnit. MILLISECONDS; String errorMsg ( ) ; }
切面类:
&#64;Aspect &#64;Component public class SdhRateLimiterAspect { private Map< String, RateLimiter> url_limitMap &#61; new ConcurrentHashMap < > ( ) ; &#64;Around ( "&#64;annotation(com.study.current.limiting.aop.SdhRateLimiter)" ) public Object around ( ProceedingJoinPoint joinPoint) throws Throwable { HttpServletRequest request &#61; ( ( ServletRequestAttributes) RequestContextHolder. getRequestAttributes ( ) ) . getRequest ( ) ; HttpServletResponse response &#61; ( ( ServletRequestAttributes) RequestContextHolder. getRequestAttributes ( ) ) . getResponse ( ) ; String url &#61; request. getRequestURI ( ) ; SdhRateLimiter limiterAnnotation &#61; getSdhRateLimiter ( joinPoint) ; if ( limiterAnnotation !&#61; null) { RateLimiter limiter &#61; null; if ( ! url_limitMap. containsKey ( url) ) { limiter &#61; RateLimiter. create ( limiterAnnotation. permitsPerSecond ( ) ) ; url_limitMap. put ( url, limiter) ; System. out. println ( "<<&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61; 请求" &#43; url&#43; ",创建令牌桶成功!!!" ) ; } limiter &#61; url_limitMap. get ( url) ; boolean acquire &#61; limiter. tryAcquire ( limiterAnnotation. timeout ( ) , limiterAnnotation. timeUnit ( ) ) ; if ( ! acquire) { return limiterAnnotation. errorMsg ( ) ; } } return joinPoint. proceed ( ) ; } private SdhRateLimiter getSdhRateLimiter ( final JoinPoint joinPoint) { Method[ ] methods &#61; joinPoint. getTarget ( ) . getClass ( ) . getDeclaredMethods ( ) ; String name &#61; joinPoint. getSignature ( ) . getName ( ) ; if ( ! StringUtils. isEmpty ( name) ) { for ( Method method : methods) { SdhRateLimiter annotation &#61; method. getAnnotation ( SdhRateLimiter. class ) ; if ( annotation!&#61; null && name. equals ( method. getName ( ) ) ) { return annotation; } } } return null; } }
《【技术分享】CPU100%问题解决与优化》 伪共享; &#64;Contended
死锁&#xff1a;用jcmd列出进程号&#xff0c;用jstack可查看进程中是否有死锁
55分-&#xff1a; cpu 100%(比如while(true)导致的) 1&#xff0c;linux命令top,找到进程 2&#xff0c;找到线程&#xff0c;top -H -P javapid 3&#xff0c;jstack pid > log.txt
64&#xff1a;14 核心方法的度量工具Metrics
78:24 接口响应很慢 监控工具arthas
90:47 【面试题】JUC包你使用过哪些类&#xff1f;在哪些场景使用&#xff1f;
页面打开太慢&#xff0c; 请求太多&#xff0c;浏览器有限制。 优化方案&#xff1a; 多个请求合并到一起。 后台优化&#xff1a;后台收到请求之后&#xff0c;要 执行多个复杂的service、多次数据库查询。多线程异步编程并发查询&#xff0c;用到futrue相关技术。