Command

  • du -h -d1 | sort -hr 列出当前目录下(含隐藏)文件大小
  • netstat -anp | grep 20501 查看端口占用,netstat -i 网卡信息
  • ipcs 显示共享内存段、消息队列和信号量的信息
  • ifconfig 显示或设置网络设备,配置IP、MAC地址、启动网卡
  • lsof 查看文件被哪个进程修改lsof tmp.txt,查看端口占用 lsof -i :8080
  • ps aux | grep -w 'hello' | grep -v grep | awk '{print $2}' | xargs kill -9
  • cmd1 | xargs -I {} cmd2 {} 将 cmd1 的每行输出作为 cmd2 的输入,{}仅作为占位符,换成如 $ 均可

Cgroup

1
2
3
4
5
6
7
8
9
10
11
## 进程绑核
cd /sys/fs/cgroup/cpuset
mkdir mygroup && cd mygroup
## 避免报错 write error: No space left on device
echo 0 > cpuset.mems
## 限制进程运行在对应的 processor
echo "0-19,40-59" > cpuset.cpus
## 进程加入 cgroup
echo 4462 > cgroup.proc
## 加入上级解除限制(或等进程结束)
echo 4462 > ../cgroup.procs

Linux Cgroup系列(04):限制cgroup的内存使用

FlameGraph

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 安装 perf 工具
yum -y install perf
git clone https://github.com/brendangregg/FlameGraph.git

# 数据采样,解析生成火焰图
perf record -a -g -F99 --call-graph dwarf -p <pid> sleep 30
perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > process.svg

# 常用命令
-p <pid>:指定待分析进程的 pid(多个用,分隔列表)
-t <tid>:指定待分析线程的 tid(多个用,分隔列表)
-a:从所有 CPU 收集系统数据
-g:开启 call-graph (stack chain/backtrace) 记录
-C <cpu-list>:只统计指定 CPU 列表的数据,如:0,1,3或1-2
-F <n>:每秒采样 n 次
-o <output.data>:指定输出文件output.data,默认输出到perf.data

GDB

断点的原理:

  1. 断点替换:在指定的地址处,GDB 会替换原有的指令为 int 3 中断指令。当程序执行到该位置时,会产生一个中断信号。GDB 捕获信号后,会停止程序进入调试模式。
  2. 保存原指令:GDB 会保存被替换的原始指令,以便在断点被移除时能够恢复。
命令 含义
gdb attach 调试附加到进程
gcore 生成core
gdb binary core 调试coredump
pstack 查看栈帧信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 关闭中途确认操作
set pagination off
set print thread-events off
set confirm off

# 输出日志到本地
set logging file my_output.log
set logging enabled on # 老版本 set logging on
set logging enabled off

# 常见流程
info threads # 找到对应线程
thread <tid>
p <value>

FlatBuffers

FlatBuffers在序列化时计算了各字段在数据体的偏移量,并存储在数据体中。因此,反序列化时,先读取字段的偏移量再读取数据即可。因为反序列化过程没有内存拷贝、数据解码等耗时操作,所以速度非常快,但是数据量比原数据有所增加。此外,生成的代码量较少,CPU占用较低

场景:延迟和性能要求高,特别是在数据不需要全部加载到内存中的场景

Protobuf

压缩后的数据包更小,但序列化与反序列化都比较重度,生成的代码量较大,CPU占用较高,内存占用较多。语言支持更广,解决方案更广泛、成熟

场景:适用于需要高效传输大量数据的分布式应用,如网络通信和数据存储

技巧:消息的字段数量不超过15、正数使用uint而非int、尽量控制int32或int64型数据在0~127

Proto 文件中定义字段的顺序与最终编码结果的字段顺序无关,两者有可能相同也可能不同。当消息被编码时,Protobuf 无法保证消息的顺序,消息的顺序可能随着版本或者不同的实现而变化。任何 Protobuf 的实现都应该保证字段以任意顺序编码的结果都能被读取。

  • 序列化后的消息字段顺序是不稳定的。
  • 对同一段字节流进行解码,不同实现或版本的 Protobuf 解码得到的结果不一定完全相同(bytes 层面)。只能保证相同版本相同实现的 Protobuf 对同一段字节流多次解码得到的结果相同。
  • 假设有一条消息foo,以下关系可能不成立:
