Focus-1


  • 归档

  • 分类

  • 标签

  • 关于

  • 搜索

Add Two Numbers

发表于 2016-03-24

算法:链表 Linked list

题目:Add Two Numbers

url:https://leetcode.com/problems/add-two-numbers/

1
2
3
4
5
6
7
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Example:
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.

分析

  • 百位大数相加

Java解法

方法 定义
链表增加节点
单链表反转 不需要,只是为了练习算法
遍历链表
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
package com.test.demo;

import java.io.IOException;

class ListNode {
int val;
ListNode next;
public ListNode(int x) {this.val = x;}
}

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode retNode = null;
int carryBit = 0;
while(l1 != null || l2!= null) {
int d1 = null==l1 ? 0 : l1.val;
int d2 = null==l2 ? 0 : l2.val;
int d = d1 + d2 + carryBit;
retNode = add(retNode, new ListNode(d%10));
carryBit = d/10;
l1 = null==l1 ? l1 : l1.next;
l2 = null==l2 ? l2 : l2.next;
}
for (int i = carryBit; i>0; i = i/10) {
retNode = add(retNode, new ListNode(i%10));
}
return retNode;
// return reverse(retNode);
}
public ListNode add(ListNode headNode, ListNode node) {
if (null == headNode) {
headNode = node;
} else {
ListNode index = headNode;
while(index.next != null) {index = index.next;}
index.next = node;
}
return headNode;
}
public ListNode reverse(ListNode headNode) {
if(headNode == null) return headNode;
ListNode pre = headNode;
ListNode cur;
ListNode temp;
for(cur = headNode.next; cur!=null; ) {
temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
headNode.next = null;
return pre;
}
}

public class MainClass {
public static int[] stringToIntegerArray(String input) {
input = input.trim();
input = input.substring(1, input.length() - 1);
if (input.length() == 0) {
return new int[0];
}

String[] parts = input.split(",");
int[] output = new int[parts.length];
for(int index = 0; index < parts.length; index++) {
String part = parts[index].trim();
output[index] = Integer.parseInt(part);
}
return output;
}

public static ListNode stringToListNode(String input) {
// Generate array from the input
int[] nodeValues = stringToIntegerArray(input);

// Now convert that list into linked list
ListNode dummyRoot = new ListNode(0);
ListNode ptr = dummyRoot;
for(int item : nodeValues) {
ptr.next = new ListNode(item);
ptr = ptr.next;
}
return dummyRoot.next;
}

public static String listNodeToString(ListNode node) {
if (node == null) {
return "[]";
}

String result = "";
while (node != null) {
result += Integer.toString(node.val) + ", ";
node = node.next;
}
return "[" + result.substring(0, result.length() - 2) + "]";
}

public static void main(String[] args) throws IOException {

ListNode l1 = stringToListNode("[9]");
ListNode l2 = stringToListNode("[1,9,9,9,9,9,9,9,9,9]");

ListNode ret = new Solution().addTwoNumbers(l1, l2);
String out = listNodeToString(ret);

System.out.print(out);
}
}

Python解法

​

Java集合类

发表于 2016-02-15 | 分类于 java , collection


参考:https://www.jianshu.com/p/32420c73941b?t=123



总纲



全貌



Set集合



List列表



Queue队列



Map键值对

Linux dstat 性能检测工具说明

发表于 2016-02-02 | 分类于 linux


dstat 介绍

dstat命令是一个用来替换vmstat、iostat、netstat、nfsstat和ifstat这些命令的工具,是一个全能系统信息统计工具。
安装:yum install -y dstat

dstat使用说明:
直接使用dstat,默认使用的是-cdngy参数,分别显示cpu、disk、net、page、system信息

  • CPU状态: CPU的使用率。显示了用户占比,系统占比、空闲占比、等待占比、硬中断和软中断情况。
  • 磁盘统计: 磁盘的读写,分别显示磁盘的读、写总数。
  • 网络统计: 网络设备发送和接受的数据,分别显示的网络收、发数据总数。
  • 分页统计: 系统的分页活动。分别显示换入(in)和换出(out)。
  • 系统统计: 统计中断(int)和上下文切换(csw)。

