
Linux下tcp socket通信优化与问题排查 @Date 2018.12.09 一. 优化 1. TPC接收窗口 问题 : 当TCP的接收窗口队列阻塞 -> 发送方继续发 -> 接受方丢掉 -> 发送方重传 -> 网络变糟糕 解决 : 接收方把接收缓存的大小告诉发送方 -> 接收缓存满了 -> 发送方不能发送 # 调大接收窗口缓存大小 net.ipv4.tcp_rmem = "40960 873800 41943040" net.core.rmem_max = 41943040 net.core.rmem_default = 873800 # 打开win scale net.ipv4.tcp_window_scaling = 1 2. TCP拥塞窗口 # 优化拥塞窗口的初始大小 3. TIME_WAIT状态的回收 # 调整TIME_WAIT的回收时间 $ vi /etc/sysctl.conf net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_fin_timeout = 30 net.core.somaxconn = 2048 net.core.rmem_default = 262144 net.core.wmem_default = 262144 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.core.somaxconn = 10000 net.core.netdev_max_backlog = 20000 net.ipv4.tcp_rmem = 7168 11264 16777216 net.ipv4.tcp_wmem = 7168 11264 16777216 net.ipv4.tcp_mem = 786432 2097152 3145728 net.ipv4.tcp_max_syn_backlog = 16384 net.ipv4.tcp_fin_timeout = 15 net.ipv4.tcp_max_syn_backlog = 16384 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_max_orphans = 131072 net.ipv4.tcp_max_tw_buckets=180000 fs.file-max = 1000000 二. 问题 1. 连接超时 问题 : # 查看是否数量很多,代码不同不同请求连接过多,Syn队列溢出,丢弃连接 $ netstat -anp | grep SYN_RECV/TIME_WAIT 解决 : 更改配置文件数量,打开syncookie 问题 : # 前面数字一直快速增长,客户端大量请求,造成accept队列满,之后来syn包也会丢弃 # 服务端接收到syn后,先看syn队列,再看accept队列,有一个满则丢弃syn $ netstat -s | grep -i listen 解决 : 增加accept队列长度--配置文件, net.core.somaxconn=8192. 计算公式:Len of accept queue = min(backlog + 1,somaxconn) 问题 : 客户端经常连接失败 # 四元组:源ip、目的ip、源port、目的port # 一个客户端连接一个server只能使用固定端口范围 # TIME_WAIT状态的socket不能复用 解决 : 客户端解决,修改socket配置文件 # 调动端口使用范围 $ --net.ipv4.ip_local_port_range="1024 65535" # 复用time_out状态端口 $ --net.ipv4.tcp_tw_reuse=1 $ net.ipv4.tcp_timestamp =1 # 加快TIME_OUT状态端口释放速度 $ net.ipv4.tcp_tw_recyle=1 $ net.ipv4.tcp_timestamp=1 2. too many open files # 用户程序没有调用close函数,不会自动释放--程序异常 $ netsata -anp | grep CLOSE_WAIT
MACOSX Apache ab压力测试 @Date 2018.12.24 一. 介绍 ab是apachebench命令的缩写, 默认mac下都已经安装了, 但是默认版本会有几个问题, 故写此文章进行总结 二. 问题 1. apr_socket_recv: Connection reset by peer (xx) 原因 : 此问题是apache的bug, 在高版本上已经解决, 故我们需要在mac上升级ab的版本 解决 : 现在较高版本的apache, 下载地址(http://mirrors.hust.edu.cn/apache//httpd/httpd-2.4.34.tar.gz) 现在apache依赖的包,分别如下 APR : http://mirrors.shu.edu.cn/apache//apr/apr-1.6.5.tar.gz APR-Util : http://mirrors.shu.edu.cn/apache//apr/apr-util-1.6.1.tar.gz pcre : https://ftp.pcre.org/pub/pcre/pcre-8.00.tar.gz 安装(prefix是指向想要安装的路径) APR : 下载的APR压缩包解压缩, 进入APR目录 执行 ./configure –prefix=/usr/local/apr 使用sudo权限执行 make 使用sudo权限执行 make install APR-Util 同样进入解压后的apr-util目录 执行 ./configure –prefix=/usr/local/apr-util -with-apr=/usr/local/apr/ (此命令依赖apr) 使用sudo权限执行 make 使用sudo权限执行 make install pcre 同样进入解压后的pcre目录 执行 ./configure –prefix=/usr/local/pcre 使用sudo权限执行 make 使用sudo权限执行 make install 安装ab 进入解压后的httpd-2.3.34目录 sudo权限创建/usr/local/httpd/目录 依赖上面安装好的各种包, 执行以下命令 ./configure –prefix=/usr/local/httpd/ -with-apr=/usr/local/apr -with-apr-util=/usr/local/apr-util/ -with-pcre=/usr/local/pcre/ 使用sudo权限执行 make 替换Mac默认的ab 在上述3.4中, httpd目录下. 执行以下命令 sudo cp support/ab /usr/sbin .将编译后的最新ab命令copy到系统中. 此时会遇到最新MacOSX中权限问题, 请看下文[权限异常 Operation not permitted]() 2. apr_poll: The timeout specified has expired (70007) 原因 : 高版本的ab需要增加-s参数, 执行超时时间, 否则会30s则超时 解决 : ab --help 查询命令帮助 -s timeout 使用ab命令时,增加-s参数 3. MacOSX中/usr/sbin报错, Operation not permitted 原因 : 系统增加了Rootless机制机制,防止恶意程序执行高权限命令 解决 : 重启Mac系统, 在重启过程中一直按住Command+R, 进入恢复模式. 在恢复模式中无需点击其它操作, 在菜单栏中打开Terminal, 执行以下命令 csrutil disable. 解锁dtrace限制 三. ab命令使用 1. 参数详解 # 显示用法信息,其实就是ab -help -h # 打印版本号并退出 -V # 即requests,用于指定压力测试总共的执行次数 -n # 即concurrency,用于指定压力测试的并发数 -c # 即timelimit,等待响应的最大时间(单位:秒) -t # 即windowsize,TCP发送/接收的缓冲大小(单位:字节) -b # 即postfile,发送POST请求时需要上传的文件,此外还必须设置-T参数 -p # 即putfile,发送PUT请求时需要上传的文件,此外还必须设置-T参数 -u # 即content-type,用于设置Content-Type请求头信息,例如:application/x-www-form-urlencoded,默认值为text/plain -T # 即verbosity,指定打印帮助信息的冗余级别 -v # 以HTML表格形式打印结果 -w # 使用HEAD请求代替GET请求 -i # 插入字符串作为table标签的属性 -x # 插入字符串作为tr标签的属性 -y # 插入字符串作为td标签的属性 -z # 添加cookie信息,例如:"key=value"(可以重复该参数选项以添加多个) -C # 添加任意的请求头HEADER,请求头将会添加在现有的多个请求头之后(可以重复该参数选项以添加多个) -H # 添加一个基本的网络认证信息,用户名和密码之间用英文冒号隔开 -A # 添加一个基本的代理认证信息,用户名和密码之间用英文冒号隔开 -P # 指定使用的代理服务器和端口号 -X # 使用HTTP的KeepAlive特性 -k # 不显示百分比 -d # 不显示预估和警告信息 -S # 输出结果信息到gnuplot格式的文件中 -g # 输出结果信息到CSV格式的文件中 -e # 指定接收到错误信息时不退出程序 -r
架构知识体系总结 @Date 2018.08.30 一. 架构是什么? 系统:相互协同可运行的实体,是一群关联个体组成, 这些个体可以是子系统/模块/组件等 架构:顶层设计,需要明确系统包含哪些个体,明确个体运作和写作的规则 框架:面向编程或者配置的半成品 组件:技术维度的复用 模块:业务维度的职责划分 二. 架构设计的背景 软件生产力远远跟不上硬件和业务的发展, 软件的扩展非常复杂 系统规模庞大,内部耦合严重,开发效率低 系统耦合严重, 牵一发动全身, 后续修改和扩展困难 系统逻辑复杂, 容易出问题, 出问题后很难排查和修复 三. 架构设计的目的 解决软件系统复杂度 熟悉和理解需求, 识别系统的复杂点, 并针对解决 并不需要面面俱到, 不需要每个架构都具体CAP特性 在一个有约束的条件(团队经验/成本/资源/进度/业务)下去求最合适的解 需求驱动架构 分析 性能 可扩展性 高可用 存储高可靠 安全性/隐私性 成本 我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。
volatile关键字 @Date 2016.06.20 共享变量 多个线程之间能够被共享的变量 存放在堆内存中的实例变量,静态变量,数组变量 内存屏障 CPU指令,用于实现对内存操作的顺序限制 Volatile 确保所有线程看到这个变量的值是一致的 不会引起线程上下文的切换和调度 JVM就会向处理器发送一条Lock前缀的指令 缓存一致性协议: 当处理器发现自己缓存行对应的内存地址被修改,会将当前处理器的缓存行设置成无效状态 将当前处理器缓存行的数据会写回到系统内存 写回内存的操作会引起在其他CPU里缓存了该内存地址的数据无效 大多数处理器高速缓存行是64个字节宽 保证了可见性(对于一个变量i,多个线程同时去操作(比如++),i的值一定是0->1->2->3,而如果不加volatile则i的值可能是0->1->1->2) 不保证顺序性和原子性(volatile不会锁住变量,你再对第一个变量i做完操作之后,下一个volatile变量j可能已经发生改变了) 补充 强制线程去主存中读取Heap的信息 在并发时可以保证读取的最新的,但是不能保证对变量的操作是互斥以及顺序执行的
JVM堆外内存分析 @Date 2017.07.20 事件回顾 在对应用进行压测的时候,观察物理内存占用以及JVM堆中对象情况,发现物理内存占用很大,堆中对象却很少.怀疑是堆外内存占用问题. 工具介绍(gperftools) 下载工具libunwind-1.0.tar.gz和gperftools-2.5.tar.gz并进行编译安装(具体可以查找教程) 在安装之后并配置好gperf路径 在JVM启动应用之前,执行以下命令 export LD_PRELOAD=/usr/local/lib/libtcmalloc.so export HEAPPROFILE=/home/admin/logs/pro 会在HEAPPROFILE指定的目录中生成.heap文件 使用以下命令可以查看堆外内存文件的构成(支持导出gif或者pdf) pprof --text /opt/taobao/install/ajdk-8.2.3-b46/bin/java pro_149025.0001.heap pprof --pdf /opt/taobao/install/ajdk-8.2.3-b46/bin/java pro_149025.0001.heap > xxx.pdf pprof默认显示方法占用,但是有的时候只显示内催地址,不显示具体方法,不容易排查,则可以用下面的工具dump出来内存地址和方法的一个关系.生成的是16进制的起始地址和16进程的地址长度.可以写个脚本计算之后与pprof结果对比 https://github.com/jvm-profiling-tools/perf-map-agent