高性能负载均衡器HAProxy

快速安装(ubuntu 14.04默认安装的v1.4版本):

apt-get install haproxy

源码安装:

wget http://www.haproxy.org/download/1.7/src/haproxy-1.7.6.tar.gz
tar -zxvf haproxy-1.7.6.tar.gz
cd haproxy-1.7.6
make TARGET=linux2628 CPU=x86_64 PREFIX=/usr/local/haprpxy
make install PREFIX=/usr/local/haproxy

启动:

/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg

配置文件:

单端口同时代理ssh和websocket:

cat /etc/haproxy/haproxy.cfg

defaults  
    timeout connect 5s  
    timeout client 50s  
    timeout server 20s  
listen http  
    bind :80
    timeout client 1h  
    tcp-request inspect-delay 5s  
    acl is_http req.payload(0,3) -m bin 474554 504f53 505554 44454c   # 包含请求头 GET POS PUT DEL
    tcp-request content accept if is_http
    use_backend websocket if is_http
    default_backend ssh
backend websocket
    mode http
    server sock :8080
    timeout server 2h
    stats refresh 30s           #统计页面自动刷新时间  
    stats uri /stats            #统计页面url  
    stats realm Haproxy Manager #统计页面密码框上提示文本  
    stats auth admin:admin      #统计页面用户名和密码设置  
    stats hide-version          #隐藏统计页面上HAProxy的版本信息
backend ssh  
    mode tcp  
    server server-ssh :22
    timeout server 1h

请求头16进制抓取

nc -l -p 8080|hexdump -C

官网:http://www.haproxy.org/

文档:https://cbonte.github.io/haproxy-dconv/

Shell语法

shell条件判断

1.文件判断:

[ -a FILE ]  如果 FILE 存在则为真。  
[ -b FILE ]  如果 FILE 存在且是一个块特殊文件则为真。  
[ -c FILE ]  如果 FILE 存在且是一个字特殊文件则为真。  
[ -d FILE ]  如果 FILE 存在且是一个目录则为真。  
[ -e FILE ]  如果 FILE 存在则为真。  
[ -f FILE ]  如果 FILE 存在且是一个普通文件则为真。  
[ -g FILE ]  如果 FILE 存在且已经设置了SGID则为真。 [ -h FILE ]  如果 FILE 存在且是一个符号连接则为真。  
[ -k FILE ]  如果 FILE 存在且已经设置了粘制位则为真。  
[ -p FILE ]  如果 FILE 存在且是一个名字管道(F如果O)则为真。  
[ -r FILE ]  如果 FILE 存在且是可读的则为真。  
[ -s FILE ]  如果 FILE 存在且大小不为0则为真。  
[ -t FD ]    如果文件描述符 FD 打开且指向一个终端则为真。  
[ -u FILE ]  如果 FILE 存在且设置了SUID (set user ID)则为真。  
[ -w FILE ]  如果 FILE 如果 FILE 存在且是可写的则为真。  
[ -x FILE ]  如果 FILE 存在且是可执行的则为真。  
[ -O FILE ]  如果 FILE 存在且属有效用户ID则为真。  
[ -G FILE ]  如果 FILE 存在且属有效用户组则为真。  
[ -L FILE ]  如果 FILE 存在且是一个符号连接则为真。  
[ -N FILE ]  如果 FILE 存在 and has been mod如果ied since it was last read则为真。  
[ -S FILE ]  如果 FILE 存在且是一个套接字则为真。  
[ FILE1 -nt FILE2 ]  如果 FILE1 has been changed more recently than FILE2, or 如果 FILE1 exists and FILE2 does not则为真。  
[ FILE1 -ot FILE2 ]  如果 FILE1 比 FILE2 要老, 或者 FILE2 存在且 FILE1 不存在则为真。  
[ FILE1 -ef FILE2 ]  如果 FILE1 和 FILE2 指向相同的设备和节点号则为真。  
[ -o OPTIONNAME ]    如果 shell选项 OPTIONNAME 开启则为真。  
[ -z STRING ]        STRING 的长度为零则为真。  
[ -n STRING ] or [ STRING ]    STRING 的长度为非零 non-zero则为真。  
[ STRING1 == STRING2 ]    如果2个字符串相同。 = may be used instead of == for strict POSIX compliance则为真。  
[ STRING1 != STRING2 ]    如果字符串不相等则为真。 
[ STRING1 < STRING2 ]     如果 “STRING1” sorts before “STRING2” lexicographically in the current locale则为真。  
[ STRING1 > STRING2 ]     如果 “STRING1” sorts after “STRING2” lexicographically in the current locale则为真。  
[ ARG1 OP ARG2 ]    OP is one of -eq, -ne, -lt, -le, -gt or -ge. These arithmetic binary operators return true if ARG1 is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to ARG2, respectively. ARG1 and ARG2 are integers.

2.字符串判断

[ str1 = str2 ]   当两个串有相同内容、长度时为真 
[ str1 != str2 ]  当串str1和str2不等时为真 
[ -n str1 ]       当串的长度大于0时为真(串非空) 
[ -z str1 ]       当串的长度为0时为真(空串) 
[ str1 ]          当串str1为非空时为真

2.1.字符串根据关键字切割

