tongsiying

阅读|运动|自律

0%

performance

java性能工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
性能工具:
async-profiler java火焰图
jprofile
arthas
j s ta c k
jstat
mat

jvm内存快照 神风炼

性能调优:
hpeng526.github

百度:良好的状态指标

top -H -p

jvm内存快照dump文件太大,怎么分析

1、场景

通常,使用eclipse的mat图形化工具打开dump的时候都会内存溢出.

img

对于比较小的dump,eclipse可以打开,但一旦dump文件太大,eclipse就有点束手无策。

这时候怎么办呢?可以使用linux下的mat,既Memory Analyzer Tools

2、dump生成

dump可以是内存溢出时让其自动生成,或者手工直接导。配置jvm参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/biapp/m.hprof

手工直接导,PID为进程号

jmap -dump:live,format=b,file=m.hprof PID

3、准备工作,下载LINUX的MAT

地址:http://www.eclipse.org/mat/downloads.php

在linux服务器执行命令 uname –m查看版本

img

下载对应的版本

img

下载后将包传到linux服务器上解压。

img

MemoryAnalyzer.ini 配置文件可以修改最大的内存,默认1G基本够用了。

4、在linux执行分析命令

执行命令

./ParseHeapDump.sh m.hprof org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components。

m.hprof就是jvm的dump文件,在mat目录下会生成3份.zip结尾的报告和一些m.相关的文件,将生成的m.hprof相关的文件都下载到windows本地磁盘。

如:

img

5、打开分析报告

1)使用浏览器

解压缩以.zip结尾的文件,解压后

img

使用浏览器打开index.html文件内容,查看分析报告

img

查看Class Histogram一项

img

发现其中一个类对象占用了7个G,这里的Heap单位都是Byte,自行换算。

Shallow Heap 既对象本身的大小

Retained Heap 对象自身加起直接或间接引用的大小

2)使用eclipse的mat工具

Eclipse需要按照mat工具,安装步骤可以百度,或者参考

https://jingyan.baidu.com/article/cb5d61053562ed005c2fe022.html

如果直接打开dump文件还是会内存溢出,所以可以使用eclipse打开分析报告即可。

使用eclipse-File-Open File打开dump文件,如下:

img

会提示错误,点击OK忽略错误,然后选择第三项,重新打开之前的运行报告

img

点击Next,出现如下界面

img

选择其中的一份报告打开,如m_System_Overview.zip

img

得到相同的结果

img

G1GC 概念与性能调优 (jdk11)

本文不讨论 G1 底层数据结构与算法, 从 G1 GC 行为上做简要介绍 G1 的过程

Garbage-First Garbage Collector 从官网的描述来看 G1 is a generational, incremental, parallel, mostly concurrent, stop-the-world, and evacuating garbage collector which monitors pause-time goals in each of the stop-the-world pauses. Similar to other collectors, G1 splits the heap into (virtual) young and old generations. Space-reclamation efforts concentrate on the young generation where it is most efficient to do so, with occasional space-reclamation in the old generation

从介绍可以加粗几个重点

  • 分代
  • 并发
  • STW
  • 在每个STW阶段关注暂停时间目标
  • 回收主要集中在最有效的young generation, old generation则没这么频繁

在G1中, 为了提升吞吐量, 有一些操作永远是(STW) stop-the-world 的. 其他的一些要长期的, 如全局标记这种要全堆进行的操作与应用程序并发进行. 为了让空间回收的 STW 尽可能减少, G1并行的分步的递增进行空间回收. G1通过追踪此前应用行为和垃圾回收停顿的信息来构建一个与开销有关的模型(Pause Prediction Model). 它使用这些信息停顿期间可做的工作. 举个例子, G1首先回收最高效的区域(也即垃圾最满的区域, 因此称为垃圾-优先).

G1把堆分成了n个大小相同的region

region

  • E 是 eden region
  • S 是 survivor region
  • O 是 old region
  • H 是 humongous (老年代可以是 humongous, 可以看出, 他可以跨越多个连续regions. 直接分配到老年代, 防止反复拷贝移动)

Java 9 以后开启的参数

自从 Java9 后, 引入的统一的日志, 也就是 Xlog 参数. 下面是建议的 GCLog 参数

1
-Xlog:gc*:file=your.log:tags,time,uptime,level:filecount=5,filesize=100m

G1 的 GC 阶段

我们明白, 调优的基本步骤就是

  1. Measure 收集相关诊断信息 (例如, 收集详细的gclog, 默认log level info 可以满足大部分情况)
  2. Understand 理解发生了什么
  3. Tune 调优

只有明白了GC内部发生了什么, 才能针对性的对其进行调整

下面通过一些正常的 GC log 来理解 GC 的三种方式 GC 做了什么

Young Only Phase

先用张图来简单理解 Young GC 过程

  • 垃圾回收的过程就是 Allocated->eden; eden -> survivor; survivor -> survivor; survivor -> old;

y1

  • 可以看到, 这里有 eden, survivor, old 还有个 free region.

y2

  • 橙色就是活着的对象

y3

  • G1会把橙色对象拷贝到free region

y4

  • 当拷贝完毕, free region 就会晋升为 survivor region, 以前的 eden 就被释放了
  • 如果 Young gc 中, 花费了大量的时间
    • 正常来说, 大部分在 Young 的对象都不会存活很长时间
  • 如果不符合这个规则 (大部分在 Young 的对象都不会存活很长时间), 你可能需要调整一下 Young 区域占比, 来降低 Young 对象的拷贝时间
    • -XX:G1NewSizePercent (默认:5) Young region 最小值
    • -XX:G1MaxNewSizePercent (默认: 60) Young region 最大值

Mixed gc Phase

  • Mixed gc 会选取所有的 Young region + 收益高的若干个 Old region.