dstat 是一个可以取代vmstat,iostat,netstat和ifstat这些命令的多功能产品。dstat克服了这些命令的局限并增加了一些另外的功能,增加了监控项,也变得更灵活了。dstat可以很方便监控系统运行状况并用于基准测试和排除故障。

dstat可以让你实时地看到所有系统资源,例如,你能够通过统计IDE控制器当前状态来比较磁盘利用率,或者直接通过网络带宽数值来比较磁盘的吞吐率(在相同的时间间隔内)。

dstat将以列表的形式为你提供选项信息并清晰地告诉你是在何种幅度和单位显示输出。这样更好地避免了信息混乱和误报。更重要的是,它可以让你更容易编写插件来收集你想要的数据信息,以从未有过的方式进行扩展。

dstat的默认输出是专门为人们实时查看而设计的,不过你也可以将详细信息通过CSV输出到一个文件,并导入到Gnumeric或者Excel生成表格中。


常见选项

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
-c, --cpu:开启cpu统计
-C:该选项跟cpu的编号(0~cpu核数-1,多个用都好隔开)如:0,3,total表示分别包含cpu0、cpu3和total
-d, --disk:开启disk统计
-D:改选跟具体的设备名(多个用逗号隔开)如:total,hda,hdb表示分别统计total、hda、hdb设备块
-g, --page:开启分页统计
-i, --int:开启中断统计
-I 5,10:没弄懂呢~巴拉巴拉
-l, --load:开启负载均衡统计,分别是1m,5m,15m
-m, --mem:开启内存统计,包括used,buffers,cache,free
-n, --net:开启net统计,包括接受和发送
-N:该选项可以跟网络设备名多个用逗号隔开,如eth1,total
-p, --proc:开启进程统计,包括runnable, uninterruptible, new
-r, --io:io开启请求统计,包括read requests, write requests
-s, --swap:开启swap统计,包括used, free
-S:该选项可以跟具体的交换区,多个用逗号隔开如swap1,total
-t, --time:启用时间和日期输出
-T, --epoch:启用时间计数,从epoch到现在的秒数
-y, --sys:开启系统统计,包括中断和上下文切换
--aio:开启同步IO统计 (asynchronous I/O)
--fs:开启文件系统统计,包括 (open files, inodes)
--ipc:开启ipc统计,包括 (message queue, semaphores, shared memory)
--lock:开启文件所统计,包括 (posix, flock, read, write)
--raw:开启raw统计 (raw sockets)
--socket:开启sockets统计,包括 (total, tcp, udp, raw, ip-fragments)
--tcp:开启tcp统计,包括(listen, established, syn, time_wait, close)
--udp:开启udp统计 (listen, active)
--unix:开启unix统计(datagram, stream, listen, active)
--vm:开启vm统计 (hard pagefaults, soft pagefaults, allocated, free)
--stat:通过插件名称开启插件扩展,详见命令插件 :可能的内置插件为aio, cpu, cpu24, disk, disk24, disk24old, epoch, fs, int, int24, io, ipc, load, lock, mem, net, page, page24, proc, raw, socket, swap, swapold, sys, tcp, time,udp, unix, vm
--list:列举内置插件扩展的名称
-a, --all:是默认值相当于 -cdngy (default)
-f, --full:相当于 -C, -D, -I, -N and -S
-v, --vmstat:相当于 -pmgdsc -D total
-bw, --blackonwhite:在白色背景终端上改变显示颜色
--float:在屏幕上的输出强制显示为浮点值(即带小数)(相反的选项设置为 --integer)
--integer:在屏幕上的输出强制显示为整数值,此为默认值(相反的选项设置为--float)
--nocolor:禁用颜色(意味着选项 --noupdate)
--noheaders:禁止重复输出header,默认会打印一屏幕输出一次header
--noupdate:当delay>1时禁止在过程中更新(即在时间间隔内不允许更新)
--output file:可以把状态信息以csv的格式重定向到指定的文件中,以便日后查看

命令参数

参数名称 参数描述
delay 两次输出之间的时间间隔,默认是1s
count 报告输出的次数,默认是没有限制,一直输出知道ctrl+c

命令插件

