分布式服务架构[原理、设计与实践]学习笔记

地震是由不可抗力导致的,而事故与之不同,任何大的生产事故在发生之前都有迹可循,而且事故的发生并不是偶然的,我们应该善于从现象中总结规律,找到发现、止损和避免的方法

海恩法则

每一起严重事故的背后,必然有29次轻微事故和300起未遂先兆及1000起事故隐患。

  • 事故的发生是量的积累的结果。
  • 再好的技术、再完美的规章,在实际操作层面也无法取代人自身的素质和责任心。

       根据海恩法则,一起重大事故发生后,我们在处理事故和解决问题的同时,还要及时对同类问题的"事故征兆"和"事故苗头"进行排查处理,以防止类似问题重复发生,把问题解决在萌芽状态,这完全可以作为互联网企业线上应急的指导思想。在线上应急的过程中,不但要定位和解决问题,还要发现问题的根源,并找到发生事故之前的各种征兆,对征兆进行排查和分析,并做响应的报警处理。

墨菲定律

       如果有两种或两种以上方式去做某件事情,而选择其中一种方式将导致灾难,则必定有人会做出这种选择。

  • 任何事情都没有表面看起来那么简单。
  • 所有事情的发展都会比你预计的时间长。
  • 会出错的事情总会出错。
  • 如果你担心某种情况发生,那么它更有可能发生。

       墨菲定律实际上是个心理学效应,如果你担心某种情况会发生,那么它更有可能发生,久而久之就一定会发生。这警示我们,在互联网公司里,对环境发生的任何怪异现象和问题都不要轻易忽视,对于其背后的原因一定要彻查。 同样,海恩法则也强调任何严重事故的背后都是多次小问题的积累,积累到一定的量级后会导致质变,严重的问题就会浮出水面。

       对于任何现象都要秉承着"为什么发生?发生了怎么应对?怎么恢复?怎么避免?"的原则,对问题要彻查,不能因为问题的现象不明显而忽略

6.2. 线上应急的目标、原则和方法

6.2.1. 应急目标

       在生产环境发生故障时快速恢复服务,避免或减少故障造成的损失,避免或减少故障对客户的影响,

6.2.2 应急原则

  • 恢复系统,快速止损,而不是彻底解决问题。
  • 有明显的资金损失时,升级问题快速止损。
  • 不影响用户体验的前提下,保留部分现场和数据。

6.2.3 线上应急的额方法和流程

有条不紊地进行,遇事胆大心细,该做决策的时候要毫不犹豫,该升级的时候要果断。

线上应急一般分为6个阶段:发现问题、定位问题、解决问题、消除影响、回顾问题、避免措施。

在应急过程中要记住,应急只有一个总体目标:尽快恢复问题,消除影响

定位问题
  • 问题系统最近是否进行了上线?
  • 依赖的基础平台和资源是否进行了上线或者升级?
  • 依赖的系统最近是否进行了上线?
  • 运营是否在系统里面做过运营变更?
  • 网络是否有波动?
  • 最近的业务量是否增加?
  • 服务的使用方是否有促销活动?
回顾问题
  • 类似的问题还有哪些没有想到?
  • 做了哪些事情,这个事故就不会发生?
  • 做了哪些事情,这个事故即使发生了,也不会产生损失?
  • 做了哪些事情,这个事故即使发生了,也不会造成这么大的损失?

6.3 技术攻关的方法论

       技术攻关的目标是解决问题,因此首先要从问题发生的环境和背景入手,首先考虑下面几个问题。

  • 最近是否有变更、升级和上线?(回滚)
  • 之前是否遇到过类似的情况?(使用历史经验)
  • 是否有相关领域的专家?例如:安全、性能、数据库、大数据和业务等领域的专家(开启专家模式)【最小化复现→找到原因→提出解决方案→验证解决方案→线上实施】。

       对于任何问题,我们必须收集发生这些问题的现象,考虑如下问题。

  • When:什么时候出的问题?
  • What:什么出了问题?
  • Who:谁在什么时间里发现了问题?问题影响了谁?
  • Where:哪里出现了问题?哪里又没出现问题?
  • Why:为什么出现了问题?

6.5高效的服务化治理脚本

