操作系统

升级CentOS6.5内核,开启Nginx的fastopen和reuseport特性

前面,张戈博客在折腾Nginx的SSL优化时,注意到前人在Nginx的listen配置中,添加了 fastopen=3 reuseport 这2个参数。 于是脑补了下,原来是启用Nginx对TCP_FASTOPEN和TCP_SO_REUSEPORT新特性的支持,至于有什么好处,请自行脑补下-->传送门 一、必要环境 当我依葫芦画瓢也添加这2个参数时,报错了: 继续脑补了下,发现系统必须支持 TCP_FASTOPEN和TCP_SO_REUSEPORT,然后重新编译Nginx加入如下参数: TCP_SO_REUSEPORT特性在kernel-2.6.32-431.29.2及kernel-3.9被启用,CentOS 6用户可以通过更新内核到2.6.32-431或更高版本来支持这项特性。 这个非常简单,直接yum -y update就行了。 关于TCP_FASTOPEN特性在kernel-3.6被客户端支持,在kernel-3.7被服务端支持,也就是说使用TCP_FASTOPEN需要CentOS 6更新内核至3.7或更高版本,以便支持这项特性。 ——摘自kn007的个人博客 二、升级内核 1、方式选择 看了下前人的分享,Centos内核升级一般有2种方式:编译安装或利用EPEL的yum源在线升级 在我看来,下载源码编译安装,不但步骤繁琐,而且容易出错,简直是小白的克星,而yum在线升级不易出错且步骤简单,简直是懒人必选良方,因此这里就只分享yum在升级方案,如果不是centos,就只能自己去找下源码编译的教程了。 在yum的ELRepo源中,有 mainline(3.13.1)、 long- term(3.10.28)这2个内核版本,考虑到long-term更稳定,会长期更新,所以选择这个版本。 2、导入public key 3、安装ELRepo到CentOS-6.5中 4、安装 kernel-lt(lt=long-term) Ps:如果是安装kernel-ml(ml=mainline版本),则把上述代码中的 kernel-lt 改为 kernel-ml。 5、确认Grub引导顺序 一般来说,新安装的内核映像会位于第一位,所以只要检查grub.conf中的default值是否指向新装内核即可,比如我的系统: 6、启用特性 编辑 /etc/sysctl.conf ,插入  net.ipv4.tcp_fastopen = 3,执行如下命令即可: 搞定一切之后,我们重启系统完成此次内核升级。 ——以上参考自 《使用yum快速升级CentOS 6.5内核到 3.10.28 | 原作者:健富的博客》 三、重新编译 接下来,我们需要重新编译我们的Nginx或Tengine,新增 --with-cc-opt=-DTCP_FASTOPEN=23 1、先查看当前Nginx的编译参数: 2、新增开启FASTOPEN参数,重新编译Nginx参数为: Ps:就是在原有的参数上新增  --with-cc-opt=-DTCP_FASTOPEN=23 ,重新编译前面已经分享过具体操作,这里就不赘述了,不会的朋友请参考:Nginx在线服务状态下平滑升级或新增模块的详细操作记录 3、重新编译,修改Nginx的listen配置: 编辑网站的配置文件,比如zhang.ge.conf,找到listen,然后再结尾分号前面新增 fastopen=3 reuseport参数,比如: 如果使用的是Tengine,这个配置就会报错: 最后了解到,Tengine关于reuserport的配置并不是在Listen,而是放到 events 模块。 所以,如果是Tengine,那么编辑nginx.conf主配置文件,找到events模块,如下新增 reuse_port on; 参数: 然后,在网站的listen处新增 fastopen=3 : 最后,reload重载Nginx即可,这样就不会报错了。 四、其他记录 升级内核,并启用了Nginx新特性之后,并没有进行深入的压力测试,所以本文无法给出优化后的各项性能数据,也不知道具体有多少提升,感兴趣的朋友可以自己开启,然后压测看看。 不过,升级内核后,系统多了200+rcuos和rcuob进程: 实际查看,也并没有占用系统内存或其他资源,看了一些老外论坛相关说明,也没得出一个所以然来,所以先视而不见吧!
阅读全文
操作系统

