这部分内容涉及的知识点比较多,我没能一次性把它们全部写完,但是会尽快更新完善。
一、cpu和内存飙高。
1)内存飙高问题可以使用MAT查看原因,CPU飙高可以使用jstack查看原因,我把具体的方法单独写到了我的这篇博客里:
2)在关于MAT的博客里也说过,jmap不是很适合线上环境,那么就需要找替代品,适合线上使用的工具。Oracle官网推荐的一个工具是:JMC/飞行记录器。这个工具的具体使用方式可以参考我的另外一篇博客:
二、开启远程调试。
很多问题我们都是采用打印日志的方式,但是日志毕竟不是很完善的,很多细节看不到,这个时候如果开启远程调试,效率会高很多。使用idea开启java的远程调试并不难,这里我使用springboot+docker+linux,演示一下如何开启java的远程调试。
1)使用idea创建一个SpringBoot程序,名字叫做debug,创建一个TestController,代码如下:
@RestController
public class TestController {
@PutMapping(value = "test")
public boolean Update()
{
return true;
}
@GetMapping(value = "test")
public String Get() {
return new Date().toString();
}
}
2)点击Edit Configurations,点击+,选择remote:
3)填写服务器地址和端口号,这里我的Linux服务器的地址是192.168.31.195。然后把黄色框里面的内容复制下来:
4)打包我们的springboot程序为jar包,把它部署到docker容器里面,这里如何部署到docker容器,我在我之前的一篇博客里有写过,不会的话可以看我的这篇博客:。但是这里的Dockerfile内容要加上上一步我们复制的东西,完整的Dockerfile如下:
FROM java:8
ADD debug.jar debug.jar
ENTRYPOINT ["java","-jar","-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005","-Dspring.profiles.active=sit","debug.jar"]
5)启动容器的时候把5005和8089端口映射出来,5005端口是用于远程调试的端口,8089端口,是我的Springboot程序要用的端口。
6)程序部署好之后,在idea里面,将配置选项设置为我们配置的那个远程配置,然后点击调试:
如果连接成功了,那么idea控制台会输出如下内容:
这个时候调用一下我们写好的接口:192.168.31.195:8089/test。你会发现,虽然我们调用的是服务器的服务,但是代码会进到你本地的idea里面:
不妨多想一下,在这种远程调试的情况下,如果代码打了断点,那么会导致应用程序暂停吗?
答案是会。所以远程调试可能会导致线上程序暂停,对于高并发的互联网场景下,使用的时候要注意。
另外说一点,远程调试分称两种,一种是主动连接,一种是被动连接。
a)attach to remote jvm 主动连接就是程序已经启动起来了,使用ide去远程连接要调试的程序,也就是本例中的这种情况
b)listent to remote jvm 被动连接是先把ide的远程调试启动起来,等待程序启动然后连接,这种一般用于程序启动不起来,需要远程调试查找原因的情况。
具体的设置方法也还是在Edit Configuration里面设置:
java的远程调试原理并不难,使用的是Java的调试体系,调戏体系的原理是对JVM Tools Interface的上层封装。基于JVMTI,可以实现很多黑科技,比如链路追踪,Cloud Debugger,各种性能监控技术,热加载技术,Java代码加密等等技术,都是用这些实现的。这块儿的内容比较多而且涉及到C++的知识,我后续会开一篇博客单独讲这部分内容。
三、sql异常。
sql异常指sql执行结果和预期不符,或者运行缓慢。一个java方法经过一系列的操作之后,最终都是要落库的,所以程序执行结果是否符合预期,sql的执行结果至关重要。sql问题排查可以采用临时开启普通日志的方式,sql执行耗时长,可以采用慢查询日志的方式来查找原因,等等。具体如何进行sql问题的排查,可以参考我的另外一篇博客:。
四、程序运行缓慢。(尽快补充)
五、链路追踪和APM。(尽快补充)