M1 M2 M3

  • 同样的, 被回收的 region 就变回 free region 了

  • 从上图可以了解到 Mixed gc 只能回收部分的老年代

  • G1 是如何选择要回收的 regions 的?

    • -XX:G1MaxNewSizePercent 与 Young 关联
    • -XX:MixedGCCountTarget 与 old 关联
  • -XX:MixedGCCountTarget
    
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140



    默认是8, 意味着要在8次以内回收完所有的 old region

    - 换句话说, 如果你有 800 个 old region, 那么一次 mixed gc 最大会回收 100 个 old region

    - G1 也可以被调整成不做这么多工作, 也就是回收少点, 浪费堆内存, 导致更堆使用

    - `-XX:G1MixedGCLiveThresholdPercent` (默认:85) 可能会提高堆使用率
    - `-XX:G1HeapWastePercent` (默认:5) 如果可回收低于这个值, 那么将不会启动Mixed gc



    ### Full gc Phase

    - Full gc 是不应该发生的



    ### 先来看看 GC 周期

    ![gcy](2021-06-29-performance/gcy.png)

    G1 有两个阶段, 它会在这两个阶段往返, 分别是 Young-only, Space Reclamation.

    - Young-only 包含一系列逐渐填满 old gen 的 gc
    - Space Reclamation G1 会递进地回收 old gen 的空间, 同时也处理 Young region

    图是来自 oracle 上对 gc 周期的描述, 实心圆都表示一次 GC 停顿

    - 蓝色 Young-only
    - 黄色 标记过程的停顿
    - 红色 Mixed gc 停顿

    在几次gc后, old gen 的对象占有比超过了 `InitiatingHeapOccupancyPercent`, gc就会进入并发标记准备(concurrent mark).

    - G1 在每一次 Young 回收中都会查找活对象(有引用的对象)
    - G1 在 old region 并发查找活对象
    - 叫 concurrent marking
    - 可能花费很长时间
    - 不会停止 Java 应用
    - G1 没有活对象的引用信息是不能进行垃圾回收的
    - Mixed gc 依赖 concurrent mark

    回到 full gc, 从上面简单分析得出, full gc 发生是没有足够的 free region, 如果堆是足够大的, Mixed gc 没有回收足够的 old region, 或者 concurrent mark 没法及时完成, 都可能会导致 full gc.



    ### gc 日志

    ```log
    [gc,start ] GC(78) Pause Young (Normal) (G1 Evacuation Pause)
    [gc,task ] GC(78) Using 10 workers of 10 for evacuation
    [gc,phases ] GC(78) Pre Evacuate Collection Set: 3.2ms
    [gc,phases ] GC(78) Evacuate Collection Set: 28.8ms
    [gc,phases ] GC(78) Post Evacuate Collection Set: 1.8ms
    [gc,phases ] GC(78) Other: 1.1ms
    [gc,heap ] GC(78) Eden regions: 538->0(871)
    [gc,heap ] GC(78) Survivor regions: 69->33(76)
    [gc,heap ] GC(78) Old regions: 1041->1077
    [gc,heap ] GC(78) Humongous regions: 3->1
    [gc,metaspace ] GC(78) Metaspace: 71777K->71777K(1114112K)
    [gc ] GC(78) Pause Young (Normal) (G1 Evacuation Pause) 3300M->2220M(6144M) 34.907ms
    [gc,cpu ] GC(78) User=0.24s Sys=0.05s Real=0.04s
    [gc,start ] GC(79) Pause Young (Concurrent Start) (G1 Humongous Allocation)
    [gc,task ] GC(79) Using 10 workers of 10 for evacuation
    [gc,phases ] GC(79) Pre Evacuate Collection Set: 0.2ms
    [gc,phases ] GC(79) Evacuate Collection Set: 22.3ms
    [gc,phases ] GC(79) Post Evacuate Collection Set: 0.9ms
    [gc,phases ] GC(79) Other: 1.8ms
    [gc,heap ] GC(79) Eden regions: 569->0(656)
    [gc,heap ] GC(79) Survivor regions: 33->55(113)
    [gc,heap ] GC(79) Old regions: 1077->1077
    [gc,heap ] GC(79) Humongous regions: 1->1
    [gc,metaspace ] GC(79) Metaspace: 71780K->71780K(1114112K)
    [gc ] GC(79) Pause Young (Concurrent Start) (G1 Humongous Allocation) 3357M->2264M(6144M) 25.305ms
    [gc,cpu ] GC(79) User=0.21s Sys=0.00s Real=0.03s
    [gc ] GC(80) Concurrent Cycle
    [gc,marking ] GC(80) Concurrent Clear Claimed Marks
    [gc,marking ] GC(80) Concurrent Clear Claimed Marks 0.147ms
    [gc,marking ] GC(80) Concurrent Scan Root Regions
    [gc,marking ] GC(80) Concurrent Scan Root Regions 16.125ms
    [gc,marking ] GC(80) Concurrent Mark (373.358s)
    [gc,marking ] GC(80) Concurrent Mark From Roots
    [gc,task ] GC(80) Using 4 workers of 4 for marking
    [gc,marking ] GC(80) Concurrent Mark From Roots 57.029ms
    [gc,marking ] GC(80) Concurrent Preclean
    [gc,marking ] GC(80) Concurrent Preclean 0.454ms
    [gc,marking ] GC(80) Concurrent Mark (373.358s, 373.415s) 57.548ms
    [gc,start ] GC(80) Pause Remark
    [gc,stringtable] GC(80) Cleaned string and symbol table, strings: 36361 processed, 315 removed, symbols: 192117 processed, 500 removed
    [gc ] GC(80) Pause Remark 2326M->956M(6144M) 14.454ms
    [gc,cpu ] GC(80) User=0.08s Sys=0.03s Real=0.02s
    [gc,marking ] GC(80) Concurrent Rebuild Remembered Sets
    [gc,marking ] GC(80) Concurrent Rebuild Remembered Sets 38.843ms
    [gc,start ] GC(80) Pause Cleanup
    [gc ] GC(80) Pause Cleanup 974M->974M(6144M) 0.660ms
    [gc,cpu ] GC(80) User=0.00s Sys=0.00s Real=0.00s
    [gc,marking ] GC(80) Concurrent Cleanup for Next Mark
    [gc,marking ] GC(80) Concurrent Cleanup for Next Mark 16.673ms
    [gc ] GC(80) Concurrent Cycle 146.748ms
    [gc,start ] GC(81) Pause Young (Prepare Mixed) (G1 Evacuation Pause)
    [gc,task ] GC(81) Using 10 workers of 10 for evacuation
    [gc,mmu ] GC(81) MMU target violated: 61.0ms (60.0ms/61.0ms)
    [gc,phases ] GC(81) Pre Evacuate Collection Set: 0.1ms
    [gc,phases ] GC(81) Evacuate Collection Set: 76.8ms
    [gc,phases ] GC(81) Post Evacuate Collection Set: 0.9ms
    [gc,phases ] GC(81) Other: 1.1ms
    [gc,heap ] GC(81) Eden regions: 211->0(136)
    [gc,heap ] GC(81) Survivor regions: 55->17(34)
    [gc,heap ] GC(81) Old regions: 392->443
    [gc,heap ] GC(81) Humongous regions: 3->1
    [gc,metaspace ] GC(81) Metaspace: 71780K->71780K(1114112K)
    [gc ] GC(81) Pause Young (Prepare Mixed) (G1 Evacuation Pause) 1320M->919M(6144M) 78.857ms
    [gc,cpu ] GC(81) User=0.41s Sys=0.37s Real=0.08s
    [gc,start ] GC(82) Pause Young (Mixed) (G1 Evacuation Pause)
    [gc,task ] GC(82) Using 10 workers of 10 for evacuation
    [gc,phases ] GC(82) Pre Evacuate Collection Set: 0.1ms
    [gc,phases ] GC(82) Evacuate Collection Set: 22.1ms
    [gc,phases ] GC(82) Post Evacuate Collection Set: 0.8ms
    [gc,phases ] GC(82) Other: 0.9ms
    [gc,heap ] GC(82) Eden regions: 136->0(142)
    [gc,heap ] GC(82) Survivor regions: 17->11(20)
    [gc,heap ] GC(82) Old regions: 443->367
    [gc,heap ] GC(82) Humongous regions: 1->1
    [gc,metaspace ] GC(82) Metaspace: 71780K->71780K(1114112K)
    [gc ] GC(82) Pause Young (Mixed) (G1 Evacuation Pause) 1191M->757M(6144M) 23.970ms
    [gc,cpu ] GC(82) User=0.15s Sys=0.08s Real=0.03s
    [gc,start ] GC(83) Pause Young (Mixed) (G1 Evacuation Pause)
    [gc,task ] GC(83) Using 10 workers of 10 for evacuation
    [gc,phases ] GC(83) Pre Evacuate Collection Set: 0.1ms
    [gc,phases ] GC(83) Evacuate Collection Set: 5.0ms
    [gc,phases ] GC(83) Post Evacuate Collection Set: 0.8ms
    [gc,phases ] GC(83) Other: 1.1ms
    [gc,heap ] GC(83) Eden regions: 142->0(783)
    [gc,heap ] GC(83) Survivor regions: 11->10(20)
    [gc,heap ] GC(83) Old regions: 367->294
    [gc,heap ] GC(83) Humongous regions: 1->1
    [gc,metaspace ] GC(83) Metaspace: 71780K->71780K(1114112K)

上面是连续几次GC的日志, 可以对照着 gc 周期来看 为了方便排版, 把时间相关的tag给精简掉了

  • GC(78) 是一次普通的young gc, 里面信息有各种 region 的变化
    • 这里简单说一下 humongous 对象的处理
    • humongous 对象在G1中是被特殊对待的, G1 只决定它们是否生存, 回收他们占用的空间, 从不会移动它们.
    • Young-Only 阶段, humongous regions 可能会被回收
    • Space-Reclamation, humongous regions 可能会被回收
  • GC(79) 开始进入并发阶段
  • GC(80) 完成了 Cleanup, 紧接着一个 Prepare Mixed GC(81) 的垃圾收集, 对应周期虚线右边的蓝实心圆
  • GC(82) 之后就是 Space Reclamation 阶段了. 多个 Mixed GC 会进行

根据日志, 可以简单看到每个步骤花费的时间, 以及对应区域垃圾的回收情况, 结合GC参数, 可以定位出什么问题, 针对性的调整参数.

吞吐量跟低延时是无法兼得的, 低延时意味着GC工作会更加频繁, 相对的, 会占用应用的资源, 吞吐量降低. 需要大吞吐量, 那么GC工作就会减少, 相对的, 每次回收的垃圾就会多, 暂停时间就会增加, 延时就会增加. -XX:MaxGCPauseMillis G1 会尽量满足这个参数设定的目标时间, 通过此参数可以平衡应用需要的吞吐量以及延时.

g1gc young shrinking

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
[gc,start      ] GC(29233) Pause Young (Normal) (G1 Evacuation Pause)
[gc,task ] GC(29233) Using 8 workers of 8 for evacuation
[gc,phases ] GC(29233) Pre Evacuate Collection Set: 0.1ms
[gc,phases ] GC(29233) Evacuate Collection Set: 28.7ms
[gc,phases ] GC(29233) Post Evacuate Collection Set: 1.2ms
[gc,phases ] GC(29233) Other: 1.1ms
[gc,heap ] GC(29233) Eden regions: 1779->0(1771)
[gc,heap ] GC(29233) Survivor regions: 64->72(231)
[gc,heap ] GC(29233) Old regions: 327->327
[gc,heap ] GC(29233) Humongous regions: 1->1
[gc,metaspace ] GC(29233) Metaspace: 75815K->75815K(1118208K)
[gc ] GC(29233) Pause Young (Normal) (G1 Evacuation Pause) 4339M->798M(6144M) 31.124ms
[gc,cpu ] GC(29233) User=0.24s Sys=0.00s Real=0.04s
[gc,start ] GC(29234) Pause Young (Normal) (G1 Evacuation Pause)
[gc,task ] GC(29234) Using 8 workers of 8 for evacuation
[gc,mmu ] GC(29234) MMU target violated: 61.0ms (60.0ms/61.0ms)
[gc,phases ] GC(29234) Pre Evacuate Collection Set: 0.1ms
[gc,phases ] GC(29234) Evacuate Collection Set: 26.6ms
[gc,phases ] GC(29234) Post Evacuate Collection Set: 870.6ms
[gc,phases ] GC(29234) Other: 1.2ms
[gc,heap ] GC(29234) Eden regions: 1771->0(84)
[gc,heap ] GC(29234) Survivor regions: 72->69(231)
[gc,heap ] GC(29234) Old regions: 327->327
[gc,heap ] GC(29234) Humongous regions: 1->1
[gc,metaspace ] GC(29234) Metaspace: 75815K->75815K(1118208K)
[gc ] GC(29234) Pause Young (Normal) (G1 Evacuation Pause) 4340M->791M(6144M) 898.525ms
[gc,cpu ] GC(29234) User=0.22s Sys=0.00s Real=0.90s
  • Eden regions shrinking 1771 -> 84
    • If not otherwise constrained, then G1 adaptively sizes the young generation size between the values that -XX:G1NewSizePercent and -XX:G1MaxNewSizePercent determine to meet pause-time. See Garbage-First Garbage Collector Tuning for more information about how to fix long pauses.
  • User=0.22s Sys=0.00s Real=0.90s, Real > User + Sys
    • gc lack of cpu time

从 GC log 了解与分析 gc

CMS 介绍

CMS, Concurrent Mark Sweep, 并发的标记清楚算法GC.

CMS 执行

  1. 初始化标记
  2. 并发标记
  3. 并发预清理
  4. 重标记
  5. 并发清理
  6. 重置

环境配置是 JDK8, HotSpot VM

应用配置的参数

1
2
3
4
5
6
7
8
9
-XX:+UseConcMarkSweepGC                             // 使用 CMS GC
-XX:+UseCMSInitiatingOccupancyOnly // 不基于运行时收集的数据来启动 CMS 垃圾收集的周期, 使用CMSInitiatingOccupancyFraction
-XX:CMSInitiatingOccupancyFraction=70 // 使用70%后开始 CMS GC
-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses // 显式 GC 执行 CMS GC 非 FGC
-XX:+CMSClassUnloadingEnabled // CMS 也收集 PermGen space (https://blogs.oracle.com/poonam/about-g1-garbage-collector,-permanent-generation-and-metaspace)
-XX:+ParallelRefProcEnabled // 并行处理 ref
-XX:+CMSScavengeBeforeRemark // 在CMS remark前执行一次minor gc清理新生代, 减少stop-the-world时间
-XX:+PrintGCDetails // 打印 GC 详细信息
-XX:+PrintGCDateStamps // 输出GC的时间戳

CMS GC log 如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// initial mark stop-the-world
2018-08-06T10:55:07.447+0800: 495808.570: [GC (CMS Initial Mark) [1 CMS-initial-mark: 1421882K(1966080K)] 1464386K(3027776K), 0.0610635 secs] [Times: user=0.05 sys=0.00, real=0.06 secs]
// concurrent mark
2018-08-06T10:55:07.510+0800: 495808.633: [CMS-concurrent-mark-start]
2018-08-06T10:55:38.879+0800: 495840.002: [CMS-concurrent-mark: 27.341/31.368 secs] [Times: user=48.82 sys=8.29, real=31.36 secs]
// concurrent preclean
2018-08-06T10:55:38.879+0800: 495840.002: [CMS-concurrent-preclean-start]
2018-08-06T10:55:39.303+0800: 495840.426: [CMS-concurrent-preclean: 0.131/0.424 secs] [Times: user=0.89 sys=0.05, real=0.43 secs]
// abortable preclean
2018-08-06T10:55:39.303+0800: 495840.427: [CMS-concurrent-abortable-preclean-start]
2018-08-06T10:55:39.303+0800: 495840.427: [CMS-concurrent-abortable-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
// final remark stop-the-world
2018-08-06T10:55:39.320+0800: 495840.444: [GC (CMS Final Remark) [YG occupancy: 237032 K (1061696 K)]2018-08-06T10:55:39.321+0800: 495840.444: [GC (CMS Final Remark) 2018-08-06T10:55:39.321+0800: 495840.444: [ParNew: 237032K->237032K(1061696K), 0.0000520 secs] 2068900K->2068900K(3027776K), 0.0004108 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
// rescan
2018-08-06T10:55:39.321+0800: 495840.444: [Rescan (parallel) , 0.1066672 secs]2018-08-06T10:55:39.428+0800: 495840.551: [weak refs processing, 0.0868804 secs]2018-08-06T10:55:39.515+0800: 495840.638: [class unloading, 0.0667963 secs]
// scrub symbol table
2018-08-06T10:55:39.582+0800: 495840.705: [scrub symbol table, 0.0554765 secs]2018-08-06T10:55:39.637+0800: 495840.761: [scrub string table, 0.0065050 secs][1 CMS-remark: 1831867K(1966080K)] 2068900K(3027776K), 0.3247966 secs] [Times: user=0.48 sys=0.01, real=0.32 secs]
2018-08-06T10:55:39.646+0800: 495840.770: [CMS-concurrent-sweep-start]
2018-08-06T10:55:48.631+0800: 495849.755: [CMS-concurrent-sweep: 6.052/8.985 secs] [Times: user=7.66 sys=4.13, real=8.99 secs]
// reset start
2018-08-06T10:55:49.130+0800: 495850.253: [CMS-concurrent-reset-start]
2018-08-06T10:55:49.139+0800: 495850.263: [CMS-concurrent-reset: 0.009/0.009 secs] [Times: user=0.03 sys=0.00, real=0.00 secs]
2018-08-06T10:55:53.548+0800: 495854.672: [CMS: 1336369K->468683K(1966080K), 2.2096604 secs] 2336499K->468683K(3027776K), [Metaspace: 120912K->120912K(1165312K)], 2.7556633 secs] [Times: user=2.87 sys=0.01, real=2.75 secs]

知识点

CMS 阶段

步骤 解释 stop-the-world
CMS Initial Mark 可达性分析, 标记 GC Roots 直接关联 对象 True
CMS-concurrent-mark GC Tracing, 从 GC Roots 开始对堆进行可达性分析, 找出存活对象 False
CMS-concurrent-preclean 负责前一个阶段标记了又发生改变的对象标记 False
CMS-concurrent-abortable-preclean 尝试着去承担 Final Remark 阶段足够多的工作, 重复的做相同的事情直到 abort 条件 False
CMS Final Remark 完成标记整个年老代的所有的存活对象 True
CMS-concurrent-sweep 开始移除对象 False
CMS-concurrent-reset 重置 CMS 算法内部结构 False

GC 触发条件

原因 说明
Allocation Failure 新生代(Young generation)不够空间给创建新对象, 触发 minor gc.
Promotion Failure 没有 连续 的空间来存放更大的对象. 通常会导致 FGC.
GCLocker Initiated GC JNI 临界区被释放就会触发
Concurrent Mode Failure CMS 采用多个线程和应用线程并发执行, 减少停顿时间, 通常发生于年老代被用完之前不能完成对无引用对象的回收或者年老代不能满足新的空间分配
Heap Dump Initiated GC heap dump 之前进行 FGC , 一般是通过工具 dump 会触发 (jmap)

GC 异常点

通过 gceasy.io 上传日志, 分析异常点得出

1
It looks like your application is waiting due to lack of compute resources (either CPU or I/O cycles). Serious production applications shouldn't be stranded because of compute resources. In 47 GC event(s), 'real' time took more than 'usr' + 'sys' time.
Timestamp User Time (secs) Sys Time (secs) Real Time (secs)
2018-08-06T10:21:12 0.26 0.01 0.61
2018-08-06T10:21:18 0.24 0.04 0.9
2018-08-06T10:33:25 0.22 0.01 0.58
2018-08-06T10:34:54 0.3 0.01 0.52
2018-08-06T10:35:15 0.55 0.02 1.15

意思就是 ‘real’ time > ‘usr’ + ‘sys’, 造成这种现象的可能性有

  1. Heavy I/O 如果有 I/O 密集任务, ‘real time’ 会变长. > 解决方案 1. 优化高 I/O 任务 1. 在服务器上减少导致高 I/O 的任务 1. 迁移应用到低 I/O 的服务器上
  2. Lack of CPU 如果是服务器上有多个进程在跑, 程序得不到足够的 CPU 周期, 就会开始等待. 因此 ‘real time’会变长 > 解决方案: 1. 减少服务器上的进程 1. 增加 CPU 1. 迁移应用到充足 CPU 服务器上

现象分析

当时出现的现象是: 1. CPU 告警 1. 上去服务器看到系统负载已经到70左右 1. top 信息看到应用占用 CPU 高 1. GC 日志显示同一台服务器上的两个服务在10点时间段 CMS 都在工作 1. 业务高峰期 1. 4核服务器

初步分析: 1. 从应用线程dump分析, 应用内线程无明显异常现象. 1. 结合 top -H 初步得到是 GC 线程在运行 1. 从 GC log 入手, 分析得出异常点, 回顾与计算两个服务 CMS 线程占用了一半的 CPU 资源 (4+3)/4*2, 导致 CPU 资源紧缺, 整体服务变慢.

参考4资料

1
2
3
4
https://www.cnblogs.com/zhangxiaoguang/p/5792468.html
https://juejin.im/post/5b651200f265da0fa00a38d7?utm_source=gold_browser_extension
https://stackoverflow.com/questions/22149075/why-promotion-failure-and-concurrent-mode-failure
https://blog.gceasy.io/2016/12/08/real-time-greater-than-user-and-sys-time/

linux性能监控

CPU、Memory、IO、Network等指标的讲解

一、CPU

1、良好状态指标

1
2
3
- CPU利用率:User Time <= 70%,System Time <= 35%,User Time + System Time <= 70%。
- 上下文切换:与CPU利用率相关联,如果CPU利用率状态良好,大量的上下文切换也是可以接受的。
- 可运行队列:每个处理器的可运行队列<=3个线程。

2、监控工具

  • vmstat

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     vmstat 1
    procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
    r b swpd free buff cache si so bi bo in cs us sy id wa st
    14 0 140 2904316 341912 3952308 0 0 0 460 1106 9593 36 64 1 0 0
    17 0 140 2903492 341912 3951780 0 0 0 0 1037 9614 35 65 1 0 0
    20 0 140 2902016 341912 3952000 0 0 0 0 1046 9739 35 64 1 0 0
    17 0 140 2903904 341912 3951888 0 0 0 76 1044 9879 37 63 0 0 0
    16 0 140 2904580 341912 3952108 0 0 0 0 1055 9808 34 65 1 0 0

    重要参数:
    r,run queue,可运行队列的线程数,这些线程都是可运行状态,只不过CPU暂时不可用;
    b,被blocked的进程数,正在等待IO请求;
    ininterrupts,被处理过的中断数
    cs,context switch,系统上正在做上下文切换的数目
    us,用户占用CPU的百分比
    sys,内核和中断占用CPU的百分比
    id,CPU完全空闲的百分比

    上例可得:
    sy高us低,以及高频度的上下文切换(cs),说明应用程序进行了大量的系统调用;
    这台4核机器的r应该在12个以内,现在r在14个线程以上,此时CPU负荷很重。
  • $查看某个进程占用的CPU资源

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ while :; do ps -eo pid,ni,pri,pcpu,psr,comm | grep 'test_command'; sleep 1; done
    PID NI PRI %CPU PSR COMMAND
    28577 0 23 0.0 0 test_command
    28578 0 23 0.0 3 test_command
    28579 0 23 0.0 2 test_command
    28581 0 23 0.0 2 test_command
    28582 0 23 0.0 3 test_command
    28659 0 23 0.0 0 test_command
    ……

二、Memory

1、良好状态指标

1
2
- swap in (si) == 0,swap out (so) == 0
- 应用程序可用内存/系统物理内存 <= 70%

2、监控工具

  • vmstat

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    $ vmstat 1
    procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
    r b swpd free buff cache si so bi bo in cs us sy id wa st
    0 3 252696 2432 268 7148 3604 2368 3608 2372 288 288 0 0 21 78 1
    0 2 253484 2216 228 7104 5368 2976 5372 3036 930 519 0 0 0 100 0
    0 1 259252 2616 128 6148 19784 18712 19784 18712 3821 1853 0 1 3 95 1
    1 2 260008 2188 144 6824 11824 2584 12664 2584 1347 1174 14 0 0 86 0
    2 1 262140 2964 128 5852 24912 17304 24952 17304 4737 2341 86 10 0 0 4

    重要参数:
    swpd,已使用的 SWAP 空间大小,KB 为单位;
    free,可用的物理内存大小,KB 为单位;
    buff,物理内存用来缓存读写操作的buffer大小,KB 为单位;
    cache,物理内存用来缓存进程地址空间的 cache 大小,KB 为单位;
    si,数据从 SWAP 读取到 RAM(swap in)的大小,KB 为单位;
    so,数据从 RAM 写到 SWAP(swap out)的大小,KB 为单位。

    上例可得:
    物理可用内存 free 基本没什么显著变化,swapd逐步增加,说明最小可用的内存始终保持在 256MB(物理内存大小) * 10% = 2.56MB 左右,当脏页达到10%的时候就开始大量使用swap。
  • free

    1
    2
    3
    4
    5
    $ free -m
    total used free shared buffers cached
    Mem: 8111 7185 926 0 243 6299
    -/+ buffers/cache: 643 7468
    Swap: 8189 0 8189

三、磁盘IO

1、良好状态指标

  • iowait % < 20%

    1
    2
    3
    提高命中率的一个简单方式就是增大文件缓存区面积,缓存区越大预存的页面就越多,命中率也越高。

    Linux 内核希望能尽可能产生次缺页中断(从文件缓存区读),并且能尽可能避免主缺页中断(从硬盘读),这样随着次缺页中断的增多,文件缓存区也逐步增大,直到系统只有少量可用物理内存的时候 Linux 才开始释放一些不用的页。

2、监控工具

  • 查看物理内存和文件缓存情况

    1
    2
    3
    4
    5
    6
    $ cat /proc/meminfo
    MemTotal: 8182776 kB
    MemFree: 3053808 kB
    Buffers: 342704 kB
    Cached: 3972748 kB
    这台服务器总共有 8GB 物理内存(MemTotal),3GB 左右可用内存(MemFree),343MB左右用来做磁盘缓存(Buffers),4GB左右用来做文件缓存区(Cached)。
  • sar

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    $ sar -d 2 3
    Linux 2.6.9-42.ELsmp (webserver) 11/30/2008 _i686_ (8 CPU)
    11:09:33 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
    11:09:35 PM dev8-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
    11:09:35 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
    11:09:37 PM dev8-0 1.00 0.00 12.00 12.00 0.00 0.00 0.00 0.00
    11:09:37 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
    11:09:39 PM dev8-0 1.99 0.00 47.76 24.00 0.00 0.50 0.25 0.05
    Average: DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
    Average: dev8-0 1.00 0.00 19.97 20.00 0.00 0.33 0.17 0.02

    重要参数:
    await表示平均每次设备I/O操作的等待时间(以毫秒为单位)。
    svctm表示平均每次设备I/O操作的服务时间(以毫秒为单位)。
    %util表示一秒中有百分之几的时间用于I/O操作。
    如果svctm的值与await很接近,表示几乎没有I/O等待,磁盘性能很好,如果await的值远高于svctm的值,则表示I/O队列等待太长,系统上运行的应用程序将变慢。
    如果%util接近100%,表示磁盘产生的I/O请求太多,I/O系统已经满负荷的在工作,该磁盘可能存在瓶颈。

四、Network IO

对于UDP

1、良好状态指标

1
接收、发送缓冲区不长时间有等待处理的网络包

2、监控工具

  • netstat

对于UDP服务,查看所有监听的UDP端口的网络情况

1
2
3
4
5
6
7
8
9
10
11
12
$ watch netstat -lunp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 0.0.0.0:64000 0.0.0.0:* -
udp 0 0 0.0.0.0:38400 0.0.0.0:* -
udp 0 0 0.0.0.0:38272 0.0.0.0:* -
udp 0 0 0.0.0.0:36992 0.0.0.0:* -
udp 0 0 0.0.0.0:17921 0.0.0.0:* -
udp 0 0 0.0.0.0:11777 0.0.0.0:* -
udp 0 0 0.0.0.0:14721 0.0.0.0:* -
udp 0 0 0.0.0.0:36225 0.0.0.0:* -

RecvQ、SendQ为0,或者不长时间有数值是比较正常的。

对于UDP服务,查看丢包情况(网卡收到了,但是应用层没有处理过来造成的丢包)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ watch netstat -su
Udp:
278073881 packets received
4083356897 packets to unknown port received.
2474435364 packet receive errors
1079038030 packets sent

packet receive errors 这一项数值增长了,则表明在丢包。

[这里](http://www.withdevo.net/?p=18)有对“packet receive errors”的稍微详细些的解释,它包含了7种错误,and通常表明是checksum错误。不过我们通常通过这个数值的变化来判断UDP服务是否丢包(第2项错误),不知道是否有其他什么方法来判断UDP的丢包?:

"packet receive errors" usually means:
\1) data is truncated, error in checksum while copying
\2) udp queue is full, so it needs to be dropped
\3) unable to receive udp package from encapsulated socket
\4) sock_queue_rcv_skb() failed with -ENOMEM
\5) it is a short packet
\6) no space for header in udp packet when validating packet
\7) xfrm6_policy_check() fails
many times it means the checksum is not right.

对于TCP(来自david的经验,thx~~)

1、良好状态指标

1
2
3
对于TCP而言,不会出现因为缓存不足而存在丢包的事,因为网络等其他原因,导致丢了包,协议层也会通过重传机制来保证丢的包到达对方。

所以,tcp而言更多的专注重传率。

2、监控工具

1
2
3
4
5
6
7
8
# cat /proc/net/snmp | grep Tcp:
Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts
Tcp: 1 200 120000 -1 78447 413 50234 221 3 5984652 5653408 156800 0 849

重传率 = RetransSegs / OutSegs
至于这个值在多少范围内,算ok的,得看具体的业务了。
业务侧更关注的是响应时间。
每天一点点,感受自己存在的意义。

CPU

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
dstat –c 打印cpu
top

[root@host-80-80-41-196 webcache]# dstat -c 2
2秒打印一次
----total-cpu-usage----
usr sys idl wai hiq siq
5 5 85 2 1 1
3 2 94 0 1 1
4 2 91 1 1 1
usr:用户占用
sys:系统占中
idl:cpu空闲
wai:等待
hiq:中断
siq:软件中断

dstat 服务器性能查看命令
# dstat -c
usr:用户占用,sys系统占中,idl cpu空闲, wai等待,hiq中断,siq软件中断
# dstat -C
-C 当多个CPU的时候用此参数
# dstat -C 0,1 显示CPU0和1
# dstat -d 显示磁盘读写数据大小
# dstat -n 显示网络状态
# dstat -N eth1 有多块网卡时指定要显示的网卡
# dstat -l 显示系统负载
# dstat -m 显示内存使用情况
# dstat -g 显示页面使用情况
# dstat -p 显示进程状态
# dstat -s 显示swap使用状态
# dstat -r I/O 请求情况
# dstat --socket 用来显示tcp udp端口状态
# dstat -v vmstat
# dstat --output /home/dd.csv可以把状态信息以csv的格式重定向到指定的文件中,以便日后查看

---------------------------------------------------
lscpu命令,查看的是cpu的统计信息.
blue@blue-pc:~$ lscpu
Architecture: i686 #cpu架构
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian #小尾序
CPU(s): 4 #总共有4核
On-line CPU(s) list: 0-3
Thread(s) per core: 1 #每个cpu核,只能支持一个线程,即不支持超线程
Core(s) per socket: 4 #每个cpu,有4个核
Socket(s): 1 #总共有1一个cpu
Vendor ID: GenuineIntel #cpu产商 intel
CPU family: 6
Model: 42
Stepping: 7
CPU MHz: 1600.000
BogoMIPS: 5986.12
Virtualization: VT-x #支持cpu虚拟化技术
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 6144K

查看/proc/cpuinfo,可以知道每个cpu信息,如每个CPU的型号,主频等。
#cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 42
model name : Intel(R) Core(TM) i5-2320 CPU @ 3.00GHz
.....

上面输出的是第一个cpu部分信息,还有3个cpu信息省略了。

内存

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
连接CPU和磁盘,放在内存速度快,规格DDR4
free -m

如下显示free是显示的当前内存的使用
-m的意思是M字节来显示内容
free -m
total used free shared buffers cached
Mem: 1002 769 232 0 62 421
-/+ buffers/cache: 286 715
Swap: 1153 0 1153

第一部分Mem行:
total 内存总数: 1002M
used 已经使用的内存数: 769M
free 空闲的内存数: 232M
shared 当前已经废弃不用,总是0
buffers Buffer缓存内存数: 62M
cached Page缓存内存数:421M
关系:total(1002M) = used(769M) + free(232M)

第二部分(-/+ buffers/cache):
(-buffers/cache) used内存数:286M
(指的第一部分Mem行中的used – buffers – cached)

(+buffers/cache) free内存数: 715M
(指的第一部分Mem行中的free + buffers + cached)

可见-buffers/cache反映的是被程序实实在在吃掉的内存,而+buffers/cache反映的是可以挪用的内存总数.

第三部分是指交换分区, 我想不讲大家都明白.
大家看了上面,还是很晕.第一部分(Mem)与第二部分(-/+ buffers/cache)的结果中有关used和free为什么这么奇怪.
其实我们可以从二个方面来解释:
对操作系统来讲是Mem的参数,buffers/cached都是属于被使用,所以它认为free只有232.
对应用程序来讲是(-/+ buffers/cach),buffers/cached 是等同可用的,因为buffer/cached是为了提高程序执行的性能,当程序使用内存时,buffer/cached会很快地被使用.
  所以,以应用来看看,以(-/+ buffers/cache)的free和used为主.所以我们看这个就好了,另外告诉大家一些常识,Linux为了提高磁盘和内存存取效率, Linux做了很多精心的设计, 除了对dentry进行缓存(用于VFS,加速文件路径名到inode的转换), 还采取了两种主要Cache方式:Buffer Cache和Page Cache.前者针对磁盘块的读写,后者针对文件inode的读写,这些Cache能有效缩短了 I/O系统调用(比如read,write,getdents)的时间。
记住内存是拿来用的,不是拿来看的,不像windows,无论你的真实物理内存有多少,他都要拿硬盘交换文件来读.这也就是windows为什么常常提示虚拟空间不足的原因。你们想想,多无聊,在内存还有大部分的时候,拿出一部分硬盘空间来充当内存,硬盘怎么会快过内存.所以我们看linux,只要不用swap的交换空间,就不用担心自己的内存太少.如果常常swap用很多,可能你就要考虑加物理内存了.这也是linux看内存是否够用的标准哦。

查看内存条数命令:
dmidecode | grep -A16 "Memory Device$"s

dstat –m
[root@host-80-80-41-196 webcache]# dstat -m
------memory-usage-----
used buff cach free
1627M 11.9M 2266M 45.3M
1631M 11.9M 2266M 41.0M
1633M 11.9M 2266M 39.1M


释放内存:
1.清理前内存使用情况
free -m
2.开始清理:
echo 3 > /proc/sys/vm/drop_caches

To free pagecache, use:
echo 1 > /proc/sys/vm/drop_caches

to free dentries and inodes, use:
echo 2 > /proc/sys/vm/drop_caches

to free pagecache, dentries and inodes, use:
echo 3 >/proc/sys/vm/drop_caches

3.清理后内存使用情况
free -m

4.完成!


概要查看内存情况
free -m
total used free shared buffers cached
Mem: 3926 3651 274 0 12 404
-/+ buffers/cache: 3235 691
Swap: 9536 31 9505
这里的单位是MB,总共的内存是3926MB。

查看内存详细使用
# cat /proc/meminfo
MemTotal: 4020868 kB
MemFree: 230884 kB
Buffers: 7600 kB
Cached: 454772 kB
SwapCached: 836 kB
.....

查看内存硬件信息
dmidecode -t memory
# dmidecode 2.11
SMBIOS 2.7 present.

Handle 0x0008, DMI type 16, 23 bytes
Physical Memory Array
Location: System Board Or Motherboard
....
Maximum Capacity: 32 GB
....

Handle 0x000A, DMI type 17, 34 bytes
....
Memory Device
Array Handle: 0x0008
Error Information Handle: Not Provided
Total Width: 64 bits
Data Width: 64 bits
Size: 4096 MB
.....

我的主板有4个槽位,只用了一个槽位,上面插了一条4096MB的内存。

IO

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
SATA,SAS,SSD(转的越快越好)

最好的磁盘是SSD
lsscsi(实际磁盘的挂载)
df –h

查看硬盘和分区分布
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 465.8G 0 disk
├─sda1 8:1 0 1G 0 part /boot
├─sda2 8:2 0 9.3G 0 part [SWAP]
├─sda3 8:3 0 74.5G 0 part /
├─sda4 8:4 0 1K 0 part
├─sda5 8:5 0 111.8G 0 part /home
└─sda6 8:6 0 269.2G 0 part

显示很直观

如果要看硬盘和分区的详细信息
# fdisk -l
Disk /dev/sda: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders, total 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x00023728

Device Boot Start End Blocks Id System
/dev/sda1 * 2048 2148351 1073152 83 Linux
/dev/sda2 2148352 21680127 9765888 82 Linux swap / Solaris
/dev/sda3 21680128 177930239 78125056 83 Linux
/dev/sda4 177932286 976771071 399419393 5 Extended/dev/sda5 177932288 412305407 117186560 83 Linux
/dev/sda6 412307456 976771071 282231808 83 Linux


iostat -xm 2
[root@host-80-80-41-196 vm]# iostat -xm 2
Linux 2.6.18-164.el5 (host-80-80-41-196) 20170204
avg-cpu: %user %nice %system %iowait %steal %idle
5.26 0.00 7.53 1.84 0.00 85.38
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
vda 0.04 2.48 3.21 17.36 0.02 0.38 40.03 2.13 103.45 2.92 6.01
vda1 0.03 2.48 3.21 17.36 0.02 0.38 40.03 2.13 103.45 2.92 6.01
vdb 0.00 0.00 0.00 0.00 0.00 0.00 21.07 0.00 4.33 4.33 0.00

第一部分包含了CPU报告
• %user : 显示了在执行用户(应用)层时的CPU利用率
• %nice : 显示了在以nice优先级运行用户层的CPU利用率
• %system : 显示了在执行系统(内核)层时的CPU利用率
• %iowait : 显示了CPU在I/O请求挂起时空闲时间的百分比
• %steal : 显示了当hypervisor正服务于另外一个虚拟处理器时无意识地等待虚拟CPU所占有的时间百分比。
• %idle : 显示了CPU在I/O没有挂起请求时空闲时间的百分比

第二部分包含了设备利用率报告
Device : 列出的/dev 目录下的设备/分区名称
tps : 显示每秒传输给设备的数量。更高的tps意味着处理器更忙。
Blk_read/s : 显示了每秒从设备上读取的块的数量(KB,MB)
Blk_wrtn/s : 显示了每秒写入设备上块的数量(KB,MB)
Blk_read : 显示所有已读取的块
Blk_wrtn : 显示所有已写入的块
注:%idle表示磁盘的忙和闲

dd if=/dev/zero of=/home/a.txt bs=100m count=10
备份/dev/zero磁盘开始100m到指定路径/home/a.txt仅拷贝10个块

带宽

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
命令:ethtool eth* 
如:ethtool eth1或者ethtool eth0
ethtool eth1
网卡down掉:ifconfig eth1 down / ifconfig eth1 up
电口和光口看Port: Twisted Pair
(Twisted Pair为电口,也叫双绞线; Port:FIBRE为光口)

[root@host-80-80-41-196 webcache]# ethtool eth1
Settings for eth1:
Supported ports: [ TP ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Advertised auto-negotiation: Yes
Speed: 1000Mb/s
Duplex: Full
Port: Twisted Pair
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: umbg
Wake-on: g
Current message level: 0x00000007 (7)
Link detected: yes

电口:1G;
光口(光纤):10G


dstat –n 2
dstat –tcmnd 同时查看CPU,内存,IO,带宽


查看网卡硬件信息
# lspci | grep -i 'eth'
02:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 06)

查看系统的所有网络接口
# ifconfig -a
eth0 Link encap:以太网 硬件地址 b8:97:5a:17:b3:8f
.....

lo Link encap:本地环回
.....
或者是
ip link show
1: lo: <LOOPBACK> mtu 16436 qdisc noqueue state DOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether b8:97:5a:17:b3:8f brd ff:ff:ff:ff:ff:ff

如果要查看某个网络接口的详细信息,例如eth0的详细参数和指标
# ethtool eth0
Settings for eth0:
Supported ports: [ TP MII ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full #支持千兆半双工,全双工模式
Supported pause frame use: No
Supports auto-negotiation: Yes #支持自适应模式,一般都支持
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Advertised pause frame use: Symmetric Receive-only
Advertised auto-negotiation: Yes #默认使用自适应模式
Link partner advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
.....
Speed: 100Mb/s #现在网卡的速度是100Mb,网卡使用自适应模式,所以推测路由是100Mb,导致网卡从支持千兆,变成要支持百兆
Duplex: Full #全双工
.....
Link detected: yes #表示有网线连接,和路由是通的

其他

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
查看pci信息,即主板所有硬件槽信息。
lspci
00:00.0 Host bridge: Intel Corporation 2nd Generation Core Processor Family DRAM Controller (rev 09) #主板芯片
00:02.0 VGA compatible controller: Intel Corporation 2nd Generation Core Processor Family Integrated Graphics Controller (rev 09) #显卡
00:14.0 USB controller: Intel Corporation Panther Point USB xHCI Host Controller (rev 04) #usb控制器
00:16.0 Communication controller: Intel Corporation Panther Point MEI Controller #1 (rev 04)
00:1a.0 USB controller: Intel Corporation Panther Point USB Enhanced Host Controller #2 (rev 04)
00:1b.0 Audio device: Intel Corporation Panther Point High Definition Audio Controller (rev 04) #声卡
00:1c.0 PCI bridge: Intel Corporation Panther Point PCI Express Root Port 1 (rev c4) #pci 插槽
00:1c.2 PCI bridge: Intel Corporation Panther Point PCI Express Root Port 3 (rev c4)
00:1c.3 PCI bridge: Intel Corporation Panther Point PCI Express Root Port 4 (rev c4)
00:1d.0 USB controller: Intel Corporation Panther Point USB Enhanced Host Controller #1 (rev 04)
00:1f.0 ISA bridge: Intel Corporation Panther Point LPC Controller (rev 04)
00:1f.2 IDE interface: Intel Corporation Panther Point 4 port SATA Controller [IDE mode] (rev 04) #硬盘接口
00:1f.3 SMBus: Intel Corporation Panther Point SMBus Controller (rev 04)
00:1f.5 IDE interface: Intel Corporation Panther Point 2 port SATA Controller [IDE mode] (rev 04) #硬盘接口
02:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 06) #网卡
03:00.0 PCI bridge: Integrated Technology Express, Inc. Device 8893 (rev 41)
如果要更详细的信息:lspci -v 或者 lspci -vv
如果要看设备树:lscpi -t

查看bios信息
# dmidecode -t bios
......
BIOS Information
Vendor: American Megatrends Inc.
Version: 4.6.5
Release Date: 04/25/2012
.......
BIOS Revision: 4.6
......
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
手工释放Linux内存——/proc/sys/vm/drop_cache

linux的内存查看:
[root@localhost 0.1.0]# free -m
total used free shared buffers cached
Mem: 4032 694 3337 0 0 25
需要说明的是,mem的used=free+buffers+cached,有些情况是cached占用很多资源,算起来数值就是不对,其实不影响实际使用,下面转载部分有说明如何清除cached的占用(实际上可以不清除,不会影响实际使用)
当在Linux下频繁存取文件后,物理内存会很快被用光,当程序结束后,内存不会被正常释放,而是一直作为caching。这个问题,貌似有不少人在问,不过都没有看到有什么很好解决的办法。那么我来谈谈这个问题。


一、通常情况
先来说说free命令:
引用[root@server ~]# free -m
total used free shared buffers cached
Mem: 249 163 86 0 10 94
-/+ buffers/cache: 58 191
Swap: 511 0 511
其中:
引用total 内存总数
used 已经使用的内存数
free 空闲的内存数
shared 多个进程共享的内存总额
buffers Buffer Cache和cached Page Cache 磁盘缓存的大小
-buffers/cache 的内存数:used - buffers - cached
+buffers/cache 的内存数:free + buffers + cached
可用的memory=free memory+buffers+cached。
有了这个基础后,可以得知,我现在used为163MB,free为86MB,buffer和cached分别为10MB,94MB。
那么我们来看看,如果我执行复制文件,内存会发生什么变化.
引用[root@server ~]# cp -r /etc ~/test/
[root@server ~]# free -m
total used free shared buffers cached
Mem: 249 244 4 0 8 174
-/+ buffers/cache: 62 187
Swap: 511 0 511
在我命令执行结束后,used为244MB,free为4MB,buffers为8MB,cached为174MB,天呐,都被cached吃掉了。别紧张,这是为了提高文件读取效率的做法。
为了提高磁盘存取效率,Linux做了一些精心的设计,除了对dentry进行缓存(用于VFS,加速文件路径名到inode的转换),还采取了两种主要Cache方式:Buffer Cache和Page Cache。前者针对磁盘块的读写,后者针对文件inode的读写。这些Cache有效缩短了 I/O系统调用(比如read,write,getdents)的时间。
那么有人说过段时间,linux会自动释放掉所用的内存。等待一段时间后,我们使用free再来试试,看看是否有释放?
[root@server test]# free -m
total used free shared buffers cached
Mem: 249 244 5 0 8 174
-/+ buffers/cache: 61 188
Swap: 511 0 511
似乎没有任何变化。(实际情况下,内存的管理还与Swap有关)
那么我能否手动释放掉这些内存呢?回答是可以的!


二、手动释放缓存
/proc是一个虚拟文件系统,我们可以通过对它的读写操作做为与kernel实体间进行通信的一种手段。也就是说可以通过修改/proc中的文件,来对当前kernel的行为做出调整。那么我们可以通过调整/proc/sys/vm/drop_caches来释放内存。操作如下:
[root@server test]# cat /proc/sys/vm/drop_caches
0
首先,/proc/sys/vm/drop_caches的值,默认为0
[root@server test]# sync
手动执行sync命令(描述:sync 命令运行 sync 子例程。如果必须停止系统,则运行sync 命令以确保文件系统的完整性。sync 命令将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件)
[root@server test]# echo 3 > /proc/sys/vm/drop_caches
[root@server test]# cat /proc/sys/vm/drop_caches
3
将/proc/sys/vm/drop_caches值设为3
[root@server test]# free -m
total used free shared buffers cached
Mem: 249 66 182 0 0 11
-/+ buffers/cache: 55 194
Swap: 511 0 511
再来运行free命令,会发现现在的used为66MB,free为182MB,buffers为0MB,cached为11MB。那么有效的释放了buffer和cache。
有关/proc/sys/vm/drop_caches的用法在下面进行了说明
引用/proc/sys/vm/drop_caches (since Linux 2.6.16)
Writing to this file causes the kernel to drop clean caches,dentries and inodes from memory, causing that memory to become free.
To free pagecache, use
echo 1 > /proc/sys/vm/drop_caches;
to free dentries and inodes, use
echo 2 > /proc/sys/vm/drop_caches;
to free pagecache, dentries and inodes, use
echo 3 >/proc/sys/vm/drop_caches.
Because this is a non-destructive operation and dirty objects are not freeable, the user should run sync first.


三、我的意见
上述文章就长期以来很多用户对Linux内存管理方面的疑问,给出了一个比较“直观”的回复,我更觉得有点像是核心开发小组的妥协。
对于是否需要使用这个值,或向用户提及这个值,我是有保留意见的:
1、从man可以看到,这值从2.6.16以后的核心版本才提供,也就是老版的操作系统,如红旗DC 5.0、RHEL 4.x之前的版本都没有;
2、若对于系统内存是否够用的观察,我还是原意去看swap的使用率和si/so两个值的大小;
用户常见的疑问是,为什么free这么小,是否关闭应用后内存没有释放?
但实际上,我们都知道这是因为Linux对内存的管理与Windows不同,free小并不是说内存不够用了,应该看的是free的第二行最后一个值:"-/+ buffers/cache: 58 191" 这才是系统可用的内存大小。
实际项目中告诉我们,如果因为是应用有像内存泄露、溢出的问题,从swap的使用情况是可以比较快速可以判断的,但free上面反而比较难查看。相反,如果在这个时候,我们告诉用户,修改系统的一个值,“可以”释放内存,free就大了。用户会怎么想?不会觉得操作系统“有问题”吗?所以说,我觉得既然核心是可以快速清空buffer或cache,也不难做到(这从上面的操作中可以明显看到),但核心并没有这样做(默认值是0),我们就不应该随便去改变它。一般情况下,应用在系统上稳定运行了,free值也会保持在一个稳定值的,虽然看上去可能比较小。当发生内存不足、应用获取不到可用内存、OOM错误等问题时,还是更应该去分析应用方面的原因,如用户量太大导致内存不足、发生应用内存溢出等情况,否则,清空buffer,强制腾出free的大小,可能只是把问题给暂时屏蔽了。
我觉得,排除内存不足的情况外,除非是在软件开发阶段,需要临时清掉buffer,以判断应用的内存使用情况;或应用已经不再提供支持,即使应用对内存的时候确实有问题,而且无法避免的情况下,才考虑定时清空buffer。(可惜,这样的应用通常都是运行在老的操作系统版本上,上面的操作也解决不了)。
测试
[root@testserver ~]# uname -a
Linux testserver 2.6.18-164.el5 #1 SMP Thu Sep 3 03:28:30 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
[root@testserver ~]# free -m
total used free shared buffers cached
Mem: 2013 1661 352 0 223 1206
-/+ buffers/cache: 231 1782
Swap: 2047 0 2047
[root@testserver ~]# sync
[root@testserver ~]# sync
[root@testserver ~]# cat /proc/sys/vm/drop_caches
0
[root@testserver ~]# echo 3 > /proc/sys/vm/drop_caches
[root@testserver ~]# cat /proc/sys/vm/drop_caches
3
[root@testserver ~]# free -m
total used free shared buffers cached
Mem: 2013 100 1913 0 0 14
-/+ buffers/cache: 85 1927
Swap: 2047 0 2047

待整理

1
2
3
4
5
6

timeout:
cat /proc/sys/net/ipv4/tcp_fin_timeout

curl多少大小:
curl -o /dev/null -H "Range:bytes=0-1048576"

命令ss

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
ss命令高级网络 
ss命令用来显示处于活动状态的套接字信息。ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容。但ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比netstat更快速更高效。 当服务器的socket连接数量变得非常大时,无论是使用netstat命令还是直接cat /proc/net/tcp,执行速度都会很慢。可能你不会有切身的感受,但请相信我,当服务器维持的连接达到上万个的时候,使用netstat等于浪费 生命,而用ss才是节省时间。 天下武功唯快不破。ss快的秘诀在于,它利用到了TCP协议栈中tcp_diag。tcp_diag是一个用于分析统计的模块,可以获得Linux 内核中第一手的信息,这就确保了ss的快捷高效。当然,如果你的系统中没有tcp_diag,ss也可以正常运行,只是效率会变得稍慢。

语法 ss(选项) 选项
-h:显示帮助信息;
-V:显示指令版本信息;
-n:不解析服务名称,以数字方式显示;
-a:显示所有的套接字;
-l:显示处于监听状态的套接字;
-o:显示计时器信息;
-m:显示套接字的内存使用情况;
-p:显示使用套接字的进程信息;
-i:显示内部的TCP信息;
-4:只显示ipv4的套接字;
-6:只显示ipv6的套接字;
-t:只显示tcp套接字;
-u:只显示udp套接字;
-d:只显示DCCP套接字;
-w:仅显示RAW套接字;
-x:仅显示UNIX域套接字

显示ICP连接
ss -t -a

显示 Sockets 摘要
ss -s
列出当前的established, closed, orphaned and waiting TCP sockets

列出所有打开的网络连接端口
ss -l

常用的 ss -antl

wget

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
wget命令用来从指定的URL下载文件。wget非常稳定,它在带宽很窄的情况下和不稳定网络中有很强的适应性,如果是由于网络的原因下载失败,wget会不断的尝试,直到整个文件下载完毕。如果是服务器打断下载过程,它会再次联到服务器上从停止的地方继续下载。这对从那些限定了链接时间的服务器上下载大文件非常有用。

语法:
wget(选项)(参数)

选项:
-a<日志文件>:在指定的日志文件中记录资料的执行过程;
-A<后缀名>:指定要下载文件的后缀名,多个后缀名之间使用逗号进行分隔;
-b:进行后台的方式运行wget; -B<连接地址>:设置参考的连接地址的基地地址;
-c:继续执行上次终端的任务;
-C<标志>:设置服务器数据块功能标志on为激活,off为关闭,默认值为on;
-d:调试模式运行指令; -D<域名列表>:设置顺着的域名列表,域名之间用“,”分隔;
-e<指令>:作为文件“.wgetrc”中的一部分执行指定的指令;
-h:显示指令帮助信息;
-i<文件>:从指定文件获取要下载的URL地址;
-l<目录列表>:设置顺着的目录列表,多个目录用“,”分隔;
-L:仅顺着关联的连接;
-r:递归下载方式;
-nc:文件存在时,下载文件不覆盖原有文件;
-nv:下载时只显示更新和出错信息,不显示指令的详细执行过程;
-q:不显示指令执行过程;
-nh:不查询主机名称;
-v:显示详细执行过程;
-V:显示版本信息;
--passive-ftp:使用被动模式PASV连接FTP服务器;
--follow-ftp:从HTML文件中下载FTP连接文件。

参数:
URL:下载指定的URL地址。

1、使用wget下载单个文件 

以下的例子是从网络下载一个文件并保存在当前目录 

wget http://cn.wordpress.org/wordpress-3.1-zh_CN.zip 

在下载的过程中会显示进度条,包含(下载完成百分比,已经下载的字节,当前下载速度,剩余下载时间)。 

2、使用wget -O下载并以不同的文件名保存 

wget默认会以最后一个符合”/”的后面的字符来命令,对于动态链接的下载通常文件名会不正确。 
错误:下面的例子会下载一个文件并以名称download.php?id=1080保存 

wget http://www.centos.bz/download?id=1 
即使下载的文件是zip格式,它仍然以download.php?id=1080命令。 
正确:为了解决这个问题,我们可以使用参数-O来指定一个文件名: 

wget -O wordpress.zip http://www.centos.bz/download.php?id=1080 

3、使用wget –limit -rate限速下载 
当你执行wget的时候,它默认会占用全部可能的宽带下载。但是当你准备下载一个大文件,而你还需要下载其它文件时就有必要限速了。 

wget –limit-rate=300k http://cn.wordpress.org/wordpress-3.1-zh_CN.zip 

4、使用wget -c断点续传 
使用wget -c重新启动下载中断的文件: 

wget -c http://cn.wordpress.org/wordpress-3.1-zh_CN.zip 
对于我们下载大文件时突然由于网络等原因中断非常有帮助,我们可以继续接着下载而不是重新下载一个文件。需要继续中断的下载时可以使用-c参数。 

5、使用wget -b后台下载 
对于下载非常大的文件的时候,我们可以使用参数-b进行后台下载。 

wget -b http://cn.wordpress.org/wordpress-3.1-zh_CN.zip 
Continuing in background, pid 1840. 
Output will be written to `wget-log’. 
你可以使用以下命令来察看下载进度 