6.5.1 show-busiest-java-threads

       此命令是用来查找java进程内CPU利用率最高的线程,一般适用于服务器负载较高的场景,并需要快速定位负载过高的成因。

命令格式:

./show-busiest-java-threads -p 进程号 -c 显示条数
./show-busiest-java-threads -h

核心命令

ps -Leo pid,lwp,user,comm,pcpu --no-headers | awk '$4=="java"{print $0}' |  sort -k5 -r -n | head --lines 10

脚本源码:

#!/bin/bash

PROG=`basename $0`
usage(){
	cat <<EOF
Usage: ${PROG} [OPTION]...
Example: ${PROG} -c 10
Options:
	-p, --pid   java process
	-c, --count thread count to show,default is 5
	-h, --help display this help and exit
EOF
    exit $1
}

# getopt:用于解析命令行参数。
# -n选项用于指定程序名称,这里使用变量$PROG的值作为程序名称
# -a选项告诉getopt允许使用短选项后面跟一个冒号的方式,即使长选项后面也跟了冒号
# -o选项用于指定短选项及其参数格式。这里的选项有:
#	c: 接受一个参数。
#	p: 接受一个参数。
#	h: 不接受参数(帮助选项)
# -l count:,pid:,help:
# -l选项用于指定长选项及其参数格式。这里的选项有:
#	`count:` 接受一个参数。
#	`pid:` 接受一个参数。
#	`help` 不接受参数(帮助选项)
# `--`:双连字符--表示之后的所有参数都应该被视为命令行参数,而不是getopt选项
# `$@`:引用所有传入脚本的命令行参数。

ARGS=`getopt -n "$PROG" -a -o c:p:h -l count:,pid:,help -- "$@"`

# 需要检查getopt的返回值,以确保命令行参数是有效的。如果getopt遇到无效的选项,它会返回非零值。
# [ ... ] 是一个测试命令(test command),用于进行条件判断
# $? 是一个特殊的shell变量,用来存储上一个命令的退出状态码
# -ne 是一个测试操作符,用于比较两个整数是否不相等(not equal)。
# 0 表示成功退出的状态码
# && 是一个逻辑运算符,在这里表示“如果前面的条件成立,则执行后面的命令
# 如果上一个命令的退出状态码不是0(即命令执行失败),则调用usage函数并传递参数1。
[ $? -ne 0 ] && usage 1
# 重新设置脚本的参数列表
# eval命令用于执行一个字符串中的命令序列
# set -- "${ARGS}"是set命令的一个变体,用于设置脚本的参数列表。--之后的部分会被解释为新的命令行参数。
# set -- "${ARGS}"实际上会将ARGS变量中的内容设置为脚本的参数列表。
# eval在这里的作用是执行set -- "${ARGS}"这一命令
eval set -- "${ARGS}"

while true; do
    case "$1" in
	-c|--count)
	   count="$2"
	   shift 2
	   ;;
	-p|--pid)
	   pid="$2"
	   shift 2
	   ;;
	-h|--help)
	    usage
		;;
	--)
        shift
		break
		;;
	# esac 是 case 语句的结束标记	
	esac
done
count=${count:-5}

redEcho(){
	# [ -c /dev/stdout ] 是一个测试表达式,用来检查 /dev/stdout 是否是一个字符设备文件
    [ -c /dev/stdout ] && {
	    # if sdout is console, turn on color output.
		echo -ne "\033[1;31m"
		echo -n "$@"
		echo -e "\033[0m"
	} || echo "$@"
}	

# Check the existence of jstack command
# if ! which jstack &> /dev/null; then: 这一行检查jstack命令是否可用。如果不可用,则条件为真
if ! which jstack &> /dev/null; then
	# -n选项测试一个字符串是否非空
	# -f选项测试一个文件是否存在
	# -x选项测试一个文件是否可执行
	# 将$JAVA_HOME/bin添加到PATH环境变量的开始位置。这样可以确保jstack工具在系统路径中可用
	# || { ... }如果前面的任何一个条件不满足,则执行大括号内的命令
    [ -n "$JAVA_HOME" ] && [ -f "$JAVA_HOME/bin/jstack" ] && [ -x "$JAVA_HOME/bin/jstack" ] && {
	    export PATH = "$JAVA_HOME/bin:$PATH"
	} || {
	    redEcho "Error: jstack not found on PATH and JAVA_HOME!"
		exit 1
	} 