虽然anyone可以自由的为dstat编写插件,但dstat附带大量的插件已经大大扩展其功能,下面是dstat附带插件的一个概述

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
-battery:电池电池百分比(需要ACPI)
-battery-remain:电池剩余小时、分钟(需要ACPI)
-cpufreq:CPU频率百分比(需要ACPI)
-dbus:dbus连接的数量(需要python-dbus)
-disk-util:显示某一时间磁盘的忙碌状况
-fan:风扇转速(需要ACPI)
-freespace:每个文件系统的磁盘使用情况
-gpfs:gpfs读/写 I/O(需要mmpmon)
-gpfs-ops:GPFS文件系统操作(需要mmpmon)
-helloworld:dstat插件Hello world示例
-innodb-buffer:显示innodb缓冲区统计
-innodb-io:显示innodb I/O统计数据
-innodb-ops:显示innodb操作计数器
-lustre:显示lustreI/O吞吐量
-memcache-hits:显示memcache 的命中和未命中的数量
-mysql5-cmds:显示MySQL5命令统计
-mysql5-conn:显示MySQL5连接统计
-mysql5-io:MySQL5 I/O统计数据
-mysql5-keys:显示MySQL5关键字统计
-mysql-io:显示MySQL I/O统计数据
-mysql-keys:显示MySQL关键字统计
-net-packets:显示接收和发送的数据包的数量
-nfs3:显示NFS v3客户端操作
-nfs3-ops:显示扩展NFS v3客户端操作
-nfsd3:显示NFS v3服务器操作
-nfsd3-ops:显示扩展NFS v3服务器操作
-ntp:显示NTP服务器的ntp时间
-postfix:显示后缀队列大小(需要后缀)
-power:显示电源使用量
-proc-count:显示处理器的总数
-rpc:显示rpc客户端调用统计
-rpcd:显示RPC服务器调用统计
-sendmail:显示sendmail队列大小(需要sendmail)
-snooze:显示每秒运算次数
-test:显示插件输出
-thermal:热系统的温度传感器
-top-bio:显示消耗块I/O最大的进程
-top-cpu:显示消耗CPU最大的进程
-top-cputime:显示使用CPU时间最大的进程(单位ms)
-top-cputime-avg:显示使用CPU时间平均最大的进程(单位ms)
-top-io:显示消耗I/O最大进程
-top-latency:显示总延迟最大的进程(单位ms)
-top-latency-avg:显示平均延时最大的进程(单位ms)
-top-mem:显示使用内存最大的进程
-top-oom:显示第一个被OOM结束的进程
-utmp:显示utmp连接的数量(需要python-utmp)
-vmk-hba:显示VMware ESX内核vmhba统计数
-vmk-int:显示VMware ESX内核中断数据
-vmk-nic:显示VMware ESX内核端口统计
-vz-io:显示每个OpenVZ请求CPU使用率
-vz-ubc:显示OpenVZ用户统计
-wifi:无线连接质量和信号噪声比

常用插件

1
2
3
4
5
6
7
--disk-util:显示某一时间磁盘的忙碌状况
--freespace:显示当前磁盘空间使用率
--proc-count:显示正在运行的程序数量
--top-bio:显示块I/O最大的进程
--top-cpu:显示CPU占用最大的进程
--top-io:显示正常I/O最大的进程
--top-mem:显示占用最多内存的进程

例如:监控磁盘

dstat -d –disk-util –disk-tps

-d 分别显示磁盘的读、写总数
–disk-tps #每秒每个磁盘事务(tps)统计
–disk-util #磁盘利用率百分比

dstat -v
-v, –vmstat:相当于 -pmgdsc -D total

linux strace命令详解_未完

发表于 2016-02-02 | 分类于 linux


strace 简介

跟踪系统调用和信号

1
2
3
4
5
6
7
NAME
strace - trace system calls and signals

SYNOPSIS
strace [-CdffhikqrtttTvVxxy] [-In] [-bexecve] [-eexpr]... [-acolumn] [-ofile] [-sstrsize] [-Ppath]... -ppid... / [-D] [-Evar[=val]]... [-uusername] command [args]

strace -c[df] [-In] [-bexecve] [-eexpr]... [-Ooverhead] [-Ssortby] -ppid... / [-D] [-Evar[=val]]... [-uusername] command [args]

安装strace