tail -f wget-log 

6、伪装代理名称下载 
有些网站能通过根据判断代理名称不是浏览器而拒绝你的下载请求。不过你可以通过–user-agent参数伪装。 

wget –user-agent=”Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16″ 下载链接 

7、使用wget –spider测试下载链接 
当你打算进行定时下载,你应该在预定时间测试下载链接是否有效。我们可以增加–spider参数进行检查。 

wget –spider URL 
如果下载链接正确,将会显示 

wget –spider URL 
Spider mode enabled. Check if remote file exists. 
HTTP request sent, awaiting response… 200 OK 
Length: unspecified [text/html] 
Remote file exists and could contain further links, 
but recursion is disabled — not retrieving. 
这保证了下载能在预定的时间进行,但当你给错了一个链接,将会显示如下错误 

wget –spider url 
Spider mode enabled. Check if remote file exists. 
HTTP request sent, awaiting response… 404 Not Found 
Remote file does not exist — broken link!!! 
你可以在以下几种情况下使用spider参数: 

定时下载之前进行检查 
间隔检测网站是否可用 
检查网站页面的死链接 

8、使用wget –tries增加重试次数 
如果网络有问题或下载一个大文件也有可能失败。wget默认重试20次连接下载文件。如果需要,你可以使用–tries增加重试次数。 

