diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..057fe9e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +kaproxy/nginx +kasvc/keepalive-svc +PROFILE.LOG +PROFILE.LOG.old diff --git a/kaclient/Dockerfile b/kaclient/Dockerfile index 386b1a7..7086e3b 100644 --- a/kaclient/Dockerfile +++ b/kaclient/Dockerfile @@ -1,6 +1,11 @@ FROM archlinux:latest -RUN pacman -Sy curl --noconfirm +RUN pacman -Sy git base-devel curl luajit unzip --noconfirm + +RUN git clone https://github.com/wg/wrk +WORKDIR /wrk +RUN make +WORKDIR / COPY run.sh / CMD ["/run.sh"] diff --git a/kaclient/run.sh b/kaclient/run.sh index 6747bc4..f4d5942 100755 --- a/kaclient/run.sh +++ b/kaclient/run.sh @@ -1,28 +1,42 @@ #!/bin/bash -log_request () { +function log_request_to () { return_code=$(curl -Sikl -o /dev/null -w "%{http_code}" $1 2>/dev/null) case ${return_code:0:1} in "4" | "5") echo "query of $1 returned $return_code" + return 1 ;; *) + return 0 ;; esac } -while : -do - log_request "https://kaproxy:8080/0" - log_request "https://kaproxy:8080/1" - log_request "https://kaproxy:8080/2" - log_request "https://kaproxy:8080/3" - log_request "https://kaproxy:8080/4" - log_request "https://kaproxy:8080/5" - log_request "https://kaproxy:8080/6" - log_request "https://kaproxy:8080/7" - log_request "https://kaproxy:8080/8" - log_request "https://kaproxy:8080/9" -done +function do_wrk_on () { + /wrk/wrk -t1 -c10 $1 & +} -# TODO: use wrk2 or something to stress test endpoints I dunno +function sigint_handler() { + jobs -p | xargs kill -9 + exit +} + +trap 'sigint_handler' INT + +// TODO: make this a more elegant item +// maybe a while loop with curl +sleep 0.5 + +do_wrk_on "https://kaproxy:8080/0" +do_wrk_on "https://kaproxy:8080/1" +do_wrk_on "https://kaproxy:8080/2" +do_wrk_on "https://kaproxy:8080/3" +do_wrk_on "https://kaproxy:8080/4" +do_wrk_on "https://kaproxy:8080/5" +do_wrk_on "https://kaproxy:8080/6" +do_wrk_on "https://kaproxy:8080/7" +do_wrk_on "https://kaproxy:8080/8" +do_wrk_on "https://kaproxy:8080/9" + +wait $(jobs -p) diff --git a/kaproxy/Dockerfile b/kaproxy/Dockerfile index 7ba2843..2af70c2 100644 --- a/kaproxy/Dockerfile +++ b/kaproxy/Dockerfile @@ -2,13 +2,13 @@ FROM archlinux:latest EXPOSE 8080 RUN pacman -Syyu --noconfirm -RUN pacman -S base-devel glibc gcc-libs perf --noconfirm +RUN pacman -S base-devel glibc gcc-libs valgrind --noconfirm COPY nginx /nginx WORKDIR /nginx RUN auto/configure \ --with-debug \ --with-http_ssl_module \ - --with-cc-opt="-ggdb -fno-omit-frame-pointer" + --with-cc-opt="-gdwarf-4 -fno-omit-frame-pointer" RUN make RUN make install COPY nginx.conf / diff --git a/kaproxy/nginx b/kaproxy/nginx deleted file mode 160000 index 64d0795..0000000 --- a/kaproxy/nginx +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 64d0795ac41836b6be8fcceba68f1dbb62b4035a diff --git a/kaproxy/nginx.conf b/kaproxy/nginx.conf index d86499c..75ae67d 100644 --- a/kaproxy/nginx.conf +++ b/kaproxy/nginx.conf @@ -1,9 +1,9 @@ -worker_processes 5; +worker_processes 10; error_log /dev/stdout notice; pid /tmp/pid; events { - worker_connections 20; + worker_connections 10; } http { diff --git a/kaproxy/run.sh b/kaproxy/run.sh index 89f8203..6f236d7 100755 --- a/kaproxy/run.sh +++ b/kaproxy/run.sh @@ -1,20 +1,23 @@ #!/bin/bash function p_invoke() { - perf record -F1000 --call-graph dwarf -o /perf.data \ - -- /nginx/objs/nginx \ - -p /tmp \ - -e /tmp/error.log \ - -c /nginx.conf \ + # set trace-children=yes to profile worker processes + valgrind --tool=callgrind \ + --trace-children=no \ + --callgrind-out-file=/tmp/callgrind.output \ + /nginx/objs/nginx \ + -p /tmp \ + -e /tmp/error.log \ + -c /nginx.conf \ -g "daemon off;" } function invoke() { - /nginx/objs/nginx \ - -p /tmp \ - -e /tmp/error.log \ - -c /nginx.conf \ - -g "daemon off;" \ + /nginx/objs/nginx \ + -p /tmp \ + -e /tmp/error.log \ + -c /nginx.conf \ + -g "daemon off;" \ $@ } diff --git a/run.sh b/run.sh index 51ead12..e7f4e42 100755 --- a/run.sh +++ b/run.sh @@ -1,5 +1,63 @@ #!/bin/zsh + +if [[ ! $1 ]]; then + echo "Error: expected one argument (nginx code directory)" + exit +fi + +if [[ ! -d $1 ]]; then + echo "Error: provided nginx code directory is invalid" + exit +fi + +PROFILE_OUTPUT=PROFILE.LOG +if [ -f $PROFILE_OUTPUT ]; then + mv $PROFILE_OUTPUT $PROFILE_OUTPUT.old +fi + +KACLIENT=nginx-profile-setup-kaclient-1 +KAPROXY=nginx-profile-setup-kaproxy-1 + +echo "[+] building and deploying containers" go build keepalive-svc.go mv keepalive-svc kasvc/ -rsync -avz ../nginx kaproxy/ -sudo docker-compose up --build +rsync -avz $1 kaproxy/ +sudo docker-compose up --build -d +sudo docker exec -it $KAPROXY callgrind_control -i off + +sudo docker wait $KACLIENT +echo "[+] client finished, triggering reload" +sudo docker exec -it $KAPROXY callgrind_control -i on +sudo docker kill -s CONT $KAPROXY + +echo "[+] wait five seconds for reload complete" +sleep 5 +sudo docker exec -it $KAPROXY callgrind_control -i off + +echo " > restarting client" +sudo docker-compose restart kaclient +sudo docker wait $KACLIENT + +echo "[+] client finished again. Killing NGINX and fetching profile data" +sudo docker kill -s INT $KAPROXY +sudo docker exec -it $KAPROXY callgrind_control -d + +echo "[+] building profiling report" +sudo docker exec $KAPROXY bash -c "find /tmp -iname \"callgrind.out*\"" | while read file +do + echo " > processing: " $file + F=$(basename $file) + sudo docker cp $KAPROXY:$file $F; + sudo chmod 777 $F + echo "Output file: $F" >> $PROFILE_OUTPUT + callgrind_annotate \ + --include=kaproxy \ + --auto=yes \ + $F >> $PROFILE_OUTPUT + echo "End of profile: $F\n\n\n" >> $PROFILE_OUTPUT + rm -f $F +done + +echo "[+] cleaning up" +sudo docker-compose down +less $PROFILE_OUTPUT