centos7 安装:yum install strace -y

跟踪特定进程

strace -ppid

使用 strace -p32557

https://segmentfault.com/a/1190000005931147

strace & ltrace & phpstrace

strace

strace是Linux环境下的一款程序调试工具,用来监察一个应用程序所使用的系统调用及它所接收的系统信息。追踪程序运行时的整个生命周期,输出每一个系统调用的名字,参数,返回值和执行消耗的时间等。

常用参数:

-p 跟踪指定的进程
-f 跟踪由fork子进程系统调用
-F 尝试跟踪vfork子进程系统调吸入,与-f同时出现时, vfork不被跟踪
-o filename 默认strace将结果输出到stdout。通过-o可以将输出写入到filename文件中
-ff 常与-o选项一起使用,不同进程(子进程)产生的系统调用输出到filename.PID文件
-r 打印每一个系统调用的相对时间
-t 在输出中的每一行前加上时间信息。 -tt 时间确定到微秒级。还可以使用-ttt打印相对时间
-v 输出所有系统调用。默认情况下,一些频繁调用的系统调用不会输出
-s 指定每一行输出字符串的长度,默认是32。文件名一直全部输出
-c 统计每种系统调用所执行的时间,调用次数,出错次数。
-e expr 输出过滤器,通过表达式,可以过滤出掉你不想要输出

这里特别说下strace的-e trace选项。

要跟踪某个具体的系统调用,-e trace=xxx即可。但有时候我们要跟踪一类系统调用,比如所有和文件名有关的调用、所有和内存分配有关的调用。

如果人工输入每一个具体的系统调用名称,可能容易遗漏。于是strace提供了几类常用的系统调用组合名字。

-e trace=file 跟踪和文件访问相关的调用(参数中有文件名)
-e trace=process 和进程管理相关的调用,比如fork/exec/exit_group
-e trace=network 和网络通信相关的调用,比如socket/sendto/connect
-e trace=signal 信号发送和处理相关,比如kill/sigaction
-e trace=desc 和文件描述符相关,比如write/read/select/epoll等
-e trace=ipc 进程见同学相关,比如shmget等

绝大多数情况,我们使用上面的组合名字就够了。实在需要跟踪具体的系统调用时,可能需要注意C库实现的差异。

比如我们知道创建进程使用的是fork系统调用,但在glibc里面,fork的调用实际上映射到了更底层的clone系统调用。使用strace时,得指定-e trace=clone, 指定-e trace=fork什么也匹配不上。

当发现进程或服务异常时,我们可以通过strace来跟踪其系统调用,“看看它在干啥”,进而找到异常的原因。熟悉常用系统调用,能够更好地理解和使用strace。

当然,万能的strace也不是真正的万能。当目标进程卡死在用户态时,strace就没有输出了。

这个时候我们需要其他的跟踪手段,比如gdb/perf/SystemTap等。

备注:

1、perf原因kernel支持

2、ftrace kernel支持可编程

3、systemtap 功能强大,RedHat系统支持,对用户态,内核态逻辑都能探查,使用范围更广

追踪多个进程方法

当有多个子进程的情况下,比如php-fpm、nginx等,用strace追踪显得很不方便。可以使用下面的方法来追踪所有的子进程。

1
2
3
4
5
6
7
8
# vim /root/.bashrc //添加以下内容
function straceall {
strace $(pidof "${1}" | sed 's/\([0-9]*\)/-p \1/g')
}
# source /root/.bashrc
# traceall php-fpm //监控phpfpm
OR
# strace -tt -T $(pidof 'php-fpm: pool www' | sed 's/\([0-9]*\)/\-p \1/g')

追踪web服务

1
2
# strace -f -F -s 1024 -o nginx-strace /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
# strace -f -F -o php-fpm-strace /usr/local/php/sbin/php-fpm -y /usr/local/php/etc/php-fpm.conf

追踪mysql

1
2
# strace -f -F -ff -o mysqld-strace -s 1024 -p mysql_pid
# find ./ -name "mysqld-strace*" -type f -print |xargs grep -n "SELECT.*FROM"

查看程序做了什么

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
# This script is from http://poormansprofiler.org/
nsamples=1
sleeptime=0
pid=$(pidof $1)