wget –tries=40 URL 

9、使用wget -i下载多个文件 
首先,保存一份下载链接文件 

cat > filelist.txt 
url1 
url2 
url3 
url4 
接着使用这个文件和参数-i下载 

wget -i filelist.txt 

10、使用wget –mirror镜像网站 
下面的例子是下载整个网站到本地。 

wget –mirror -p –convert-links -P ./LOCAL URL 
–miror:开户镜像下载 
-p:下载所有为了html页面显示正常的文件 
–convert-links:下载后,转换成本地的链接 
-P ./LOCAL:保存所有文件和目录到本地指定目录 

11、使用wget –reject过滤指定格式下载 
你想下载一个网站,但你不希望下载图片,你可以使用以下命令。 

wget –reject=gif url 

12、使用wget -o把下载信息存入日志文件 
你不希望下载信息直接显示在终端而是在一个日志文件,可以使用以下命令: 

wget -o download.log URL 

13、使用wget -Q限制总下载文件大小 
当你想要下载的文件超过5M而退出下载,你可以使用以下命令: 

wget -Q5m -i filelist.txt 
注意:这个参数对单个文件下载不起作用,只能递归下载时才有效。 

14、使用wget -r -A下载指定格式文件 
可以在以下情况使用该功能 

下载一个网站的所有图片 
下载一个网站的所有视频 
下载一个网站的所有PDF文件 
wget -r -A.pdf url 