分享一次Linux任务计划crontab不执行的问题排查过程

朋友弄了一个小项目,要我帮忙做下Linux系统运维,上线一段时间后,发现项目偶尔会挂掉导致服务不可用。开发朋友一时之间也没空去研究项目奔溃的根因,只好由我这个运维先写一个项目进程自拉起脚本,通过Linux任务计划每分钟检查一下进程是否存在来避免项目挂了没人管的情况。 自拉起脚本很简单,随便写几行就搞定了: 然后丢到 crontab,1分钟执行一次: 本以为万事大吉了,结果还是坑了,进程再一次挂了,尼玛什么鬼? 一、检查日志 根据经验,先看一下crontab的日志: tail /var/log/messages 没发现相关日志,看来不是打印到了这,于是查看了下crontab的默认日志位置: tail /var/log/cron 很明显,任务计划确实在正常执行着,看来问题在脚本上了。 二、检查脚本 ①、直接执行 检查脚本第一步,直接按照crontab里面的命令行,执行脚本: 结果进程正常拉起了! 直接执行成功,而放到crontab就失败,经验告诉我肯定的脚本环境变量有问题了! ②、环境变量 于是在脚本里面载入环境变量: 然后手工把进程杀死,等待自拉起,结果... 还是不行! ③、系统邮件 经验告诉我,crontab执行失败,如果没有屏蔽错误的话,会产生一个系统邮件, 位置在 /var/spool/mail/root 所以,我把crontab里面的 2>&1 这个屏蔽错误先取消掉,等待几分钟查看邮件。 cat /var/spool/mail/root 发现有如下报错: 居然是脚本里面的sudo执行失败了,找不到这个文件。看来单纯的载入 profile 不一定靠谱啊! ③、修复脚本 知道问题所在,解决就简单了,粗暴点,直接写入sudo的绝对路径 /usr/bin/sudo 继续测试自拉起,结果... 还是不行!R了G了!! 三、最终解决 继续查看了下系统邮件,发现如下信息: 很明显,提示了sudo必须需要tty才能执行,解决很简单,取消这个限制即可! 编辑 /etc/sudoers ,找到 Defaults    requiretty, 然后注释掉这行: 最后使用 :x! 或 :wq! 强制保存即可。 结果观察还是报了相同的错误!原来改完这个sudo并不会影响已经运行的crontab,所以需要重启crontab服务刷新下设置: 这下终于可以了! 四、分析总结 Linux系统里面计划任务,crontab 没有如期执行这是运维工作中比较常见的一种故障了,根据经验,大家可以从如下角度分析解决: ①、检查crontab服务是否正常 这个一般通过查看日志来检查,也就是前文提到的 /var/log/cron 或 /var/log/messages,如果里面没有发现执行记录,那么可以重启下这个服务:service crond restart ②、检查脚本的执行权限 一般来说,在crontab中建议使用 sh 或 bash 来执行shell脚本,避免因脚本文件的执行权限丢失导致任务失败。当然,最直接检查就是人工直接复制crontab -l 里面的命令行测试结果。 ③、检查脚本需要用到的变量 和上文一样,通常来说从crontab里面执行的脚本和人工执行的环境变量是不一样的,所以对于一些系统变量,建议写绝对路径,或使用witch动态获取,比如  sudo_bin=$(which sudo) 就能拿到 sudo在当前系统的绝对路径了。 ④、放大招:查看日志 其实,最直接最有效的就是查看执行日志了,结合crontab执行记录,以及crontab执行出错后的系统邮件,一般都能彻底找到失败的原因了!当然,要记住在crontab中如果屏蔽了错误信息,就不会发邮件了。 这又让我想起了如果crontab未屏蔽日志,可能会导致硬盘 inode 爆满 ==> 历史文章传送门 ,感兴趣的童鞋也可以谷歌一下 /var/spool/clientmqueue/ 这个关键词了解下。 好了,本文分享到此,希望对你有所帮助!
阅读全文
操作系统

