菜单

Administrator
发布于 2025-03-20 / 4 阅读
0
0

针对云站务应急预案

目的:

此文档的目的是指导研发同事在线上系统发生紧急问题的时候,如何快速,有条理的排查和解决问题。

总则:

1、首先明确处理问题的原则,快速恢复服务的可用性,将影响降低到最低。

2、问题升级策略,自己无法决策的问题立刻升级到部门经理,最高可直接升级到CTO。

1. 查询应用服务器

① 查询内存

free -m 剩余内存 = free +cached 200M以下 则需要升级配置或找到占用内存的进程进行处理

top 再按大写的M按内存占用排序

ps -p pid -o rss,vsz RSS VSZ 7152568 17485844

​ VSZ是虚拟内存,RSS是实际使用的内存,单位KB

jstat -gc -h10 pid 3000

​ 看oc 和ou

​ 看错误日志有没有OOM

​ OOM,全称“Out Of Memory”,来源于java.lang.OutOfMemoryError

​ java.lang.OutOfMemoryError: Java heap space

​ java.lang.OutOfMemoryError: PermGen space

​ 抓取内存dump并分析

​ jmap -dump:format=b,file=文件名 [pid]

​ MemoryAnalyzer.exe打开保存的内存dump,查看leak suspects,分析是哪个线程占用的内存

② 查询磁盘

Linux:

​ 查询磁盘空间是否满了 df -h

​ 找到占用空间的目录 du -sh du -sh *

​ 查询未释放已删除文件 //TODO

windows

​ SpaceSniffer

③ 查询CPU

1.使用 top -p 命令查看占用cpu的进程:

2.使用 top -Hp pid 命令查看该Java进程内所有线程的资源占用情况

​ windows用ProcessExplorer,无需安装,下载后双击即可运行,查看想要观察的进程,选择属性可看到线程占用CPU情况

​ windows下也可以用pslist -d pid(下载psexec工具)

​ 使用 printf "%x\n" tid 命令(tid指线程的id号)将以上10进制的线程号转换为16进制:

jstack pid | grep 0x86a -A20 打印进程的堆栈

常见线程

1、jobs-thread-n play项目中的JOB执行线程

2、play-thread-n play项目中的http请求处理线程

3、pool-n-thread-n java自定义线程池内的线程默认名称

4、C2 CompilerThread0 这个线程是JVM在server模式下字节码编译器,JVM启动的时候所有代码都处于解释执行模式,当某些代码被执行到一定阈值次数,这些代码(称为热点代码)就会被 C2 Compiler编译成机器码,编译成机器码后执行效率会得到大幅提升。

流量进来后,大部分代码成为热点代码,这个过程中C2 Compiler需要频繁占用CPU来运行,当大部分热点代码被编译成机器代码后,C2 Compiler就不再长期占用CPU了,这个过程也可以看作抖动。

5、GC task thread#n GC线程

④ 服务响应慢

ps -ef |grep NvBus 查进程

jps -v |grep NvBus 查JAVA进程

jstack -l pid >./jstacklog.txt 命令来获取线程快照结果并输入到指定文件。

windows服务启动的java进程,直接用jstack会报错没有system权限,可下载psexec工具 ,用psexec -s jstack运行即可

如果是VM线程上用CPU,则要分析是不是GC活动太频繁导致 jstat -gc -h10 pid 3000

jmap -dump:format=b,file=base3sync pid 配合MemoryAnalyzer.exe工具分析

jvm.memory=-XX:MaxDirectMemorySize=1024M -Xmx1024M -Xms128M -XX:PermSize=64M -XX:MaxPermSize=128M -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8686 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=127.0.0.1 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/

play status

看controls平均执行时长、最大执行时长、执行次数

看play线程池Queue siz、Waiting for execution

看数据库连接busy connection num

数据库超时BUG

db.busytimeout=120 单位秒,超时120秒后杀掉长连接正式环境不允许配置

搜索日志:A checked-out resource is overdue

db.pool.timeout=10000 单位毫秒,10秒后获取数据库连接失败

db.pool.maxSize=30 最大连接数

查看端口监听:lsof -i:9000

查看网络连接: netstat -anp |grep 3306 netstat -ano|findstr 9000

群文件网络诊断工具

畅达各平台日志查询

2.查询数据库sql

① 首先查询是否有表锁