for x in $(seq 1 $nsamples)
do
gdb -ex "set pagination 0" -ex "thread apply all bt" -batch -p $pid
sleep $sleeptime
done | \
awk '
BEGIN { s = ""; }
/^Thread/ { print s; s = ""; }
/^\#/ { if (s != "" ) { s = s "," $4} else { s = $4 } }
END { print s }' | \
sort | uniq -c | sort -r -n -k 1,1

ltrace

-a 对齐具体某个列的返回值
-c 计算时间和调用,并在程序退出时打印摘要
-C 解码低级别名称(内核级)为用户级名称
-d 打印调试信息
-e 改变跟踪的事件
-f 跟踪子进
-h 打印帮助信息
-i 打印指令指针,当库调用时。
-l 只打印某个库中的调用。
-L 不打印库调用。
-n, –indent=NR 对每个调用级别嵌套以NR个空格进行缩进输出。
-o, –output=file 把输出定向到文件。
-p PID 附着在值为PID的进程号上进行ltrace。
-r 打印相对时间戳。
-s STRLEN 设置打印的字符串最大长度。
-S 显示系统调用。
-t, -tt, -ttt 打印绝对时间戳。
-T 输出每个调用过程的时间开销。
-u USERNAME 使用某个用户id或组ID来运行命令。
-V, –version 打印版本信息,然后退出。
-x NAME treat the global NAME like a library subroutine.

phpstrace

phpstrace追踪php进程

1
2
3
4
5
Usage: ./php-strace [ options ]
-h|--help show this help
-l|--lines <integer> output the last N lines of a stacktrace. Default: 100
--process-name <string> name of running php processes. Default: autodetect
--live search while running for new upcoming pid's

使用truss/strace/ltrace跟踪进程

linux vmstat命令详解

发表于 2016-02-01 | 分类于 linux

一、前言

​ 很显然,从名字我们就可以知道 vmstat 是一个查看虚拟内存(Virtual Memory)使用状况的工具,但是怎样通过vmstat 来发现系统中的瓶颈呢?在回答这个问题前,还是让我们回顾一下Linux中关于虚拟内存的相关内容。


二、虚拟内存

​ 在系统中运行的每个进程都需要使用到内存,但不是每个进程都需要每时每刻使用系统分配的内存空间。当系统运行所需内存超过实际的物理内存,内核会释放某些进程所占用但未使用的部分或所有物理内存,将这部分资料存储在磁盘上直到下一次调用,将释放出的内存提供给有需要的进程使用。

​ 在Linux内存管理中,主要通过”调页Paging“和”交换Swapping“来完成内存调度。调页算法是将内存中最近不常使用的页面换到磁盘上,把活动页面保留在内存中供进程使用。交换技术是将整个进程,而不是部分页面,全部交换到磁盘上。

​ 分页(Page)写入磁盘的过程被称为Page-Out,分页(Page)从磁盘重新回到内存的过程叫Page-In。当内核需要一个分页时,但发现此分页不再物理内存中(因为已经被Page-Out了),此时就发生了分页错误(Page-Fault)。

​ 当系统内核发现可运行内存变少时,会通过Page-Out来释放一部分物理内存。尽管Page-Out不是经常发生,但是如果Page-Out频繁不断的发生,直到当内核管理分页的时间超过运行程式的时间时,熊效能会急剧下降。这时系统已经运行非常慢或进入暂停状态,这种状态被称为 thrashing(颠簸)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1、page fault出现的原因:
a). 页表中找不到对应虚拟地址的PTE(无效地址/有效地址但是没有载入主存);
b). 对应虚拟地址的PTE拒绝访问。

2、page fault在哪里进行处理
page fault被CPU捕获,跳转到 page_fault_handler 进行处理。

3、page fault的处理方式
page fault -> 访问地址是否合法
a. 无效地址:segment fault,返回(用户地址杀死进程、内核地址杀死内核)
b. 有效地址:
1) page第一次被访问: demand_page_faults (demanding pages,请求调页)
检查页表中是否存在该PTE    pmd_none, pte_none
分配新的页帧,初始化(从磁盘读入内存)
2) page被交换到swap分区
检查present标志位,如果该位为0表示不在主存中。
分配新的页帧,从磁盘重新读入内存。
3) COW(Copy-On-Write)
vm_area_struct允许写,但是对应的PTE禁止写操作。