解决Linux修改密码报PAM authentication failed错误

最近接到一个运维开发任务,需要开发一个帐号管理系统,对手头三千多台Linux服务器的root帐号进行批量系统的管理,实现定期修改root为随机密码并加密存储,并向运维管理WEB前台提供密码查询解密接口等功能。 刚开始,我基于php+ssh2_exec开发了一套雏形。基本功能都实现了,结果老大说这里的运维就我稍微会点php,后面可不好维护。本来也被我说服了,因为写都写好了,难道要重构? 后面线上测试发现,公司有部分系系统接入了ldap鉴权,php的ssh2_exec就无法工作了,返回登陆失败的错误。 不得已,最后苦逼的用python将这个系统重构了一遍,并实现了多线程模式,因为不太会python的cgi框架,就用php搭的api接口,到此为止,基本全部搞定了。 在线上测试了几天后,发现总是有一台服务器要卡半天,登陆校验日志倒是成功的,但总是卡在修改密码那一步。 于是,print一下过程,发现chpasswd改密码这一步报错了!导致expect卡住了。 看了下错误信息是: chpasswd: PAM authentication failed 实际登陆这台机器,执行chpasswd,发现也是报这个错误。 试着执行passwd,也报错了: passwd: pam_start() failed, error 26 搜了半天,也看了半天的洋文案例,都没找到一个贴切的解决办法。最终,我看到有一篇类似的案例,他是通过检查 /var/log/secure 日志文件找到的错误。 于是,我也试着碰碰运气,发现还真有记录! 在 /var/log/secure 中,发现我在执行chpasswd命令是会提示找不到/etc/pam.conf文件。于是到其他系统上去看有没有这个文件,发现也没有的。 最终,我无奈之下,对比了2个系统的/etc目录,让我发现了猫腻!不知道哪个无聊的人把这个系统的/etc/pam.d给重命名为pam.d_bak了!!我去你XXX,浪费我半天时间。 直接 mv pam.d_bak pam.d,然后就能够执行 echo 'root:newpassword'|chpasswd 来修改密码了。 这种奇葩的原因并不多见,所以出了问题不一定能在搜索引擎得到答案。 不过,我写这篇文章的时候,特意把pam.d再一次重命名,chpasswd还是报一样的错,但是passwd报错却变成了: passwd: Permission denied 罗里吧嗦说了半天,主要分享一下这个奇葩的案例和解决过程。当搜索引擎都找不到的时候,那么恭喜你成为了第一个吃螃蟹的人,有了造福互联网的机会,赶紧解决问题再分享吧。。。 目前我开发的帐号管理系统运行良好,后续有时间再整理分享一下,也许有人需要,敬请期待!
阅读全文
操作系统

解决dos2unix/unix2dos报错,并在家目录下生成u2dtmp*文件问题

最近接到一个 case:大数据分析那边反馈我们这边推送的数据同比去年同期少了很多。这是很不正常的,因为业务一直在增长。 于是,我开始顺藤摸瓜的跟进。一开始就发现一个小问题:scp 推送文件脚本执行后居然会报错: # sh pushdata.sh dos2unix: converting file pushdata.log to UNIX format ... dos2unix: problems renaming './u2dtmp8jwsge' to 'pushdata.log' output file remains in './u2dtmp8jwsge' dos2unix: problems converting file pushdata.log 原来是将生成的日志转换成Unix格式。按理说应该不会影响数据的推送,不过还是顺手处理下。 奇怪的是,人工去执行 dos2unix 却是正常的,看来和脚本有关系了。看了半天的脚本,也没看出哪儿有明显的错误: dos2unix  /data/pushdata.log 还是先不浪费时间自己摸索了,直接丢百度一下,发现并没有什么luan用。进而丢谷歌,终于在一个国外论坛找到了正确的解释: It turns out that when you run the script from cron your current directory (PWD) is set to your home directory. Unix2dos creates the temporary file used in the conversion in your home directory then can't find it to rename it. Not sure why it can't find it. I added a change directory command (cd) and Unix2dos worked. 大概意思是,crontab 计划任务中的脚本当前执行路径默认会设置为家目录。所以,dos2unix/unix2dos 会在家目录下创建转换后的临时文件(u2dtmp****),导致命令无法在目标路径找到将临时文件,并重命名为被处理的文件名,作者表示他也不知道为什么会找不到。不过他给出的解决办法就是:在脚本里面加入cd到日志所在路径的命令即可。 比如,本文case中可以在脚本一开始处加入...
阅读全文
操作系统