SELECT object_name, machine, s.sid, s.serial#
  FROM gv$locked_object l, dba_objects o, gv$session s
 WHERE l.object_id  = o.object_id
   AND l.session_id = s.sid;
   
   
-- 释放SESSION SQL: 
Alter system kill session 'sid, serial#'; 
-- 使用第一步执行出来的sid和serial
ALTER system kill session '23, 1647'; 

-- 锁特别多的情况下使用z

SELECT 'Alter system kill session ''' || s.sid || ',' || s.serial# || ''';'
  FROM gv$locked_object l, dba_objects o, gv$session s
 WHERE l.object_id  = o.object_id
   AND l.session_id = s.sid;

② 查询正在执行的任务

select a.program, b.spid, c.sql_text,c.SQL_ID
from v$session a, v$process b, v$sqlarea c
where a.paddr = b.addr
and a.sql_hash_value = c.hash_value
and a.username is not null;

③ 查询Oracle正在执行的sql语句及执行该语句的用户

SELECT c.sql_ID,
       c.SQL_FULLTEXT,
       c.EXECUTIONS "执行次数",
       round(c.ELAPSED_TIME / 1000000, 2) "总执行时间",
       round(c.ELAPSED_TIME / 1000000 / c.EXECUTIONS, 2) "平均执行时间",
       sql_text 正在执行的SQL,
       b.machine 计算机名,
       paddr,
       b.sid oracleID,
       b.username 登录Oracle用户名,
       b.serial#,
       spid 操作系统ID
  FROM v$process a, v$session b, v$sqlarea c
 WHERE a.addr = b.paddr
   AND b.sql_hash_value = c.hash_value
   and round(c.ELAPSED_TIME / 1000000 / c.EXECUTIONS, 2) > 0
   and c.EXECUTIONS > 0
    order by   c.EXECUTIONS desc;

④查看正在执行sql的发起者的发放程序

SELECT OSUSER 电脑登录身份,
       PROGRAM 发起请求的程序,
       USERNAME 登录系统的用户名,
       SCHEMANAME,
       B.Cpu_Time 花费cpu的时间,
       STATUS,
       B.SQL_TEXT 执行的sql
  FROM V$SESSION A
  LEFT JOIN V$SQL B ON A.SQL_ADDRESS = B.ADDRESS
                   AND A.SQL_HASH_VALUE = B.HASH_VALUE
 ORDER BY b.cpu_time DESC

⑤查询执行时间打印3秒的sql

SELECT t.LAST_LOAD_TIME,t.MODULE,trunc(t.ELAPSED_TIME/t.EXECUTIONS/1000000),t.SQL_FULLTEXT,t.EXECUTIONS     
  FROM v$sqlarea t  
 Where t.EXECUTIONS>0 And t.ELAPSED_TIME/t.EXECUTIONS/1000000>3
    and t.MODULE ='JDBC Thin Client'
--  and t.LAST_LOAD_TIME>sysdate-1/24
-- 	and t.LAST_ACTIVE_TIME>sysdate-1/24
  ORDER BY t.ELAPSED_TIME/t.EXECUTIONS DESC;

⑥查询锁等待

select (select username from v$session where sid = a.sid) username,
       a.sid,
       (select serial# from v$session where sid = a.sid) serial#,
       a.type,
       a.id1,
       a.id2,
       a.lmode,
       a.request,
       a.block,
       b.sid blocking_sid
  from v$lock a,
       (select *
          from v$lock
         where request > 0
           and type <> 'MR') b
 where a.id1 = b.id1(+)
   and a.id2 = b.id2(+)
   and a.lmode > 0
   and a.type <> 'MR'
   And b.sid is not null
 order by username, a.sid, serial#, a.type
此时可以查询到锁等待的现象,最后一列不为空的就是等待的事件

-- 查询当前ACTIVE的的v$session
select t.sql_id as a, t.* from v$session  t
where username is not null and status = 'ACTIVE'
order by logon_time, sid;
        
-- 根据sid 查询IP
SELECT sid,serial#,username,port,machine,logon_time FROM v$session WHERE sid=84;

netstat -ano |findstr port

select vs.SQL_TEXT,vsess.sid,vsess.SERIAL#,vsess.MACHINE,vsess.OSUSER
,vsess.TERMINAL,vsess.PROGRAM,vs.CPU_TIME,vs.DISK_READS
from v$sql vs,v$session vsess
where vs.ADDRESS=vsess.SQL_ADDRESS
and vsess.sid=1599


评论