4、如何判断访问地址是否合法?如果地址合法有什么操作?
判断地址合法的方式:
static int __do_page_fault()函数 vma = find_vma(mm, addr);
根据传入的地址addr查找对应的vm_area_struct,如果没有找到证明该地址访问无效,返回segment fault。

三、vmstat详解

1、用法

1
2
3
4
5
6
7
vmstat [-a] [-n] [-S unit] [delay [ count]]
vmstat [-s] [-n] [-S unit]
vmstat [-m] [-n] [delay [ count]]
vmstat [-d] [-n] [delay [ count]]
vmstat [-p disk partition] [-n] [delay [ count]]
vmstat [-f]
vmstat [-V]

-a:显示活跃和非活跃内存
-f:显示从系统启动至今的fork数量 。
-m:显示slabinfo
-n:只在开始时显示一次各字段名称。
-s:显示内存相关统计信息及多种系统活动数量。
delay:刷新时间间隔。如果不指定,只显示一条结果。
count:刷新次数。如果不指定刷新次数,但指定了刷新时间间隔,这时刷新次数为无穷。
-d:显示磁盘相关统计信息。
-p:显示指定磁盘分区统计信息
-S:使用指定单位显示。参数有 k 、K 、m 、M ,分别代表1000、1024、1000000、1048576字节(byte)。默认单位为K(1024 bytes)
-V:显示vmstat版本信息。


2、使用说明

vmstat 5 5 【在5秒时间内进行5次采样】

1
vmstat 5 5

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
procs(进程):
r: 运行队列中进程数量,这个值也可以判断是否需要增加CPU。(长期大于1)
b: 等待IO的进程数量

memory(内存):
swpd: 使用虚拟内存大小。注意:如果swpd的值不为0,但是si,so的值长期为0,这种情况不会影响系统性能。
free: 空闲物理内存大小
buff: 用作缓冲的内存大小
cache: 用作缓存的内存大小。注意:如果cache的值大的时候,说明cache处的文件数多,如果频繁访问到的文件都能被cache处,那么磁盘的读IO bi会非常小。
inact: 非活跃内存大小(当使用-a选项时显示)
active: 活跃的内存大小(当使用-a选项时显示)

swap:
si: 每秒从交换区写到内存的大小,由磁盘调入内存
so: 每秒写入交换区的内存大小,由内存调入磁盘
注意:内存够用的时候,这2个值都是0,如果这2个值长期大于0时,系统性能会受到影响,磁盘IO和CPU资源都会被消耗。有些朋友看到空闲内存(free)很少的或接近于0时,就认为内存不够用了,不能光看这一点,还要结合si和so,如果free很少,但是si和so也很少(大多时候是0),那么不用担心,系统性能这时不会受到影响的。

io:(现在的Linux版本块的大小为1024bytes)
bi: 每秒读取的块数
bo: 每秒写入的块数

system:
in: 每秒中断数,包括时钟中断。【interrupt】
cs: 每秒上下文切换数。【count/second】
注意:随机磁盘读写的时候,这2个值越大(如超出1024k),能看到CPU在IO等待的值也会越大。

cpu(以百分比表示):
us: 用户进程执行时间(user time)。注意: us的值比较高时,说明用户进程消耗的CPU时间多,但是如果长期超50%的使用,那么我们就该考虑优化程序算法或者进行加速。
sy: 系统进程执行时间(system time)。注意:sy的值高时,说明系统内核消耗的CPU资源多,这并不是良性表现,我们应该检查原因。
id: 空闲时间(包括IO等待时间),中央处理器的空闲时间 。
wa: 等待IO时间。注意:wa的值高时,说明IO等待比较严重,这可能由于磁盘大量作随机访问造成,也有可能磁盘出现瓶颈(块操作)。

vmstat -a 2 5 【-a 显示活跃和非活跃内存,所显示的内容除增加inact和active 】

vmstat -f 【 linux下创建进程的系统调用是fork】


四、总结

目前说来,对于服务器监控有用处的度量主要有:

  • r(运行队列)
  • pi(页导入)
  • us(用户CPU)
  • sy(系统CPU)
  • id(空闲)