fi

# $$: 当前进程的进程ID
uuid=`date +%s`_${RANDOM}_$$

cleanupWhenExit() {
  rm /tmp/${uuid}_* & > /dev/null
}
trap "cleanupWhenExit" EXIT

printStackOfThread(){
    while read threadLine ; do
	    pid=`echo ${threadLine} | awk '{print $1}'`
		threadId=`echo ${threadLine} | awk '{print $2}'`
		threadId0x=`printf %x ${threadId}`
		user=`echo ${threadLine} | awk '{print $3}'`
		pcpu=`echo ${threadLine} | awk '{print $5}'`
		echo "pid=${pid},threadId=${threadId},threadId0x=${threadId0x},user=${user},pcpu=${pcpu}"

	    jstackFile=/tmp/${uuid}_${pid}
		
		[ ! -f "${jstackFile}" ] && {
		    jstack ${pid} > ${jstackFile} || {
			    redEcho "Fail to jstack java process ${pid}!"
				rm ${jstackFile}
				continue
			
			}
		}
		
		redEcho "The stack of busy(${pcpu}%) thread (${threadId}/0x${threadId0x}) of java process(${pid}) of user(${user}):"
		sed "/nid=0x${threadId0x}/,/^$/p" -n ${jstackFile}
	done
}
# -z 是否为空,-n 是否不为空
[ -z "${pid}" ] && {
# -Leo: 这些选项组合在一起用于定制输出格式:
#	-L: 显示线程信息。
#	-eo: 指定输出格式

# pid,lwp,user,comm,pcpu: 这些字段名指定了要显示的列:
#	pid: 进程ID。
#	lwp: 线程ID。
#	user: 运行进程的用户。
#	comm: 进程的命令名称。
#	pcpu: 进程使用的CPU百分比。
    ps -Leo pid,lwp,user,comm,pcpu --no-headers | awk '$4=="java"{print $0}' | 
	sort -k5 -r -n | head --lines "${count}" | printStackOfThread
} || {
    ps -Leo pid,lwp,user,comm,pcpu --no-headers | awk -v "pid=${pid}" '$1==pid,$4=="java"{print $0}' |
	sort -k5 -r -n | head --lines "${count}" | printStackOfThread
}

		

6.5.2 查找特定线程

查找进程ID是 12345线程ID为 16344 的线程信息


jstack 12345 | grep -A 20 '16344'

6.5.3 查看特定进程的线程资源使用情况

# -H: 这个选项告诉 top 显示进程中的各个线程的资源使用情况。默认情况下,top 只显示进程级别的信息。
top -H -p <PID>

6.5.4 jmap 命令

这个命令对于诊断内存泄漏(OutOfMemoryError)或内存不足报警时及其他与内存相关的问题非常有用。

# -histo:live: 这个选项告诉 jmap 生成存活对象的直方图。live 参数意味着只统计当前存活的对象,而不是堆中所有对象(包括已不可达的对象)。

# -k3: 指定按照每行的第三个字段进行排序。字段通常由空格或制表符分隔。

# -r: 表示反向排序,即从大到小排序。

# -n: 按照数字值进行排序,而不是默认的字符顺序。

# head 命令是 Unix/Linux 系统中的一个实用工具,它可以用来查看文件的开头部分内容。

# --lines: 指定要显示的行数。
jmap -histo:live <pid>  | sort -k3 -r -n | head --lines 10

      Java堆内存结构很复杂,包括新生代、老年代、持久代、直接内存等,通过jmap命令可以查看堆的概要信息