${VAR#*xxx}      从左往右→  截取xxx第一次出现以后的内容
${VAR##*xxx}     从左往右→  截取xxx最后出现以后的内容

${VAR%xxx*}      从右往左←  截取xxx第一次出现之前的内容
${VAR%%xxx*}     从右往左←  截取xxx最后出现之前的内容

2.2.字符串根据索引切割

${VAR:0:7}       其中的 0 表示左边第一个字符开始,7 表示字符的个数
${VAR:0-3:2}     其中的 0-3 表示右往左第3个字符开始,2表示字符的个数

3.数字的判断

[ int1 -eq int2 ]    两数相等为真 
[ int1 -ne int2 ]    两数不等为真 
[ int1 -gt int2 ]    int1大于int2为真 
[ int1 -ge int2 ]    int1大于等于int2为真 
[ int1 -lt int2 ]    int1小于int2为真 
[ int1 -le int2 ]    int1小于等于int2为真

4.逻辑判断

-a         与 
-o        或 
!        非

特殊变量

$#      是传给脚本的参数个数
$0      是脚本本身的名字
$1      是传递给该shell脚本的第一个参数
$2      是传递给该shell脚本的第二个参数
$@      是传给脚本的所有参数的列表
$*      是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
$$      是脚本运行的当前进程ID号,即PID
$?      是显示最后命令的退出状态,0表示没有错误,其他表示有错误
$PPID   是当前脚本的PPID

循环

1.while循环

#!/bin/bash
a=0
while [ $a -lt 10 ]
do
   echo $a
   a=`expr $a + 1`
done

1.1.while死循环

#!/bin/bash
while true
do
    echo 'hello'
done

2.for循环

#!/bin/bash
for var in 0 1 2 3 4 5 6 7 8 9
do
   echo $var
done

2.1.for遍历文件

#!/bin/bash
for FILE in $HOME/.bash*
do
   echo $FILE
done

3.list遍历

#!/bin/bash
list=("baidu.com" "google.com" "malu.me" "max mia")
list[${#list[@]}]="ssh"  # 追加
echo ${#list[@]}         # 输出数组长度
for i in "${list[@]}"
do
    echo "hello $i 100"
done
echo ${list[2]}          # 输出指定元素

select和case用法

#!/bin/bash
select DRINK in tea cofee water juice appe all none
do
    case $DRINK in
        tea|cofee|water|all)
            echo "Go to canteen"
            ;;
        juice|appe)
            echo "Available at home"
            ;;
        none)
            break
            ;;
        *)
            echo "ERROR: Invalid selection"
            ;;
    esac
done

注释

多行注释

#!/bin/bash
<< EOF
这里是注释 1
这里是注释 2
这里是注释 3
这里是注释 4
EOF

单行注释

#!/bin/bash
# 这里是注释

Windows终端模拟器Cygwin

Cygwin是一个在windows平台上运行的类UNIX模拟环境

官网:https://cygwin.com/

安装:

下载地址: https://cygwin.com/setup-x86.exe

使用国内源:

http://mirrors.163.com/cygwin/
或
http://mirrors.sohu.com/cygwin/

安装apt-cyg

apt-cyg是Cygwin环境下的软件安装工具,相当于Ubuntu下的apt-get命令

依赖的工具:wget、tar、gawk、bzip2

这些工具可以使用Cygwin安装setup-x86.exe选择安装

下载地址:https://github.com/transcode-open/apt-cyg

安装:

wget rawgit.com/transcode-open/apt-cyg/master/apt-cyg
install apt-cyg /bin

apt-cyg的使用

设置安装源

apt-cyg -m http://mirrors.163.com/cygwin

更新源

apt-cyg update

安装软件:

apt-cyg install vim

Cygwin安装pip

依赖工具:python环境、libuuid-devel和binutils

下载地址:https://bootstrap.pypa.io/get-pip.py

安装:

python get-pip.py

部署PHPSocket.IO记录

Github地址:https://github.com/walkor/phpsocket.io

方法一:

下载代码后使用composer安装依赖:

> composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing workerman/workerman (v3.3.7)
    Downloading: 100%

  - Installing workerman/channel (v1.0.3)
    Downloading: 100%

workerman/workerman suggests installing ext-event (For better performance.)
Writing lock file
Generating autoload files

方法二:

编辑项目composer.json文件,添加:

"require": {
    "workerman/workerman" : ">=3.1.8",
    "workerman/channel" : ">=1.0.0",
    "workerman/phpsocket.io" : ">=1.1.1"
}

然后更新composer:

> composer update

注:国内用户建议修改composer源:

打开命令行窗口(windows用户)或控制台(Linux、Mac 用户)并执行如下命令:

composer config -g repo.packagist composer https://packagist.phpcomposer.com

一个非常简单的聊天服务端示例

<?php
require_once __DIR__ . '/vendor/autoload.php';
use PHPSocketIO\SocketIO;

// listen port 2021 for socket.io client
$io = new SocketIO(2021);
$io->on('connection', function($socket)use($io){
  $socket->on('chat message', function($msg)use($io){
    $io->emit('chat message from server', $msg);
  });
});

客户端

<script src='//cdn.bootcss.com/socket.io/1.3.7/socket.io.js'></script>
<script>
// 连接服务端
var socket = io('http://127.0.0.1:2021');
// 触发服务端的chat message事件
socket.emit('chat message', '这个是消息内容...');
// 服务端通过emit('chat message from server', $msg)触发客户端的chat message from server事件
socket.on('chat message from server', function(msg){
	console.log('get message:' + msg + ' from server');
});
</script>

运行

Start

php server.php start for debug mode

php server.php start -d for daemon mode

Stop

php server.php stop

Status

php server.php status

ERROR:

运行时报错:PHP Fatal error: Call to undefined function Workerman\Lib\pcntl_signal() in …

解决办法:

由于walkman依赖PHP的pcntl多进程扩展,所以需要先安装该扩展:

# 进入PHP源码包扩展目录,如果不存在则去官网下载,下载对应版本提取出来 http://php.net/releases/
cd /data/soft/php/php-5.6.3/ext/pcntl
/usr/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make
make install

# 增加pcntl.so 到 php.ini文件中
vim /usr/local/php/etc/php.ini
extension = pcntl.so

# 重启php-fpm
/etc/init.d/php-fpm restart

另外一种安装的方法
centos
1、命令行运行yum install php-cli php-process git php-devel php-pear libevent-devel
2、命令行运行pecl install channel://pecl.php.net/libevent-0.1.0
3、命令行运行echo extension=libevent.so > /etc/php.d/libevent.ini

debian/ubuntu
1、命令行运行apt-get update && apt-get install php5-cli git php-pear php5-dev libevent-dev
2、命令行运行pecl install channel://pecl.php.net/libevent-0.1.0
3、命令行运行echo extension=libevent.so > /etc/php5/cli/conf.d/libevent.ini

验证model加载情况:

> php -m |grep pcntl
pcntl

客户端IE9以下无法发送中文问题

解决办法:

发送时对消息使用encodeURIComponent编码,接收端使用decodeURIComponent解码

本地与线上调试通讯,在IE9以下无法收发

因为在跨域的时候,IE9以下优先用的不是jsonp,而是xhr-polling(XDomainRequest),因为XDomainRequest跨域请求localhost会拒绝访问

常用脚本

记录日常使用到的脚本

监控脚本持续运行,看门狗(每次只有一个脚本在执行)

使用方法:把文件命名cron.sh,放入crontab: */1 * * * * /app/cron.sh ws.py

#!/bin/bash
# 监测$1一直运行
MY_PATH=$(cd "$(dirname "$0")"; pwd)
cd $MY_PATH

function run_only_one(){
        snum=`ps -ef|grep $1|grep -v grep|grep -v $0|wc -l`
        if [ $snum -lt 1 ]; then
            echo "start process $1..."
        else
            echo "$1 runing....."
            exit
        fi
}
run_only_one $1

screen -dmS cron_$1 ./$1
screen -S cron_$1 -p 0 -X stuff 'exit\n'

防止脚本重复执行(每次只有一个脚本在执行)

#!/bin/bash
function run_only_one(){
        PID=$$
        snum=`ps -ef|grep $0|grep -v grep|grep -v " $PPID "|grep -v " $PID "|wc -l`
        if [ $snum -lt 1 ]; then
            echo "start process....."
        else
            echo "runing....."
            exit
        fi  
}
run_only_one

把桌面mp4,m4a文件到mp3

C:\auto_run\bin\mp4tomp3.sh

#!/bin/bash
# 转换桌面的mp4,m4a文件到mp3
cd ~/Desktop
# 不要用空格做为IFS,用于遍历文件名存在空格的情况
IFS=$(echo -en "\n\b")
function conversion_to_mp3(){
   files=$(ls *.$1 2> /dev/null | wc -l)
   if [ "$files" != "0" ] ; then
      myarr=($(ls *.$1))
      for i in "${myarr[@]}"
      do
         NAME=`basename $i .$1`
         echo "****************ffmpeg $NAME******************"
         ffmpeg -i $i -f mp3 $NAME.mp3
      done
   else
      echo "路径:"`pwd`
      echo "不存在$1"
   fi
}
conversion_to_mp3 mp4
conversion_to_mp3 m4a

从视频网站URL剪贴板直接下载MP4到桌面

C:\auto_run\bin\vurldown.ps1

$a = Get-Clipboard 
Write-Output $a
lux $a

.ps1,因为在此系统上禁止运行脚本解决方案

管理员打开PowerShell

执行:

# 默认Scope是LocalMachine
Set-ExecutionPolicy RemoteSigned
Set-ExecutionPolicy RemoteSigned -Scope Process
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
# 啰嗦写法:Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Confirm:$False

查看权限情况:

Get-ExecutionPolicy -List

C:\auto_run\bin\vurldown.sh

#!/bin/bash
cd ~/Desktop
powershell C:/auto_run/bin/vurldown.ps1

并行拉取远程仓库

C:\auto_run\bin\UPALL.sh

#!/bin/bash
list=(
    "C:/01_cloud/github/pingmalu"
)

svnlist=(
    "C:/01_cloud/SAE/pingmalu"
)

for i in "${list[@]}"; do
    echo "****************git -C $i pull******************"
    start bash -c "echo -en \"\033]0;git -C $i pull\a\";git -C $i pull"
done

for i in "${svnlist[@]}"; do
    echo "****************svn up $i******************"
    start bash -c "echo -en \"\033]0;svn up $i\a\";svn up $i"
done

同时推送到所有远程git分支上

C:\auto_run\bin\pushall

#!/bin/bash
myarr=($(git remote -v |grep "push"|awk '{print $1}'|grep -v "origin"))
for i in "${myarr[@]}"
do
   echo "****************git push $i******************"
   start bash -c "echo -en \"\033]0;git push $i\a\";git push $i"
done

指定终端的title

如何更改 xterm 的标题:https://tldp.org/HOWTO/Xterm-Title-3.html

printf '\e]0;%s\e\\' "My title here"

系统 Proxy切换开关

cat proxy

#!/bin/bash
CLASH='http://192.168.50.1:50003'
if [[ $1 == "off" ]];then
    unset ALL_PROXY
    unset HTTP_PROXY
    unset HTTPS_PROXY
else
    export ALL_PROXY=$CLASH
    export HTTP_PROXY=$CLASH
    export HTTPS_PROXY=$CLASH
fi

放入/usr/local/bin/proxy

source proxy      #开启代理
source proxy off  #关闭代理

Git Proxy切换开关

bash_aliases写法:

alias px='git config --global --replace-all http.proxy http://192.168.50.1:50003'
alias nopx='git config --global --unset http.proxy'

cat git-proxy

#!/bin/bash
if [[ $1 == "no" ]];then
    git config --global --unset https.proxy
else
    git config --global https.proxy socks5://192.168.2.2:10808
fi

放入/usr/local/bin/git-proxy

git-proxy     #开启代理
git-proxy no  #关闭代理

本地hosts模拟实现DNS轮询脚本

cat auto_change_hosts.sh

#!/bin/bash
MY_PATH=$(cd "$(dirname "$0")"; pwd)
cd $MY_PATH

F='iplist'
F2=`cat ${F}|grep -A 1 '|1|'`
F3=`echo $F2|grep '|0|'`
if [[ $F3 == '' ]];then
	# 到最后一行的话取第一行
	F4=`head $F -n 1`
else
	F2=`echo $F3|awk '{print $1}'`
	F4=`echo $F3|awk '{print $2}'`
fi
IPOLD=`echo $F2|awk -F '|' '{print $1}'`
NUMOLD=`echo $F2|awk -F '|' '{print $3}'`
IPNEW=`echo $F4|awk -F '|' '{print $1}'`
NUMNEW=`echo $F4|awk -F '|' '{print $3}'`
if [[ $1 == 'error' ]];then
	NUMOLD=$[NUMOLD+1]
fi
sed -i "s/${IPOLD}.*/${IPOLD}\|0\|${NUMOLD}/;s/${IPNEW}.*/${IPNEW}\|1\|${NUMNEW}/" $F
cp -f /etc/hosts ~/hosts.new
sed -i "s/^[0-9].* malu\.me/$IPNEW malu\.me/" ~/hosts.new
cp -f ~/hosts.new /etc/hosts
cat /etc/hosts|grep 'malu.me'

cat iplist

11.5.100.200|1|0
11.5.100.201|0|0
11.5.200.202|0|0
11.5.200.203|0|0
11.5.300.204|0|0

cat /etc/hosts

11.5.100.200 malu.me

使用方法:

auto_change_hosts.sh [error]

如果加参数error,则iplist最后一列数值会累加,用于调用次数统计。

创建低权限用户脚本

首先添加用户boy并修改sshd_config文件

useradd boy
passwd boy

如果遇到无法找到/bin/sh的提示,则修改/etc/passwd文件中boy的shell

把 /bin/sh 改成 /bin/bash

vim /etc/ssh/sshd_config

Match User boy
ChrootDirectory /home/test

cat create_low_user.sh

#!/bin/bash
CHROOT_PATH='/home/test'
mkdir -p ${CHROOT_PATH}/dev/      
cd ${CHROOT_PATH}/dev/
mknod -m 666 null c 1 3
mknod -m 666 tty c 5 0
mknod -m 666 zero c 1 5
mknod -m 666 random c 1 8

chown root:root ${CHROOT_PATH}
chmod 0755 ${CHROOT_PATH}
ls -ld ${CHROOT_PATH}

mkdir -p ${CHROOT_PATH}/bin
cp -v /bin/bash ${CHROOT_PATH}/bin/

ldd /bin/bash
mkdir -p ${CHROOT_PATH}/lib64
cp -v /lib64/ld-linux-x86-64.so.2 ${CHROOT_PATH}/lib64/
mkdir -p ${CHROOT_PATH}/lib/x86_64-linux-gnu/
cp -v /lib/x86_64-linux-gnu/{libtinfo.so.5,libdl.so.2,libc.so.6} ${CHROOT_PATH}/lib/x86_64-linux-gnu/

mkdir ${CHROOT_PATH}/etc
cp -vf /etc/{passwd,group} ${CHROOT_PATH}/etc/

把本地文件夹备份至远程服务器

1.通过scp拷贝目录

#!/bin/bash
dd=`date '+%Y-%m-%d-%H%M%S'`
scp -i /root/.ssh/id_rsa -P 22 -r /local root@malu.me:/backup/${dd}

2.拷贝目录至windows共享 (如果有防火墙,需允许445, 135, 137, 138, 139 UDP和TCP)

#!/bin/bash
dd=`date '+%Y-%m-%d-%H%M%S'`
smbclient -c "mkdir ${dd};prompt OFF;recurse ON;lcd /local;cd ${dd};mput *" //IP/share -U username%password

切换到当前目录执行脚本

#!/bin/bash
MY_PATH=$(cd "$(dirname "$0")"; pwd)
cd $MY_PATH

scp拷贝最近3天日期命名的tar.z文件,并删除本地6天前的tar.z文件

#!/bin/bash
for((i=0;i<=3;i++)); do
	datefile=`date -d"$i day ago" +%Y%m%d`.tar.z
	if [ ! -f "$datefile" ]; then
		scp malu.me:/backup/$datefile /home/backup/
	fi
done
find ./ -mtime +6 -type f -name "*.tar.z"|xargs rm -f

防止脚本重复执行(每次只有一个脚本在执行)

#!/bin/bash
function run_only_one(){
        PID=$$
        snum=`ps -ef|grep $0|grep -v grep|grep -v " $PPID "|grep -v " $PID "|wc -l`
        if [ $snum -lt 1 ]; then
            echo "start process....."
        else
            echo "runing....."
            exit
        fi  
}
run_only_one

合并指定目录下的所有文本,并去除重复行,并过滤^M字符 (生成超级字典)

#!/bin/bash
if [ $# != 1 ] ; then 
echo "USAGE: $0 FLODER" 
exit 1;  
fi
root_dir=$1
NEWFILE=newfile_dic.txt
NEWFILE_TMP=newfile_dic.txt.tmp
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
function getdir(){
    for element in `ls $1`
    do  
        dir_or_file=$1"/"$element
        if [ -d $dir_or_file ]
        then 
            getdir $dir_or_file
        else
            echo -n $dir_or_file
            cat $dir_or_file |sed 's/^M//g'>> $NEWFILE_TMP
            echo '              ok'
        fi  
    done
}
getdir $root_dir
IFS=$SAVEIFS
sort $NEWFILE_TMP|uniq > $NEWFILE
rm -f $NEWFILE_TMP

注意:^M的输入方式是 Ctrl + v ,然后Ctrl + m

杀死进程及其所有子进程

pstree -p PID | grep -oP '(?<=\()[0-9]+(?=\))'|xargs kill -9

杀死包含关键字的进程,及其所有子进程

#!/bin/bash
PID=`ps -ef|grep [n]ame|awk '{print $2}'`
expr 1 + $PID > /dev/null 2>&1
if [[ $? -eq 0 ]]; then
	pstree -p $PID | grep -oP '(?<=\()[0-9]+(?=\))'|xargs kill -9
fi

将目录下所有文件名改成小写

for i in `find ./`;do mv $i `echo $i |tr [A-Z] [a-z]`;done

防御CC攻击脚本

#!/bin/sh
status=`netstat -na|awk '$5 ~ /[0-9]+:[0-9]+/ {print $5}' |awk -F ":" -- '{print $1}' |sort -n|uniq -c |sort -n|tail -n 1`
NUM=`echo $status|awk '{print $1}'`
IP=`echo $status|awk '{print $2}'`
result=`echo "$NUM > 150" | bc`
if [ $result = 1 ]
then
  echo IP:$IP is over $NUM, BAN IT!
  /sbin/iptables -I INPUT -s $IP -j DROP
fi

向进程发送按键指令

其实用C写的,算不上脚本。需要先编译:

gcc key.c -o key.bin

运行:

./key.bin PID cmd

#include <sys/ioctl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

void stackchar(int fd,char c)
{
        if (ioctl(fd, TIOCSTI, &c) < 0) {
                perror("ioctl");
                exit(1);
        }
}

int main(int argc, char *argv[])
{
        int i, j;
        char c;
        char proc_file[20];
        int mixer_fd=0;

        strcpy(proc_file,"/proc/");
        strcat(proc_file,argv[1]);
        strcat(proc_file,"/fd/1");

        if ((mixer_fd = open(proc_file,O_WRONLY))){
                for (i = 2; i < argc; i++) {
                        if (i > 1) stackchar(mixer_fd,' ');
                        for (j=0; (c = argv[i][j]); j++) {
                                stackchar(mixer_fd,c);
                        }
                }
        }

        stackchar(mixer_fd,'\n');
        exit(0);
}

向本地监听的所有匹配端口发送curl请求

netstat -lnt4p|grep sshd|grep -v ':22 '|awk -F '0.0.0.0:' '{print $2}'|awk '{print $1}'|xargs -t -i curl localhost:{}

rsync同步工具

Rsync可以同步目录和文件。还可以通过远程shell如rsh和ssh同步。

rsync的主要好处是:

速度:最初会在本地和远程之间拷贝所有内容。下次,只会传输发生改变的块或者字节。

安全:传输可以通过ssh协议加密数据。

低带宽:rsync可以在两端压缩和解压数据块。

目前的linux发行版本,大部分都默认安装了。

示例: 1 - 启用压缩

rsync -zvr /home/malu/ /backuphomedir

示例: 2 - 保留文件和文件夹的属性

rsync -azvr /home/malu/ /backuphomedir

示例: 3 - 远程同步到本地

rsync -rtvzp -e 'ssh -p2227'  --include '*.tar.gz' --exclude '*' root@c1.malu.me:/Projects/md5/ /backup/web

上面表示只同步远程的*.tar.gz后缀的文件


下面介绍参数作用,转自:http://roclinux.cn/?p=2643

[不带任何选项]

我们经常这样使用rsync:

$ rsync main.c machineB:/home/userB

1 只要目的端的文件内容和源端不一样,就会触发数据同步,rsync会确保两边的文件内容一样。

2 但rsync不会同步文件的“modify time”,凡是有数据同步的文件,目的端的文件的“modify time”总是会被修改为最新时刻的时间。

3 rsync不会太关注目的端文件的rwx权限,如果目的端没有此文件,那么权限会保持与源端一致;如果目的端有此文件,则权限不会随着源端变更。

4 只要rsync有对源文件的读权限,且对目标路径有写权限,rsync就能确保目的端文件同步到和源端一致。

5 rsync只能以登陆目的端的账号来创建文件,它没有能力保持目的端文件的输主和属组和源端一致。(除非你使用root权限,才有资格要求属主一致、属组一致)

[-t选项]

我们经常这样使用-t选项:

$ rsync -t main.c machineB:/home/userB

1 使用-t选项后,rsync总会想着一件事,那就是将源文件的“modify time”同步到目标机器。

2 带有-t选项的rsync,会变得更聪明些,它会在同步前先对比两边文件的时间戳和文件大小,如果一致,则就认为两边文件一样,对此文件就不再采取更新动作了。

3 因为rsync的聪明,也会反被聪明误。如果目的端的文件的时间戳、大小和源端完全一致,但是内容恰巧不一致时,rsync是发现不了的。这就是传说中的“坑”!

4 对于rsync自作聪明的情况,解决办法就是使用-I选项。

[-I选项]

我们经常这样使用-I选项:

$ rsync -I main.c machineB:/home/userB

1 -I选项会让rsync变得很乖很老实,它会挨个文件去发起数据同步。

2 -I选项可以确保数据的一致性,代价便是速度上会变慢,因为我们放弃了“quick check”策略。(quick check策略,就是先查看文件的时间戳和文件大小,依次先排除一批认为相同的文件)

3 无论情况如何,目的端的文件的modify time总会被更新到当前时刻。

[-v选项]

这个选项,简单易懂,就是让rsync输出更多的信息,我们可以举一个例子:

$ rsync -vI main.c machineB:/home/userB                                                   
main.c

sent 81 bytes  received 42 bytes  246.00 bytes/sec
total size is 11  speedup is 0.09

你增加越多的v,就可以获得越多的日志信息。

$ rsync -vvvvt abc.c machineB:/home/userB 
cmd= machine=machineB user= path=/home/userB
cmd[0]=ssh cmd[1]=machineB cmd[2]=rsync cmd[3]=--server cmd[4]=-vvvvte. cmd[5]=. cmd[6]=/home/userB 
opening connection using: ssh machineB rsync --server -vvvvte. . /home/userB 
note: iconv_open("ANSI_X3.4-1968", "ANSI_X3.4-1968") succeeded.
(Client) Protocol versions: remote=28, negotiated=28
(Server) Protocol versions: remote=30, negotiated=28
[sender] make_file(abc.c,*,2)
[sender] flist start=0, used=1, low=0, high=0
[sender] i=0  abc.c mode=0100664 len=11 flags=0
send_file_list done
file list sent
send_files starting
server_recv(2) starting pid=31885
recv_file_name(abc.c)
received 1 names
[receiver] i=0   abc.c mode=0100664 len=11
recv_file_list done
get_local_name count=1 /home/userB
recv_files(1) starting
generator starting pid=31885 count=1
delta transmission enabled
recv_generator(abc.c,0)
abc.c is uptodate
generate_files phase=1
send_files phase=1
recv_files phase=1
generate_files phase=2
send files finished
total: matches=0  hash_hits=0  false_alarms=0 data=0
generate_files finished
recv_files finished
client_run waiting on 14318

sent 36 bytes  received 16 bytes  104.00 bytes/sec
total size is 11  speedup is 0.21
_exit_cleanup(code=0, file=main.c, line=1031): entered
_exit_cleanup(code=0, file=main.c, line=1031): about to call exit(0)

[-z选项]

这是个压缩选项,只要使用了这个选项,rsync就会把发向对端的数据先进行压缩再传输。对于网络环境较差的情况下建议使用。

一般情况下,-z的压缩算法会和gzip的一样。

[-r选项]

我们在第一次使用rsync时,往往会遇到这样的囧境:

$ rsync superman machineB:/home/userB
skipping directory superman

如果你不额外告诉rsync你需要它帮你同步文件夹的话,它是不会主动承担的,这也正是rsync的懒惰之处。

所以,如果你真的想同步文件夹,那就要加上-r选项,即recursive(递归的、循环的),像这样:

$  rsync -r superman machineB:/home/userB

我们在上面的讲解中说过,如果时间戳和文件大小完全一致,只有文件内容不同,且你没有使用-I选项的话,那么,rsync是不会进行数据同步的。

那么,提个问题:“因为在Linux的世界里,文件夹也是文件,如果这类文件(文件夹)也只有内容不同,而时间戳和文件大小都相同,rsync会发现么?”

实验大家可以自己动手做,结论在这里告诉大家:

对于文件夹,rsync是会明察秋毫的,只要你加了-r选项,它就会恪尽职守的进入到文件夹里去检查,而不会只对文件夹本身做“quick check”的。

[-l选项]

如果我们要同步一个软链接文件,你猜rsync会提示什么?

$ ll
total 128
-rw-rw-r--  1 userA userA 11 Dec 26 07:00 abc.c
lrwxrwxrwx  1 userA userA  5 Dec 26 11:35 softlink -> abc.c
$ rsync softlink machineB:/home/userB
skipping non-regular file "softlink"

嗯,你猜对了,rsync又无情地拒绝了我们。它一旦发现某个文件是软链接,就会无视它,除非我们增加-l选项。

$ rsync -l softlink machineB:/home/userB

使用了-l选项后,rsync会完全保持软链接文件类型,原原本本的将软链接文件复制到目的端,而不会“follow link”到指向的实体文件。

如果我偏偏就想让rsync采取follow link的方式,那就用-L选项就可以了。你可以自己试试效果。

[-p选项]

这个选项的全名是“perserve permissions”,顾名思义,就是保持权限。

如果你不使用此选项的话,rsync是这样来处理权限问题的:

1 如果目的端没有此文件,那么在同步后会将目的端文件的权限保持与源端一致;

2 如果目的端已存在此文件,那么只会同步文件内容,权限保持原有不变。

如果你使用了-p选项,则无论如何,rsync都会让目的端保持与源端的权限一致的。

[-g选项和-o选项]

这两个选项是一对,用来保持文件的属组(group)和属主(owner),作用应该很清晰明了。不过要注意的一点是,改变属主和属组,往往只有管理员权限才可以。

[-D选项]

-D选项,原文解释是“preserve devices(root only)”,从字面意思看,就是保持设备文件的原始信息。由于博主没有实际体验过它的好处,所以没有太多发言权。

[-a选项]

1 -a选项是rsync里比较霸道的一个选项,因为你使用-a选项,就相当于使用了-rlptgoD这一坨选项。以一敌七,唯-a选项也。(在看了前文之后,你应该可以很轻松的理解这七个选项的作用了)

2 -a选项的学名应该叫做archive option,中文叫做归档选项。使用-a选项,就表明你希望采取递归方式来同步,且尽可能的保持各个方面的一致性。

3 但是-a选项也有阿克琉斯之踵,那就是-a无法同步“硬链接”情况。如果有这方面需求,要加上-H选项。

[–delete选项、–delete-excluded选项和–delete-after选项]

三个选项都是和“删除”有关的:

1 –delete:如果源端没有此文件,那么目的端也别想拥有,删除之。(如果你使用这个选项,就必须搭配-r选项一起)

2 –delete-excluded:专门指定一些要在目的端删除的文件。

3 –delete-after:默认情况下,rsync是先清理目的端的文件再开始数据同步;如果使用此选项,则rsync会先进行数据同步,都完成后再删除那些需要清理的文件。

看到这么多delete,你是否有点肝颤? 的确,在rsync的官方说明里也有这么一句话:

This option can be dangerous if used incorrectly!
It is a very good idea to run first using the dry run option (-n) to see what files would be deleted to make sure important files aren’t listed.

从这句话里,我们学到了一个小技巧,那就是-n选项,它是一个吓唬人的选项,它会用受影响的文件列表来警告你,但不会真的去删除,这就让我们有了确认的机会和回旋的余地。我们看看实际用法吧:

$ rsync -n --delete -r . machineB:/home/userB/
deleting superman/xxx
deleting main.c
deleting acclink

[–exclude选项和–exclude-from选项]

如果你不希望同步一些东西到目的端的话,可以使用–exclude选项来隐藏,rsync还是很重视大家隐私的,你可以多次使用–exclude选项来设置很多的“隐私”。

如果你要隐藏的隐私太多的话,在命令行选项中设置会比较麻烦,rsync还是很体贴,它提供了–exclude-from选项,让你可以把隐私一一列在一个文件里,然后让rsync直接读取这个文件就好了。

[–partial选项]

这就是传说中的断点续传功能。默认情况下,rsync会删除那些传输中断的文件,然后重新传输。但在一些特别情况下,我们不希望重传,而是续传。

我们在使用中,经常会看到有人会使用-P选项,这个选项其实是为了偷懒而设计的。以前人们总是要手动写–partial –progress,觉得太费劲了,倒不如用一个新的选项来代替,于是-P应运而生了。有些读者会问–partial我知道作用了,可–progress是干什么用的呢?为什么很多人要使用它呢,它有那么大的吸引力?(真有…)

[–progress选项]

使用这个选项,rsync会显示出传输进度信息,有什么用呢,rsync给了一个很有意思的解释:

This gives a bored user something to watch.

rinetd端口转发工具

使用iptables 很容易将TCP 和UDP 端口从防火墙转发到内部主机上。但是如果需要将流量从专用地址转发到甚至不在您当前网络上的机器上,可尝试另一个应用层端口转发程序,如rinetd。这些代码有点古老,但很短小、高效,对于解决这种问题来说是非常完美的。

官网:https://boutell.com/rinetd/

快速安装:

apt-get install rinetd

配置文件:

# cat /etc/rinetd.conf
allow 192.168.1.*                 //设置允许访问的ip地址信息,不写允许所有
0.0.0.0 80 192.168.0.2 8080       //设置端口转发
logfile /var/log/rinetd.log       //设置打印的log,不写不记录日志

启动:

rinetd

指定配置文件启动:

rinetd -c /etc/rinetd.conf

前台启动(不放入后台启动):

rinetd -f

查看启动状态:

# netstat -lntp|grep [r]inetd
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1469/rinetd

关闭:

killall rinetd

在Windows下通过netsh命令实现端口映射

在Windows环境下,可以通过netsh命令实现简单快速的配置端口映射功能

  1. 新增端口映射

    netsh interface portproxy add v4tov4 listenport=1234 connectaddress=192.168.0.1 connectport=5678

  2. 查看端口映射

    netsh interface portproxy show all

  3. 删除端口映射

    netsh interface portproxy delete v4tov4 listenport=1234

xdotool自动化工具笔记

xdotool可以在linux终端下模拟键盘和鼠标操作

官网:http://www.semicomplete.com/projects/xdotool/

安装:

 apt-get install xdotool

使用方法:

模拟击键a [*注1]

xdotool key a

模拟按两个键alt+tab

xdotool key alt+Tab

自动输入word

xdotool type 'word'

自动输入word带回车

xdotool type "word
"

模拟鼠标移动+点击,这会让鼠标移动到(x,y),然后点击鼠标左键。“1”代表鼠标左键,“2”则是滚轮,“3”则是右键。

xdotool mousemove 655 320 click 1

获取窗口名称

$ xdotool search "Chrome"
Defaulting to search window name, class, and classname
37748741
$ xdotool getwindowname 37748741
马路的个人网站_MaLu.me - Google Chrome

在打开的窗口中搜索对应名称的窗口,并聚焦于该窗口,然后模拟击键。

#!/bin/bash
export DISPLAY=:1
/opt/google/chrome/chrome --user-data-dir --display=:1 &
#/opt/google/chrome/chrome --user-data-dir --app=http://s.malu.me/ --start-maximized --enable-low-end-device-mode --disable-translate --display=:1 &
WID=`xdotool search --name "Chrome" | head -1`
xdotool windowfocus $WID
xdotool key ctrl+49
sleep 1
xdotool type 'malu.me'
xdotool key 65

export DISPLAY=:1 用于设置X11默认显示通道,在打开浏览器中会用到

[*注1]: xdotool key ctrl+l 这种别名不再工作。应该使用在xev的输出中找到的值,来替换l。

比如键入l输出:

KeyPress event, serial 40, synthetic NO, window 0x2000001,
    root 0x25, subw 0x0, time 180522539, (110,120), root:(661,427),
    state 0x0, keycode 49 (keysym 0x6c, l), same_screen YES,
    XLookupString gives 1 bytes: (6c) "l"
    XmbLookupString gives 1 bytes: (6c) "l"
    XFilterEvent returns: False

那应该用49替换字母l

chrome常用命令行参数介绍:

1. --incognito,设置浏览器直接从隐身模式启动功能,您在隐身模式中浏览网页不会保留浏览器记录、Cookie存储库或搜索记录,会保留下载的文件和已存的书签。
2. --start-maximized,启动时自动最大化窗口。
3. --lang=en_US,设置语言为英语_美国(这里可以写各种语言代码),快速切换显示语言,而免去在设置中点击数次并重启的麻烦。
4. --user-agent="thatis my user agent"(如果字符串不含空格则无需引号),设置伪造的用户代理字符串,可以验证网站对于不同浏览器采取的不同的行为。
5. --user-data-dir=/userdata,设置自定义用户数据位置,对于系统盘空间较小,希望把用户数据(包含缓存)放在其他位置的用户非常有用。
6. --disable-images,设置为禁止图像,对于流量有限制,或者其他不想看图的人群非常有用。
7. --no-sandbox,不使用沙箱,在和某些杀毒软件有冲突时,可以关闭沙箱。
8. --trusted-plugins,仅使用信任的插件。
9. --restore-last-session,启动时恢复最近的会话。

Chrome命令行参数之基础类:

1. --debug-on-start,如果程序包含基础/调试/debug_on_start_win.h,(仅限于Windows),该过程将​​自启动JIT系统注册的调试器,并会等待60秒钟,让调试器连接到自身并打一个断点。
2. --disable-breakpad,禁用崩溃报告。
3. --wait-for-debugger,在60秒之内,等待一个调试器接入Chrome。
4.--test-child-process,当运行特定的派生子进程的测试,此开关会告诉测试框架,当前进程是一个子进程。
5.--enable-crash-reporter,表示崩溃报告应该启用。由辅助进程不能访问到所需文件的平台作出这个决定,此标志由内部产生。
6.--enable-crash-reporter-for-testing,用于在调试环境中打开Breakpad(一个非常实用的跨平台的崩溃转储和分析模块)崩溃报告,崩溃报告在那里通常会被编译,但被禁用了。
7.--full-memory-crash-report,生成全部内存崩溃报告。
8.--enable-low-end-device-mode,改写低端设备检测,启用低端设备的优化。
9.--disable-low-end-device-mode,改写低端设备检测,禁止低端设备的优化。

Chrome其它收集命命令行参数:

disable-accelerated-compositing    禁用加速
disable-winsta    禁用渲染备用窗口
disable-application-cache    禁用应用程序缓存
disable-apps  禁用应用程序
disable-audio    禁用音频
disable-auth-negotiate-cname-lookup
disable-background-networking  禁用后台联网
disable-backing-store-limit    禁用存储数量限制,可以防止在打开大量的标签窗口时,页面出现闪烁的现象。
disable-byte-range-support    禁用缓存的支持字节范围
disable-click-to-play    禁用点击播放
disable-connect-backup-jobs    如果超过指定的时间,则禁用建立备份的TCP连接
disable-content-prefetch    禁用内容预取
disable-custom-jumplist    禁用Windows 7的JumpList自定义功能
disable-databases    禁用HTML5的数据库支持
disable-desktop-notifications    禁用桌面通知(默认窗口启用)
disable-dev-tools    禁用所有页面的渲染检测
disable-device-orientation    禁用设备向导
disable-webgl    禁用WebGL实验功能
disable-extensions    禁用扩展
disable-extensions-file-access-check    禁用扩展文件访问检查
disable-geolocation    禁用地理位置的JavaScript API
disable-glsl-translator    禁用GLSL翻译
disable-hang-monitor    禁止任务管理器监视功能
disable-internal-flash    禁用内部的Flash Player
disable-ipv6    禁用IPv6
disable-preconnect    禁用TCP/IP协议
disable-javascript    禁用JS
disable-java    禁用Java
disable-local-storage     禁用本地存储
disable-logging    禁用调试记录
disable-new-tab-first-run  禁用新标签显示的通知
disable-outdated-plugins    禁用过时的插件
disable-plugins    禁止插件
disable-popup-blocking    禁用阻止弹出窗口
disable-prompt-on-repost
disable-remote-fonts    禁用远程字体
disable-renderer-accessibility    禁用渲染辅助功能
disable-restore-background-contents    当浏览器重新启动后之前的网址被记录
disable-session-storage    禁用会话存储
disable-shared-workers    禁用共享,功能尚未完成
disable-site-specific-quirks    禁用指定站点设置的WebKit兼容性问题。
disable-speech-input    禁用语音输入
disable-ssl-false-start    禁用SSL的虚假启动
disable-sync    禁用同步
disable-sync-apps    禁用同步应用程序
disable-sync-autofill    禁用同步自动填表
disable-sync-bookmarks    禁用同步书签
disable-sync-extensions    禁用同步扩展
disable-sync-passwords    禁用同步密码
disable-sync-preferences    禁用同步偏好设置
disable-sync-sessions    禁用同步会话
disable-sync-themes    禁用同步主题(皮肤)
disable-sync-typed-urls    禁用同步输入网址
disable-tab-closeable-state-watcher    
disable-translate    禁用翻译
disable-web-resources    禁用网络资源后台加载服务
disable-web-security    禁用网络安全提示?
disable-web-sockets    禁用网络接口
safebrowsing-disable-auto-update  禁用自动升级(安全浏览)
disable-tls    禁用设置XMPP协议的客户端同步控制
disable-flash-core-animation    禁用Flash核心动画
disable-hole-punching    禁用Punching
disable-seccomp-sandbox    禁用沙盒
no-sandbox      启动无沙盒模式运行

Redis压力测试说明

redis-benchmark是redis自带的压力测试工具:

使用方法:

可以使用redis-benchmark –help来显示使用方法:

序号 选项 描述 默认值
1 -h 指定服务器主机名 127.0.0.1
2 -p 指定服务器端口 6379
3 -s 指定服务器 socket  
4 -c 指定并发连接数 50
5 -n 指定请求数 10000
6 -d 以字节的形式指定 SET/GET 值的数据大小 2
7 -k 1=keep alive 0=reconnect 1
8 -r SET/GET/INCR 使用随机 key, SADD 使用随机值  
9 -P 通过管道传输 numreq 请求 1
10 -q 强制退出 redis。仅显示 query/sec 值  
11 –csv 以 CSV 格式输出  
12 -l 生成循环,永久执行测试  
13 -t 仅运行以逗号分隔的测试命令列表。  
14 -I Idle 模式。仅打开 N 个 idle 连接并等待。  

例如:

> redis-benchmark -h 127.0.0.1 -p 6379 -n 10000 -q

PING_INLINE: 126582.27 requests per second
PING_BULK: 136986.30 requests per second
SET: 93457.95 requests per second
GET: 42194.09 requests per second
INCR: 113636.37 requests per second
LPUSH: 90909.09 requests per second
LPOP: 91743.13 requests per second
SADD: 123456.79 requests per second
SPOP: 128205.13 requests per second
LPUSH (needed to benchmark LRANGE): 125000.00 requests per second
LRANGE_100 (first 100 elements): 48543.69 requests per second
LRANGE_300 (first 300 elements): 20576.13 requests per second
LRANGE_500 (first 450 elements): 14306.15 requests per second
LRANGE_600 (first 600 elements): 11123.47 requests per second
MSET (10 keys): 74626.87 requests per second

表示对本地redis进行并发为50的10000次测试。

例2:

> redis-benchmark -h 127.0.0.1 -p 6379 -t get,set,lpush -n 10000 -q

只测试get,set,lpush操作。

基准测试

ThinkPad E14

C:\Users\malu>redis-benchmark -h 127.0.0.1 -p 6379 -n 10000 -q
PING_INLINE: 79365.08 requests per second
PING_BULK: 82644.63 requests per second
SET: 81967.21 requests per second
GET: 78740.16 requests per second
INCR: 78125.00 requests per second
LPUSH: 80645.16 requests per second
RPUSH: 83333.34 requests per second
LPOP: 80645.16 requests per second
RPOP: 92592.59 requests per second
SADD: 100000.00 requests per second
SPOP: 102040.82 requests per second
LPUSH (needed to benchmark LRANGE): 95238.10 requests per second
LRANGE_100 (first 100 elements): 33898.30 requests per second
LRANGE_300 (first 300 elements): 14326.65 requests per second
LRANGE_500 (first 450 elements): 9784.74 requests per second
LRANGE_600 (first 600 elements): 7806.40 requests per second
MSET (10 keys): 90909.09 requests per second

单核:Intel(R) Xeon(R) Platinum 8163 CPU @ 2.50GHz

[ root@php72:~ ]$ redis-benchmark -h 127.0.0.1 -p 6379 -n 10000 -q
PING_INLINE: 46948.36 requests per second
PING_BULK: 57142.86 requests per second
SET: 63291.14 requests per second
GET: 57471.27 requests per second
INCR: 65359.48 requests per second
LPUSH: 66225.17 requests per second
RPUSH: 64102.56 requests per second
LPOP: 66225.17 requests per second
RPOP: 65789.48 requests per second
SADD: 64935.07 requests per second
HSET: 66225.17 requests per second
SPOP: 64516.13 requests per second
LPUSH (needed to benchmark LRANGE): 29585.80 requests per second
LRANGE_100 (first 100 elements): 32786.88 requests per second
LRANGE_300 (first 300 elements): 13175.23 requests per second
LRANGE_500 (first 450 elements): 8176.61 requests per second
LRANGE_600 (first 600 elements): 5678.59 requests per second
MSET (10 keys): 49751.24 requests per second

8核:Intel(R) Xeon(R) CPU E5-2682 v4 @ 2.50GHz

root@iZ28ygxxh8fZ:~# redis-benchmark -h 127.0.0.1 -p 6379 -n 10000 -q
PING_INLINE: 88495.58 requests per second
PING_BULK: 97087.38 requests per second
SET: 76335.88 requests per second
GET: 72992.70 requests per second
INCR: 74074.07 requests per second
LPUSH: 78125.00 requests per second
LPOP: 75187.97 requests per second
SADD: 71428.57 requests per second
SPOP: 71942.45 requests per second
LPUSH (needed to benchmark LRANGE): 72992.70 requests per second
LRANGE_100 (first 100 elements): 38910.51 requests per second
LRANGE_300 (first 300 elements): 13642.57 requests per second
LRANGE_500 (first 450 elements): 13812.16 requests per second
LRANGE_600 (first 600 elements): 11454.75 requests per second
MSET (10 keys): 69444.45 requests per second

MySQL压力测试说明

mysqlslap是mysql自带的压力测试工具:

使用方法:

可以使用mysqlslap –help来显示使用方法:

--concurrency代表并发数量,多个可以用逗号隔开,concurrency=10,50,100, 并发连接线程数分别是10、50、100个并发。
--engines代表要测试的引擎,可以有多个,用分隔符隔开。
--iterations代表要运行这些测试多少次。
--auto-generate-sql 代表用系统自己生成的SQL脚本来测试。
--auto-generate-sql-load-type 代表要测试的是读还是写还是两者混合的(read,write,update,mixed)
--number-of-queries 代表总共要运行多少次查询。每个客户运行的查询数量可以用查询总数/并发数来计算。
--debug-info 代表要额外输出CPU以及内存的相关信息。
--number-int-cols :创建测试表的 int 型字段数量
--auto-generate-sql-add-autoincrement : 代表对生成的表自动添加auto_increment列,从5.1.18版本开始
--number-char-cols 创建测试表的 char 型字段数量。
--create-schema 测试的schema,MySQL中schema也就是database。
--query 使用自定义脚本执行测试,例如可以调用自定义的一个存储过程或者sql语句来执行测试。
--only-print 如果只想打印看看SQL语句是什么,可以用这个选项。

例如:

mysqlslap -h localhost -P 3306 -uadmin  --concurrency=1000 --iterations=5 --create-schema=test -p

然后输入密码。

表示拿用户admin对本地数据库test进行5次1000并发测试。