注意:如果r经常大于4 ,且id经常少于40,表示cpu的负荷很重。如果bi,bo 长期不等于0,表示内存不足。

通过VMSTAT识别CPU瓶颈:
r(运行队列)展示了正在执行和等待CPU资源的任务个数。当这个值超过了CPU数目,就会出现CPU瓶颈了。

Linux下查看CPU核心数的命令:
cat /proc/cpuinfo|grep processor|wc -l

当r值超过了CPU个数,就会出现CPU瓶颈,解决办法大体几种:

  1. 最简单的就是增加CPU个数和核数
  2. 通过调整任务执行时间,如大任务放到系统不繁忙的情况下进行执行,进尔平衡系统任务
  3. 调整已有任务的优先级

通过vmstat识别CPU满负荷:
首先需要声明一点的是,vmstat中CPU的度量是百分比的。当us+sy的值接近100的时候,表示CPU正在接近满负荷工作。但要注意的是,CPU 满负荷工作并不能说明什么,Linux总是试图要CPU尽可能的繁忙,使得任务的吞吐量最大化。唯一能够确定CPU瓶颈的还是r(运行队列)的值。

通过vmstat识别RAM瓶颈:

数据库服务器都只有有限的RAM,出现内存争用现象是Oracle的常见问题。

首先用free查看RAM的数量:
[oracle@oracle-db02 ~]$ free
total used free shared buffers cached
Mem: 2074924 2071112 3812 0 40616 1598656
-/+ buffers/cache: 431840 1643084
Swap: 3068404 195804 2872600

当内存的需求大于RAM的数量,服务器启动了虚拟内存机制,通过虚拟内存,可以将RAM段移到SWAP DISK的特殊磁盘段上,这样会 出现虚拟内存的页导出和页导入现象,页导出并不能说明RAM瓶颈,虚拟内存系统经常会对内存段进行页导出,但页导入操作就表明了服务器需要更多的内存了, 页导入需要从SWAP DISK上将内存段复制回RAM,导致服务器速度变慢。

解决的办法有几种:

  1. 最简单的,加大RAM;
  2. 改小SGA,使得对RAM需求减少;
  3. 减少RAM的需求。(如:减少PGA)

如果disk经常不等于0,且在b中的队列大于3,表示io性能不好。

  1. 如果在processes中运行的序列(process r)是连续的大于在系统中的CPU的个数表示系统现在运行比较慢,有多数的进程等待CPU。
  2. 如果r的输出数大于系统中可用CPU个数的4倍的话,则系统面临着CPU短缺的问题,或者是CPU的速率过低,系统中有多数的进程在等待CPU,造成系统中进程运行过慢。
  3. 如果空闲时间(cpu id)持续为0并且系统时间(cpu sy)是用户时间的两倍(cpu us)系统则面临着CPU资源的短缺。

解决办法:
当发生以上问题的时候请先调整应用程序对CPU的占用情况.使得应用程序能够更有效的使用CPU.同时可以考虑增加更多的CPU. 关于CPU的使用情况还可以结合mpstat, ps aux top prstat –a等等一些相应的命令来综合考虑关于具体的CPU的使用情况,和那些进程在占用大量的CPU时间.一般情况下,应用程序的问题会比较大一些.比如一些sql语句不合理等等都会造成这样的现象.

内存问题现象:
内存的瓶颈是由scan rate (sr)来决定的.scan rate是通过每秒的始终算法来进行页扫描的.如果scan rate(sr)连续的大于每秒200页则表示可能存在内存缺陷.同样的如果page项中的pi和po这两栏表示每秒页面的调入的页数和每秒调出的页数.如果该值经常为非零值,也有可能存在内存的瓶颈,当然,如果个别的时候不为0的话,属于正常的页面调度这个是虚拟内存的主要原理.

解决办法:

  1. 调节applications & servers使得对内存和cache的使用更加有效.
  2. 增加系统的内存.
  3. Implement priority paging in s in pre solaris 8 versions by adding line “set priority paging=1” in /etc/system. Remove this line if upgrading from Solaris 7 to 8 & retaining old /etc/system file.