jmap -heap <pid>
6.5.4.1堆

      在 Java 中,堆(Heap)是 JVM(Java 虚拟机)管理的一个重要内存区域,主要用于存储对象实例和数组。Java 堆的主要作用可以概括为以下几个方面:

  1. 对象存储

    • Java 应用程序中的所有对象实例都在堆上分配内存。
    • 这些对象可以是类的实例或者是数组。
  2. 动态分配内存

    • 当应用程序创建新的对象时,JVM 在堆上为其分配所需的内存。
    • 对象的大小取决于对象的状态(成员变量)。
  3. 垃圾回收

    • Java 堆是 Java 垃圾回收器(Garbage Collector, GC)主要的工作区域。
    • 不再被引用的对象会被垃圾回收器自动回收,释放其占用的内存空间。
    • 垃圾回收过程包括检测不再使用的对象,并释放这些对象所占用的内存。
  4. 分代收集

    • Java 堆通常被划分为不同的区域,最常见的是新生代(Young Generation)和老年代(Old Generation)。
      • 新生代:用于存放新创建的对象,通常对象生命周期较短。
      • 老年代:存放经过多次垃圾回收后仍然存活的对象,通常对象生命周期较长。
    • 不同的代有各自的垃圾回收策略,以优化内存使用效率。
  5. 内存溢出处理

    • 如果程序创建的对象过多,或者存在内存泄漏等问题,可能会导致堆内存不足。
    • 当堆空间不足时,程序会抛出 OutOfMemoryError 异常。
  6. 线程共享

    • Java 堆是所有线程共享的内存区域,这意味着堆上的对象可以被多个线程访问。

      Java 堆的大小可以在启动 JVM 时通过命令行参数进行配置,例如 -Xms-Xmx 分别设置初始堆大小和最大堆大小。

      理解 Java 堆及其工作原理对于有效地管理内存资源、避免内存泄漏以及提高应用性能至关重要。

6.5.4.2 栈

      Java 栈(Stack)是 Java 虚拟机 (JVM) 中的一个重要内存区域,它主要用于存储线程的局部变量和方法调用的信息。每个线程在其生命周期内都有自己的栈空间,这个栈空间由一系列的栈帧组成。以下是 Java 栈的主要作用:

  1. 方法调用

    • 每次调用一个新的方法时,JVM 会在当前线程的栈中创建一个新的栈帧来存储该方法的局部变量、操作数栈、动态链接信息以及返回地址等。
    • 栈帧是方法调用的上下文环境,当方法执行完毕后,相应的栈帧会被弹出栈。
  2. 局部变量存储

    • 栈帧中包含了局部变量表,用于存储方法内的局部变量(包括方法参数和局部声明的变量)。
    • 局部变量的生命周期与方法调用的生命周期相同,当方法结束时,局部变量随之销毁。
  3. 操作数栈

    • 每个栈帧都包含一个操作数栈,用于存储中间计算结果,以及支持方法执行过程中的表达式计算。
    • 操作数栈随着方法的执行而动态变化。
  4. 线程私有

    • Java 栈是线程私有的,这意味着每个线程都有自己的独立栈空间。
    • 这种设计有助于避免线程间的内存竞争,提高并发性能。
  5. 异常处理

    • 栈还用于处理异常。当方法中发生异常时,异常对象会在栈中创建,并通过异常处理机制传递给适当的异常处理器。
  6. 递归调用

    • Java 栈支持递归调用,每次递归调用都会创建一个新的栈帧,直到达到递归终止条件或栈空间耗尽。
  7. 线程调度和同步

    • 栈中的数据结构(如栈帧)可用于支持线程调度和同步操作。
  8. 栈溢出错误

    • 如果一个方法调用层次过深或递归次数太多,可能会导致栈空间耗尽,从而引发 StackOverflowError
    • 类似的,如果线程栈大小设置得太小,也可能会导致栈溢出。

      Java 栈的大小可以通过 JVM 启动参数来配置,例如 -Xss 参数可以用来设置每个线程的栈大小。

      理解 Java 栈的工作原理对于编写高效且无内存泄漏的 Java 代码非常重要。例如,合理使用递归和理解方法调用的内存管理机制有助于避免常见的性能问题。

6.5.4.3 对于jmap更深层次的使用

      有些Java内存问题不是显而易见的,从类、动态链接库、堆的概要信息的角度无法定位具体产生的原因,我们需要对Java堆内部结构进行剖析才能进一步分析产生问题的根本原因,这通常通过jmap命令导出Java堆的快照,然后通过其他工具甚至可视化内存分析工具(JVisualVM、JConsole、Jprofiler、JMAT、JHAT)等进行详细分析。

