xiaobaoqiu Blog

Think More, Code Less

Lscpu命令

最近看到lscpu命令,简单实在。CPU的型号和L1,L2,L3 Cache大小等信息一目了然了。

类似的命令包括lsusb、lsblk命令。

1.lscpu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
xiaobaoqiu@xiaobaoqiu:~/octopress$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                4                //逻辑cpu的个数
On-line CPU(s) list:   0-3
Thread(s) per core:    2
Core(s) per socket:    2
Socket(s):             1
NUMA 节点:         1
厂商 ID:           GenuineIntel
CPU 系列:          6
型号:              58
步进:              9
CPU MHz:             1200.000
BogoMIPS:              5183.37
虚拟化:           VT-x
L1d 缓存:          32K
L1i 缓存:          32K
L2 缓存:           256K
L3 缓存:           3072K
NUMA node0 CPU(s):     0-3

2.lsusb

lsusb命令显示usb设备的情况

1
2
3
4
5
6
7
8
9
xiaobaoqiu@xiaobaoqiu:~/octopress$ lsusb
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 003: ID 046d:c05a Logitech, Inc. M90/M100 Optical Mouse
Bus 003 Device 002: ID 04b3:3025 IBM Corp. NetVista Full Width Keyboard
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

3.lsblk

lsblk命令显示块设备的情况

1
2
3
4
5
6
7
8
9
xiaobaoqiu@xiaobaoqiu:~/octopress$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 111.8G  0 disk 
├─sda1   8:1    0   350M  0 part 
└─sda2   8:2    0 111.5G  0 part 
sdb      8:16   0 465.8G  0 disk 
├─sdb1   8:17   0 299.8G  0 part 
├─sdb2   8:18   0  15.1G  0 part [SWAP]
└─sdb3   8:19   0 150.9G  0 part /

Squid学习

之前在处理图片下载延时比较大问题的时候,OPS说使用Squid这个东东,抽时间看看这个东西。

简而言之,Squid就是一个Web缓存代理服务器。

1.什么是代理服务器

代理服务器是介于浏览器和Web服务器之间的另一台服务器。有了该服务器之后,浏览器发出的信息会先送到代理服务器,由代理服务器来取回网页内容并传送给客户的浏览器。对于企业网络而言,代理服务器可以起到控制网络访问并屏蔽不安全信息,以及网络加速的目的。

2.Squid简介

Squid官方网站 : http://www.squid-cache.org/

Squid 是一个 Web 缓存代理,支持 HTTP, HTTPS, FTP, 以及更多。它通过缓存与重用经常请求的web页面,减少带宽使用同时提升了响应时间,并设置过滤。使用Squid可以通过访问控制特性来灵活的控制用户访问时间、站点等限制。

2.1 原理简介

客户端请求访问 WEB 服务时,DNS 将访问的域名解析为 Squid 代理服务器的 IP 地址,这样客户端的 URL 请求将被发送到代理服务器。如果 Squid代理服务器中缓存了该请求的资源,则将该请求的资源直接返回给客户端,否则代理服务器将向后台的WEB服务器请求资源,然后将请求的应答返回给客户端,同时也将该应答缓存在本地,供下一个请求者使用。

2.2 缓存限制

Squid 代理一般只缓存可缓冲的数据(比如 html 网页和图片等),而一些ASP、JSP 之类的动态程序默认不缓存。它根据从 WEB 服务器返回的 HTTP 头标记来缓冲静态页面。有四个最重要 HTTP 头标记:

Last-Modified: 告诉代理页面什么时间被修改
Expires: 告诉代理页面什么时间应该从缓冲区中删除
Cache-Control: 告诉代理页面是否应该被缓冲
Pragma: 用来包含实现特定的指令,最常用的是 Pragma:no-cache

3.Squid安装

(1).下载 squid,这里下载的是3.4版本 : http://www.squid-cache.org/Versions/v3/3.4/
(2).解压缩
```
xiaobaoqiu@xiaobaoqiu:~/Download$ tar -xzvf squid-3.4.11.tar.gz
```
(3).配置
(待续...)