关于内存的使用情况还可以结ps aux top prstat –a等等一些相应的命令来综合考虑关于具体的内存的使用情况,和那些进程在占用大量的内存.一般情况下,如果内存的占用率比较高,但是,CPU的占用很低的时候,可以考虑是有很多的应用程序占用了内存没有释放,但是,并没有占用CPU时间,可以考虑应用程序,对于未占用CPU时间和一些后台的程序,释放内存的占用。


Nginx+keepalived双机热备(主从模式)

发表于 2016-02-01 | 分类于 nginx


参考:https://blog.csdn.net/l1028386804/article/details/80098334

Nginx+keepalived双机热备(主从模式)

发表于 2016-02-01 | 分类于 nginx


参考:https://blog.csdn.net/l1028386804/article/details/80098334

nginx 转发 tcp/udp

发表于 2016-02-01 | 分类于 nginx


参考:https://blog.csdn.net/l1028386804/article/details/80098334

Nginx四层负载均衡

nginx 永久跳转(301) 和 临时重定向(302)

发表于 2016-01-14 | 分类于 nginx


科普

301永久跳转:当用户或搜索引擎向网站服务器发出浏览请求时,服务器返回的HTTP数据流中头信息中的状态码的一种,表示本网页永久性转移到另一个地址。

302临时跳转:也是状态码的一种,意义是暂时转向到另外一个网址。

主要区别

一句话,302容易被搜索引擎视为spam,301则不会。

conf设置

301跳转设置

1
2
3
4
5
6
server {
listen 80;
server_name 123.com;
rewrite ^/(.*) http://456.com/$1 permanent;
access_log off;
}

302跳转设置

1
2
3
4
5
6
server {
listen 80;
server_name 123.com;
rewrite ^/(.*) http://456.com/$1 redirect;
access_log off;
}

研究

Nginx的重定向用到了Nginx的HttpRewriteModule

rewrite命令

nginx的rewrite相当于apache的rewriterule(大多数情况下可以把原有apache的rewrite规则加上引号就可以直接使用),它可以用在server,location 和IF条件判断块中

rewrite 正则表达式 替换目标 flag标记,flag标记可以用以下几种格式:

  • last – 基本上都用这个Flag。
  • break – 中止Rewirte,不在继续匹配
  • redirect – 返回临时重定向的HTTP状态302
  • permanent – 返回永久重定向的HTTP状态301

特别注意:

last和break用来实现URL重写,浏览器地址栏的URL地址不变,但是在服务器端访问的路径发生了变化;

redirect和permanent用来实现URL跳转,浏览器地址栏会显示跳转后的URL地址;

例如下面这段设定nginx将某个目录下面的文件重定向到另一个目录,$2对应第二个括号(.*)中对应的字符串:

1
2
3
location /download/ {
rewrite ^(/download/.*)/m/(.*)\..*1 /nginx-rewrite/$2.gz break;
}

例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下:

1
2
if (httpuseragent MSIE)
rewrite (.∗)$ /nginx−ie/$1 break;

文件和目录判断:

  • −f和!−f判断是否存在文件
  • −d和!−d判断是否存在目录
  • −e和!−e判断是否存在文件或目录
  • −x和!−x判断文件是否可执行

例如下面设定nginx在文件和目录不存在的时候重定向:

1
2
3
4
if(!−e request_filename) {
proxy_pass http://127.0.0.1;
}
return

nginx防盗链

返回http代码,例如设置nginx防盗链:

1
2
3
4
5
6
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked www.test.com www.test1.com;
if ($invalid_referer) {
return 404;
}
}

nginx 动静分离配置

发表于 2016-01-14 | 分类于 nginx


正则表达式

1
2
3
4
5
6
7
8
~ 或 ^:  表示 正则表达式的开始
. : 匹配除 \n 之外 的 一个任意字符
( :子表达式的开始
) :子表达式的结束
| :表示 在两个 或者 多个之间进行的选择
\ :转义字符
$ 或 ^ :表示 表达式的结尾
* :0个或多个匹配前面的 正则表达式
1…22232425

Focus-1

250 日志
63 分类
102 标签
Links
  • repository - https://gitee.com/carloz
© 2015 — 2020 Focus-1
Hosted by Gitee Repo