15、使用wget FTP下载 
你可以使用wget来完成ftp链接的下载。 
使用wget匿名ftp下载 

wget ftp-url 

使用wget用户名和密码认证的ftp下载 

wget –ftp-user=USERNAME –ftp-password=PASSWORD url

wget是在Linux下开发的开放源代码的软件,作者是Hrvoje Niksic,后来被移植到包括Windows在内的各个平台上。它有以下功能和特点: 

1)支持断点下传功能;这一点,也是网络蚂蚁和FlashGet当年最大的卖点,现在,Wget也可以使用此功能,那些网络不是太好的用户可以放心了; 
2)同时支持FTP和HTTP下载方式;尽管现在大部分软件可以使用HTTP方式下载,但是,有些时候,仍然需要使用FTP方式下载软件; 
3)支持代理服务器;对安全强度很高的系统而言,一般不会将自己的系统直接暴露在互联网上,所以,支持代理是下载软件必须有的功能; 
4)设置方便简单;可能,习惯图形界面的用户已经不是太习惯命令行了,但是,命令行在设置上其实有更多的优点,最少,鼠标可以少点很多次,也不要担心是否错点鼠标; 
5)程序小,完全免费;程序小可以考虑不计,因为现在的硬盘实在太大了;完全免费就不得不考虑了,即使网络上有很多所谓的免费软件,但是,这些软件的广告却不是我们喜欢的; 