1
2
3
4
foo.SerializeAsString() == foo.SerializeAsString()
Hash(foo.SerializeAsString()) == Hash(foo.SerializeAsString())
CRC(foo.SerializeAsString()) == CRC(foo.SerializeAsString())
FingerPrint(foo.SerializeAsString()) == FingerPrint(foo.SerializeAsString())
  • 假设有两条逻辑上相等消息,但是序列化之后的内容(bytes 层面)不相同,部分可能的原因有:
    • 其中一条消息可能使用了较老版本的 protobuf,不能处理某些类型的字段,设为 unknwon。
    • 使用了不同语言实现的 Protobuf,并且以不同的顺序编码字段。
    • 消息中的字段使用了不稳定的算法进行序列化。
    • 某条消息中有 bytes 类型的字段,用于储存另一条消息使用 Protobuf 序列化的结果,而这个 bytes 使用了不同的 Protobuf 进行序列化。
    • 使用了新版本的 Protobuf,序列化实现不同。
    • 消息字段顺序不同。

GRPC

gRPC是一种高性能 RPC 框架。使用Protocol Buffers作为二进制序列化,并使用HTTP/2协议进行传输。gRPC基于服务的思想:定义一个服务,描述这个服务的方法以及入参出参,服务器端有这个服务的具体实现,客户端保有一个存根,提供与服务端相同的服务。

  • 基于 ProtoBuf 接口定义语言:它可以定义服务的方法和消息类型,并生成各种语言的代码桩,实现跨平台。
  • HTTP/2作为底层传输协议:支持二进制传输效率高、双向流、消息头压缩、单 TCP 的多路复用、服务端推送等。
  • 支持流式数据:gRPC支持流式传输,即服务可以持续发送数据,而客户端可以持续接收数据。这在传输大量数据时非常有用。
  • gRPC同时支持同步调用和异步调用,同步RPC调用时会一直阻塞直到服务端处理完成返回结果,异步RPC是客户端调用服务端时不等待服务段处理完成返回,而是服务端处理完成后主动回调客户端告诉客户端处理完成

gRPC与HTTP/2的关系:HTTP/2为长连接、实时的通信流提供了基础。gRPC建立在这个基础之上,具有连接池、健康语义、高效使用数据帧和多路复用以及KeepAlive,gRPC的通讯基石就是HTTP/2

基于http2协议的特性:gRPC允许定义如下四类服务方法

  1. 一元RPC:客户端发送一次请求,等待服务端响应结构,会话结束,就像一次普通的函数调用这样简单
  2. 服务端流式RPC:客户端发起一起请求,服务端会返回一个流,客户端会从流中读取一系列消息,直到没有结果为止
  3. 客户端流式RPC:客户端提供一个数据流并写入消息发给服务端,一旦客户端发送完毕,就等待服务器读取这些消息并返回应答
  4. 双向流式RPC:客户端和服务端都一个数据流,都可以通过各自的流进行读写数据,这两个流是相互独立的,客户端和服务端都可以按其希望的任意顺序独写

名称解析器和负载平衡器:解析器将名称转换为地址,然后将这些地址交给负载均衡器。负载均衡器负责从这些地址创建连接,并在连接之间对rpc进行负载均衡。

当连接失败时,负载均衡器将开始使用最后已知的地址列表重新连接。同时,解析器将开始尝试重新解析主机名列表,告知负载均衡器。

对于失效连接:

  • 对方主动关闭、超时计时器情况:TCP的 FIN 语义即可完成 HTTP2/GRPC 连接的关闭
  • 端点死亡、挂起而不通知客户端:TCP得长时间重试,gRPC 使用 HTTP2 语义中的 PING 帧绕过流量控制,判断连接是否有效

BRPC

  1. 性能好,M:N (bthread:pthread)高效轻量的线程模型
  2. 自带性能监控和分析功能:bvar,一般的RPC框架没有提供热点分析、延时统计的工具,brpc通过自带的 bvar 能够监控并采集到多种性能相关的数据,便于快速确定热点、定位瓶颈。

Bthread

线程模型:1:1,一个内核线程里只有一个用户线程。利于调度到其他核上,多核扩展性好。缺点:线程锁、线程调度到另一个CPU时,data要从L1 cache同步到其他cpu,锁住总线。

协程模型:n:1,n个用户线程跑在一个CPU上。无多线程竞争,数据的locality好,但难以扩展到多核,一个线程阻塞会阻塞整个内核线程。