4.参考

http://www.ibm.com/developerworks/cn/linux/l-cn-squid/

Nc命令

nc(netcat)是网络工具中的瑞士军刀。

1.参数

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
xiaobaoqiu@xiaobaoqiu:~$ nc -h
OpenBSD netcat (Debian patchlevel 1.105-7ubuntu1)
This is nc from the netcat-openbsd package. An alternative nc is available
in the netcat-traditional package.
usage: nc [-46bCDdhjklnrStUuvZz] [-I length] [-i interval] [-O length]
      [-P proxy_username] [-p source_port] [-q seconds] [-s source]
      [-T toskeyword] [-V rtable] [-w timeout] [-X proxy_protocol]
      [-x proxy_address[:port]] [destination] [port]
    Command Summary:
        -4          使用IPv4
        -6          使用IPv6
        -b          允许广播(broadcast)
        -C          每行结尾加上CRLF(回车换行符),即自动换行
        -D          启动debug sock选项
        -d          从stdin解绑(Detach from stdin)
        -h          帮助文档
        -I length   设置TCP接受的buffer长度
        -i secs     设置消息发送及端口扫描时间间隔,单位秒
        -j          Use jumbo frame
        -k          当一个连接结束时,强制nc监听另一个连接。必须和-l一起使用
        -l          监听模式,监听进入进入的连接(inbound connects)
        -n          直接使用IP地址,而不通过域名服务器
        -O length   设置TCP发送的buffer长度
        -P proxyuser    代理权限使用的用户名
        -p port     设置本地主机使用的通信端口
        -q secs     quit after EOF on stdin and delay of secs
        -r          随机指定本地主机使用的通信端口
        -S          Enable the TCP MD5 signature option
        -s addr     设置本地主机送出数据包的IP地址
        -T toskeyword   指定链接的IP服务类型
        -t          Answer TELNET negotiation
        -U          Use UNIX domain socket
        -u          使用UDP传输协议
        -V rtable   指定可选的路由表
        -v          显示指令执行过程
        -w secs     设置连接的超时时间,单位秒
        -X proto    指定代理协议: "4", "5" (SOCKS) or "connect"
        -x addr[:port]  指定代理地址和端口号
        -Z          DCCP mode
        -z          0输入输出模式(只在端口扫描的时候使用)

    注意:参数中端口号可以为单个端口,也可以是端口区间:low-high(闭区间)

2.典型使用case

下面列举了几个典型的使用,更多使用case参见: http://xmodulo.com/useful-netcat-examples-linux.html

2.1.文件传输

在线上机器和本地机器之间传输文件,使用scp的话通常需要多次scp,并且通常需要密码,这是nc命令就显示其强大之处:

文件源端:

1
sudo cat abc.gz | nc -l 192.168.111.222 45678

文件目的端:

1
nc 192.168.111.222 45678 > abc.gz

2.2.端口扫描

测试远端机器的某一个端口是否打开,succeeded表示打开:

1
2
3
4
5
xiaobaoqiu@xiaobaoqiu:~$ nc -v -w 2 192.168.111.222 -z 21-24
Connection to 192.168.111.222 21 port [tcp/ftp] succeeded!
Connection to 192.168.111.222 22 port [tcp/ssh] succeeded!
nc: connect to 192.168.111.222 port 23 (tcp) failed: Connection refused
nc: connect to 192.168.111.222 port 24 (tcp) failed: Connection refused

2.3.简单聊天工具

一端打开:

1
2
3
xiaobaoqiu@xiaobaoqiu:~$ nc -l 1234
hello
yes

另外一端连接,就可以聊天了:

1
2
3
xiaobaoqiu@xiaobaoqiu:~$ nc 192.168.111.222 1234
hello
yes

3.参考

http://xmodulo.com/useful-netcat-examples-linux.html