wget虽然功能强大,但是使用起来还是比较简单的,基本的语法是:wget [参数列表] URL。下面就结合具体的例子来说明一下wget的用法。 

1、下载整个http或者ftp站点。 
wget http://place.your.url/here 
这个命令可以将http://place.your.url/here 首页下载下来。使用-x会强制建立服务器上一模一样的目录,如果使用-nd参数,那么服务器上下载的所有内容都会加到本地当前目录。 

wget -r http://place.your.url/here 
这 个命令会按照递归的方法,下载服务器上所有的目录和文件,实质就是下载整个网站。这个命令一定要小心使用,因为在下载的时候,被下载网站指向的所有地址同 样会被下载,因此,如果这个网站引用了其他网站,那么被引用的网站也会被下载下来!基于这个原因,这个参数不常用。可以用-l number参数来指定下载的层次。例如只下载两层,那么使用-l 2。 

要是您想制作镜像站点,那么可以使用-m参数,例如:wget -m http://place.your.url/here 
这时wget会自动判断合适的参数来制作镜像站点。此时,wget会登录到服务器上,读入robots.txt并按robots.txt的规定来执行。 

2、断点续传。 
当文件特别大或者网络特别慢的时候,往往一个文件还没有下载完,连接就已经被切断,此时就需要断点续传。wget的断点续传是自动的,只需要使用-c参数,例如: 
wget -c http://the.url.of/incomplete/file 
使用断点续传要求服务器支持断点续传。-t参数表示重试次数,例如需要重试100次,那么就写-t 100,如果设成-t 0,那么表示无穷次重试,直到连接成功。-T参数表示超时等待时间,例如-T 120,表示等待120秒连接不上就算超时。 

