查看Linux Cpu软中断脚本

代码如下:

#!/bin/sh
# filename softirqs_status.sh

PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH

interrupts_=cat /proc/interrupts |grep -E "CPU0|em[0-9]{1,2}.*-[0-9]{1,3}$|eth[0-9]{1,2}.*-[0-9]{1,3}$|p[0-9]{1,2}p[0-9]{1,2}.*-[0-9]{1,3}$|nvme" |cat -s |column -t 
#interrupts_=cat /proc/interrupts |grep -E "CPU0|em[0-9]{1,2}.*-[0-9]{1,3}$|eth[0-9]{1,2}.*-[0-9]{1,3}$|p[0-9]{1,2}p[0-9]{1,2}.*-[0-9]{1,3}$" |cat -s |column -t 
#interrupts_=cat /proc/interrupts |grep -E "CPU0|em[0-9]{1,2}|eth[0-9]{1,2}|p[0-9]{1,2}p[0-9]{1,2}" |grep -i  "TxRx" |cat -s |column -t 
interrupts_=echo "${interrupts_}" |awk '{ if(NR == 1){one=$0;gsub(one, "- &", $0); print $0}else{print $0}}' |cat -s |column -t 
interrupts_=echo "${interrupts_}" |awk '{ for(i=2;i<=NF;i++){ if( $i ~ /^[[:digit:]]*$/ && $i >= 1000 && $i < 1000000 ){$i=int( $i / 1000 + 1)"K"}else if( $i ~ /^[[:digit:]]*$/ && $i >= 1000000 ){$i=int( $i / 1000000)"M"}}; print $0 }'
echo "${interrupts_}" |sed 's/CPU/U/g' |column -t

echo

cpu_c=expr $(cat /proc/cpuinfo |grep -i processor |wc -l) + 1 ;

softirqs_=cat /proc/softirqs |grep -E 'TX|RX|CPU' 
softirqs_=echo "${softirqs_}" |awk -v cpu_c=$cpu_c '{ if(NR == 1){one=$0;gsub(one, "- &", $0)}; for(i=1;i<=cpu_c;i++){print $i} }' 
softirqs_=echo "${softirqs_}" |xargs -n $cpu_c |column -t 
softirqs_=echo "${softirqs_}" |awk '{ for(i=2;i<=NF;i++){ if( $i ~ /^[[:digit:]]*$/ && $i >= 1000 && $i < 1000000 ){$i=int( $i / 1000 + 1)"K"}else if( $i ~ /^[[:digit:]]*$/ && $i >= 1000000 ){$i=int( $i / 1000000)"M"}}; print $0 }'
echo "${softirqs_}" |sed 's/CPU/U/g' |column -t

echo

显示结果如下

 bash /tmp/softirqs_status.sh
-    U0   U1  U2  U3  U4  U5  U6  U7  U8  U9  U10  U11  U12  U13  U14  U15  U16  U17  U18  U19  U20  U21  U22  U23  U24  U25  U26  U27  U28  U29  U30  U31
89:  102  0   0   0   0   0   0   0   0   0   0    0    0    0    0    0    0    0    0    0    0    0    0    4M   0    0    0    0    0    0    0    0    IR-PCI-MSI-edge  em49-fp-0
90:  4K   0   0   0   6M  0   0   0   0   0   0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    IR-PCI-MSI-edge  em49-fp-1
91:  50   5M  0   0   0   0   0   0   0   0   0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    IR-PCI-MSI-edge  em49-fp-2
92:  51   0   7M  0   0   0   0   0   0   0   0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    IR-PCI-MSI-edge  em49-fp-3
93:  64   0   0   6M  0   0   0   0   0   0   0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    IR-PCI-MSI-edge  em49-fp-4
94:  32   0   0   0   3K  0   0   0   0   0   0    0    0    0    0    0    0    5M   0    0    0    0    0    0    0    0    0    0    0    0    0    0    IR-PCI-MSI-edge  em49-fp-5
95:  41   0   0   0   0   6M  0   0   0   0   0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    IR-PCI-MSI-edge  em49-fp-6
96:  53   0   0   0   0   0   6M  0   0   0   0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    0    IR-PCI-MSI-edge  em49-fp-7

