tomcat,keepalived,lvs,zabbix,vanish,haproxy,nginx,lamp,mysql复制,分布式文件系统;

    linux rpm packs: https://pkgs.org

    lvs:真正工作在内核中;传输层调度;不需要工作在用户空间打开一个套接字文件;可以支持400-500万并发;
    nginx haproxy:都是模拟,假装是tcp的;可以基于应用来进行负载均衡调度;

    系统构建:
    分层:将每个应用单独使用一台主机来使用;
    分割:每个大业务分割成多个小业务,每个小业务分布在不同的应用主机上,然后通过点击链接来实现;
    分布式:应用、数据、存储、计算

    keepalived:是vrrp协议在linux上一款软件实现,在其内部添加了一种内在的线程,完成监控后端的各real server,向ipvs上添加事先定义好的高可用集群服务,并监控各realserver健康状态,完成增删的功能;

    messaging layer: 消息层,通过配置的地址以及方式来完成集群心跳及事务信息传递的;
    通常程序能自己调动messaging layer接口

    CRM:集群资源管理器;

    在创建centos7的时候使用tab键在最后边加上net.ifnames=0 biosdevname=0

    Mac安装软件地址:https://mac-torrents.io

    机器初始化:
    防火墙和selinux
    主机名解析
    时间同步

    文件系统:
    df -hT
    blkid

    时间转成整数型:
    date +%s

    查看登录详细信息:
    who /var/log/wtmp

    visudo编辑文件显示颜色:
    echo export EDITOR=vim >> /etc/profile.d/env.sh

    探测服务是否起来:
    killall -0 nginx > /tmp/nginx.log 向nginx发出0信号,如果$?非0则表示nginx服务有问题;

    df显示磁盘100%,而du查找目录的磁盘容量占用却很小:
    yum -y install lsof
    lsof -n | grep deleted
    kill -9 pid

    修改网卡名称:
    ip link set dev ens33 name eth0

    主机转发:
    /proc/sys/net/ipv4/ip_forward

    如何快速定位mysql性能瓶颈:
    1. top、free分析硬件资源使用
    2. iostat分析磁盘压力,iowait
    3. mysql_slow.log分析慢SQL
    4. show full processlist;
    5. explain命令
    6. show profile

    总结排查mysql宕机思路:
    1. 复核问题
    2. 确认进程/端口
    3. 远端模拟连接
    4. 差mysql日志
    5. 查系统日志

    mysql宕机:
    1. 进程 ps -ef | grep mysql
    2. mysql的error.log
    3. 内存溢出(OOM)了?
    /var/log/message

    在线搭建新从库:
    方法一:
    1. stop当前的从库
    2. cp数据目录到新机器
    3. 修改server-id
    4. 删除auto.cnf
    5. 启动新数据库

    1. 方法二(当前仅有一台主库):
    2. 1. mysqldump主库
    3. 2. --single-transaction
    4. 3. --master-data=2
    5. 4. 当如sql到新从库
    6. 5. change master

    扫目录大小:
    ncdu
    du -ah —max-depth=1 |sort -nr
    du -h —max-depth=1

    更改pypi源:
    ~/.pip/pip.conf
    [global]
    index-url = https://pypi.tuna.tsinghua.edu.cn/simple/ #这个pypi源自己定义[install]
    trusted-host=pypi.tuna.tsinghua.edu.cn # 这个也是根据pypi源自己定义

    1. 阿里云 http://mirrors.aliyun.com/pypi/simple/
    2. 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
    3. 豆瓣(douban) http://pypi.douban.com/simple/
    4. 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
    5. 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/

    磁盘报错:
    报错信息:ls: cannot access xxx: Input/output error
    dmesg|grep sd或dmesg|grep error,获得有详细报错信息

    1. 手动修复:fsck /dev/sda1
    2. 开机自检修复:修改/etc/fstab文件,最后0 1

    ssh隧道:
    ssh本地转发:
    ssh -L 9906:10.1.0.2:3306 root@10.1.0.2
    即使ssh关闭隧道也保持存在:
    ssh -f -N -L 9906:10.1.0.2:3306 root@10.1.0.2 //只会监听本地127.0.0.1
    ssh -f -N -L 10.1.0.1:9906:10.1.0.2:3306 root@10.1.0.2
    ssh -g -f -N -L 9906:10.1.0.2:3306 root@10.1.0.2 //全部地址都监听

    1. ssh远程转发:
    2. ssh -f -N -R 9906:10.1.0.2:3306 root@10.1.0.1 //在0.2上执行的,将本地的3306与公网的0.1建立隧道

    cpu排查:
    查看cpu个数:
    cat /proc/cpuinfo |grep ‘processor’ |wc -l

    1. 实时显示占用cpu时钟最多的函数或指令:
    2. perf top
    3. Overhead,性能事件在所有采样中的比例;
    4. Shared,是该函数或指令所在的动态共享对象(Dynamic Shared Object),如内核、进程名、动态链接库名、内核模块名等。
    5. Object,动态共享对象的类型。比如 [.] 表示用户空间的可执行程序、或者动态链接库,而 [k] 则表示内核空间。
    6. Symbol,符号名,也就是函数名。当函数名未知时,用十六进制的地址来表示。
    7. perf record 则提供了保存数据的功能,保存后的数据,需要你用 perf report 解析展示。
    8. htop:
    9. 显示各种性能参数
    10. vmstat:
    11. r: 运行队列长度和正在运行的线程数;
    12. b: 表示阻塞的进程数;
    13. swpd: 虚拟内存已使用的大小,如果大于0,表示你的机器物理内存不足了,如果不是程序内存泄露的原因,那么你该升级内存了或者把耗内存的任务迁移到其他机器;
    14. si:?每秒从磁盘读入虚拟内存的大小,如果这个值大于0,表示物理内存不够用或者内存泄露了,要查找耗内存进程解决掉。我的机器内存充裕,一切正常。
    15. so:?每秒虚拟内存写入磁盘的大小,如果这个值大于0,同上;
    16. bi:?块设备每秒接收的块数量,这里的块设备是指系统上所有的磁盘和其他块设备,默认块大小是1024byte,我本机上没什么IO操作,所以一直是0,但是我曾在处理拷贝大量数据(2-3T)的机器上看过可以达到140000/s,磁盘写入速度差不多140M每秒;
    17. bo:?块设备每秒发送的块数量,例如我们读取文件,bo就要大于0bibo一般都要接近0,不然就是IO过于频繁,需要调整;
    18. in: 每秒CPU的中断次数,包括时间中断;
    19. cs:??每秒上下文切换次数,例如我们调用系统函数,就要进行上下文切换,线程的切换,也要进程上下文切换,这个值要越小越好,太大了,要考虑调低线程或者进程的数目,例如在apachenginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。
    20. st: cpu在虚拟化环境上在其他租户上的开销;
    21. mpstat:
    22. 报告与 CPU 的一些统计信息,这些信息存放在 /proc/stat 文件中。在多 CPU 系统里,其不但能查看所有 CPU 的平均状况信息,而且能够查看特定 CPU 的信息。
    23. mpstat -P ALL 1
    24. -P {cpu l ALL} 表示监控哪个 CPU cpu [0,cpu 个数 - 1] 中取值
    25. 参数 释义
    26. CPU 处理器 ID
    27. %usr internal 时间段里,用户态的 CPU 时间(%),不包含 nice 值为负进程
    28. %nice internal 时间段里,nice 值为负进程的 CPU 时间(%)
    29. %sys internal 时间段里,核心时间(%)
    30. %iowait internal 时间段里,硬盘 IO 等待时间(%)
    31. %irq internal 时间段里,硬中断时间(%)
    32. %soft internal 时间段里,软中断时间(%)
    33. %steal 显示虚拟机管理器在服务另一个虚拟处理器时虚拟 CPU 处在非自愿等待下花费时间的百分比
    34. %guest 显示运行虚拟处理器时 CPU 花费时间的百分比
    35. %gnice
    36. %idle internal 时间段里,CPU 除去等待磁盘 IO 操作外的因为任何原因而空闲的时间闲置时间(%)
    37. 出现cpu瓶颈的时候:
    38. 1.最简单的就是增加cpu个数和核数
    39. 2.通过调整任务执行时间,如大任务放到系统不繁忙的情况下进行执行,平衡任务系统
    40. 3.调整已有任务的优先级

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

    nmap命令:
    网络扫描命令,查看目标主机是否存活,扫描端口
    nmap -PP IP

    lsof命令:
    列举系统中已经打开的文件或查看监听的端口
    lsof -i:22
    查看某文件被哪个进程占用
    lsof /usr/lib64/ld-2.17.so

    清理buffer and cache:
    1. 仅清理页面缓存
    sync; echo 1 > /proc/sys/vm/drop_caches
    2. 清除目录项和inode
    sync; echo 2 > /proc/sys/vm/drop_caches
    3. 清除页面缓存,目录项和inode
    sync; echo 3 > /proc/sys/vm/drop_caches

    内存:
    查看进程占用内存:
    ps aux | awk ‘{mem += $6} END {print mem/1024/1024}’

    1. buff/cache构成:buffers + cached + slab

    测试硬盘读写速度:
    dd if=/dev/zero bs=1M count=1000 of=./1Gb.file

    1. fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data --size=22m --bs=2300 --name=mytest

    变量说明:
    $$: Shell本身的PID(ProcessID)
    $!: Shell最后运行的后台Process的PID
    $?: 最后运行的命令的结束代码(返回值)
    $-: 使用Set命令设定的Flag一览
    日常笔记 - 图1*”用「”」括起来的情况、以”$1 $2 … $n”的形式输出所有参数。
    日常笔记 - 图2@”用「”」括起来的情况、以”$1” “日常笔记 - 图3n” 的形式输出所有参数。
    $#: 添加到Shell的参数个数
    $0: Shell本身的文件名
    日常笔记 - 图4n: 添加到Shell的各参数值。$1是第1参数、$2是第2参数…。

    获取url返回码:
    curl -I -m 10 -o /dev/null -s -w %{http_code}
    curl -m 10 -o /dev/null -s -w %{http_code}

    查看被kill进程:
    egrep -i ‘killed process’ /var/log/messages
    egrep -i -r ‘killed process’ /var/log

    查找指定的文件并删除:
    find / -name ifcfg-ens33 -exec rm -rf {} ;
    查找大于1M,且类型为普通文件的所有文件:
    find /etc -size +1M -type f
    快速查找文件:
    locate ifcfg-ens33

    监控清理磁盘文件:
    cd /data-rrd/data/of_rrd/6070
    find . -name ‘*.rrd’ -mtime +7 | xargs rm -f

    修改vim的tab的缩进:
    /etc/vim/vimrc 或 ~/.vimrc
    set ts=4
    set expandtab
    set autoindent
    hi comment ctermfg=2

    1. 复制模式:
    2. :set paste
    3. 取消高亮:
    4. :noh

    筛选出IP:
    ifconfig ens33 |grep ‘inet ‘| awk ‘{print $2}’

    添加某个命令免密使用:
    USERNAME ALL=NOPASSWD:CMD_PATH

    nohup命令:
    命令可以在你退出帐户/关闭终端之后继续运行相应的进程
    nohup CMD &

    cuda升级:
    查看现用版本:
    cat /usr/local/cuda/version.txt

    1. 移除旧版本:
    2. apt-get --purge remove cuda
    3. 官网链接:
    4. https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html
    5. https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1804&target_type=deblocal
    6. 安装命令:
    7. wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
    8. sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
    9. wget http://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda-repo-ubuntu1804-10-1-local-10.1.243-418.87.00_1.0-1_amd64.deb
    10. sudo dpkg -i cuda-repo-ubuntu1804-10-1-local-10.1.243-418.87.00_1.0-1_amd64.deb
    11. sudo apt-key add /var/cuda-repo-10-1-local-10.1.243-418.87.00/7fa2af80.pub
    12. sudo apt-get update
    13. sudo apt-get -y install cuda
    14. 如果报错: package XXX needs to be reinstalled, but I can't find an archive
    15. sudo cp /var/lib/dpkg/status status.bkp
    16. sudo gedit /var/lib/dpkg/status
    17. 在文件中找到错误的package状态,并删除
    18. 为安全起见 再使用 apt-get -f install 修复一下。即可
    19. 继续报错:.... Try 'apt --fix-broken install '。。。
    20. apt --fix-broken install
    21. nvidia-docker2升级为nvidia-container-toolkit:
    22. 添加源:
    23. distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
    24. curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
    25. curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
    26. 安装重启:
    27. sudo apt update && sudo apt install -y nvidia-container-toolkit
    28. sudo systemctl restart docker

    gitlab webhook:
    注意:运行nginx和php以及登录gitlab的用户的要一样
    php:
    <?php
    日常笔记 - 图5valid_ip = array(‘192.168.131.130’); //这里填你的gitlab服务器ip
    $client_token = 日常笔记 - 图6client_ip = 日常笔记 - 图7client_token !== 日常笔记 - 图8%20die(‘Token%20mismatch!’)%3B%0A%09%09%2F%2Fif%20(!in_array(#card=math&code=valid_token%29%20die%28%27Token%20mismatch%21%27%29%3B%0A%09%09%2F%2Fif%20%28%21in_array%28&id=lPcVn)client_ip, $valid_ip)) die(‘Ip mismatch!’);
    exec(“cd /root/gitlab/zky_test; git pull origin master”);
    //exec(“cd /var/www/html/; git pull origin master 2>&1”, 日常笔记 - 图9%3B%0A%09%09%2F%2Fvar_dump(#card=math&code=output%29%3B%0A%09%09%2F%2Fvar_dump%28&id=KV120)output); 这样可以用浏览器调试输出
    ?>
    nginx:
    location ~ .php$ {
    root /root/nginx/www;
    fastcgi_pass 192.168.131.132:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME 日常笔记 - 图10fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param PATH_TRANSLATED 日常笔记 - 图11fastcgi_path_info;
    include fastcgi_params;
    }

    记录操作:
    第一种:记录操作录像
    # vim /etc/profile
    if [ 日常笔记 - 图12USER-日常笔记 - 图13USER-$UID-date +%Y%m%d%H%M.log
    fi
    # mkdir /var/log/script
    # chmod 777 /var/log/script/
    # source /etc/profile

    1. # scriptreplay root-0-201712221545.date root-0-201712221545.log
    2. 第二种:记录操作记录,清除history的危险
    3. vim /etc/profile.d/log.sh
    4. history
    5. USER=`whoami`
    6. USER_IP=`who -u am i 2>/dev/null| awk '{print $NF}'|sed -e 's/[()]//g'`
    7. if [ "$USER_IP" = "" ]; then
    8. USER_IP=`hostname`
    9. fi
    10. if [ ! -d /var/log/history ]; then
    11. mkdir /var/log/history
    12. chmod 777 /var/log/history
    13. fi
    14. if [ ! -d /var/log/history/${LOGNAME} ]; then
    15. mkdir /var/log/history/${LOGNAME}
    16. chmod 300 /var/log/history/${LOGNAME}
    17. fi
    18. export HISTSIZE=4096
    19. DT=`date +"%Y%m%d_%H:%M:%S"`
    20. export HISTFILE="/var/log/history/${LOGNAME}/${USER}@${USER_IP}_$DT"
    21. chmod 600 /var/log/history/${LOGNAME}/*history* 2>/dev/null

    nginx配置代理:
    grpc代理:
    1.nginx版本要大于1.13.10+,在编译安装的时候要支持两个模块—with-http_ssl_module —with-http_v2_module,可以使用nginx -V查看;
    2.配置nginx代理的时候
    server {
    listen PORT http2;

                location / {
                grpc_pass grpc://IP:PORT;
                }
            }
    
    websocket代理:
        server {
        listen       801;
        server_name  localhost;
        #布置websocket处理服务器
            location / {
                    proxy_pass http://127.0.0.1:8110;
    
                    #配置Nginx支持webSocket开始
                    proxy_set_header Host $http_host;
    
                    proxy_http_version 1.1;
                    proxy_set_header Upgrade $http_upgrade;
                    proxy_set_header Connection "upgrade";
            }
        }
    

    蓝绿部署:
    减少发布时的中断时间、能够快速撤回发布;
    一共有两套系统:一套是正在提供服务系统,标记为“绿色”;另一套是准备发布的系统,标记为“蓝色”。两套系统都是功能完善的,并且正在运行的系统,只是系统版本和对外服务情况不同。两套系统之间进行切换;

    金丝雀发布:
    只准备几台服务器,在上面部署新版本的系统并测试验证。测试通过之后,担心出现意外,还不敢立即更新所有的服务器。 先将线上的一万台服务器中的10台更新为最新的系统,然后观察验证。确认没有异常之后,再将剩余的所有服务器更新。

    注:蓝绿部署和金丝雀是发布策略,目标是确保新上线的系统稳定,关注的是新系统的BUG、隐患;
    

    A/B测试:
    效果测试,同一时间有多个版本的服务对外服务,这些服务都是经过足够测试,达到了上线标准的服务,有差异但是没有新旧之分;
    在A/B测试中,需要能够控制流量的分配,譬如说,为A版本分配10%的流量,为B版本分配10%的流量,为C版本分配80%的流量;

    lvm:
    安装:
    # yum -y install lvm2
    创建pv:
    # pvcreate /dev/${disk_name}{number} //可以是多个盘,如:pvcreate /dev/sda7 /dev/sda8
    # pvs/pvdispaly
    创建vg:
    # vgcreate vg-test /dev/xxx
    # vgs/vgdisplay
    创建lv:
    # lvcreate -L 100M -n lv-test vg-test
    # lvcreate -l 100%FREE -n lv-test vg-test
    创建文件系统:
    # mkfs.ext4 /dev/vg-test/lv-test
    # mkfs.xfs /dev/vg-test/lv-test

    扩容:
        裸盘分区:
            # echo -e "o\nn\np\n1\n\n\nt\n8e\nw" | fdisk /dev/${disk_name}
            # echo -e "o\nn\np\n1\n\n\nw" | fdisk /dev/${disk_name}
        刷新分区:
            # partprobe /dev/vdb
        创建pv:
            # pvcreate  /dev/${disk_name}{number}
        扩容vg:
            # vgextend  vg-test /dev/${disk_name}{number}
        扩容lv:
            # lvextend -l +100%FREE /dev/vg-test/lv-test  //使用free vg的全部容量
            # lvextend -L +300M /dev/vg-test/lv-test  //使用free vg的300M容量
        初始化:
            # mkfs.ext4 /dev/vg-test/lv-test
        刷新扩容后的容量:
            ext3/4文件系统:
                # resize2fs /dev/vg-test/lv-test
            xfs文件系统:
                # xfs_growfs  /dev/vg-test/lv-test
    
    lvm直接扩容:
        扩容物理卷PV:
            # pvresize /dev/vdf
        查看物理卷使用情况:
            # pvs 
        扩容逻辑卷:
            # lvextend -L +500G /dev/lvm_01/lv01 
        扩容逻辑卷文件系统:
            # resize2fs /dev/lvm_01/lvm_01
    
    linux大于2T磁盘分区:
        1. parted -l  #查看所有磁盘状态
          2. parted /dev/vdb   #通过parted工具来创建大于2T的分区
          3. mklabel gpt   #创建创建磁盘标签
          4. mkpart primary 0% 100% #创建整个分区
          5. q #退出
    
          #其他命令
          -------------------
          (parted) mklabel    #创建创建磁盘标签
          New disk labeltype? gpt
          (parted) p  #查看分区状态
          (parted) mkpart
          Partition name? []? gpt2t   #指定分区名称
          File system type? [ext2]ext3    #指定分区类型
          Start? 1    #指定开始位置
          End? 2190GB #指定结束位置
          (parted) P  #显示分区信息
          (parted) Q  #退出
    
    重装系统后挂载旧数据盘:
        1.扫描所有的卷组,vgscan
        2.重新命名挂载盘的卷组名 vgrename,两个卷组名是一样的话所有LVM分区无法进行挂载,必须改名:
            vgrename G8ysH1-61Mc-hVQI-YvNk-0301-KgJV-54x9CP vg01
        3.查看此盘有没有激活,lvscan
        4.激活此卷,vgchange -ay /dev/vgdata
        6.挂载
    

    扩容已存在的分区:
    https://zhuanlan.zhihu.com/p/83340525

    mysql5.7:
    # cat >>/etc/yum.repos.d/mysql56.repo<< EOF
    #Enable to use MySQL 5.6
    [mysql57-community]
    name=MySQL 5.6 Community Server
    baseurl=http://repo.mysql.com/yum/mysql-5.6-community/el/7/$basearch/
    enabled=1
    gpgcheck=0
    EOF
    # yum install -y mysql-community-server
    # systemctl start mysqld
    查看root密码:
    # grep ‘temporary password’ /var/log/mysqld.log
    修改密码:
    # ALTER USER ‘root’@’localhost’ IDENTIFIED BY ‘MyNewPass4!’;
    # set password for ‘root’@’localhost’=password(‘MyNewPass4!’);
    以后通过set设置:
    # update user set password=PASSWORD(‘MyNewPass5!’) where user=’root’;
    # flush privileges;

    僵尸进程
    查看:
    ps -ef | grep defunct
    ps -A -o stat,ppid,pid,cmd | grep -e ‘[1]‘ (比较详细)
    ps -A -o stat,user,ppid,pid,cmd | grep -e ‘[2]
    杀死:
    ps -e -o ppid,stat | grep Z | cut -d” “ -f1|xargs kill -9
    ps -e -o ppid,stat | grep Z | awk ‘{print $1}’|xargs kill -9
    ps -e -o ppid,stat | grep Z | awk ‘{print $1}’|xargs kill -9

    ubuntu查看安装包状态:
    查看信息:
    # dpkg -l nano
    查看详细信息:
    # dpkg -s nano
    查看安装包文件:
    # dpkg-query -L nano

    vxlan:
    ip link show | grep vx
    ip link delete vx-…

    查看占用swap的进程:
    for i in $(ls /proc | grep “[3]“ | awk ‘$0>100’); do awk ‘/Swap:/{a=a+日常笔记 - 图14i”‘,a/1024”M”}’ /proc/$i/smaps;done| sort -k2nr | head

    ubuntu关闭swap:
    # 查看是否有swap(返回空表示没有),也可以使用 top/free 查看
    sudo swapon —show
    # 关掉 swap
    sudo swapoff -v /swap.img
    # 修改 fstab ,取消启动挂载
    vim /etc/fstab
    # 删除交换分区文件
    rm -rf /swap.img

    systemd:
    /usr/lib/systemd/system
    开机级别的unit:
    .target
    服务级别的unit:
    .service

        系统服务:开机不登录就能运行的程序(常用于开机自启);
        用户服务:需要登录以后才能运行的程序;
    
    *.service的配置文件:
        [Unit]区块:启动顺序与依赖关系
            Description字段:给出当前服务的简单描述。
            Documentation字段:给出文档位置。
            After字段:如果network.target或sshd-keygen.service需要启动,那么sshd.service应该在它们之后启动。
            Before字段:定义sshd.service应该在哪些服务之前启动。
            注:After和Before字段只涉及启动顺序,不涉及依赖关系。
    
        [Service] 区块:启动行为
            启动命令:
                ExecStart字段:定义启动进程时执行的命令
                ExecReload字段:重启服务时执行的命令
                ExecStop字段:停止服务时执行的命令
                ExecStartPre字段:启动服务之前执行的命令
                ExecStartPost字段:启动服务之后执行的命令
                ExecStopPost字段:停止服务之后执行的命令
    
                注:所有的启动设置之前,都可以加上一个连词号(-),表示"抑制错误",即发生错误的时候,不影响其他命令的执行。比如EnvironmentFile=-/etc/sysconfig/sshd(注意等号后面的那个连词号),就表示即使/etc/sysconfig/sshd文件不存在,也不会抛出错误。
                注意:[Service]中的启动、重启、停止命令全部要求使用绝对路径!
    
            启动类型
                Type字段定义启动类型。它可以设置的值如下:
                    simple(默认值):ExecStart字段启动的进程为主进程
                    forking:ExecStart字段将以fork()方式启动,此时父进程将会退出,子进程将成为主进程(后台运行)
                    oneshot:类似于simple,但只执行一次,Systemd 会等它执行完,才启动其他服务
                    dbus:类似于simple,但会等待 D-Bus 信号后启动
                    notify:类似于simple,启动结束后会发出通知信号,然后 Systemd 再启动其他服务
                    idle:类似于simple,但是要等到其他任务都执行完,才会启动该服务。一种使用场合是为让该服务的输出,不与其他服务的输出相混合
    
            重启行为
                Service区块有一些字段,定义了重启行为:
                    KillMode字段:定义 Systemd 如何停止 sshd 服务:
                    control-group(默认值):当前控制组里面的所有子进程,都会被杀掉
                    process:只杀主进程
                    mixed:主进程将收到 SIGTERM 信号,子进程收到 SIGKILL 信号
                    none:没有进程会被杀掉,只是执行服务的 stop 命令。
                    Restart字段:定义了 sshd 退出后,Systemd 的重启方式
                    上面的例子中,Restart设为on-failure,表示任何意外的失败,就将重启sshd。如果 sshd 正常停止(比如执行systemctl stop命令),它就不会重启。
                    Restart字段可以设置的值如下。
                    no(默认值):退出后不会重启
                    on-success:只有正常退出时(退出状态码为0),才会重启
                    on-failure:非正常退出时(退出状态码非0),包括被信号终止和超时,才会重启
                    on-abnormal:只有被信号终止和超时,才会重启
                    on-abort:只有在收到没有捕捉到的信号终止时,才会重启
                    on-watchdog:超时退出,才会重启
                    always:不管是什么退出原因,总是重启
                    注:对于守护进程,推荐设为on-failure。对于那些允许发生错误退出的服务,可以设为on-abnormal。
                    RestartSec字段:表示 Systemd 重启服务之前,需要等待的秒数。
    
            [Install] 区块
                Install区块,定义如何安装这个配置文件,即怎样做到开机启动。
                    WantedBy字段:表示该服务所在的 Target。
                    Target的含义是服务组,表示一组服务。
                    WantedBy=multi-user.target指的是:sshd 所在的 Target 是multi-user.target。
                    这个设置非常重要,因为执行systemctl enable sshd.service命令时,sshd.service的一个符号链接,就会放在/etc/systemd/system目录下面的multi-user.target.wants子目录之中。
                    Systemd 有默认的启动 Target。
                    默认的启动 Target 是multi-user.target。在这个组里的所有服务,都将开机启动。这就是为什么systemctl enable命令能设置开机启动的原因。
                    使用 Target 的时候,systemctl list-dependencies命令和systemctl isolate命令也很有用。
    
                    一般来说,常用的 Target 有两个:
                        multi-user.target:表示多用户命令行状态;
                        graphical.target:表示图形用户状态,它依赖于multi-user.target;
    
        配置文件目录:
            systemctl脚本目录:/usr/lib/systemd/
            系统服务目录:/usr/lib/systemd/system/
            用户服务目录:/usr/lib/systemd/user/
    
            在/usr/lib/systemd/system目录下新建service-name.service文件:
    
        重载系统服务:systemctl daemon-reload
        设置开机启动:systemctl enable *.service
        启动服务:systemctl start *.service
        停止服务:systemctl stop *.service
        重启服务:systemctl restart *.service
    
        注:修改完配置文件要重载配置文件。
    

    Linux系统优化:
    1.永久关闭selinux

    2.加大系统文件描述符最大值
        https://segmentfault.com/a/1190000009724931
    

    CPU 100%:
    1. top -c —> P,找到最耗CPU的进程PID1;
    2. top -Hp PID1 —> P,找到最耗CPU的线程PID2;
    3. printf “%x\n” PID2,将线程PID2转化为16进制PID3;
    4. 查看堆栈,找到线程在干嘛:
    工具:pstack/jstack/grep
    方法:jstack PID1 | grep ‘PID3’ -C5 —color

        linux自带pstack,如果没有,yum -y install gdb
    

    md5校验:
    # md5sum FILE1 FILE2 > MD5_PATH
    # md5sum -c MD5_PATH
    FILE1: OK
    FILE2: OK
    修改内容后:
    # md5sum -c MD5_PATH
    FILE1: OK
    FILE2: FAILED
    # md5sum —status -c MD5_PATH
    # echo $?
    只要有一条failed记录,则状态码为1,否则为0;

    VPN:
    yum makecache
    && yum install -y python-setuptools m2crypto
    && yum install -y epel-release
    && yum install -y python-pip
    && pip install —upgrade pip -i http://pypi.douban.com/simple/ —trusted-host pypi.douban.com
    && pip install setuptools==33.1.1 -i http://pypi.douban.com/simple/ —trusted-host pypi.douban.com
    && pip install shadowsocks -i http://pypi.douban.com/simple/ —trusted-host pypi.douban.com

    echo '{
        "server":"0.0.0.0",
        "server_port":8388,
        "local_port":1080,
        "password":"MDBiNmQwZm",
        "timeout":600,
        "method":"aes-256-cfb"
    }' > /etc/shadowsocks.json
    nohup ssserver -c /etc/shadowsocks.json > /dev/null 2>&1 &
    
    autossh -p58422 vp@47.93.151.21 -NR 10003:localhost:10001 -M 23460 -f
    
    autossh配置vpn:
        https://gitissue.com/issues/5a81f25dc830d222b3803ae6
    
    linux安装shadowsocks客户端:
        # pip install shadowsocks 
        # vim /etc/shadowsocks/shadowsocks.json
        {
            "server":"vp.datagrand.com",
            "local_address": "127.0.0.1",
            "local_port":1080,
            "server_port":10001,
            "password":"MDBiNmQwZm",
            "timeout":300,
            "method":"aes-256-cfb"
        }
        # nohup sslocal -c /etc/shadowsocks/shadowsocks.json /dev/null 2>&1 &
    
        # yum -y install privoxy
        # vim /etc/privoxy/config
             forward-socks5t   /               127.0.0.1:1080 .
        # privoxy /etc/privoxy/config
    
        # vim /etc/profile
            export http_proxy=http://127.0.0.1:8118
            export https_proxy=http://127.0.0.1:8118
        # source /etc/profile
    
    启动容器的用户的~/.docker/config.json:
        "proxies": {
            "default": {
                "httpProxy": "http://172.17.19.216:4440",
                "httpsProxy": "http://172.17.19.216:4440",
                "noProxy": "4p5gxeik.mirror.aliyuncs.com"
            }
        }
    
    配置docker代理:
        # vim /usr/lib/systemd/system/docker.service
            Environment="HTTPS_PROXY=http://127.0.0.1:8118/"
            Environment="HTTP_PROXY=http://127.0.0.1:8118/"
            Environment="NO_PROXY=localhost,127.0.0.0/8,192.168.131.0/24,tbscd2mg.mirror.aliyuncs.com
    

    查看用户的crontab:
    cat /etc/passwd | cut -f 1 -d : |xargs -I {} crontab -l -u {}

    测试网卡:
    ethtool -p eno1

    添加阿里云源:
    cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
    wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-7.repo

    linux配置core dump:
    打开core dump:
    1.ulimit -c,如果输出结果为0,则默认是关闭core dump;
    2.ulimit -c unlimited开启core dump,不限制文件的大小;如果要限制文件大小,将unlimited改成生成core文件最大的大小,单位为KB;
    3.永久生效,修改/etc/security/limits.conf
    * soft core unlimited
    修改core文件保存的路径:
    1.默认生成的core文件保存在可执行文件所在的目录下,文件名就为core;
    2.echo 1 > /proc/sys/kernel/core_uses_pid,生成的core文件名将会变成core.pid,其中pid表示该进程的PID;
    3.echo “/tmp/corefile-%e-%p-%t” > /proc/sys/kernel/core_pattern设置生成的core文件保存在“/tmp/corefile”目录下,文件名格式为“core-命令名-pid-时间戳”;

    捕获内核crash—kdump:
    安装kdump:
    # yum install kexec-tools
    配置kdump文件:
    /etc/kdump.conf, path 指定捕获的文件路径
    修改grub配置:
    在/etc/default/grub文件中找到GRUB_CMDLINE_LINUX字段,加入crashkernel=[size],如果是默认是crashkernel=auto的话,只有物理内存大小2G时才会保留内存,如果小于2G内存,要想让系统保留内存必须手工指定一个固定保留内存大小如:crashkernel=128M;
    重新生成系统的grub配置文件:
    # grub2-mkconfig -o /boot/grub2/grub.cfg
    启动并开机启动:
    # systemctl start kdump

    效果测试:
        # echo 1 > /proc/sys/kernel/sysrq
        # reboot 
        # echo "c" > /proc/sysrq-trigger     触发系统蓝屏
    

    查看占资源的进程:
    1.CPU占用最多的前10个进程:
    ps auxw|head -1;ps auxw|sort -rn -k3|head -10

    2.内存消耗最多的前10个进程 
        ps auxw|head -1;ps auxw|sort -rn -k4|head -10 
    
    3.虚拟内存使用最多的前10个进程 
        ps auxw|head -1;ps auxw|sort -rn -k5|head -10
    

    linux去掉重复行:
    1.sort -n test.txt | uniq
    2.sort -n $file | awk ‘{if($0!=line)print; line=$0}’
    3.sort -n 日常笔记 - 图15!N; /^.?\n\1$/!P; D’

    linux中!的作用:
    1.执行history命令
    2.向一条新命令传递旧命令的参数
    !$
    3.多个参数:
    1.第一个参数用!^;
    2.第N个参数用!命令名字:N
    3.所有参数用!*
    4.调用最近使用的命令:
    !!
    例:su -c !! 使用sudo权限来执行之前的命令
    5.使用!(file_name)的方式来避免命令对某个文件的影响;

    排障:
    上下文切换:
    vmstat pid:
    cs(context switch)一列则表示了上下文切换的次数;
    pidstat -w pid:
    cswch和nvcswch表示自愿及非自愿切换;

    网络:
        tcpdump为Wireshark抓包:
            tcpdump -i en0 tcp -w test.cap 
    
        查看time_wait 和 close_wait:
            netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’
            ss -ant | awk '{S[$1]++} END {for(i in S) {print i,S[i]}}'
    
        探测命令:
            mtr -c 10 -r -n -T 8.140.139.87 -P 5900
    
        time_wait相关内核调优:
            小流量机器:
                net.ipv4.tcp_syncookies = 1   #表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
                net.ipv4.tcp_tw_reuse = 1    #表示开启重用,允许将time_wait sockets重新用于新的TCP连接,默认为0;
                net.ipv4.tcp_tw_recycle = 1        #表示开启TCP连接中time_wait sockets的快速回收,默认为0;
                net.ipv4.tcp_fin_timeout = 30    #修改系統默认的 TIMEOUT 时间。
            大流量机器:
                net.ipv4.tcp_keepalive_time = 1200   #表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。
                net.ipv4.ip_local_port_range = 10000 65000   #表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为10000到65000。(注意:这里不要将最低值设的太低,否则可能会占用掉正常的端口!)
                net.ipv4.tcp_max_syn_backlog = 8192  #表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
                net.ipv4.tcp_max_tw_buckets = 6000  #表示系统同时保持TIME_WAIT的最大数量,如果超过这个数字,TIME_WAIT将立刻被清除并打印警告信息。默认180000,改为6000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于 Squid,效果却不大。此项参数可以控制TIME_WAIT的最大数量,避免Squid服务器被大量的TIME_WAIT拖死。
    
                内核其他TCP参数说明:
                net.ipv4.tcp_max_syn_backlog = 65536  #记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M内存的系统而言,缺省值是1024,小内存的系统则是128。
                net.core.netdev_max_backlog = 32768   #每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
                net.core.somaxconn = 32768   #web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而nginx定义的NGX_LISTEN_BACKLOG默认为511,所以有必要调整这个值。
    
                net.core.wmem_default = 8388608
                net.core.rmem_default = 8388608
                net.core.rmem_max = 16777216           #最大socket读buffer,可参考的优化值:873200
                net.core.wmem_max = 16777216           #最大socket写buffer,可参考的优化值:873200
                net.ipv4.tcp_timestsmps = 0    #时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。
                net.ipv4.tcp_synack_retries = 2   #为了打开对端的连接,内核需要发送一个SYN并附带一个回应前面一个SYN的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量。
                net.ipv4.tcp_syn_retries = 2  #在内核放弃建立连接之前发送SYN包的数量。
                net.ipv4.tcp_tw_reuse = 1     # 开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接。
    
                net.ipv4.tcp_wmem = 8192 436600 873200   # TCP写buffer,可参考的优化值: 8192 436600 873200
                net.ipv4.tcp_rmem  = 32768 436600 873200  # TCP读buffer,可参考的优化值: 32768 436600 873200
                net.ipv4.tcp_mem = 94500000 91500000 92700000  # 同样有3个值,意思是:
                net.ipv4.tcp_mem[0]:低于此值,TCP没有内存压力。
                net.ipv4.tcp_mem[1]:在此值下,进入内存压力阶段。
                net.ipv4.tcp_mem[2]:高于此值,TCP拒绝分配socket。
                上述内存单位是页,而不是字节。可参考的优化值是:786432 1048576 1572864
    
                net.ipv4.tcp_max_orphans = 3276800   #系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。
                如果超过这个数字,连接将即刻被复位并打印出警告信息。
                这个限制仅仅是为了防止简单的DoS攻击,不能过分依靠它或者人为地减小这个值,
                更应该增加这个值(如果增加了内存之后)。
                net.ipv4.tcp_fin_timeout = 30   #如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60秒。2.2 内核的通常值是180秒,你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能吃掉1.5K内存,但是它们的生存期长些。
    
        close_wait:
            往往是因为应用程序写的有问题,没有在ACK后再次发起FIN报文;
    
        RST报文多会导致程序报错,在一个已关闭的连接上读操作会报connection reset;
        而在一个已关闭的连接上写操作则会报connection reset by peer;
        通常我们可能还会看到broken pipe错误,这是管道层面的错误,表示对已关闭的管道进行读写,往往是在收到 RST,报出connection reset错后继续读写数据报的错;
    

    rysnc:
    rsync -avz -e “ssh -p 5222” nginx zky1@192.168.131.130:/home/zky1/
    rsync -avzP product_extract /guangda/ 整个目录复制到目的目录下
    rsync -avzP product_extract/ /guangda/ 目录里的内容复制到目的目录下
    screen:
    screen # 进入一个screen
    ctrl_a d # 切出screen
    screen -ls # 查看正在运行的screen
    screen -r id # 重新进入screen
    screen -D -r id # 意外退出

    权限恢复:
    getfacl -R / > facl.bak
    setfacl —restore=facl.bak

    统计文件个数:
    ls -l | grep “^-“ | wc -l

    删除海量文件:
    创建一个空文件夹:
    mkdir /tmp/del
    rsync -avz —delete —progress /tmp/del/ $dest 清空某个文件夹
    rsync -avz —delete —progress —exclude “*.pdf” /tmp/del/ $src 删除某个文件夹内除了以.pdf结尾的文件

        find $src -mtime +14 -exec rm -rf {} \;
        find $src -mtime +14 -exec mv {} $dest \;
    
    清除某目录内某时间点之前的文件:
        import os, time, datetime
    
        def remove_files(remove_path, time_limit):
            files = os.listdir(remove_path)
            for file in files:
                file_path = os.path.join(remove_path, file)
                if not os.path.isfile(file_path):
                    continue
                file_create_time = datetime.datetime.fromtimestamp(
                    os.path.getctime(file_path))
                if datetime.datetime.now() - file_create_time > datetime.timedelta(
                        days=int(time_limit)):
                    print '{} deleted'.format(file_path)
                    os.remove(file_path)
    
    
        if __name__ == "__main__":
            remove_path = os.sys.argv[1]
            time_limit = os.sys.argv[2]
            print 'path: {}'.format(remove_path)
            print 'time limit: {}'.format(time_limit)
            remove_files(remove_path, time_limit)
    

    查看tcp连接:
    netstat -na | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’

    centos安装显卡驱动:
    rpm —import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
    rpm -Uvh https://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm

    yum install nvidia-detect
    
    查找合适驱动:
    nvidia-detect -v
    yum install $(nvidia-detect)
    reboot
    
    查看占用显卡进程:
        fuser -v /dev/nvidia*
    

    安装nvidia-docker2:
    distribution=$(. /etc/os-release;echo 日常笔记 - 图16VERSION_ID)
    curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | sudo tee /etc/yum.repos.d/nvidia-docker.repo
    yum install -y nvidia-container-toolkit
    systemctl restart docker

    查找可安装的nvidia docker版本:
        yum search --showduplicates nvidia-docker
    
    nvidia-smi报错:NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
        原因:由于内核版本与安装驱动时的版本不匹配造成的
        # ls /usr/src | grep nvidia
        # apt-get install dkms
        # dkms install -m nvidia -v 470.63.01
    

    elk自动清理curator:
    curator.yml:
    client:
    hosts:
    - 172.17.174.205
    port: 9200
    url_prefix:
    use_ssl: False
    certificate:
    client_cert:
    client_key:
    ssl_no_validate: False
    http_auth: datapro:Datapro
    timeout:
    master_only: False

        logging:
            loglevel: INFO
            logfile:
            logformat: default
            blacklist: ['elasticsearch','urllib3']
    
    action.yml:
        actions:
            1:
                action: delete_indices
                description: "delete index expire date"
                options:
                    ignore_empty_list: True
                    timeout_override:
                    disable_action: False
                filters:
                - filtertype: pattern
                  kind: prefix
                  value: logstash-
                - filtertype: age
                  source: name
                  direction: older
                  unit: days
                  unit_count: 30
                  timestring: '%Y.%m.%d'
    

    mysql:
    查看事务:
    SELECT FROM information_schema.INNODB_TRX
    查看锁:
    SELECT
    FROM INFORMATION_SCHEMA.INNODB_LOCKS
    查看事务进程:
    show PROCESSLIST
    修改表的默认字符集:
    SHOW VARIABLES LIKE ‘character%’;
    ALTER TABLE table_name DEFAULT CHARACTER SET character_name;
    修改表字段的默认字符集:
    ALTER TABLE table_name CHANGE field field field_type CHARACTER SET character_name [other_attribute]
    修改表的默认字符集和所有列的字符集:
    ALTER TABLE table_name CONVERT TO CHARACTER SET character_name

    查询每个库的容量大小:
    SELECT table_schema as '数据库', sum(table_rows) as '记录数', sum(truncate(data_length/1024/1024, 2)) as '数据容量(MB)', sum(truncate(index_length/1024/1024, 2)) as '索引容量(MB)', sum(truncate(DATA_FREE/1024/1024, 2)) as '碎片占用(MB)' from information_schema.tables group by table_schema order by sum(data_length) desc, sum(index_length) desc;
    

    linux文件名乱码:
    yum install convmv
    convmv -f gbk -t utf-8 -r —notest 文件夹路径

    修改linux编码:
    vi /etc/profile
        export LC_ALL="zh_CN.GBK"
        export LANG="zh_CN.GBK"
    
    source /etc/profile
    
    locale
    

    k8s通过域名:
    http://SERVICE_NAME.NAMESPACE.svc.cluster.local

    linux内核参数:
    net.core.rmem_default 默认的tcp数据接收窗口大小(字节)
    net.core.rmem_max 最大的tcp数据接收窗口(字节)
    net.core.wmem_default 默认的tcp数据发送窗口大小(字节)
    net.core.wmem_max 最大的tcp数据发送窗口(字节)
    net.core.netdev_max_backlog 当内核处理速度比网卡接收速度慢时,这部分多出来的包就会被保存在网卡的接收队列上,而该参数说明了这个队列的数量上限
    net.core.somaxconn 定义了系统中的每一个端口最大的监听队列的长度,是个全局参数;该参数和net.ipv4.tcp_max_syn_backlog,后者指的是还在三次握手的半连接的上限,该参数指的是处于established的数量上限
    net.core.optmem_max 表示每个套接字所允许的最大缓冲区的大小
    net.ipv4.tcp_mem 确定TCP栈应该如何反映内存使用,每个值的单位都是内存页(通常是4KB)。
    第一个值是内存使用的下限。
    第二个值是内存压力模式开始对缓冲区使用应用压力的上限。
    第三个值是内存使用的上限。在这个层次上可以将报文丢弃,从而减少对内存的使用。对于较大的BDP可以增大这些值(其单位是内存页而不是字节)
    net.ipv4.tcp_rmem 为自动调优定义Socket使用的内存。
    第一个值是为Socket接收缓冲区分配的最少字节数。
    第二个值是默认值(该值会被rmem_default覆盖),缓冲区在系统负载不重的情况下可以增长到这个值。
    第三个值是接收缓冲区空间的最大字节数(该值会被rmem_max覆盖)
    net.ipv4.tcp_wmem 为自动调优定义Socket使用的内存。
    第一个值是为Socket发送缓冲区分配的最少字节数。
    第二个值是默认值(该值会被wmem_default覆盖),缓冲区在系统负载不重的情况下可以增长到这个值。
    第三个值是发送缓冲区空间的最大字节数(该值会被wmem_max覆盖)
    net.ipv4.tcp_keepalive_time tcp发送keepalive探测消息的间隔时间(秒),用于确认tcp连接是否有效
    net.ipv4.tcp_keepalive_intvl 探测消息未获得响应时,重发该消息的间隔时间(秒)
    net.ipv4.tcp_keepalive_probes 在认定tcp连接失效之时,最多发送多少个keepalive探测消息
    net.ipv4.tcp_sack 启用转发应答(1表示启用),通过有选择地应答乱序接收到的
    net.ipv4.tcp_fack 启用转发应答,可以进行有选择应答(SACK)从而减少拥塞情况的发生,这个选项也应该启用
    net.ipv4.tcp_timestamps tcp时间戳(会在tcp包头增加12B),以一种比重发超时更精确的方法来启用对RTT的计算,为实现更好的性能应该启用这个选项
    net.ipv4.tcp_window_scaling 启用RFC 1323定义的window scaling,要支持超过64KB的TCP窗口,必须启用该值(1表示启用),TCP窗口最大至1GB,TCP连接双方都启用时才生效
    net.ipv4.tcp_syncookies 该参数表示是否打开TCP同步标签(SYN_COOKIES),内核必须开启并编译CONFIG_SYN_COOKIES,SYN_COOKIES可以防止一个套接字在有过多试图连接到达时,引起过载。默认值0表示关闭。
    当该参数被设置为1,且SYN_RECV队列满了之后,内核会对SYN包的回复做一定的修改,即在响应的SYN+ACK包中,初始的序列号是由源IP+Port、目的IP+Port及时间这五个参数共同计算出一个值组成精心组装的TCP包。
    由于ACK包中确认的序列号并不是之前计算出的值,恶意攻击者无法响应或误判,而请求者会根据收到的SYN+ACK包做正确的响应。启用net.ipv4.tcp_syncookies后,会忽略net.ipv4.tcp_max_syn_backlog
    net.ipv4.tcp_tw_reuse = 0 表示是否允许将处于TIME-WAIT状态的socket(TIME-WAIT的端口)用于新的TCP连接
    net.ipv4.tcp_tw_recycle = 0 能够更快地回收TIME-WAIT套接字
    net.ipv4.tcp_fin_timeout = 30 对于本端断开的Socket连接,TCP保持在FIN-WAIT-2状态的时间(秒),对方可能会断开连接或一直不结束连接或不可预料的进程死亡
    net.ipv4.ip_local_port_range 表示TCP/UDP协议允许使用的本地端口
    net.ipv4.tcp_max_syn_backlog 该参数决定了系统中处于SYN_RECV状态的TCP连接数量,SYN_RECV状态指的是当系统收到SYN后,作为SYN+ACK响应后等待对方回复三次握手阶段中的最后一个ACK的阶段,默认为1024
    net.ipv4.tcp_low_latency 允许TCP/IP栈适应在高吞吐量情况下低延时的情况,这个选项应该禁用
    net.ipv4.tcp_westwood 启用发送者端的拥塞控制算法,它可以维护对吞吐量的评估,并试图对带宽的整体利用情况进行优化,对于WAN通信来说应该启用这个选项
    net.ipv4.tcp_bic 为快速长距离网络启用Binary Increase Congestion,这样可以更好地利用以GB速度进行操作的链接,对于WAN通信应该启用这个选项
    net.ipv4.tcp_max_tw_buckets 该参数设置系统的TIME_WAIT的数量,如果超过默认值会被立即清楚,默认为180000
    net.ipv4.tcp_synack_retries 指明了处于SYC_RECV状态时重传SYN+ACK包的次数
    net.ipv4.ip_forward 接口间转发报文

    搭建本地yum源:
    1.使用centos光盘:
    # mkdir /mnt/cdrom
    # mount /dev/cdrom /mnt/cdrom
    如果不想每次都要放光盘,复制光盘文件到本地硬盘:
    # cp -avf /mnt/cdrom /yum # -a

        创建repo文件:
            cat >> /etc/yum.repo.d/CentOS-Local.repo << -EOF
            [Local]
            name=Local yum
            baseurl=file:///yum/
            gpgcheck=1
            gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
            enabled=1
    
    2.同步阿里云镜像到本地,搭建本地yum源:
    

    配置私有CA和nginx的https:
    1.生成CA证书:
    openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt
    Country Name (2 letter code) [AU]:CN # 指定国家代码
    State or Province Name (full name) [Some-State]:shanghai # 省份
    Locality Name (eg, city) []:shanghai # 城市名称
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:ceshi # 公司名称
    Organizational Unit Name (eg, section) []:devops # 部门
    Common Name (e.g. server FQDN or YOUR name) []:test.com # 一般写当前主机名即可
    Email Address []: # 邮箱,也可以不写

        ca.crt        # 公钥
        ca.key        # 私钥
    
    2.生成证书请求文件:
        openssl req -newkey rsa:4096 -nodes -sha256 -keyout test.ky -out test.csr
            Country Name (2 letter code) [AU]:CN                                    
            State or Province Name (full name) [Some-State]:shanghai                
            Locality Name (eg, city) []:shanghai                                    
            Organization Name (eg, company) [Internet Widgits Pty Ltd]:ceshi        
            Organizational Unit Name (eg, section) []:devops                        
            Common Name (e.g. server FQDN or YOUR name) []:test.com                    # 注意,这里可用写泛域名,在生产环境中最好写你公司的网站地址,如果多网站需要使用证书可用泛域名,当对来说比较贵
            Email Address []:                                                        
    
            Please enter the following 'extra' attributes
            to be sent with your certificate request
            A challenge password []:                                                # 注意,这里不要输入密码,直接回车即可,否则nginx在使用证书时需要交互式输入密码
            An optional company name []:
    
        test.key        # 专门用于网站的私钥
        test.csr        # 专门用于网站的公钥,但是该公钥还没有被签发证书,需要找自建的CA服务器做证书签发,有时候也可以说它是证书请求文件
    
    3.签发证书
        openssl x509 -req -days 36500 -in test.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out test.crt
    
        test.crt         # 被私有CA签发证书的公钥,这个证书文件可以直接使用了
    
    4.验证证书内容
        openssl x509 -in test.crt -noout -text
    
    5.查看证书过期时间
        openssl x509 -in test.crt -noout -dates
    

    证书相关:
    SSL:Secure Sockets Layer,现在应该叫”TLS”,https就是带加密的http协议,而https的加密是基于SSL的;
    OpenSSL:是SSL的一个实现,SSL只是一种规范;
    X.509: 一种证书标准,主要定义了证书中应该包含哪些内容;

    同样的X.509证书,可能有不同的编码格式,目前有以下两种编码格式:
        PEM:Privacy Enhanced Mail,打开看文本格式,以"------BEGIN..."开头,"-----END..."结尾,内容是BASE64编码;
            查看PEM格式证书的信息:openssl x509 -in cerificate.pem -text -noout
            Apache和*NIX服务器偏向于使用这种编码格式;
        DER:Distinguished Encoding Rules,打开看是二进制格式,不可读;
            查看DER格式证书的信息:openssl x509 -in certificate.der -inform der -text -noout
            JAVA和Windows服务器偏向于使用这种编码格式;
    
    相关的文件扩展名:
        CRT:CRT应该是certificate的三个字母,其实还是证书的意思,常见于*NIX系统,有可能是PEM编码,也有可能是DER编码,大多数应该是PEM编码;
        CER:还是certificate,还是证书,常见于Windows系统,同样的,可能是PEM编码,也可能是DER编码,大多数应该是DER编码;
        KEY:通常用来存放一个公钥或者私钥,并非X.509证书,编码同样的,可能是PEM,也可能是DER;
            查看KEY的办法:openssl rsa -in mykey.key -text -noout
            如果是DER格式的话:openssl rsa -in mykey.key -text -noout -inform der
        CSR:Certificate Signing Request,即证书签名请求,这个并不是证书,而是向权威证书颁发机构获得签名证书的申请,其核心内容是一个公钥,
            在生成这个申请的时候,同时也会生成一个私钥,私钥要自己保存好;
            查看的办法:openssl req -noout -text -in my.csr(如果是DER格式的话照旧加上-inform der)
        PFX/P12:predecessor of PKCS#12,对*nix服务器来说,一般CRT和KEY是分开存放在不同文件中的,但Windows的IIS则将它们存在一个PFX文件中,
                因此这个文件包含了证书和私钥,PFX通常会有一个提取密码,想把里面的东西读取出来的话,它就要求你提供提取密码,PFX使用的是DER编码;
                PFX转换为PEM编码:openssl pkcs12 -in for-iis.pfx -out for-iis.pem -nodes
                生成PFX的命令:openssl pkcs12 -export -in certificate.crt -inkey privatekey.key -out certificate.pfx -certfile CACert.crt
                            其中CACert.crt是CA的根证书,有的话也通过-certfile参数一起带进来,PFX其实是个证书密钥库;
        JKS:Java Key Storage,Java的专利,跟Openssl关系不大,利用Java的一个叫keytool工具生成,也可以将PFX转为JKS;
    
    证书编码的转换:
        PEM转为DER:openssl x509 -in cert.crt -outform der -out cert.der
        PEM转成CRT:openssl x509 -in fullchain.pem -out fullchain.crt
                openssl rsa -in privkey.pem -out privkey.key
        DER转为PEM:openssl x509 -in cert.crt -inform der -outform pem -out cert.pem
        (要转换KEY文件也类似,要把x509换成rsa,要转CSR的话,把x509换成req)
    
    获得证书:
        向权威证书颁发机构申请证书:
            openssl req -newkey rsa:2048 -new -nodes -keyout my.key -out my.csr
            把csr交给权威证书颁发机构,权威证书颁发机构对此进行签名,完成。保留好csr,当权威证书颁发机构颁发的证书过期的时候,你还可以用同样的csr来申请新的证书,key保持不变;
        生成自签名的证书:
            openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
            在生成证书的过程中会填一堆东西,其实真正要填的只有Common Name,通常填写你服务器的域名,或者服务器的IP
    
    可获得免费ssl证书:https://letsencrypt.org/zh-cn/getting-started/
    

    vsftp配置单用户多目录:
    mount —bind -o rw SOURCE_FILE FTP_DIR_FILE

    centos7安装Java8:
    # yum -y install java-1.8.0-openjdk java-1.8.0-openjdk-devel
    # vim /etc/profile
    # set java environment
    JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.262.b10-0.el7_8.x86_64
    JRE_HOME=日常笔记 - 图17JAVA_HOME/lib/dt.jar:日常笔记 - 图18JRE_HOME/lib
    PATH=日常笔记 - 图19JAVA_HOME/bin:$JRE_HOME/bin
    export JAVA_HOME JRE_HOME CLASS_PATH PATH
    # source /etc/profile

    nginx配置代理的相关参数:
    server {
    listen 80;
    server_name localhost;
    client_max_body_size 100M; 上传文件大小

        location / {
            proxy_pass    http://ip:port;
        }
    }
    
    
    
    
    grant replication slave on *.* to 'mysql1'@'10.0.2.%' identified by 'mysql1';
    

    change master to master_host=’mysql-master2’, master_user=’mysql2’, master_password=’mysql2’, master_log_file=’mysql-bin.000003’, master_log_pos=443;

    mysql:
    Slave_SQL_Running:No 同步故障解决办法
    > stop slave;
    > set GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
    > start slave;

    查看线程并按状态排序:
    top -H -d 0.1
    按f选择S然后按s,然后R倒叙排序

    统计打开文件数:
    lsof -n|awk ‘{print $2}’|sort|uniq -c |sort -nr|more

    文件名加时间戳:
    touch access_date +%Y%m%d%H.log

    查看某服务某时间段的日志:
    journalctl —since “2021-06-23 15:20:00” —until “2021-06-23 15:40:00” -u docker > /root/docker.log

    拼接字符串:
    paste -d: name.txt tag.txt > test.txt

    文件权限检查和修改:
    1.查找系统中任何用户都有写权限的文件和目录:
    查找文件:find / -type f -perm -2 -o -perm -20 |xargs ls -al
    查找目录:find / -type d -perm -2 -o -perm -20 |xargs ls –ld

    2.查找系统中所有含“s”位的程序:
        find / -type f -perm -4000 -o -perm -2000 -print | xargs ls –al
        含有“s”位权限的程序对系统安全威胁很大,通过查找系统中所有具有“s”位权限的程序,可以把某些不必要的“s”位程序去掉,这样可以防止用户滥用权限或提升权限的可能性。
    
    3.检查系统中所有suid及sgid文件:
        find / -user root -perm -2000 -print -exec md5sum {} ;
        find / -user root -perm -4000 -print -exec md5sum {} ;
        将检查的结果保存到文件中,可在以后的系统检查中作为参考。
    
    4.检查系统中没有属主的文件:
        find / -nouser -o –nogroup
        没有属主的孤儿文件比较危险,往往成为黑客利用的工具,因此找到这些文件后,要么删除掉,要么修改文件的属主,使其处于安全状态。
    

    容器单进程概念:
    由于容器实际上是一个“单进程”模型,所以如果你在容器里启动多个进程,只有一个可以作为PID=1的进程,而这时候,如果这个PID=1的进程挂了,或者说失败退出了,
    那么其他三个进程就会自然而然的成为孤儿,没有人能够管理它们,没有人能够回收它们的资源,这是一个非常不好的情况。
    如果真的把这个应用本身改成了systemd,或者在容器里面运行了一个 systemd,将会导致另外一个问题:使得管理容器不再是管理应用本身了,而等于是管理systemd,
    这里的问题就非常明显了。比如说我这个容器里面run的程序或者进程是systemd,那么接下来,这个应用是不是退出了?是不是fail了?是不是出现异常失败了?
    实际上是没办法直接知道的,因为容器管理的是systemd。这就是为什么在容器里面运行一个复杂程序往往比较困难的一个原因。

    panic_on_oom:
    1.检查文件/proc/sys/vm/panic_on_oom,如果里面的值为2,那么系统一定会触发panic
    2.如果/proc/sys/vm/panic_on_oom的值为1,那么系统有可能触发panic
    3.如果/proc/sys/vm/panic_on_oom的值为0,或者上一步没有触发panic,那么内核继续检查文件/proc/sys/vm/oom_kill_allocating_task
    3.如果/proc/sys/vm/oom_kill_allocating_task为1,那么内核将kill掉当前申请内存的进程
    4.如果/proc/sys/vm/oom_kill_allocating_task为0,内核将检查每个进程的分数,分数最高的进程将被kill掉

    为是死在那里,目的是给开发人员一个连上去debug的机会。但对于大多数应用层开发人员来说没啥用,倒是希望它赶紧重启。为了让内核panic后重启,可以修改文件/proc/sys/kernel/panic,里面表示的是panic多少秒后系统将重启,这个文件的默认值是0,表示永远不重启。
    

    离线安装包:
    rpm包下载链接:
    http://mirrors.163.com/centos/7/os/x86_64/Packages/
    通过yum下载依赖包:
    yum install —downloadonly —downloaddir=./ autoconf
    rpm安装不检查依赖:
    rpm -ivh *.rpm —nodeps —force

    通过inode号删除文件:
    ll -i
    find . -inum INUM -exec rm -i {} ;

    控制台显示设置:
    # vim /etc/profile.d/xx.sh
    POOL_NAME=日常笔记 - 图20%0A%09%09PS1_POOL%3D#card=math&code=%28hostname%29%0A%09%09PS1_POOL%3D&id=lkYte)(echo 日常笔记 - 图21%0A%09%09PS1_INT%3D#card=math&code=%7BPOOL_NAME%7D%20%7C%20tr%20%27A-Z%27%20%27a-z%27%29%0A%09%09PS1_INT%3D&id=Rc8nf)(/sbin/ip a | egrep -v ‘inet6|127.0.0.1|/32’ | awk -F’[ /]+’ ‘/inet/{print $NF” = “日常笔记 - 图22%0A%09%09export%20PS1%3D’%5B%5Ce%5B1%3B32m%5Cu%5Ce%5Bm%5Ce%5B1%3B33m%40%5Ce%5Bm’%22%5Ce%5B1%3B35m#card=math&code=3%7D%27%20%7C%20head%20-n1%29%0A%09%09export%20PS1%3D%27%5B%5Ce%5B1%3B32m%5Cu%5Ce%5Bm%5Ce%5B1%3B33m%40%5Ce%5Bm%27%22%5Ce%5B1%3B35m&id=qdarI)PS1_POOL\e[m”‘ \e[4m\w\e[m] \e[1;36m$PS1_INT\e[m\n$ ‘

        export HISTTIMEFORMAT="%F %T $USER_IP:`whoami` " 
        alias vi=vim
    

    curl将IP映射:curl -v —resolve test.datagrand.com:443:10.110.90.37 https://test.datagrand.com

    git查看用户名和邮箱地址:
    git config user.name
    git config user.email

    nginx文件服务器:
    server {
    listen 51111;
    server_name localhost;
    charset utf-8;
    root /tmp/static;

        location / {
            autoindex on;
            autoindex_exact_size on;
            autoindex_localtime on;
        }
    }
    

    nginx stream转发配置:
    nginx.conf:
    stream {
    log_format proxy ‘日常笔记 - 图23time_local] ‘
    ‘$protocol $status $bytes_sent 日常笔记 - 图24session_time “日常笔记 - 图25upstream_bytes_sent” “日常笔记 - 图26upstream_connect_time”‘;
    access_log /var/log/nginx/stream.access.log proxy;

        include /etc/nginx/stream.d/*.conf;
    }
    
    配置转发文件:/etc/nginx/stream.d/mysql.conf:
        upstream dg_mysql {
                server x.x.x.x:3306 weight=5 max_fails=3 fail_timeout=30s;
        }
        server {
            listen 53306(可以任意可用端口);
            proxy_pass dg_mysql;
        }
    

    centos 7进入单用户模式:
    1. 重启系统,在开机过程中,按下键盘方向键,让引导程序暂停;
    2. 按下e,进入编辑模式;
    3. 将光标一直移动到 LANG=en_US.UTF-8 后面,空格,再追加init=/bin/sh。这里特别注意,需要写在UTF-8后,保持在同一行,并注意空格。由于屏幕太小,会自动添加\换行,这个是正常的;
    4. 按下CTRL+X进行引导启动,成功后进入该界面

    输入命令:
    1. 挂载根目录,mount -o remount, rw /
    2. 选择要修改密码的用户名,这里选择root用户进行修改,可以更换为你要修改的用户 passwd root
    3. 重启系统即可exec /sbin/init 或 exec /sbin/reboot
    

    在执行更新sudo apt-get upgrade或者利用sudo apt-get install安装软件包时遇到:Errors were encountered while processing,查看错误信息发现:2 not fully installed or removed:

    解决方法:
        cd /var/lib/dpkg
        sudo mv info info.bak
        sudo mkdir info
        sudo apt-get upgrade
    

    查看机器信息:
    系统创建时间:dumpe2fs /dev/sda2 | grep “Filesystem”
    硬盘信息:smartctl —all /dev/sdb 或 hdparm -i /dev/sda

    Windows-PE相关操作:
    1.系统备份: ctrl + g —> local —> Partion —> to image —> 选定显示windows
    2.恢复系统: crtl + g —> local —> Partion —> from image —> 选定生成的系统文件
    Dism —> 选定C盘 —> 恢复功能 —> 引导修复

    nas删除却没有卸载:
    umount -fl …

    循环打印D状态进程:
    for x in seq 1 1 10; do ps -eo state,pid,cmd | grep “^D”; echo “——“$x; sleep 5; done

    设置rsyslogd和systemd journald
    mkdir /var/log/journal # 持久化保存日志的目录
    mkdir /etc/systemd/journald.conf.d
    cat > /etc/systemd/journald.conf.d/99-prophet.conf <[Journal]
    # 持久化保存到磁盘
    Storage=persistent

    # 压缩历史日志
    Compress=yes
    
    SyncIntervalSec=5m
    RateLimitInterval=30s
    RateLimitBurst=1000
    
    # 最大占用空间 10G
    SystemMaxUse=10G
    
    # 单日志文件最大 200M
    SystemMaxFileSize=200M
    
    # 日志保存时间2周
    MaxRetentionSec=2week
    
    # 不将日志转发到syslog
    ForwardToSyslog=no
    EOF
    
    systemctl restart systemd-journald
    

    显示路径
    vim /etc/porfile
    export PS1=’[\u@\h $PWD]# ‘

    查看公网:curl cip.cc

    https加密过程:
    1. 客户端打开URL,向服务端发送证书请求;
    2. 服务端将证书发过来;
    3. 客户端验证证书合法性;
    4. 客户端生成一个随机值,用证书加密以后发送个服务端;
    5. 服务端用私钥进行解密,得到随机值;
    6. 然后双方通过这个随机值对内容对称加密

    csi-driver-nfs