解决SOAP客户端在请求https时设置超时时间无效导致进程卡死问题

目前有一个进程服务脚本是不断查询渠道的接口,但是历史问题是有时订单量大的时候进程会卡死,这次遇到了进行排查一下:

首先获取该进程ID

ps -aux | grep QueryABC.php

sync360  11115  0.0  0.0   6564   864 ?        Ss   14:00   0:00 /bin/sh -c /usr/local/bin/php /xxxx/xxxx/xxxx/xxxx/xxxx/xxxx/xxxx/xxxx/xxxx/QueryABC.php BILL99DF 10-8>> /home
sync360  11124  0.0  0.4 361628 17296 ?        S    14:00   0:04 /usr/local/bin/php /xxxx/xxxx/xxxx/xxxx/xxxx/xxxx/xxxx/xxxx/xxxx/QueryABC.php BILL99DF 10-8
sync360  25230  0.0  0.0  63384   872 pts/0    S+   15:28   0:00 grep QueryABC.php

strace查看该进程正在持续的状态

sudo strace -T -tt -e trace=all -p 11124
[sudo] password for ancongcong: 
Process 11124 attached - interrupt to quit
15:33:07.259044 read(9, 

lsof查看进程的所使用的文件

lsof -p 11124

....
php     11124 sync360  mem    REG        8,1    23736    3211320 /lib64/libnss_dns-2.5.so
php     11124 sync360    0r  FIFO        0,6          1522728709 pipe
php     11124 sync360    1w   REG        8,1  4088819    1869737 /xxxx/xxxx/xxxx/xxxx/logs/QueryABC.log
php     11124 sync360    2w  FIFO        0,6          1522728710 pipe
php     11124 sync360    3w   CHR        1,3                 982 /dev/null
php     11124 sync360    4u  IPv4 1522728838                 TCP 211.151.122.234:46004->10.117.128.47:rtmp-port (CLOSE_WAIT)
php     11124 sync360    5wW  REG        8,1        0    2704363 /xxxx/xxxx/xxxx/xxxx/xxxx/xxxx/xxxx/xxxx/xxxx/lockfile/QueryABC.php.BILL99DF.10-8
php     11124 sync360    6u  IPv4 1522728841                 TCP 211.151.122.234:51019->10.117.128.46:rtmp-port (CLOSE_WAIT)
php     11124 sync360    7w   REG        8,1 31960384    1869789 /xxxx/xxxx/xxxx/xxxx/logs/XXXX_info.log.20180118
php     11124 sync360    8w   REG        8,1 18151722    1869806 /xxxx/xxxx/xxxx/xxxx/logs/XXXX_QRY_info.log.20180118
php     11124 sync360    9u  IPv4 1522729884                 TCP 211.151.122.234:54976->61.152.114.130:https (ESTABLISHED)
sudo netstat -tunpa | grep 11124
tcp        0      0 211.151.122.234:54976       61.152.114.130:443          ESTABLISHED 11124/php           
tcp        1      0 211.151.122.234:51019       10.117.128.46:3500          CLOSE_WAIT  11124/php           
tcp        1      0 211.151.122.234:46004       10.117.128.47:3500          CLOSE_WAIT  11124/php      

可以发现最终是停留在https的链接建立,等待获取数据,查看此处代码

ini_set('default_socket_timeout',30);
scOptions = array('connection_timeout' => 30);clientObj = new SoapClient( wsdl ,scOptions);

当前版本php较老,这里是有个bug的在https链接请求时SOAPClient的超时时间是不生效,最终采取如下方案解决此问题:

复写SOAPClient,在https时候使用curl来完成请求解决问题

<?php
class SoapClientTimeout extends SoapClient
{
    private timeout;

    public function __setTimeout(timeout)
    {
        if (!is_int(timeout) && !is_null(timeout))
        {
            throw new Exception("Invalid timeout value");
        }

        this->timeout =timeout;
    }

    public function __doRequest(request,location, action,version, one_way = FALSE)
    {
        if (!this->timeout)
        {
            // Call via parent because we require no timeout
            response = parent::__doRequest(request, location,action, version,one_way);
        }
        else
        {
            // Call via Curl and use the timeout
            curl = curl_init(location);

            curl_setopt(curl, CURLOPT_VERBOSE, FALSE);
            curl_setopt(curl, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt(curl, CURLOPT_POST, TRUE);
            curl_setopt(curl, CURLOPT_POSTFIELDS, request);
            curl_setopt(curl, CURLOPT_HEADER, FALSE);
            curl_setopt(curl, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
            curl_setopt(curl, CURLOPT_TIMEOUT, this->timeout);response = curl_exec(curl);

            if (curl_errno(curl))
            {
                throw new Exception(curl_error(curl));
            }

            curl_close(curl);
        }

        // Return?
        if (!one_way)
        {
            return (response);
        }
    }
}

解决PHP7下Session callback expects true/false return value in 问题

升级项目致PHP7遇到Session报警告,既然升级新版本,警告什么的肯定要一起都处理了

session_start(): Session callback expects true/false return value in

经过跟踪排查,发现是到session_start这一步遇到问题,session_start()使用你之前通过session_set_save_handler(….)方法设置的处理器,现在PHP7要求必须返回true/false,所以你需要检查一下你的这些处理器方法是否准确返回true/false了

session_start() uses any handlers you’ve previously set with session_set_save_handler(…), and that handler (or the individual functions) must return a true/false result to signal success or failure. You have a handler that does not return a true/false result. To recap; the actual error is the implementation of your session handler, not the code that calls session_start().

记录Linux系统邮件mail无法发送问题

很多应用,比如wordpress使用PHP的mail函数,将会调用系统邮件发送功能,这时候邮件无法发送该如何排查呢?

  • 安装sendmail来发送邮件
yum -y install sendmail
  • 启动sendmail
/etc/init.d/sendmail start

可通过ps -ef | grep sendmail,观察是否启动成功

  • 测试邮件发送
echo “mail content”| mail -s 'Test mail' accacc@126.com

如果没收到那么查看一下 /var/spool/clientmqueue下面是否存在未发送邮件,tail -f /var/log/maillog 查看邮件发送日志。

另外查看一下网络访问及25端口有无问题。

解决/var/spool/clientmqueue/文件过多问题并记录Linux下快速列出含文件较多文件夹的内容方法

最近发现sendmail的进程较多,观察了一下,是在消费/var/spool/clientmqueue/下的内容,这里面文件太多ls直接卡死了,那么如何列出来呢?

先后使用了ls、tree、find等命令,效果都不明显。

最后使用locate成功解决~

sudo locate clientmqueue > ~/1.txt

观察了一下至少有600多万个文件。。。

当你使用简单的sendmail发邮件的时候, 或者系统默认要发一些邮件(比如cron发的邮件)的时候,首先会把邮件拷贝到这个目录里,然后等待MTA(mail transfer agent) 来处理,MTA做的事情通常是把这个目录中的邮件弄到/var/spool/mqueue里,然后再发送到真正的目的地。出现/var/spool /clientmqueue/非常大的情况通常因为没有合适的MTA发送邮件,就都积累在这里了,假如这里的邮件并不是你需要的,你可以简单的删掉他们。

根据需要发邮件的内容来看,解决这块主要两点:

1、针对crontab一些输出之类的其会发邮件,需要定时任务后加上

 >/dev/null 2>&1

2>是重定向错误

2、梳理业务逻辑控制发邮件频次

当然这两个前段时间都处理了一下,这次主要启用的机器有一些之前的邮件,所以删除了

ls /var/spool/clientmqueue | xargs rm -f

xargs的功能:它将输入输出给xargs后面的命令,作为那个命令的参数

如果你感觉删的比较慢想先快速解决,那么先给他mv一下吧,把事情解决了,然后慢慢删

完事后记得重启一下sendmail sudo /etc/init.d/sendmail restart

Spring Tools报IOException: Server returned HTTP response code: 400 for URL记录

Spring Tools准备创建Spring工程时,报

IOException: Server returned HTTP response code: 400 for URL: http://start.spring.io

这是因为IE为系统配置了代理,但是代理服务器没有开,所以优先检查IE->Internet选项->连接->局域网设置,不要勾选代理服务器,如还不行,检查eclipse的代理设置

解决eclipse遇到An internal error occurred during: “Building UI model”问题

尝试使用Spring Tools创建工程时遇到,An internal error occurred during: “Building UI model问题,这是因为STS版本与eclipse版本不匹配,以下两种解决方式可以处理:

方案一:在这里 “https://spring.io/tools/sts/legacy” 下载eclipse STS,下载前记得看一下eclipse版本

方案二:你不能在“eclipse Market Place”下载STS,因为eclipse会去找最新版本的STS,你可以点击Help->Install new software ,然后使用这个网址去下载 http://dist.springsource.com/release/TOOLS/update/e4.X/ (X替换为你的eclipse版本号)

解决启动Spring报java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy问题

这是JDK以特殊的方式告知你,在class path下找不到这个需要依赖的注解,很不幸的是他并不会告知你是哪个注解,或者是哪个类缺失。

可以检查一下依赖管理,尝试修复一下,maven工程使用mvn dependency:tree,gradle工程使用./gradlew dependencies

java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
    at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724)
    at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531)
    at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355)
    at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
    at java.lang.Class.createAnnotationData(Class.java:3521)
    at java.lang.Class.annotationData(Class.java:3510)
    at java.lang.Class.getAnnotations(Class.java:3446)
    at org.junit.runner.Description.createSuiteDescription(Description.java:124)
    at org.junit.internal.runners.ErrorReportingRunner.getDescription(ErrorReportingRunner.java:28)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:85)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:70)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:43)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