-        U0  U1  U2   U3   U4  U5   U6   U7   U8   U9   U10  U11  U12  U13  U14  U15  U16  U17  U18  U19  U20  U21  U22  U23  U24  U25  U26  U27  U28  U29  U30  U31
NET_TX:  35  26  667  114  93  160  106  1    0    0    0    0    0    0    0    0    1    2K   0    2    0    0    0    51   0    0    0    0    0    0    0    0
NET_RX:  5K  5M  7M   6M   6M  6M   6M   707  720  462  542  507  541  866  392  332  127  5M   289  199  251  244  194  4M   204  3K   396  446  217  165  164  128

Linux一些查看系统状态的命令

查看网卡速率

ethtool eth0 |grep Speed

这里的Speed是网卡的实际最大速率;如果开启了自动协商,就是是网卡和交换机协商之后的速率。

附带一个自动化脚本

PREFIX="p1p1"
ETH=ifconfig |grep ${PREFIX} | head -n1 | awk -F":" '{print $1;}'

if [ -z "${ETH}" ];then
   echo "emxx is not found"
   ifconfig
   exit 1
fi

ethtool eth0 |grep Speed

查看内存信息

  • 支持的内存槽数
  • 支持的最大内存

sudo dmidecode -t memory

输出如下:

# dmidecode 3.2
Getting SMBIOS data from sysfs.
SMBIOS 2.8 present.

Handle 0x0028, DMI type 16, 23 bytes
Physical Memory Array
        Location: System Board Or Motherboard
        Use: System Memory
        Error Correction Type: None
        Maximum Capacity: 8 GB
        Error Information Handle: Not Provided
        Number Of Devices: 2

Handle 0x002A, DMI type 17, 40 bytes
Memory Device
        Array Handle: 0x0028
        Error Information Handle: Not Provided
        Total Width: 64 bits
        Data Width: 64 bits
        Size: 4 GB
        Form Factor: DIMM
        Set: None
        Locator: A1_DIMM0
        Bank Locator: A1_BANK0
        Type: DDR3
        Type Detail: Unknown
        Speed: 1600 MT/s
        Manufacturer: Samsung
        Serial Number: 37A52995
        Asset Tag: A1_AssetTagNum0
        Part Number: M471B5173DB0-YK0
        Rank: 1
        Configured Memory Speed: 1333 MT/s
        Minimum Voltage: 1.35 V
        Maximum Voltage: 1.5 V
        Configured Voltage: 1.35 V

Handle 0x002C, DMI type 17, 40 bytes
Memory Device
        Array Handle: 0x0028
        Error Information Handle: Not Provided
        Total Width: Unknown
        Data Width: 64 bits
        Size: No Module Installed
        Form Factor: DIMM
        Set: None
        Locator: A1_DIMM1
        Bank Locator: A1_BANK1
        Type: Unknown
        Type Detail: Unknown
        Speed: Unknown
        Manufacturer: A1_Manufacturer1
        Serial Number: A1_SerNum1
        Asset Tag: A1_AssetTagNum1
        Part Number: Array1_PartNumber1
        Rank: Unknown
        Configured Memory Speed: Unknown
        Minimum Voltage: Unknown
        Maximum Voltage: Unknown
        Configured Voltage: Unknown

Linux 常用Yum仓库

EPEL

EPEL的全称叫 Extra Packages for Enterprise Linux 。EPEL是由 Fedora 社区打造,为 RHEL 及衍生发行版如 CentOS、Scientific Linux 等提供高质量软件包的项目。

官方网址为:https://fedoraproject.org/wiki/EPEL

Centos安装命令: sudo yum install epel-release

rpmfusion

RPM Fusion provides software that the Fedora Project or Red Hat doesn’t want to ship. That software is provided as precompiled RPMs for all current Fedora versions and current Red Hat Enterprise Linux or clones versions; you can use the RPM Fusion repositories with tools like yum and PackageKit.

RPM Fusion is a merger of Dribble, Freshrpms, and Livna; our goal is to simplify end-user experience by grouping as much add-on software as possible in a single location. Also see our FoundingPrinciples.

官方网站为 https://rpmfusion.org/

Remi repository

Remi repository 是包含最新版本 PHP、MySQL、Python 包的 Linux 源,由 Remi 提供维护。

官方网站为 http://rpms.remirepo.net/

Enterprise Linux 7 (with EPEL) x86_64 的安装方法:

wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
wget https://rpms.remirepo.net/enterprise/remi-release-7.rpm
rpm -Uvh remi-release-7.rpm epel-release-latest-7.noarch.rpm

如何要安装php的7.4版本则执行下面的命令:

yum -y --nogpgcheck install epel-release \
&& yum -y --nogpgcheck install https://rpms.remirepo.net/enterprise/remi-release-7.rpm \
&& yum -y --nogpgcheck install yum-utils \
&& yum-config-manager --enable remi-php74 \
&& yum -y --nogpgcheck install yum install nginx php  php-cli php-fpm php-mysqlnd php-zip php-devel php-gd php-mcrypt php-mbstring php-curl php-xml php-pear php-bcmath php-json

WANDisco

安装新版本的git 库

# 卸载旧版 git
yum -y remove git

# 安装 centos7 WANDisco 仓库
yum install http://opensource.wandisco.com/centos/7/git/x86_64/wandisco-git-release-7-2.noarch.rpm

yum -y install git

mysql

https://dev.mysql.com/downloads/

Linux Shell 命令小技巧

Top 监控某一多进程任务

以nginx 为例: d PL=pidof nginx

PL=${PL//\ /,}

top -p $PL

SSH

ssh scp等消除每次问yes/no

ssh -o StrictHostKeyChecking no dev.zuocheng.net

链接复用

创建ssh sock链接目录

mkdir ~/.ssh/socks

修改~/.ssh/config文件,若该文件不存在,则创建。增加以下内容:

Host *
    KeepAlive yes
    ServerAliveInterval 60
    ControlMaster auto
    ControlPersist yes
    ControlPath ~/.ssh/socks/%h-%p-%r

grep

常用参数 -Irn

find

清空所有log文件

find ./ -name *.log | xargs truncate -s 0

删除所有nohup文件

find ./ -name nohup.out | xargs rm -rf

find ./ -name *.swp | xargs rm -rf

删除过期日志(60天前)

find ./ -mtime +60 -name log.* -exec rm -rf {} \;

使用正则删除过期日志(7天有效期)
30 4 * * * (find /workdir -type f -mtime +7 -regex '.+?/log/app\.20[0-9]+' -exec rm -f {} \;)

把当前目录下所有文件都MD5

find ./ -type f -exec md5sum {} \; | sort -k 2 > md5sum

date

依据时间戳获取时间

date -d @1525856172

生成日期
DATE=$(date +%Y%m%d)

比较两个文件夹的不同

生成MD5值 find ./dir -type f -exec md5sum {} \; > md5sum.txt

生成MD5值,并排除日志文件 find "dir" -path 'dir/log*' -prune -o -type f -exec md5sum {} \; > md5sum.txt

校验md5值 md5sum -c > md5sum.txt

sed 相关

sed -i '/^$/d' 删除空行
sed -i 's/\s*$//g' #删除行尾空白

工程师手记-将Memcached内存管理机制移植至Redis

Idea 的提出

  • Redis 有其高效的异步网络框架
  • Memcached 有其高效的内存管理机制

将这两者结合在一起后,会如何呢?开始试验将Memcached内存管理机制移植至Redis。

本篇博客的姊妹篇链接: 《工程师手记-将Redis异步网络框架移植至Memcached》

调研和选型

Redis内存管理的几个缺点:

  • 使用tcmalloc 或者 jmalloc 库,这两个库封装较重,内部特性也较多。
  • tcmalloc 适合小空间分配,稍大的空间分配会有瓶颈。
  • Redis 主要是单线程运行(只在后台任务cache持久化功能处又启动了新线程), tcmalloc 和 jmalloc 有保证线程安全,但对redis来说是不必要的功能。尤其是jmalloc,为线程安全做了很重的设计。

软件选型

  • 并不是把 Memcached 的内存管理直接替换redis的内存分配,而是使用ae-memcached的内存分配方式。
  • ae-memcached 的内存分配和 Memcached在原理上毫无不同,仅是从软件架构上对其进行重构和优化。具体参考:《AE-Memcached 优化记录》
  • 选择 Redis 2.8.24 作为移植受体

Redis代码修改和编译 / 移植方案

  • 从ae-memcached中拿出mem_cache / slab 两个类,直接移植到Redis src 目录中
  • 新建两个文件 mc_malloc.h mc_malloc.c,封装mem_cache,让其提供类似 malloc、 alloc、realloc、free的接口
  • 修改 zmalloc.c zmalloc.h 这两个文件,让其支持mc_malloc
  • 修改 Makefile ,默认MALLOC 使用 mc_malloc
  • 修改bio.c 文件,把zmalloc 和 zfree用 libc的 malloc 和 free 代替,这么做主要考虑到线程安全
  • 编译、运行

代码托管地址

给新的redis起了一个新名字mc-redis,源代码托管于Github上:

https://github.com/zuocheng-liu/mc-redis

性能测试实验

硬件

  • Redis-server 服务端 GenuineIntel 6 Common KVM processor 6 核 2.0GHZ 4G 内存
  • redis-benchmark 和服务端部署在同一台服务器上

测试方法

  • 分别运行原本Redis 和 mc-redis, 分别作为实验和对照,参数为 redis-server –port 7777
  • 启动Redis,运行redis-benchmark 测试三次。重复前面步骤,Redis共重启3次,redis-benchmark共测试9次。
  • mc-redis 的测试也使用上面方法
  • 测试命令 ./redis-benchmark -h 127.0.0.1 -p 7778 -q -d 100
  • 只观察set / get 命令的并发度

测试结果

启动一次redis,做了三组实验,数据如下:

  • mc-redis GET 62972.29 / 58275.06 / 55897.15 (requests per second)
  • redis GET 47281.32 / 62034.74 / 51759.83 (requests per second)
  • mc-redis SET 64808.82 / 59031.88 / 56915.20 (requests per second)
  • redis SET 51733.06 / 53676.86 / 56947.61 (requests per second)

结论

在刚启动时(预热阶段),mc-redis 的 set 和 get 操作,比原版redis 的并发处理能力高大约有 15%-20%。 但是稳定运行后, mc-redis 和 原版redis,性能相差较小。

AE-Memcached 优化记录

优化背景和目的

  • 学习Memcached 代码
  • 将 Memcached 的代码成为自己的技术积累
  • 优化Memcache 代码,提高自己系统分析能力

源代码托管于Github上:

https://github.com/zuocheng-liu/ae-memcached

性能优化

网络模型的优化

  • 网络IO多路复用 + 单线程

  • 将 Redis 异步库 移植至 Memcached

优化动态申请内存机制

  • 使用预分配,减小系统调用 malloc、realloc、free的次数,主要出现在新建/关闭链接时,会有较多的系统调用

部分小的函数使用宏代替

优化Memcache协议命令的解析

  • 调整各个命令的解析顺序,把get 和 set 命令放到最前面

软件架构优化

软件架构优化,保证关键代码性能不变

使用宏加强代码复用

  • 重构verbose日志
  • 重构网络库
  • 重构slab

命令模式重构 Memcache 协议

  • 创建command_service类,统一管理命令的解析、处理

更深层次的抽象

将 stats 、 settings 、 logger 和全局资源进行抽象

解耦

  • 将各个模块接口化,减少模块间耦合,尤其是 slab item memcached之间的耦合
  • 依赖注入原则,增强各个模块的复用,其中mem_cache模块 settings等可以形成框架。
  • logger
  • command service

Git 使用经验总结

常用命令

按使用频度排序

  • git pull
  • git log
  • git diff
  • git commit
  • git commit –amend
  • git review
  • git clone
  • git push
  • git reset –hard/soft
  • git checkout
  • git fetch –all
  • git merge
  • git branch -b develop origin/develop
  • git clean -df

git 命令非常多,但常用的只有以上几个

常用配置

用户名和密码

$ git config --global user.name liuzuocheng

$ git config --global user.email zuocheng.liu@gmail.com

权限验证

在git pull/push/clone 时输入密码会比较麻烦。在所有的解决方法中,除了使用密钥之外,还可以使用.git-credentials配置文件。这种方法的坏处则是密码用明文存储,安全风险大。

touch ${HOME}/.git-credentials
输入内容
https://username:password@gitlab.zuocheng.net
执行下面命令使其生效
git config --global credential.helper store

默认编辑器

$ git config --global core.editor vim

配置比较工具

git config --global merge.tool vimdiff

git config --global diff.tool vimdiff

git config --global difftool.prompt false

git config --global alias.d difftool

或者直接更改配置文件 ~/.gitconfig,添加手工添加配置

常用经验

  • 将远程主干合并到本地分支

在代码上线前,这一步非常重要

git fetch && git rebase origin/master

git fetch --all && git merge origin master

分支间文件差异大,频繁切换显示aborting, git status后发现大量为trace的文件

通过下面的命令清理它们
git clean -df

解决版本冲突

暂存本地修改

$ git stash

拉取版本库中最新版本

$ git pull

将本地修改与版本库中最新版本合并

$ git stash pop stash@{0}

解决冲突,使用下面的工具会非常方便

$ git d

  • 将源码导出tar包

git对应的功能是归档

mkdir ../working

git archive master | tar -x -C ../working

Git 高级功能

submodule

git submodule add 仓库地址 路径

git submodule update --init

git submodule update

fork后如何同步源的新更新 ?

  • 首先要先确定一下是否建立了主repo的远程源

git remote -v

  • 如果里面只能看到你自己的两个源(fetch 和 push),那就需要添加主repo的源:

git remote add upstream URL

  • 查看主repo的远程源

git remote -v

  • 拉取主repo源的代码

git fetch upstream

  • 合并

git merge upstream/master

  • 提交

git push

git 项目打包导出

示例, 项目中有为1.0的tag

git archive 1.0 | bzip2 > v1.0.tar.bz2

示例,打包master分支

git archive --format tar.gz --output "../project.tar.gz" master

与 Gerrit 配合使用

提交代码审核 git push origin HEAD:refs/for/mybranch

submodule

一键更新所有submodule,包含所有层级

git submodule update --init --recursive

submodule 更新后,版本不一致,引发意外出core

重新初始化并拉取所有的submodule

git submodule deinit -f --all
git submodule update --init --recursive

高级用法

git rebase

这是介绍rebase用法特别好的博客,http://blog.chinaunix.net/uid-27714502-id-3436706.html

git清除所有commit历史记录

# 新建初始分支
git checkout --orphan new_branch 
# 添加文件
git add -A
# 提交修改
git commit -m "Initial commit" -s
# 覆盖原master分支后push
git branch -D master
git branch -m master
git push origin master -f

常见异常处理

fatal: Not possible to fast-forward, aborting.

处理方法是 rebase
git pull origin master --rebase
git rebase --continue

error: remote unpack failed: error Missing tree

执行push时添加–no-thin选项,参考stackoverflow
git push --no-thin

Server does not allow request for unadvertised object

常为更改了submodule的引用地址造成,可以使用git submodule sync命令解决,参考stackoverflow

Redis 和 Memcahe 比较和总结

Redis 和 Memcahe 比较和总结
项目 Redis Memcache
读速率 批量读效率高
写速率
冗余备份 master-slave模式,交换文件备份,支持binlog
内存使用率 依赖具体使用场景
主从复制 支持master – slaver 不支持 ,若需支持需要代理软件memagent
数据结构 key-value 、Set、 List 、Zset、hash key-value
数据的持久化 支持 不支持
特性 内存数据库、VM特性 内存缓存
存储方式 内存 + 交换文件备份 内存
未来发展 支持cluster

apache nginx 配置多端口监听,浏览器自动跳转到80端口

       最近两天在分别在配置apache 和 nginx 时,都遇到了一个相同的问题:        

为apache和nginx开启监听多个端口(比如监听80和8080端口)时,改好配置,重启服务。

在浏览器端访问8080端口,url自动跳转到80端口,例如url输入http://**.**.**.**:8080, 则浏览器自动跳转到http://**.**.**.**。

而如果如果在url中的8080端口的后面添加访问文件,则正常展示8080端口下的目录或文件。

离奇的是,过一段时间,大约1个小时后,再访问http://**.**.**.**:8080,就不会跳转到http://**.**.**.**了。

网上搜索,记录此问题的网文不多。 然后自己分析了一下,大概有2种可能性。

1.浏览器端的缓存造成。但是,我换了浏览器,清空了缓存,依然如上。

2.服务器端缓存,1小时后才能恢复正常。 第2种情况比较靠谱些,顺着这个思路,最终找到了答案: 是因为开启了RPCBind服务造成。

解决方法是,将RPCBind的缓存清空。

LNMP启停控制自动脚本

常常在更改LNMP配置之后,需要重启LNMP,在此写了一个自动化脚本,方便重启LNMP。 除了方便重新启动,还增加了关闭与开启功能。 Operating System: Ubuntu Server 代码


# !/bin/bash
function start(){ sudo service nginx start sudo service php5-fpm start } 
function startall(){ start sudo service mysql start }
function stop(){ sudo service nginx stop sudo service php5-fpm stop } 
function stopall(){ stop sudo service mysql start } 
function restart(){ sudo service nginx restart sudo service php5-fpm restart } 
function restartall(){ restart sudo service mysql restart }

## main()

case "$1" in 
    "start") start ;; 
    "startall") startall ;; 
    "stop") stop ;; 
    "stopall") stopall ;; 
    "restart") restart ;; 
    "restartall") restartall ;; 
    "configtest") configtest ;; 
*) echo "Usage: $0 {start|stop|restart|startall|stopall|restartall}" 

esac exit 0 

webserver restart //重启nginx 和 php-fpm