jmap -dump:format=b,file=./heap.hprof <pid>

6.5.5 jstat

      jstah利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令监控,包括对堆大小和垃圾回收状况的监控等。与jmap相比,jstat更倾向于输出积累的信息与打印GC等的统计信息等;

jstat -gcutil <pid> <间隔时间> <输出的统计信息条数>

jstat -gcutil <pid> 5000 10 这个命令是用来监控 Java 进程 (<pid>) 的垃圾回收 (GC) 活动的。这里对命令中的各个部分进行解释:

  • jstat: 是一个用于监视 JVM 运行时状态的命令行工具。
  • -gcutil: 是 jstat 的一个选项,用于显示 GC 的利用率统计数据。
  • <pid>: 需要被替换为实际的 Java 进程 ID。
  • 5000: 表示每隔 5000 毫秒(即 5 秒)输出一次统计数据。
  • 10: 表示总共输出 10 次统计信息。

当你运行这个命令后,你会看到类似于以下的输出格式:

S0    S1    E     O     M     CCS    YGC    YGCT   FGC    FGCT   GCT

其中每个列代表不同的含义:

  • S0/S1: Survivor Space 0 和 Survivor Space 1 的利用率。
  • E: Eden Space 的利用率。
  • O: Old Gen 的利用率。
  • M: MetaSpace 的利用率(在 Java 9 及以上版本中可用;在 Java 8 及以下版本中可能是 PermGen)。
  • CCS: 如果启用了 Concurrent Mark Sweep (CMS) 垃圾收集器,则显示其利用率。其他类型的垃圾收集器可能显示不同的标记或不显示此列。
  • YGC: 自 JVM 启动以来 Young Generation 的垃圾收集次数。
  • YGCT: Young Generation 的垃圾收集总耗时(以秒为单位)。
  • FGC: Full Garbage Collection(老年代)的次数。
  • FGCT: Full Garbage Collection 的总耗时(以秒为单位)。
  • GCT: 所有垃圾收集的总耗时(以秒为单位)。

如果你想要执行这个命令,请确保你的系统上安装了 JDK,并且环境变量已经正确配置,以便你可以从命令行调用 jstat。此外,请确保 <pid> 替换为你想要监控的 Java 进程的实际 PID。

6.5.6 jstack

jstack 是一个非常有用的命令行工具,它允许你获取 Java 进程的线程堆栈跟踪信息。这对于诊断线程死锁、挂起等问题非常有用。下面是一些 jstack 命令的使用方法和一些常见选项:

基本语法

jstack [options] <pid>

选项说明

  • -l: 输出详细的堆栈跟踪信息,包括本地变量和锁信息。
  • -F: 当无法连接到进程时,尝试生成一个堆栈转储文件。
  • -m: 显示 native 方法的堆栈信息(如果可用的话)。
  • -h--help: 显示帮助信息。
  • -V: 显示版本信息。

使用示例

1. 获取指定进程 ID 的线程堆栈
jstack <pid>

这将输出所有活动线程的堆栈跟踪信息。

2. 获取详细信息
jstack -l <pid>

这将输出更详细的堆栈跟踪信息,包括局部变量和锁信息。

3. 尝试生成堆栈转储文件

当无法通过标准方式连接到进程时,可以使用 -F 选项尝试生成一个堆栈转储文件:

jstack -F <pid>

如果成功,会生成一个名为 hs_err_pid<pid>.log 的文件。

4. 包含 native 方法的堆栈信息
jstack -m <pid>

这会包含 native 方法的堆栈信息,如果它们可用的话。

5. 查找死锁

jstack 可以自动检测并报告线程死锁情况:

jstack -l <pid> | grep "Deadlock"

如果存在死锁,jstack 会在输出中明确指出。

6. 查看特定线程的堆栈

如果你知道某个线程 ID,可以只查看该线程的堆栈信息:

jstack -l <pid> | grep "ThreadID=<thread_id>"
7. 查看帮助信息
jstack -h

或者

jstack --help