Bthread 通过实现上层 M:N 线程绑定减小了线程间的来回调度,减小了cache buncing;通过内部的多个队列和 stealing worker 机制,保证了整体的并发度QPS*latency最大;

Bthread的机制核心是 work stealing,即 pthread 之间可以偷bthread来执行。每个bthread两种调度方式,既可以只在某一个内核线程里调度(locality不错),也可以在该bthread被卡住时,允许被偷到其他内核线程去运行,只要有空闲的worker(pthread)在,就不会有bthread被阻塞,保证了多核在任意时刻只要有bthread被创建出来就可以去跑任务。

内存管理
BRPC通过IOBuf(非连续零拷贝缓存)方式减少数据传递处理过程中的拷贝,提高了数据传输效率。此外,各种ThreadLocal的ResourcePool、Object Pool等优化了定长的短生命周期的申请和释放,减少了内存分配和释放的开销。

执行队列
BRPC使用多生产者单消费者无锁队列作为执行队列,实现了多生产者单消费者之间的的高效通信。这种队列设计避免了锁竞争和线程同步的问题,提高了系统的吞吐量和并发性能。在实现单TCP连接复用、高效发送-接收数据等方面发挥了很重要的作用。


Centos Env

Proxy

  1. 切换默认shell chsh -s /bin/bash root
  2. 配代理
1
2
3
4
5
6
export http_proxy=http://xxx
export https_proxy=http://xxx
export HTTP_PROXY=http://xxx
export HTTPS_PROXY=http://xxx
export no_proxy="localhost,127.0.0.1,localaddress,localdomain.com,xxx”
export NO_PROXY="localhost,127.0.0.1,localaddress,localdomain.com,xxx"

注意:在sudo或切换用户时代理会失效,可以通过 visudo 保留代理环境变量

1
2
3
4
## find Defaults env_reset
Defaults env_reset
## add following exceptions
Defaults env_keep = "http_proxy ftp_proxy"
  1. centos换源
1
2
3
4
5
cd /etc/yum.repos.d
## 备份 & 去掉有问题的源
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all
yum makecache
  1. 环境变量添加第三方库
1
2
3
4
5
6
7
8
9
10
#在PATH中找到可执行文件程序的路径。
export PATH =$PATH:/MyBin
#gcc找到头文件的路径
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/include/xxx
#g++找到头文件的路径
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/include/xxx
#找到动态链接库的路径
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/MyLib
#找到静态库的路径
export LIBRARY_PATH=$LIBRARY_PATH:/MyLib

Vim

1. 安装 Vim-plug 插件

下载 plug.vim 文件,放置在 ~/.vim/autoload 目录中:

1
2
mkdir -p  ~/.vim/autoload/
cp plug.vim ~/.vim/autoload/plug.vim

2. 配置Vim,执行 :PlugInstall 安装主题

Folding

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
call plug#begin('~/.vim/plugged')
Plug 'sainnhe/sonokai'
call plug#end()

" 关闭对vi的兼容
set nocompatible
" 设置backspace键功能
set backspace=eol,start,indent

" 显示行号
set number
" 高亮显示当前行
set cursorline
" 让一行的内容不换行
set nowrap
" 距窗口边缘还有多少行时滚动窗口
set scrolloff=8

" tab设为4个空格
set tabstop=2
set shiftwidth=2
set softtabstop=2
set expandtab
set smarttab
" 新一行与上一行的缩进一致
set autoindent

" 开启语法高亮
syntax on
" 代码颜色主题
set t_Co=256
colorscheme sonokai

" 显示括号匹配
set showmatch
" 高亮查找匹配
set hlsearch
" 增量式搜索
set incsearch
" 不区分大小写,除非含有大写字母
set ignorecase
set smartcase

" 检测文件类型
filetype on
" 文件编码
set encoding=utf-8
set fileencodings=ucs-bom,utf-8,utf-16,gbk,big5,gb18030,latin1
" 没有保存或文件只读时弹出确认
set confirm

" 记录历史记录的条数
set history=1000
set undolevels=1000
" 禁用自动备份
set nobackup
set nowritebackup
set noswapfile

Bash

Bash 的彩色配色主题,将 ~/.bashrc 中的 PS1 替换:

1
PS1='${debian_chroot:+($debian_chroot)}\[\033[00;33m\][\u@\h]\[\033[00m\]:\[\033[00;36m\]\w\[\033[00m\]\$ '

GCC

CentOS 7 默认 gcc 版本为 4.8,可通过 devtoolset 工具安装多个不同的高版本 gcc 备用切换

可以通过 yum search devtooset 查看其他版本安装,devtoolset 安装目录为 /opt/rh/devtoolset-x

1
2
3
4
5
6
7
8
9
10
11
12
13
## 安装 centos-release-scl
yum install centos-release-scl
## 安装 devtoolset
yum install devtoolset-9-gcc
## 切换 gcc 版本
vim /etc/profile
source /opt/rh/devtoolset-9/enable
source /etc/profile
## 软连接(备份gcc同理)
mv /usr/bin/g++ /usr/bin/g++.bak
ln -s /opt/rh/devtoolset-11/root/usr/bin/g++ /usr/bin/g++
## 检验
gcc --version

GDB

官网 Download GDB 获取最新版 gdb-x.x.tar.gz 下载地址

1
2
3
4
5
6
wget https://ftp.gnu.org/gnu/gdb/gdb-11.2.tar.gz
tar -zxvf gdb-11.2.tar.gz
cd gdb-11.2/
./configure
make && make install
gdb --version

Make

官网 Index of /gnu/make 获取最新版 make-x.x.tar.gz 下载地址

1
2
3
4
5
6
7
8
9
10
11
12
wget https://ftp.gnu.org/gnu/make/make-4.3.tar.gz
tar -zxvf make-4.3.tar.gz
cd make-4.3/
## 指定 make 的安装路径
./configure --prefix=/usr/local/make
make && make install
## 备份原版 make
mv /usr/bin/make /usr/bin/make.bak
## 创建软连接
ln -s /usr/local/make/bin/make /usr/bin/make
## 验证
make -v

CMake

1. 二进制方式安装

1
2
3
4
5
6
7
8
9
10
## 在系统源代码目录下载二进制分发压缩包
cd /usr/local/src
curl -LO https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz
## 解压 直接安装
tar -xvf cmake-3.22.2.tar.gz
mv cmake-3.22.2 /usr/local/cmake
vim /etc/profile
export PATH="/usr/local/cmake/bin:$PATH"
source /etc/profile
cmake --version

2. 源码安装

官网 Download | CMake 获取最新版 cmake-x.xx.x.tar.gz 下载地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
wget https://github.com/Kitware/CMake/releases/download/v3.23.0/cmake-3.23.0.tar.gz
tar -zxvf cmake-3.23.0.tar.gz
cd cmake-3.23.0/
./configure --prefix=/usr/local/cmake
make && make install
## 卸载原有 CMake
yum -y remove cmake
## 创建软连接
ln -s /usr/local/cmake/bin/cmake /usr/bin/cmake
## 配置环境变量
vim /etc/profile
export CMAKE_HOME=/usr/local/cmake
export PATH=$PATH:$CMAKE_HOME/bin
source /etc/profile
## 检验
cmake --version

CMake Error:Could not find OpenSSL 报错,可通过以下命令解决:yum install openssl-devel

Gflags

1
2
3
4
git clone https://github.com/gflags/gflags.git && cd gflags
mkdir build && cd build
cmake .. -DBUILD_SHARED_LIBS=ON
make && make install

Glog

1
2
3
4
git clone https://github.com/google/glog.git && cd glog
cmake -S . -B build -G "Unix Makefiles"
cmake --build build
cmake --build build --target install # optional

Gtest

1
2
3
4
git clone https://github.com/google/googletest.git && cd googletest
mkdir build && cd build
cmake ..
make && make install

MacOS

MacOS 删除 ABC输入法
链接1 链接2

Font Family

Rec Mono 字体

1
2
3
// VSCode 用户配置
"editor.fontLigatures": "'dlig','ss01'",
"editor.fontFamily": "\"Rec Mono Linear\", monospace",

Vscode MonoKai Pro

  1. 生成license key
1
2
email=yourMail@mail.com
echo -n fd330f6f-3f41-421d-9fe5-de742d0c54c0$email | md5sum | cut -c1-25 | sed 's/.\{5\}/&-/g;s/-$//g'
  1. 打开VS Code的命令面板,ctrl+shift+p
  2. 输入 Monokai Pro: enter license
  3. 依次输入 email 和 lincese key