3、批量下载。 
如果有多个文件需要下载,那么可以生成一个文件,把每个文件的URL写一行,例如生成文件download.txt,然后用命令:wget -i download.txt 
这样就会把download.txt里面列出的每个URL都下载下来。(如果列的是文件就下载文件,如果列的是网站,那么下载首页) 

4、选择性的下载。 
可以指定让wget只下载一类文件,或者不下载什么文件。例如: 
wget -m –reject=gif http://target.web.site/subdirectory 
表示下载http://target.web.site/subdirectory,但是忽略gif文件。–accept=LIST 可以接受的文件类型,–reject=LIST拒绝接受的文件类型。 

5、密码和认证。 
wget只能处理利用用户名/密码方式限制访问的网站,可以利用两个参数: 
–http-user=USER设置HTTP用户 
–http-passwd=PASS设置HTTP密码 
对于需要证书做认证的网站,就只能利用其他下载工具了,例如curl。 

6、利用代理服务器进行下载。 
如果用户的网络需要经过代理服务器,那么可以让wget通过代理服务器进行文件的下载。此时需要在当前用户的目录下创建一个.wgetrc文件。文件中可以设置代理服务器: 
http-proxy = 111.111.111.111:8080 
ftp-proxy = 111.111.111.111:8080 
分别表示http的代理服务器和ftp的代理服务器。如果代理服务器需要密码则使用: 
–proxy-user=USER设置代理用户 
–proxy-passwd=PASS设置代理密码 
这两个参数。 
使用参数–proxy=on/off 使用或者关闭代理。 
wget还有很多有用的功能,需要用户去挖掘。 

