文章目录
《4.5.1 单机限流(限流算法及隔离策略》
-
四种限流算法:计数器、滑动窗口、漏桶、令牌桶
- 计数器、滑动窗口的讲解可参考https://www.cnblogs.com/linjiqin/p/9707713.html
- 漏桶:
- 34分:令牌桶:
此缺点真的存在?《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();
}
切面类:
@Aspect
@Component
public class SdhRateLimiterAspect {
private Map<String, RateLimiter> url_limitMap = new ConcurrentHashMap<>();
@Around("@annotation(com.study.current.limiting.aop.SdhRateLimiter)")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取request,response
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
String url = request.getRequestURI();
// 获取自定义注解
SdhRateLimiter limiterAnnotation = getSdhRateLimiter(joinPoint);
if (limiterAnnotation != null) {
RateLimiter limiter = null;
if (!url_limitMap.containsKey(url)) {
// 创建令牌桶
limiter = RateLimiter.create(limiterAnnotation.permitsPerSecond());
url_limitMap.put(url, limiter);
System.out.println("<<================= 请求"+url+",创建令牌桶成功!!!");
}
limiter = url_limitMap.get(url);
// 获取令牌
boolean acquire = limiter.tryAcquire(limiterAnnotation.timeout(), limiterAnnotation.timeUnit());
if (!acquire) {
return limiterAnnotation.errorMsg();
}
}
return joinPoint.proceed();
}
/**
* 获取注解对象
*
* @param joinPoint 对象
* @return ten LogAnnotation
*/
private SdhRateLimiter getSdhRateLimiter(final JoinPoint joinPoint) {
Method[] methods = joinPoint.getTarget().getClass().getDeclaredMethods();
String name = joinPoint.getSignature().getName();
if (!StringUtils.isEmpty(name)) {
for (Method method : methods) {
SdhRateLimiter annotation = method.getAnnotation(SdhRateLimiter.class);
if (annotation!=null && name.equals(method.getName())) {
return annotation;
}
}
}
return null;
}
}
《【技术分享】CPU100%问题解决与优化》
-
伪共享; @Contended
-
死锁:用jcmd列出进程号,用jstack可查看进程中是否有死锁
-
55分-: cpu 100%(比如while(true)导致的)
1,linux命令top,找到进程
2,找到线程,top -H -P javapid
3,jstack pid > log.txt -
64:14 核心方法的度量工具Metrics
-
78:24 接口响应很慢
监控工具arthas
-
90:47 【面试题】JUC包你使用过哪些类?在哪些场景使用?
页面打开太慢, 请求太多,浏览器有限制。
优化方案: 多个请求合并到一起。
后台优化:后台收到请求之后,要 执行多个复杂的service、多次数据库查询。多线程异步编程并发查询,用到futrue相关技术。