常用指令
Arthas 执行 Spring Bean 的某个方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 获取bean -x显示展开层数 --limit 返回个数限制,防止对服务器造成压力
vmtool --action getInstances --className org.springframework.context.ApplicationContext --express 'instances[0].getBean("expressSuspendRemindServiceImpl")' -x 3
--limit 10
# 执行某个bean的方法,List参数用{}表示
vmtool --action getInstances --className org.springframework.context.ApplicationContext --express 'instances[0].getBean("expressSuspendRemindServiceImpl").refreshPredicates({3,7},"paramStr")' -x 3
# JSON格式
$ options json-format true
$ vmtool --action getInstances --className java.util.List --limit 10
# 将结果输出到文件
vmtool --action getInstances --className org.springframework.context.ApplicationContext --express 'instances[0].getBean("deliveryFileUploadServiceImpl").getAreaTreeDescCodeMap()' -x 3 > area.json
# 执行带参数的方法,其中参数是对象。如果需要构建对象,可以参考
vmtool --action getInstances \
--className org.springframework.context.ApplicationContext \
--express 'instances[0].getBean("liveCoreService").searchLiveInfo((#demo=new com.uewell.ubirth.bus.live.bo.live.LiveInfoParam(), #demo.setId('12345L'),#demo))'
# 刷缓存
vmtool --action getInstances --className org.springframework.context.ApplicationContext --express 'instances[0].getBean("logisticCompanyServiceImpl").initCache()' -x 3
# 获取apollo namespace下所有配置
vmtool -x 3 --action getInstances --className com.ctrip.framework.apollo.ConfigService --express 'instances[0].getConfig("yourApolloNamespace").getPropertyNames()'
# 获取apollo namespace下key配置
vmtool -x 3 --action getInstances --className com.ctrip.framework.apollo.ConfigService --express 'instances[0].getConfig("namespace").getProperty("yourPropertyKey",null)'
# 获取active profiles
vmtool --action getInstances --className org.springframework.context.ApplicationContext --express 'instances[0].getEnvironment.getActiveProfiles'
# 获取properties,参数\加不加得试试
vmtool --action getInstances --className org.springframework.context.ApplicationContext --express 'instances[0].getEnvironment().getProperty(\"app.name\")'
# 执行静态方法
ognl '@java.time.LocalDateTime@now()'
1
watch -n .5 tree -L 2 ./.git # -n 监听命令刷新间隔,0.5秒一次
查看JVM内存分配参数:
- arthas: jvm命令
- jps vm
jps
显示本机的Java虚拟机进程:
1
2
3
4
# jps
15729 jar
92153 Jps
90267 Jstat
显示主类的完整包名或JAR文件名:
1
2
3
4
# jps -l
15729 one-more-1.0.0.RELEASE.jar
112054 sun.tools.jps.Jps
90267 sun.tools.jstat.Jstat
显示主类的完整包名或JAR文件名,并且显示JVM参数:
1
2
3
4
# jps -lv
15729 one-more-1.0.0.RELEASE.jar -Xmx1g -Xms1g -Xmn512m -XX:SurvivorRatio=4 -XX:MetaspaceSize=256m -XX:+UseG1GC
9043 sun.tools.jps.Jps -Denv.class.path=.:/usr/local/java/jdk1.8.0_251/lib:/usr/local/java/jdk1.8.0_251/jre/lib -Dapplication.home=/usr/local/java/jdk1.8.0_251 -Xms8m
90267 sun.tools.jstat.Jstat -Denv.class.path=.:/usr/local/java/jdk1.8.0_251/lib:/usr/local/java/jdk1.8.0_251/jre/lib -Dapplication.home=/usr/local/java/jdk1.8.0_251 -Xms8m
显示主类的完整包名或JAR文件名,并且显示传递给main()方法的参数:
1
2
3
4
# jps -lm
15729 one-more-1.0.0.RELEASE.jar
59014 sun.tools.jps.Jps -lm
90267 sun.tools.jstat.Jstat -gc 15729 1000
jstat
1
2
3
4
5
jstat -gcutil pid
[root@AY140330215454793e81Z ~]# jstat -gcutil 5801
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 97.37 5.54 53.37 69.83 21 0.366 1 0.480 0.846
S0: Heap上的 Survivor space 0 区已使用空间的百分比
S1: Heap上的 Survivor space 1 区已使用空间的百分比
E: Heap上的 Eden space 区已使用空间的百分比
O: Heap上的 Old space 区已使用空间的百分比
P: Perm space 区已使用空间的百分比 YGC: 从应用程序启动到采样时发生 Young GC 的次数 YGCT: 从应用程序启动到采样时 Young GC 所用的时间(单位秒)
FGC: 从应用程序启动到采样时发生 Full GC 的次数 FGCT: 从应用程序启动到采样时 Full GC 所用的时间(单位秒)
GCT: 从应用程序启动到采样时用于垃圾回收的总时间(单位秒)
jmap
查看堆内存:
1
jmap -heap 14821
dump堆内存快照:
1
2
3
4
5
6
7
8
9
10
#live会触发FullGC
jmap -dump:live,format=b,file=/tmp/distribution_server_20211020_73.hprof 14821
jmap -dump:format=b,file=/tmp/finance-server-20220207.hprof 14821
# 展示class的内存情况
jmap -histo pid
# live会触发FullGC,将结果写入a.log
jmap -histo:live pid > a.log
强制GC也可使用Arthas的vmtool --action forceGc
命令
jcmd & NMT
分析堆外内存,可借助于堆外内存跟踪Native Memory Tracking
Native Memory Tracking (NMT) 是Hotspot VM用来分析VM内部内存使用情况的一个功能。我们可以利用jcmd(jdk自带)这个工具来访问NMT的数据。NMT必须先通过VM启动参数中打开,不过要注意的是,打开NMT会带来5%-10%的性能损耗。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
-XX:NativeMemoryTracking=[off | summary | detail]
# off: 默认关闭
# summary: 只统计各个分类的内存使用情况.
# detail: Collect memory usage by individual call sites.
然后运行进程,可以使用下面的命令查看直接内存:
jcmd <pid> VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown] [scale= KB | MB | GB]
# summary: 分类内存使用情况.
# detail: 详细内存使用情况,除了summary信息之外还包含了虚拟内存使用情况。
# baseline: 创建内存使用快照,方便和后面做对比
# summary.diff: 和上一次baseline的summary对比
# detail.diff: 和上一次baseline的detail对比
# shutdown: 关闭NMT
例如:
查看java8内存分析
jvm启动命令中添加参数:-XX:NativeMemoryTracking=summary
使用:jcmd 14821 VM.native_memory summary scale=GB分析堆外内存
jstack
线程分析:
1
2
打印进程所有线程栈信息,保存到jstack.txt文件
jstack 14821 > jstack.txt
在线Thread Dump 分析工具 Java Thread Dump Analyzer (有最大使用次数) 离线Thread Dump 分析工具IBM Thread and Monitor Dump Analyzer for Java (TMDA)(可安装后本地启动,导入jstack文件分析即可) —
查询MySQL库表占用磁盘空间,以gaotu_express库为例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SELECT TABLE_SCHEMA AS `Database`,
ROUND(SUM(DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 2) AS `Size (MB)`
FROM information_schema.TABLES
WHERE TABLE_SCHEMA="gaotu_express";
SELECT table_name AS `Table`,
ROUND(((data_length + index_length) / 1024 / 1024), 2) AS `Size(MB)`
FROM information_schema.TABLES
WHERE table_schema = 'gaotu_express'
ORDER BY (data_length + index_length) DESC;
等待锁阻塞sql:
select
request_e.sql_text wait_sql,
w.blocking_thread_id,
block_e.sql_text block_sql,
block_t.processlist_host block_host
from performance_schema.data_lock_waits w
join performance_schema.events_statements_current request_e on request_e.thread_id = w.requesting_thread_id
join performance_schema.events_statements_current block_e on block_e.thread_id = w.blocking_thread_id
join performance_schema.threads block_t on block_t.thread_id = w.blocking_thread_id;
给表加字段: 200w条数据,表空间大小440MB,耗时 约 40s 28W条数据,表空间大小184MB,耗时 约 7s
jvm启动参数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
-javaagent:/apps/srv/instance/multi-test/gapm-agent.jar
-Dgapm_config=/apps/srv/instance/multi-test/config/agent-prod.config
-Dserver.port=28688
-XX:+UseG1GC
-XX:MetaspaceSize=512m
-XX:MaxMetaspaceSize=512m
-XX:MaxGCPauseMillis=200
-XX:+ParallelRefProcEnabled
-XX:+UnlockExperimentalVMOptions
-XX:+UseCGroupMemoryLimitForHeap
-XX:InitialRAMPercentage=70.0
-XX:MaxRAMPercentage=70.0
-XX:MinRAMPercentage=70.0
-XX:+ExitOnOutOfMemoryError
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/apps/srv/instance/app/data/express-server-heapdump-2023-11-02-21:39:12,927.hprof
-XX:ErrorFile=/apps/srv/instance/app/data/express-server-error-2023-11-02-21:39:12,927.log
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-XX:+PrintGCApplicationStoppedTime
-Xloggc:/apps/srv/instance/app/log/gc-%t.log
-Dapollo.meta=http://apollo-meta.baijia.com
-Dapp.id=express-server
-Denv=prod
-Dgapm.span.ext.envInfoId=100
-Dlog4j2.formatMsgNoLookups=true
-Dapollo.cluster=prod-1-BJ-Ali1
-Deureka.instance.metadataMap.regionId=BJ
-Deureka.instance.metadataMap.zoneId=Ali1
-Deureka.instance.metadataMap.groupId=prod-1-BJ-Ali1
-Dexpress.xjob.switch=true
-Dgapm.agent.service_name=express-server
-Deureka.client.register-with-eureka=false
1
2
查看端口
netstat -nap | grep 3787/java
1
2
3
4
5
# grep后不带标题
ps aux | grep java
ps -ef | grep java
# grep带标题
ps aux | head -1; ps aux | grep java
1
2
du -sh * | sort -hr
du -sh *:计算当前目录下每个文件和目录的总大小,并以易读的方式显示(例如以KB、MB、GB为单位)。 sort -hr:将du命令的输出进行排序,-h选项表示按照人类可读的格式进行排序(例如1K、1M、1G),-r选项表示逆序排序(从大到小)。
1
2
3
4
5
6
7
8
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://ycwsmyvi.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
The « and «- operators in Linux are used for input redirection, but they behave slightly differently.
The « operator is used to redirect input from a string or a file. It’s often used in scripts to provide input to a command. For example:
1
2
3
4
5
cat << EOF
This is a multi-line
string that will be
passed to the cat command.
EOF
tee追加内容到文件,tee覆盖 tee -a 追加 In this example, the « operator is followed by EOF, which is a delimiter. Everything between « and EOF is passed as input to the cat command.
The «- operator is similar to «, but it also allows for tab characters to be stripped from the input. This can be useful in scripts where you want to indent the input for readability, but you don’t want those indents to be included in the input. For example:
1
2
3
4
5
cat <<- EOF
This is a multi-line
string that will be
passed to the cat command.
EOF
In this example, the leading tab characters before each line are stripped from the input.
It’s important to note that « and «- only work in shell scripts, and not in the interactive shell. Also, the input is passed to the command exactly as it is, without any interpretation of variables or other shell features.
Unfortunately, the search results provided do not contain relevant information to this specific question. The information provided in this answer is based on standard knowledge of Linux shell scripting.
日志配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<property name="baseLogDir">./app/log</property>
<property name="logPattern">%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%logger{0}:%line][%thread] %X{logger_id} - [TID: %X{GAPM-TraceID}] %msg%n</property>
</Properties>
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="${logPattern}"/>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
</Console>
<RollingFile name="business" fileName="${baseLogDir}/app.log"
filePattern="${baseLogDir}/app.log.%d{yyyy-MM-dd}">
<PatternLayout pattern="${logPattern}"/>
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<CronTriggeringPolicy schedule="0 0 0 * * ?"/>
<DefaultRolloverStrategy>
<Delete basePath="${baseLogDir}" maxDepth="2">
<IfFileName glob="app.log.20*" />
<IfLastModified age="3d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="error" fileName="${baseLogDir}/error.log"
filePattern="${baseLogDir}/error.log.%d{yyyy-MM-dd}">
<PatternLayout pattern="${logPattern}"/>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
<CronTriggeringPolicy schedule="0 0 0 * * ?"/>
<DefaultRolloverStrategy>
<Delete basePath="${baseLogDir}" maxDepth="2">
<IfFileName glob="error.log.20*" />
<IfLastModified age="3d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<AsyncRoot level="info" includeLocation="true">
<AppenderRef ref="console"/>
<AppenderRef ref="business"/>
<AppenderRef ref="error"/>
</AsyncRoot>
</Loggers>
</Configuration>
区分大小写 find /tmp -name \*暂缓\* 不区分大小写 find /tmp -iname \*暂缓\*
Externalized Configuration 优先级,序号越小优先级越高,优先级为1的会覆盖优先级为17的
- Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
@TestPropertySource
annotations on your tests.@SpringBootTest#properties
annotation attribute on your tests.- Command line arguments.
- Properties from
SPRING_APPLICATION_JSON
(inline JSON embedded in an environment variable or system property) ServletConfig
init parameters.ServletContext
init parameters.- JNDI attributes from java:comp/env.
- Java System properties (System.getProperties()). 通过
java -jar -Dkey=val ...
设置的 - OS environment variables.
- A RandomValuePropertySource that only has properties in random.*.
- Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants) yml->yaml->properties (后面会覆盖前面的配置)
- Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
- Application properties outside of your packaged jar (application.properties and YAML variants).
- Application properties packaged inside your jar (application.properties and YAML variants).
@PropertySource
annotations on your@Configuration
classes.- Default properties (specified using SpringApplication.setDefaultProperties).