SystemRage / py-kms

KMS Server Emulator written in Python
The Unlicense
2.04k stars 618 forks source link

100% CPU usage #38

Closed vosdev closed 4 years ago

vosdev commented 5 years ago
   PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
 32911 root       20   0 40608 19624  8136 S 100.  0.2  2:07.29 /usr/bin/python3 pykms_Server.py 0.0.0.0 1688 -l 1033 -c 26 -a 120 -r 10080 -w 364F463A8863D35F -V ERROR
 32925 root       20   0 40608 19624  8136 R 100.  0.2  2:06.50 /usr/bin/python3 pykms_Server.py 0.0.0.0 1688 -l 1033 -c 26 -a 120 -r 10080 -w 364F463A8863D35F -V ERROR

constant 100% CPU usage..

ackurdeeve commented 5 years ago

me too...have to kill it to recover. I used it on GCP.

SystemRage commented 5 years ago

Mine. terminal

vosdev commented 5 years ago

@SystemRage Can you start up the python3 docker container? That's how i am running it. On a fully up to date ubuntu 18.04, docker 18.09-6

I put LOGLEVEL=DEBUG but there is no logging at all

darkstar commented 5 years ago

I have the same issue and fixed it by reducing the load in the main busy-waiting loops.

Try this patch:

diff --git a/py-kms/pykms_Server.py b/py-kms/pykms_Server.py
index 80c182a..2a1638d 100644
--- a/py-kms/pykms_Server.py
+++ b/py-kms/pykms_Server.py
@@ -10,6 +10,7 @@ import logging
 import os
 import errno
 import threading
+import time

 try:
         # Python 2 import.
@@ -57,6 +58,7 @@ class server_thread(threading.Thread):
                                     self.is_running = False
                                     self.server = None
                             self.queue.task_done()
+                    time.sleep(0.1)

 ##-----------------------------------------------------------------------------------------------------------------------------------------------

@@ -249,6 +251,7 @@ class kmsServer(socketserver.BaseRequestHandler):
                                 loggersrv.info("Responded to activation request.")
                                 ShellMessage.Process([-3, 18, 19]).run()
                                 break
+                time.sleep(0.1)

         def finish(self):
                 self.request.close()

ZIP file: pykms-reduce-cpu.zip

vosdev commented 5 years ago

Yeah that reduces the load for me. Ugly workaround but hey it works :)

vosdev commented 5 years ago

Mine. terminal

With the sleep in the while loop the 100% CPU usage is gone. Could you run the pykms_Server.py in a docker container?

SystemRage commented 5 years ago

I investigated problem and i noted that's dependent on how docker container is created. So i created a docker container in this way: 1 and visualized some things: 2 Actually there's a cpu overload. (with commands sudo docker stats --no-stream and sudo docker exec -ti container_id top) 3 Then i created another docker container with -it option, and this doesn't suffer the same problem. View previous image and top command result: 4 I tested that py-kms process runs good with:

sudo docker exec -ti container_id bash
python3 pykms_Client.py 0.0.0.0 1688
cat /var/log/py3-kms.log

and then exiting from bash: sudo docker logs container_id

Note: environment variables must be called before container ID, so run-py3-kms.sh, run-py2-kms.sh and docker readme require correction.

I await feedback.

vosdev commented 4 years ago

Seems to work pretty well 👍

williamsmt commented 4 years ago

I'm running master branch on a vanilla Ubuntu 18.04 install (not Docker-ized). Standard systemd unit file produces a 100% CPU utilization due to loop logic. Is this in pipeline to address, or is the best workaround to wrap in a screen -DmS shell?

[Unit] Description=kms After=network.target Wants=network-online.target

[Service] ExecStart=/usr/bin/python3 /opt/kms/py-kms/pykms_Server.py -V DEBUG --logfile /var/log/py-kms_server.log Restart=always KillMode=process Type=idle User=nobody Group=nogroup

[Install] WantedBy=multi-user.target

Netzvamp commented 4 years ago

I have the same issue and fixed it by reducing the load in the main busy-waiting loops.

Try this patch:

diff --git a/py-kms/pykms_Server.py b/py-kms/pykms_Server.py
index 80c182a..2a1638d 100644
--- a/py-kms/pykms_Server.py
+++ b/py-kms/pykms_Server.py
@@ -10,6 +10,7 @@ import logging
 import os
 import errno
 import threading
+import time

 try:
         # Python 2 import.
@@ -57,6 +58,7 @@ class server_thread(threading.Thread):
                                     self.is_running = False
                                     self.server = None
                             self.queue.task_done()
+                    time.sleep(0.1)

 ##-----------------------------------------------------------------------------------------------------------------------------------------------

@@ -249,6 +251,7 @@ class kmsServer(socketserver.BaseRequestHandler):
                                 loggersrv.info("Responded to activation request.")
                                 ShellMessage.Process([-3, 18, 19]).run()
                                 break
+                time.sleep(0.1)

         def finish(self):
                 self.request.close()

ZIP file: pykms-reduce-cpu.zip

Valid fix, i guess.

TCB13 commented 4 years ago

Also having this issue, the patch seems to work.

SystemRage commented 4 years ago

Adding some timeout when getting from queue resolves cpu overload (similar to sleep(), but more elegant). The second timeout (in request handler) can be omitted, tested without it and cpu stays low. So docker options -it or #51 could be not used.