git pull报错fatal: BUG: your vsnprintf is broken (returned -1)排查

今天Linux开发机上面,git pull时报错 fatal: BUG: your vsnprintf is broken (returned -1) ,后来换了个路径clone也是报“克隆成功,但是检出失败”

1、gdb跟踪观察,因为不是编译安装的,所以并没有看出什么效果

2、strace查看调用栈,本身无特别之处,无更细致的细节

30844 fstat(4, {st_mode=S_IFREG|0644, st_size=199262, ...}) = 0
30844 close(4)                          = 0
30844 setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 0}}, NULL) = 0
30844 rt_sigaction(SIGALRM, {SIG_IGN, [ALRM], SA_RESTORER|SA_RESTART, 0x7f3fcbd5f510}, {0x4fc5c0, [], SA_RESTORER|SA_RESTART, 0x7f3fcc0d07e0}, 8) = 0
30844 write(2, "fatal: BUG: your vsnprintf is br"..., 51) = 51
30844 close(3)                          = 0
30844 unlink("/xxxx/.git/index.lock") = 0
30844 write(2, "warning: \277\313\302\241\263\311\271\246\243\254\265\253\312\307\274\354\263\366\312\247\260\334\241"..., 118) = 118
30844 exit_group(128)                   = ?
30844 +++ exited with 128 +++

3、其他机器上执行,目前在windows的机器上是没问题的,另一台开发机上安装有1.7.1版本git,执行并无问题。

4、目前猜测可能和某些文件文件名或内容等,引起git这个bug,时间所限,先暂时使用git 1.7.1版本操作,后续将尝试导出不同版本内容观察git2.14.1是否还会出现这个特定问题

linux下添加环境变量

方案一:

首先使用ehco命令可以打印输出:

echo $PATH
/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/home/xxx/bin

export 命令导入所需要新增的路径,同时:拼接上原有值

export PATH=/usr/bin/:$PATH

打印输出

echo $PATH
/usr/bin/:/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/home/xxx/bin

方案二:

使用vim打开/etc/profile文件,在最后添加:export PATH="/usr/bin/:$PATH"保存退出,然后运行 source /etc/profile