Linux在批量服务器管理中实用的PS1命令提示符格式

作为一个大公司的运维,手头管理了成百上千的服务器是家常便饭,甚至更多。而我们一般都是用跳板机登陆,由于这些机器一般都是克隆或者虚拟化出来的,所以登陆后的命令行提示符几乎是一个模子刻出来的,比如都是:# 这时,我们肯定会经常遇到这样一个困扰:操作服务器时因某事中断,回头继续操作的时候肯定会ifconfg确认下是否是我要操作的服务器,因为无法从表象识别。 所以,我们很有必要将这个PS1命令行提示符优化一下。每个运维攻城狮肯定都有自己的习惯,不过我还是推荐一个服务器批量管理中比较使用的PS1格式吧! PS1是神马?PS1是linux里头的一个默认的环境变量,至于当前系统的PS1是如何设置的,你可以使用命令“env|grep PS1”来查看 。 其实PS1就是用来设置命令提示符格式的环境变量。 下面贴一下PS1的配置参数: 当然,为了更好的识别,我们还可以加入一些颜色设置,这个就不赘述了,百度一下shell颜色即可,当然记得参考下文的PS1进行自定义。 为了更好的区分服务器,我建议使用如下格式: 所以PS1可以如下设置: 但是机器太多,这个IP总不能每次手动修改,所以还是写个脚本来修改吧!(当然,你也可以先获取IP,赋值变量加入到PS1) 脚本很简单: 好了,最后直接 source ./update_PS1.sh 即可看到效果: 重新登陆或source /etc/profile,就可以看到效果了: 这样设置之后,就能清晰的知道现在操作的是服务器是哪一台,而不至于混淆。
阅读全文
操作系统

Linux系统编译安装Redis以及主从复制配置小记

Redis的安装配置很简单,而且很早之前就装过Redis,可这几天再次安装时居然又遗忘了一些细节,看来好记性不如烂笔头,还是在博客记录一下比较好,至少不用总是抱度娘大腿了。 今天编译安装了几次,发现居然没在prefix指定目录生成文件??看了半天结果发现PREFIX我用了小写字母。。。 看来还是得记录一次正确的操作步骤,免得再次出现这种窘迫。 一、选择版本 前往官方网站:http://www.redis.io/download 选择一个适合的稳定版本,比如最新的redis-3.0稳定版(stable),获得下载地址: http://download.redis.io/releases/redis-3.0.0.tar.gz 二、编译安装 安装完成后,redis目录结构如下: 三、注册服务 ①、编写服务控制脚本 vi /etc/init.d/redis ②、注册服务与启动 四、主从配置 ①、配置 在从机上按照上面的步骤安装redis,然后在从机的redis.conf里面新增如下配置项目: 保存后启动redis即可完成简单的主从配置。  ②、测试 测试很简单,先在主机上通过客户端 redis-cli 执行新增键值命令: 然后,登录从机上同样执行 redis-cli 执行查询命令: 很明显主机上新增的键值已经自动同步到了从机,主从同步成功! 本文只是记录一下基本的编译安装和主从配置,当然,redis还有其可以继续进行自定义设置或优化的项目,后续有机会再继续整理补充一下。
阅读全文