http://mylinuxbook.com/linux-netcat-command/

Java中MessageDigest计算MD5

最近项目的图片处理的系统出问题比较多,典型的一个问题就是因为计算md5出现的问题。

1.问题

问题的现象很简单,使用这套代码批量切图,会出现一张灵异图片,灵异之处在于,很多人批量切图都会出现这张图片,且这张图片不在他们的原始图片中。

2.原因

最后分析的原因是计算图片md5的代码,使用的是Java自带的MessageDigest,大致使用如下

1
2
3
4
5
6
7
8
9
10
11
12
13
//声明
private static MessageDigest md = null;

//初始化
static {
    md = MessageDigest.getInstance("MD5");
}

//使用
public static byte[] getMD5(byte[] bytes) {
    md.update(bytes);   //-----------------------A
    return md.digest(); //-----------------------B
}

问题的原因就是多线程计算md5的时候getMD5这个函数有问题。

2.1 问题md5

最后定位发现重复出现的md5是

d41d8cd98f00b204e9800998ecf8427e

这是一个特殊的md5,即其是空字符串的md5:

1
MD5("") = d41d8cd98f00b204e9800998ecf8427e

参考: http://zh.wikipedia.org/wiki/MD5

2.1 代码问题

在MessageDigest类的源代码注释有这样一段话:

1
2
3
4
5
6
7
8
9
10
 * <p>A MessageDigest object starts out initialized. The data is
 * processed through it using the {@link #update(byte) update}
 * methods. At any point {@link #reset() reset} can be called
 * to reset the digest. Once all the data to be updated has been
 * updated, one of the {@link #digest() digest} methods should
 * be called to complete the hash computation.
 *
 * <p>The <code>digest</code> method can be called once for a given number
 * of updates. After <code>digest</code> has been called, the MessageDigest
 * object is reset to its initialized state.

上面这段话第二部分的意思是说,digest()这个方法只能被调用一次,一旦调用MessageDigest对象会被重置到初始状态。

根据这个逻辑,getMD5这个函数的代码,多个线程进入这段代码的时候(这里假设两个线程),线程A执行完步骤1,在执行步骤2之前,线程B也执行完步骤1,之后线程B调用了步骤2得到正确的md5,之后线程A再调用步骤2的时候得到的md5就是d41d8cd98f00b204e9800998ecf8427e。

本地验证:

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
    String src = "HelloWorld";

    messageDigest.update(src.getBytes());

    String md5 = bytesToHex(messageDigest.digest());
    System.out.println("md5 = " + md5.toLowerCase());

    String md5Again = bytesToHex(messageDigest.digest());
    System.out.println("md5Again = " + md5Again.toLowerCase());
}

得到的结果:

1
2
md5 = 68e109f0f40ca72a15e05cc22786f8e6
md5Again = d41d8cd98f00b204e9800998ecf8427e

3.解决

3.1 MessageDigest正确用法

MessageDigest类的注释里面其实给出了正确的用法,注意其md.clone()的调用:

1
2
3
4
5
6
7
8
9
10
11
 MessageDigest md = MessageDigest.getInstance("MD5");

 try {
     md.update(toChapter1);
     MessageDigest tc1 = md.clone();
     byte[] toChapter1Digest = tc1.digest();
     md.update(toChapter2);
     ...etc.
 } catch (CloneNotSupportedException cnse) {
     throw new DigestException("couldn't make digest of partial content");
}

3.1 Apache的DigestUtils

Apache的DigestUtils是一个线程安全的类,是对MessageDigest的封装,使用很简单,首先加入依赖:

1
2
3
4
5
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.9</version>
</dependency>

然后就可以使用DigestUtils计算md5:

1
DigestUtils.md5(bytes)

Netstat与ss命令

ss是Socket Statistics的缩写。顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容。但ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比netstat更快速更高效。

当服务器的socket连接数量变得非常大时,无论是使用netstat命令还是直接cat /proc/net/tcp,执行速度都会很慢。这是很ss还是会很快。

ss 和 netstat 效率对比:

1
2
3
4
5
6
7
8
9
xiaobaoqiu@xiaobaoqiu:~/octopress$ time ss
real    0m0.330s
user    0m0.004s
sys 0m0.013s

xiaobaoqiu@xiaobaoqiu:~/octopress$ time netstat -at
real    1m37.135s
user    0m0.143s
sys 0m0.020s

1.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
Usage: ss [ OPTIONS ]
       ss [ OPTIONS ] [ FILTER ]
   -h, --help       帮助
   -V, --version    版本信息
   -n, --numeric    不解析服务名称
   -r, --resolve    解析服务名称
   -a, --all        显示所有套接字(sockets)
   -l, --listening  显示listening状态的套接字(sockets)
   -o, --options    显示计时器(timer)信息
   -e, --extended   显示详细的套接字信息
   -m, --memory     显示套接字的内存使用情况
   -p, --processes  显示使用套接字的进程
   -i, --info       显示TCP内部信息
   -s, --summary    显示套接字使用概况
   -b, --bpf        show bpf filter socket information
   -4, --ipv4       仅显示IPv4的套接字
   -6, --ipv6       仅显示IPv6的套接字
   -0, --packet     显示 PACKET 套接字
   -t, --tcp        仅显示TCP的套接字
   -u, --udp        仅显示UDP的套接字
   -d, --dccp       仅显示DCCP的套接字
   -w, --raw        仅显示RAW的套接字
   -x, --unix       仅显示Unix的套接字(domain sockets)
   -f, --family=FAMILY 显示FAMILY类型的套接字(sockets)
                    FAMILY可选,支持unix,inet,inet6,link,netlink

   -A, --query=QUERY, --socket=QUERY
       QUERY := {all|inet|tcp|udp|raw|unix|packet|netlink}[,QUERY]

   -D, --diag=FILE     将原始TCP套接字(sockets)信息转储到文件
   -F, --filter=FILE   从文件中读取过滤器信息
       FILTER := [ state TCP-STATE ] [ EXPRESSION ]

2.简单使用

2.1 显示TCP连接

1
2
3
4
5
6
7
xiaobaoqiu@xiaobaoqiu:~/octopress$ ss -ta
State      Recv-Q Send-Q                 Local Address:Port                     Peer Address:Port   
LISTEN     0      50                                 *:50955                               *:*       
LISTEN     0      128                        127.0.0.1:11211                               *:*       
LISTEN     0      50                                 *:63342                               *:*       
LISTEN     0      50                                 *:2864                                *:*       
LISTEN     0      5                          127.0.1.1:domain                              *:*    

2.2 显示 Sockets 摘要

1
2
3
4
5
6
7
8
9
10
11
xiaobaoqiu@xiaobaoqiu:~/octopress$ ss -s
Total: 871 (kernel 0)
TCP:   44 (estab 8, closed 13, orphaned 0, synrecv 0, timewait 12/0), ports 0

Transport Total     IP        IPv6
*     0         -         -        
RAW   0         0         0        
UDP   21        16        5        
TCP   31        23        8        
INET      52        39        13       
FRAG      0         0         0

2.3 列出所有打开的网络连接端口

即处于Listening的端口

1
xiaobaoqiu@xiaobaoqiu:~/octopress$ ss -l

2.4 查看进程使用的socket

1
xiaobaoqiu@xiaobaoqiu:~/octopress$ ss -pl

可以根据ss -pl结果进行grep

2.5 匹配远程地址和端口号

1
2
3
xiaobaoqiu@xiaobaoqiu:~/octopress$ ss dst 192.168.138.115

xiaobaoqiu@xiaobaoqiu:~/octopress$ ss dst 192.168.138.115:17582

2.6 匹配本地地址和端口号

1
xiaobaoqiu@xiaobaoqiu:~/hotel/CRM/crm-main$ ss src 192.168.138.115

3.参考