linux cpu使用率过高排查
方法一
创新互联建站-云计算及IDC服务提供商,涵盖公有云、IDC机房租用、成都天府联通服务器托管、等保安全、私有云建设等企业级互联网基础服务,欢迎咨询:18980820575
第一步:使用
top命令,然后按shift+p按照CPU排序
找到占用CPU过高的进程的pid
第二步:使用
top -H -p [进程id]
找到进程中消耗资源最高的线程的id
第三步:使用
echo 'obase=16;[线程id]' | bc或者printf "%x\n" [线程id]
将线程id转换为16进制(字母要小写)
bc是linux的计算器命令
第四步:执行
jstack [进程id] |grep -A 10 [线程id的16进制]”
查看线程状态信息
方法二
第一步:使用
top命令,然后按shift+p按照CPU排序
找到占用CPU过高的进程
第二步:使用
ps -mp pid -o THREAD,tid,time | sort -rn
获取线程信息,并找到占用CPU高的线程
第三步:使用
echo 'obase=16;[线程id]' | bc或者printf "%x\n" [线程id]
将需要的线程ID转换为16进制格式
第四步:使用
jstack pid |grep tid -A 30 [线程id的16进制]
打印线程的堆栈信息
案例分析
场景描述
生产环境下JAVA进程高CPU占用故障排查
解决过程
1、根据top命令,发现PID为2633的Java进程占用CPU高达300%,出现故障。
2、找到该进程后,如何定位具体线程或代码呢,首先显示线程列表,并按照CPU占用高的线程排序:
1
[root@localhost ~]# ps -mp 2633 -o THREAD,tid,time | sort -rn
显示结果如下:
找到了耗时最高的线程(TID)3626,占用CPU时间有12分钟了!
3、将需要的线程TID转换为16进制格式
12
[root@localhost ~]# printf "%x\n" 3626e18
4、最后使用jstack命令打印出该进程下面的此线程的堆栈信息:
1
[root@localhost ~]# jstack 2633 |grep "e18" -A 30
相比故障的解决而言,发现故障也同等的重要!市场上的大多数监控软件都能实现服务器负载的实时观测,比如:Zabbix、Nagios、阿里云监控(针对云服务器)等。但是当中大部分的软件都需要运维同学主动去设置规则或者检测才能发现问题,如何被动的也能收到告警呢?
推荐大家一个实用的运维软件——王教授,对于业务部署在阿里云上的用户,只需绑定需要监控的只读AcessKey,即可将云上资源的告警信息及时通知给对应的团队成员。
化主动为被动的方式,一方面减轻了运维工程师的工作,另一方面也减小了运维漏看或者忽略告警的情况发生。
在Linux下,用shell编写一个简单的计算器,要实现加减乘除4个功能就行了
不用写吧,本来有个 bc 命令可用,没有下载就成.
非要写一个,zsh 的function里有一个,名 zcalc,
贴上来给你
#!/usr/bin/zsh -i
#
# Zsh calculator. Understands most ordinary arithmetic expressions.
# Line editing and history are available. A blank line or `q' quits.
#
# Runs as a script or a function. If used as a function, the history
# is remembered for reuse in a later call (and also currently in the
# shell's own history). There are various problems using this as a
# script, so a function is recommended.
#
# The prompt shows a number for the current line. The corresponding
# result can be referred to with $line-no, e.g.
# 1 32 + 10
# 42
# 2 $1 ** 2
# 1764
# The set of remembered numbers is primed with anything given on the
# command line. For example,
# zcalc '2 * 16'
# 1 32 # printed by function
# 2 $1 + 2 # typed by user
# 34
# 3
# Here, 32 is stored as $1. This works in the obvious way for any
# number of arguments.
#
# If the mathfunc library is available, probably understands most system
# mathematical functions. The left parenthesis must be adjacent to the
# end of the function name, to distinguish from shell parameters
# (translation: to prevent the maintainers from having to write proper
# lookahead parsing). For example,
# 1 sqrt(2)
# 1.4142135623730951
# is right, but `sqrt (2)' will give you an error.
#
# You can do things with parameters like
# 1 pi = 4.0 * atan(1)
# too. These go into global parameters, so be careful. You can declare
# local variables, however:
# 1 local pi
# but note this can't appear on the same line as a calculation. Don't
# use the variables listed in the `local' and `integer' lines below
# (translation: I can't be bothered to provide a sandbox).
#
# Some constants are already available: (case sensitive as always):
# PI pi, i.e. 3.1415926545897931
# E e, i.e. 2.7182818284590455
#
# You can also change the output base.
# 1 [#16]
# 1
# Changes the default output to hexadecimal with numbers preceded by `16#'.
# Note the line isn't remembered.
# 2 [##16]
# 2
# Change the default output base to hexadecimal with no prefix.
# 3 [#]
# Reset the default output base.
#
# This is based on the builtin feature that you can change the output base
# of a given expression. For example,
# 1 [##16] 32 + 20 / 2
# 2A
# 2
# prints the result of the calculation in hexadecimal.
#
# You can't change the default input base, but the shell allows any small
# integer as a base:
# 1 2#1111
# 15
# 2 [##13] 13#6 * 13#9
# 42
# and the standard C-like notation with a leading 0x for hexadecimal is
# also understood. However, leading 0 for octal is not understood --- it's
# too confusing in a calculator. Use 8#777 etc.
#
# Options: -#base is the same as a line containing just `[#base],
# similarly -##base; they set the default output base, with and without
# a base discriminator in front, respectively.
#
#
# To do:
# - separate zcalc history from shell history using arrays --- or allow
# zsh to switch internally to and from array-based history.
emulate -L zsh
setopt extendedglob
local line ans base defbase forms match mbegin mend psvar optlist opt arg
local compcontext="-math-"
integer num outdigits outform=1
# We use our own history file with an automatic pop on exit.
history -ap "${ZDOTDIR:-$HOME}/.zcalc_history"
forms=( '%2$g' '%.*g' '%.*f' '%.*E' )
zmodload -i zsh/mathfunc 2/dev/null
: ${ZCALCPROMPT="%1v "}
# Supply some constants.
float PI E
(( PI = 4 * atan(1), E = exp(1) ))
# Process command line
while [[ -n $1 $1 = -(|[#-]*) ]]; do
optlist=${1[2,-1]}
shift
[[ $optlist = (|-) ]] break
while [[ -n $optlist ]]; do
opt=${optlist[1]}
optlist=${optlist[2,-1]}
case $opt in
('#') # Default base
if [[ -n $optlist ]]; then
arg=$optlist
optlist=
elif [[ -n $1 ]]; then
arg=$1
shift
else
print "-# requires an argument" 2
return 1
fi
if [[ $arg != (|\#)[[:digit:]]## ]]; then
print - "-# requires a decimal number as an argument" 2
return 1
fi
defbase="[#${arg}]"
;;
esac
done
done
for (( num = 1; num = $#; num++ )); do
# Make sure all arguments have been evaluated.
# The `$' before the second argv forces string rather than numeric
# substitution.
(( argv[$num] = $argv[$num] ))
print "$num $argv[$num]"
done
psvar[1]=$num
while vared -cehp "${(%)ZCALCPROMPT}" line; do
[[ -z $line ]] break
# special cases
# Set default base if `[#16]' or `[##16]' etc. on its own.
# Unset it if `[#]' or `[##]'.
if [[ $line = (#b)[[:blank:]]#('[#'(\#|)(-|)']')[[:blank:]]#(*) ]]; then
if [[ -z $match[4] ]]; then
if [[ -z $match[3] ]]; then
defbase=
else
defbase=$match[1]
fi
print -s -- $line
line=
continue
else
base=$match[1]
fi
else
base=$defbase
fi
print -s -- $line
case ${${line##[[:blank:]]#}%%[[:blank:]]#} in
q) # Exit if `q' on its own.
return 0
;;
norm) # restore output format to default
outform=1
;;
sci[[:blank:]]#(#b)(-)(#B))
outdigits=$match[1]
outform=2
;;
fix[[:blank:]]#(#b)(-)(#B))
outdigits=$match[1]
outform=3
;;
eng[[:blank:]]#(#b)(-)(#B))
outdigits=$match[1]
outform=4
;;
local([[:blank:]]##*|))
eval $line
line=
continue
;;
*)
# Latest value is stored as a string, because it might be floating
# point or integer --- we don't know till after the evaluation, and
# arrays always store scalars anyway.
#
# Since it's a string, we'd better make sure we know which
# base it's in, so don't change that until we actually print it.
eval "ans=\$(( $line ))"
# on error $ans is not set; let user re-edit line
[[ -n $ans ]] || continue
argv[num++]=$ans
psvar[1]=$num
;;
esac
if [[ -n $base ]]; then
print -- $(( $base $ans ))
elif [[ $ans = *.* ]] || (( outdigits )); then
printf "$forms[outform]\n" $outdigits $ans
else
printf "%d\n" $ans
fi
line=
done
return 0
支援小数点,+ - * / , ok
linux有哪些基本命令 5个基本linux命令
1、显示日期的指令: date
2、显示日历的指令:cal
3、简单好用的计算器:bc
怎么10/100会变成0呢?这是因为bc预设仅输出整数,如果要输出小数点下位数,那么就必须要执行 scale=number ,那个number就是小数点位数,例如:
4、重要的几个热键[Tab],[ctrl]-c, [ctrl]-d
[Tab]按键---具有『命令补全』不『档案补齐』的功能
[Ctrl]-c按键---让当前的程序『停掉』
[Ctrl]-d按键---通常代表着:『键盘输入结束(End Of File, EOF 戒 End OfInput)』的意思;另外,他也可以用来取代exit
5、man
退出用q,
man -f man
6、数据同步写入磁盘: sync
输入sync,那举在内存中尚未被更新的数据,就会被写入硬盘中;所以,这个挃令在系统关机戒重新启劢乀前, 径重要喔!最好多执行几次!
7、惯用的关机指令:shutdown
此外,需要注意的是,时间参数请务必加入指令中,否则shutdown会自动跳到 run-level 1 (就是单人维护的登入情况),这样就伤脑筋了!底下提供几个时间参数的例子吧:
重启,关机: reboot, halt,poweroff
8、切换执行等级: init
Linux共有七种执行等级:
--run level 0 :关机
--run level 3 :纯文本模式
--run level 5 :含有图形接口模式
--run level 6 :重新启动
使用init这个指令来切换各模式:
如果你想要关机的话,除了上述的shutdown -h now以及poweroff之外,你也可以使用如下的指令来关机:
9、改变文件的所属群组:chgrp
10、改变文件拥有者:chown
他还可以顸便直接修改群组的名称
11、改变文件的权限:chmod
权限的设定方法有两种, 分别可以使用数字或者是符号来进行权限的变更。
--数字类型改变档案权限:
--符号类型改变档案权限:
12、查看版本信息等
13、变换目录:cd
14、显示当前所在目录:pwd
15、建立新目录:mkdir
不建议常用-p这个选项,因为担心如果你打错字,那么目录名称就回变得乱七八糟的
16、删除『空』的目录:rmdir
17、档案与目录的显示:ls
18、复制档案或目录:cp
19、移除档案或目录:rm
20、移动档案与目录,或更名:mv
21、取得路径的文件名与目录名:basename,dirname
22、由第一行开始显示档案内容:cat
23、从最后一行开始显示:tac(可以看出 tac 是 cat 的倒着写)
24、显示的时候,顺道输出行号:nl
25、一页一页的显示档案内容:more
26、与 more 类似,但是比 more 更好的是,他可以往前翻页:less
27、只看头几行:head
28、只看尾几行:tail
29、以二进制的放置读取档案内容:od
30、修改档案时间或新建档案:touch
31、档案预设权限:umask
32、配置文件档案隐藏属性:chattr
33、显示档案隐藏属性:lsattr
34、观察文件类型:file
35、寻找【执行挡】:which
36、寻找特定档案:whereis
37、寻找特定档案:locate
38、寻找特定档案:find
39、压缩文件和读取压缩文件:gzip,zcat
40、压缩文件和读取压缩文件:bzip2,bzcat
41、压缩文件和读取压缩文件:tar
ps:IP.GZIP.TAR有啥区别?那个压缩的程度大?
tar是打包,不是压缩,只是把一堆文件打成一个文件而已GZIP用在HTTP协议上是一种用来改进WEB应用程序性能的技术,将网页内容压缩后再传输。
zip就不用说了,主流的压缩格式。
zip最新的压缩算法还是很好的,建议还是用zip格式化,全平台通用。
tar没有怎样压缩,压缩率100%,主要是永远打包,
zip压缩率看文件类型,jpg就没怎么压缩率,但bmp很高
gzip一般比zip高
复制代码
zip
zip -r myfile.zip ./*
将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件.
unzip
unzip -o -d /home/sunny myfile.zip
把myfile.zip文件解压到 /home/sunny/
-o:不提示的情况下覆盖文件;
-d:-d /home/sunny 指明将文件解压缩到/home/sunny目录下
zip 命令:
# zip test.zip test.txt
它会将 test.txt 文件压缩为 test.zip ,当然也可以指定压缩包的目录,例如 /root/test.zip
# unzip test.zip
它会默认将文件解压到当前目录,如果要解压到指定目录,可以加上 -d 选项
# unzip test.zip -d /root/
linux借用外部命令expr,实现计算器功能,利用管道,进程
test指令(使用指令man查询)
功能:检查文件类型,值比较。
test的各种参数和使用。
test EXPRESSION1 –a EXPRESSION2
当表达式1和表达式2同时为真时值为真
test EXPRESSION1 –o EXPRESSION2
当表达式1或者表达式2为真时值为真
test –n STRING
或者
test STRING
当STRING串的长度不为零时值为真
test –z STRING
当STRING串长度为零时值为真
test STRING1 = STRING2
当STRING1和STRING2相同时值为真
test STRING1 != STRING2
当STRING1 和 STRING2不同时值为真
test INTEGER1 –eq INTEGER2
当INTEGER1等于INTEGER2时值为真
test INTEGER1 –ge INTEGER2
当INTEGER1大于或者等于INTEGER2时值为真
test INTEGER1 –gt INTEGER2
当INTEGER1 大于INTEGER2时值为真
test INTEGER1 –le INTEGER2
当INTEGER1小于等于INTEGER2时值为真
test INTEGER1 –lt INTEGER2
当INTEGER1 小于INTEGER2时值为真
test INTEGER1 –ne INTEGER2
当INTEGER1不等于INTEGER2时值为真
test FILE1 –ef FILE2
当FILE1和FILE2有同样的device和inode号时为真(详细见linux文件学习笔记)
test FILE1 –nt FILE2
当FILE1修改时间比FILE2新时值为真
test FILE1 –ot FILE2
当FILE1修改时间比FILE2旧时值为真
test –b FILE
FILE存在并且内容是block类型的
test –c FILE
FILE存在并且是字符类型的
test –d FILE
FILE存在并且是一个目录
test –e FILE
FILE是否存在
test –f FILE
FILE存在并且是一个正则表达式类型的文档
test –g FILE
FILE存在并且是 set-group-ID也就是SGID(详细见后文学习笔记)
test –G FILE
FILE存在并且由有效的GROUP ID所拥有(详细见后文学习笔记)
test –h FILE
FILE存在并且是一个符号链接(详细见后文学习笔记)
test –k FILE
FILE存在并且设置了sticky bit set(详细见后文学习笔记)
test –L FILE
FILE存在并且是一个符号链接
test –O FILE
FILE存在并且由一个有效的USER ID所拥有
test –p FILE
FILE存在并且是一个命名管道(命名管道见后文学习笔记)
test –r FILE
FILE存在并且授予了可读的权限
test –s FILE
FILE存在并且size大于0
test –S FILE
FILE存在并且是一个socket
test –t FD
文件的描述符FD在终端打开
test –u FILE
FILE存在并且SUID已经被设置
test –w FILE
FILE存在并且授予了写操作权限
test –x FILE
FILE存在并且授予了可执行的权限
----------------------------------------------------------------------------------------------------------------------------------------------------
expr
expr是linux的手工命令行计数器,它可以帮助我们完成一些基本的表达式值运算。同时它也是一个字符串处理工具
(1) 整数运算
$expr ARG1 | ARG2
$expr ARG1 ARG2
$expr ARG1 ARG2
$expr ARG1 = ARG2
$expr ARG1 = ARG2
$expr ARG1 != ARG2
$expr ARG1 = ARG2
$expr ARG1 ARG2
$expr ARG1 + ARG2
$expr ARG1 – ARG2
$expr ARG1 * ARG2
使用乘法时,需要使用反斜杠进行转义
$expr ARG1 % ARG2
(2) 字符串操作
$expr length “xxx” //计算字符串长度
$expr substr “this is a”pos length //从第pos位开始截取length长度的子串
$expr index “tesr”e //获取e在主串中首次出现的位置
(3) 增量计数
例子
loop=3
loop=`expr $loop + 1`
echo $loop
结果是4,在第二行代码中,使用反引号,shell会将反引号中的内容作为一个系统命令,这样一来,就好像我们在命令行内输入了expr $loop + 1然后这个命令的返回结果被赋值到loop。
(4) 模式匹配(按照正则表达式模式匹配串)
通过指定冒号选项计算字符串中字符数。.*意即任何字符重复0次或多次。
VALUE=account.doc
expr $VALUE : ’.*’
8
在expr中可以使用字符串匹配操作,这里使用模式抽取.doc文件附属名。
$expr $VALUE : ‘\(.*\).doc’
accounts
(5) 其他
+ TOKEN
将TOKEN解释为串,不管它是一个关键字或者一个操作符
延伸知识:
引号的作用
1 双引号(“”)
1)使用””可引用除字符$(美元符号)、`(反引号)、\(反斜线)外的任意字符或字符串。双引号不会阻止shell对这三个字符做特殊处理(标示变量名、命令替换、反斜线转义)。
Eg:name=gezn; echo “User name:$name”//将打印User name :gezn
Echo “The date is:`date +date-%d-%m-%Y`”//将打印The date is: 03-05-2009
Echo –e “$USER\t$UID” //将打印gezn 500
2)如果要查新包含空格的字符串经常用到双引号
2 单引号(’’)
1) 如果用单引号把字符串括起来,则dayi9nhao内字符串中的任何特殊字符的特殊含义均被屏蔽。
2) 举例:echo –e ‘$USER\t$UID’//将打印$USER $UID(没有屏蔽\t,是因为选项“-e”的缘故)
echo ‘USER\t$UID’ //将打印$USER\t$UID
3 反引号(``)
1) shell将反引号中的内容作为一个系统命令,并执行其内容。使用这种方法可以替换输出为一个变量
2) 举例:a=`date + date-%d-%m-%Y` //将打印The date is: 03-05-2009
4.反斜线(\)
1)如果下一个字符有特殊含义,反斜线防止shell误解其含义,即屏蔽其特殊含义。
2)下属字符包含有特殊含义: * + $ ` “ | ?
3) 在打印字符串时要加入八进制字符(ASCII相应字符)时,必须在前面加反斜线,否则shell作普通数字处。
举例: bj=Beijing; echo ”variable\$bj=$bj”//将打印variable $bj = beijing
------------------------------------------------------------------------------------------------------------------------------------------------
Shell特殊变量
在Shell中,预先定义了几个有特殊含义的Shell变量,它们的值只能由Shell根据实际情况进行赋值,而不能通过用户重新设置。shell的特殊变量包括它的位置和一些系统变量.
(一)常用位置变量:
$# 命令行上实际参数的个数,但不包含Shell脚本名。
$? 上一条命令执行后的返回值(也称作 “退出码”)。它是一个十进制数。多数Shell命令执行成功时,则返回值为0;如果执行失败,则返回非0值。
$$ 当前进程的进程号。
$! 上一个后台命令对应的进程号,这是一个由1~5位数字构成的数字串。
$- 由当前Shell设置的执行标志名组成的字符串。例如:
set -xv 这个命令行给Shell设置了标志-x和-v(用于跟踪输出)。
$* 表示在命令行中实际给出的所有实参字符串,它并不仅限于9个实参。
$@ 它与$*基本功能相同,但是使用时加引号,并在引号中返回每个参数
$0 脚本名称
$1..$9 第N个参数
下面的aaa bbb 为变量名
${aaa:-bbb} 如果$aaa为空或未定义,则取值$bbb.否则取值$aaa
${aaa:+bbb} 如果$aaa非空,则取值$bbb,否则取值为空
${aaa:=bbb} 如果$aaa非空,则取值$aaa,否则取值$bbb而且赋值(aaa=bbb)
${aaa:3} 如果aaa=abcdefg,则${aaa:3}的值为:defg ,相当于substr,计数从0开始
${aaa:3:2} 如上; ${aaa:3:2}取值为: de.相当于substr
${#aaa} 字符串$aaa的长度.
(二)常用系统变量:
$HOME 用户的主目录
$USER 用户名称
$GROUP 用户所属组名
$PATH 默认的搜索路径
$HOSTNAME 主机名称
$TZ 时区
$MAIL 存放邮件的路径名
练手:
#!/bin/bash
echo $0
echo $*
echo $@
echo $#
echo $$
echo $_
在terminal窗口中执行:
./test.sh -a -b –c /home
./test.sh
-a -b -c /home
-a -b -c /home
4
3250
/home
区别$*和$@编写如下test.sh脚本:
#!/bin/bash
function testargs
{
echo "$# args"
}
testargs "$*"
testargs "$@"
unset -f testargs
在terminal窗口中执行:
./test.sh -a -b /home
1 args //很明显就一个嘛,传入的是$*这个串,不是解释后的参数
3 args //$@必须和引号搭配,所以结果正确
#!/bin/bash
function testargs
{
echo "$# args"
}
testargs $*
testargs $@
unset -f testargs
再次执行有:
./test.sh -a -b /home
3 args
3 args
作者:Aga.J
出处:
linux下计算器指令为什么是“bc”
没有,因为windows是视窗操作系统,为了方便用户操作,很少有命令行的常用应用程序。 linux是原生命令行系统,所以绝大多数的工具、程序都有命令行的版本。
网页标题:Linux的计算器命令,linux编写shell程序计算器
URL分享:http://scpingwu.com/article/hdgjjc.html