注意事项

  • 确保你的系统路径中包含了 jstack 的可执行文件路径。
  • <pid> 应该替换为你想要分析的 Java 进程的实际进程 ID。
  • 如果你在没有管理员权限的情况下运行 jstack,可能需要使用 sudo 命令来提升权限。
  • 如果你需要分析远程机器上的 Java 进程,可以使用 jstack -remote 选项,但需要确保远程机器上开启了 JMX 并正确配置了相关参数。

这些是 jstack 的基本用法和一些常见的应用场景。希望这些信息对你有所帮助!如果有具体的问题或者需要进一步的帮助,请随时告诉我。

6.6.6 jinfo

jinfo 可以输出并修改运行时的Java进程的环境变量和虚拟机参数。

jinfo <pid>

6.6.8 小结

场景命令
内存不足、OutOfMemoryErrorjmap
内存不足、OutOfMemoryError、GC频繁、服务超时、出现长尾响应现象jstat
服务超时、线程卡死、线程死锁、服务器负载高jstack
查看或修改Java进程的环境变量和Java虚拟机变量jinfo
查找Java进程IDjps
内存分析工具,功能丰富,JDK自带JVisualVM

6.7 重要的Linux基础命令

6.7.1 必不可少的基础命令和工具

1.gerp

      grep是Linux下通用的文本内容查找命令,可以利用它打印匹配的上下几行。在线上查找问题时可以使用下列命令查找关键字,显示关键字所在行的前后多行,并给关键字着色。

使用方式

jstack -l <pid> | grep -i "waiting" # 打印当前监控进程<pid>包含waiting的行
grep -5 'pattern' FILE # 打印匹配行的前后5行
grep -C 5 'pattern' FILE # 打印匹配行的前后5行
grep -A 5 'pattern' FILE # 打印匹配行的后5行
grep -B 5 'pattern' FILE # 打印匹配行的前5行
grep -A -15 --color 1010061938 * # 查找后着色
2.find

      通过文件名查找文件所在的位置,文件名查找支持模糊匹配

find. -name FILE

find 命令是在 Linux 和类 Unix 系统中非常强大的工具,用于在文件系统中搜索文件和目录。它可以基于多种条件来查找文件,例如文件名、类型、大小、权限属性、时间戳等。下面是一些基本的用法和选项:

基本语法

find [path] [expression]
  • [path]: 起始目录。
  • [expression]: 查找条件,可以包含多个选项,用逻辑运算符连接。

选项和参数

  • -name: 根据文件名匹配。
  • -iname: 忽略大小写的文件名匹配。
  • -type: 根据文件类型匹配(d - 目录, f - 文件, l - 符号链接等)。
  • -perm: 根据文件权限匹配。
  • -size: 根据文件大小匹配。
  • -mtime, -atime, -ctime: 根据文件的修改时间、访问时间和状态改变时间匹配。
  • -newer: 根据文件是否比另一个文件新。
  • -user, -group: 根据文件的所有者或组匹配。
  • -exec: 对找到的文件执行一个命令。
  • -print: 输出找到的文件路径。
  • -print0: 输出找到的文件路径,以空字符分隔。
  • -ok: 与 -exec 类似,但在执行前询问用户确认。

逻辑运算符

  • -a: 逻辑与(AND)。
  • -o: 逻辑或(OR)。
  • !: 逻辑非(NOT)。

示例

  1. 根据文件名搜索:

    find / -name "a.txt"
    
  2. 根据文件权限搜索:

    find / -perm 777
    
  3. 根据文件类型搜索:

    find / -type d
    
  4. 根据文件大小搜索:

    find / -size +1M
    
  5. 根据时间戳搜索:

    find / -mtime -1
    
  6. 组合多个条件:

    find / -type f -name "*.txt" -mtime -7
    
  7. 执行命令:

    find / -name "*.log" -exec gzip {} \;
    
  8. 忽略大小写:

    find / -iname "A.TXT"
    
  9. 查找特定权限文件:

    find / -type f -perm 755
    
  10. 查找大文件:

    find / -size +100M
    
  11. 根据时间查找:

    find / -mtime -10
    
  12. 查找并删除文件:

    find / -name "temp.*" -mtime +30 -delete
    