附录: 

命令格式: 
wget [参数列表] [目标软件、网页的网址] 

-V,–version 显示软件版本号然后退出; 
-h,–help显示软件帮助信息; 
-e,–execute=COMMAND 执行一个 “.wgetrc”命令 

-o,–output-file=FILE 将软件输出信息保存到文件; 
-a,–append-output=FILE将软件输出信息追加到文件; 
-d,–debug显示输出信息; 
-q,–quiet 不显示输出信息; 
-i,–input-file=FILE 从文件中取得URL; 

-t,–tries=NUMBER 是否下载次数(0表示无穷次) 
-O –output-document=FILE下载文件保存为别的文件名 
-nc, –no-clobber 不要覆盖已经存在的文件 
-N,–timestamping只下载比本地新的文件 
-T,–timeout=SECONDS 设置超时时间 
-Y,–proxy=on/off 关闭代理 

-nd,–no-directories 不建立目录 
-x,–force-directories 强制建立目录 

–http-user=USER设置HTTP用户 
–http-passwd=PASS设置HTTP密码 
–proxy-user=USER设置代理用户 
–proxy-passwd=PASS设置代理密码 

-r,–recursive 下载整个网站、目录(小心使用) 
-l,–level=NUMBER 下载层次 

-A,–accept=LIST 可以接受的文件类型 
-R,–reject=LIST拒绝接受的文件类型 
-D,–domains=LIST可以接受的域名 
–exclude-domains=LIST拒绝的域名 
-L,–relative 下载关联链接 
–follow-ftp 只下载FTP链接 
-H,–span-hosts 可以下载外面的主机 
-I,–include-directories=LIST允许的目录 
-X,–exclude-directories=LIST 拒绝的目录 

中文文档名在平常的情况下会被编码, 但是在 –cut-dirs 时又是正常的, 
wget -r -np -nH –cut-dirs=3 ftp://host/test/ 
测试.txt 
wget -r -np -nH -nd ftp://host/test/ 
%B4%FA%B8%D5.txt 
wget “ftp://host/test/*” 
%B4%FA%B8%D5.txt 

由 於不知名的原因,可能是为了避开特殊档名, wget 会自动将抓取档名的部分用 encode_string 处理过, 所以该 patch 就把被 encode_string 处理成 “%3A” 这种东西, 用 decode_string 还原成 “:”,并套用在目录与档案名称的部分,decode_string 是 wget 内建的函式。 

wget -t0 -c -nH -x -np -b -m -P /home/sunny/NOD32view/ http://downloads1.kaspersky-labs.com/bases/ -o wget.log
赞赏一下吧~