这些只是 find 命令的基本用法,实际上还有很多其他的选项和参数可以根据具体的需要来使用。如果您有具体的场景或问题,可以提供更多的细节以便我能给出更具体的建议。

3.update

      查看机器的启动时间、登录时间、平均负载等情况,通常用于线上应急或技术攻关中确定操作系统的重启时间。

      uptime 命令在 Linux 和类 Unix 系统中用于显示系统已经运行了多长时间以及一些其他相关信息。这个命令对于了解系统的运行状态非常有用,特别是对于管理员来说。

基本语法

uptime

输出示例

假设您运行 uptime 命令,输出可能类似于以下内容:

11:59:43 up 1 day,  2:11,  2 users,  load average: 0.67, 0.71, 0.75

输出解释

  • 时间: 当前时间,这里是 11:59:43
  • up: 表示系统已经运行的时间,这里是 1 day, 2:11(即一天零两小时十一分钟)。
  • users: 当前登录系统的用户数量,这里是 2 users
  • load average: 系统的负载平均值,分别对应过去一分钟、五分钟和十五分钟内的平均值,这里是 0.67, 0.71, 0.75

更多信息

  • Load average: 负载平均值是一个衡量系统活跃进程数的指标,它表示在过去一段时间内平均有多少个进程正在等待处理或正在被处理。一般来说,负载平均值接近于处理器的数量时,系统处于良好的运行状态;如果负载平均值远大于处理器数量,则系统可能过载。(每个CPU内核对应的活动进程数不大于3时,系统运行良好,也就是说活动进程数小于CPU核心数的3倍。)

查看CPU核心数

lscpu

其他相关命令

  • w: 这个命令提供了与 uptime 类似的输出,但还包含了当前登录用户的列表以及他们所在的终端信息。
  • last: 显示用户登录的历史记录。

示例用法

如果您想查看系统的运行时间和其他相关信息,只需在终端中输入 uptime 命令即可:

uptime

如果需要查看更详细的系统运行时间信息,可以使用 tophtop 命令,它们提供了实时的系统监控信息,包括CPU使用率、内存使用情况以及进程列表等。

希望这些信息对您有所帮助!如果有任何其他问题或需要进一步的帮助,请随时告诉我。

文件句柄
      文件句柄是在计算机程序中用于标识已打开文件的一种抽象标识符。当一个程序打开一个文件时,操作系统会给这个文件分配一个唯一的句柄,程序可以通过这个句柄来读取、写入、关闭等操作该文件。

4. lsof

查看某个进程打开的问价句柄

lsof -p <进程号>

查看端口的使用方式

lsof -i:<端口号>
5.ulimit

      用于限制 shell 启动的进程所能使用的资源。这些限制可以应用于各种资源,包括文件大小、打开的文件数、最大内存使用量等。ulimit 命令不仅可以查看当前的资源限制,还可以设置新的限制。

当前各种系统对永固使用资源的限制:

ulimit -a

设置用户的最大进程数:

ulimit -u 1024

设置用户可以打开的最大文件句柄数:

ulimit -n 65530
6.curl
curl -i "http://"

# 发送简单的 POST 请求,d 参数后面跟着要发送的数据
curl -X POST -d  'name=whaleson' http://localhost:8080/ok 

# 发送 JSON 数据
curl -X POST -H 'Content-Type: application/json' -d '{"Head":{},"Body":{"name":"w","age":19}}' http://localhost:8080/ok 

# 添加认证信息
curl -X POST -u username:password -d "name=w,age=14" http://localhost:8080/ok 
7.scp

      文件传输命令;
1. 从远程主机复制文件到本地

# user@remotehost 是远程主机的用户名和主机名,/path/to/file 是远程主机上的文件路径,/local/path/ 是本地的目标路径。
scp user@remotehost:/path/to/file /local/path/
8. vi 和vim
  • set number:显示行号
  • shift + g:移动到最后1行
  • 1 + shift + g:移动到第1行
  • n + shift + g:移动到第n行
  • 0:移动到行首
  • $:移动到行尾
  • /text:查找text,按n查找下一个,按N查找前一个;
  • ?text:向上查找text;
  • %s/old/new/g:将old替换成new,替换当前行的所有匹配。
  • u:撤销。
  • U:撤销对整个行的操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值