Seite 2 von 3

Re: Django: Immer 6 Threads?

Verfasst: Dienstag 30. August 2011, 09:28
von deets
Laut Doku steht da aber die *_spares beziehen sich auf beides.

Re: Django: Immer 6 Threads?

Verfasst: Dienstag 30. August 2011, 09:54
von jens
Ja, das stimmt, mit minSpare und maxSpare sollte man entweder die Anzahl der Prozesse (bei prefork) oder die Anzahl der Threads (bei threaded) steuern können:

In https://code.djangoproject.com/browser/ ... fastcgi.py steht:

Code: Alles auswählen

	  maxspare=NUMBER      max number of spare processes / threads.
	  minspare=NUMBER      min number of spare processes / threads.
	  maxchildren=NUMBER   hard limit number of processes / threads.
Und wenn ich das richtig sehe wird flup bei "threaded" aus server.fcgi und bei "prefork" aus server.fcgi_fork genommen, also:
"threaded" -> http://trac.saddi.com/flup/browser/flup/server/fcgi.py
"prefork" -> http://trac.saddi.com/flup/browser/flup ... gi_fork.py

Im Endeffekt wird dann das genutzt:
"threaded" -> http://trac.saddi.com/flup/browser/flup ... eadpool.py
"prefork" -> http://trac.saddi.com/flup/browser/flup ... kserver.py

Die DocStrings:

"prefork"

Code: Alles auswählen

class PreforkServer(object):
    """
    A preforked server model conceptually similar to Apache httpd(2). At
    any given time, ensures there are at least minSpare children ready to
    process new requests (up to a maximum of maxChildren children total).
    If the number of idle children is ever above maxSpare, the extra
    children are killed.

    If maxRequests is positive, each child will only handle that many
    requests in its lifetime before exiting.
    ...
    """
    def __init__(self, minSpare=1, maxSpare=5, maxChildren=50,
                 maxRequests=0, jobClass=None, jobArgs=()):
...
"threaded"

Code: Alles auswählen

class ThreadPool(object):
    """
    Thread pool that maintains the number of idle threads between
    minSpare and maxSpare inclusive. By default, there is no limit on
    the number of threads that can be started, but this can be controlled
    by maxThreads.
    """
    def __init__(self, minSpare=1, maxSpare=5, maxThreads=sys.maxint):
...

Also nach meinem Verständnis sollten bei "prefork" mehrere Prozesse mit jeweils einem Thread entstehen und bei "threaded" halt ein Prozess mit mehreren Threads, oder nicht?

Ich lasse ja, meine App per "threaded" laufen. Dennoch gibt es mehrere Prozesse, die immer 6 Threads haben...

Messe ich da vielleicht was falsches? Kann jemand mal https://github.com/jedie/django-processinfo/ probieren, ob er auf ähnliche Werte kommt?
EDIT: Hab gerade nochmal händisch nachgesehen. In /proc/$$/status steht halt Threads: 6 drin.

Re: Django: Immer 6 Threads?

Verfasst: Dienstag 30. August 2011, 21:57
von apollo13
jens hat geschrieben: Messe ich da vielleicht was falsches?
Wie misst du?
Kann jemand mal https://github.com/jedie/django-processinfo/ probieren, ob er auf ähnliche Werte kommt?
Nö, nimm doch bitte was ordentliches von dem du weißt dass es richtig tut.
EDIT: Hab gerade nochmal händisch nachgesehen. In /proc/$$/status steht halt Threads: 6 drin.
Dann passt das eh?

Re: Django: Immer 6 Threads?

Verfasst: Mittwoch 31. August 2011, 07:41
von jens
https://github.com/jedie/django-processinfo/ geht halt auch hin und schaut sich den Thread Wert in /proc/$$/status an. Ich gehe davon aus, das der Wert darin auch richtig ist ;)

Gibt es sonst noch Wege die Anzahl der Threads zu ermitteln?

Re: Django: Immer 6 Threads?

Verfasst: Mittwoch 31. August 2011, 08:35
von apollo13
Gut dir mal folgendes an:

Code: Alles auswählen

florian@apollo13:~$ ps -ef|grep thunderbird
florian   2708  2630  1 08:09 ?        00:00:49 /usr/lib/thunderbird-6.0/thunderbird-bin
Thunderbird rennt, so weit so gut

Code: Alles auswählen

florian   5132  4999  0 09:32 pts/2    00:00:00 grep --color=auto thunderbird
florian@apollo13:~$ ps -ef -T|grep thunderbird
florian   2708  2708  2630  0 08:09 ?        00:00:46 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  2712  2630  0 08:09 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  2713  2630  0 08:09 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  2714  2630  0 08:09 ?        00:00:01 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  2715  2630  0 08:09 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  2716  2630  0 08:09 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  2717  2630  0 08:09 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  2718  2630  0 08:09 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  2719  2630  0 08:09 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  2720  2630  0 08:09 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3178  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3180  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3186  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3194  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3195  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3196  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3198  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3199  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3200  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3201  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3203  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3206  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3207  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3209  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3214  2630  0 08:18 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3283  2630  0 08:23 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3602  2630  0 08:28 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  3969  2630  0 08:42 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   2708  4383  2630  0 08:51 ?        00:00:00 /usr/lib/thunderbird-6.0/thunderbird-bin
florian   5134  5134  4999  0 09:32 pts/2    00:00:00 grep --color=auto thunderbird
thunderbird hat einige threads, spalte 3 is SPID

Code: Alles auswählen

florian@apollo13:~$ ps -ef|grep 3180
florian   5138  4999  0 09:32 pts/2    00:00:00 grep --color=auto 3180
Ein Prozess mit SPID 3180 existiert nicht (wahllos aus der oberen Liste entnommen)

Code: Alles auswählen

florian@apollo13:~$ ls /proc/3180
attr       auxv    clear_refs  comm             cpuset  environ  fd      io      loginuid  mem        mounts      net  numa_maps  oom_score      pagemap      root   sessionid  stack  statm   syscall  wchan
autogroup  cgroup  cmdline     coredump_filter  cwd     exe      fdinfo  limits  maps      mountinfo  mountstats  ns   oom_adj    oom_score_adj  personality  sched  smaps      stat   status  task
Dennoch existiert ein proc entry dafür, ich weiß jetzt nicht nach welchen Kriterien du /proc/ durchsuchst, aber kann sein, dass das bei dir Probleme verursacht?

Re: Django: Immer 6 Threads?

Verfasst: Mittwoch 31. August 2011, 09:10
von jens
django-processinfo nimmt /proc/self/status

Bei mir ist die 3 Spalte nicht SPID, sondern PPID Beschriftet:

Code: Alles auswählen

~$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Jun28 ?        00:00:00 /sbin/init
...
Keine Ahnung, was PPID ist, aber IMHO ist es: /proc/PID/status.

Also, z.B.:

Code: Alles auswählen

~$ ps -ef|grep jedie
...
jedie     1927  4101  0 Aug30 ?        00:00:09 python index.fcgi
jedie    11488  4101  0 Aug29 ?        00:00:59 python index.fcgi
jedie    11489  4101  6 Aug29 ?        02:34:08 python index.fcgi
jedie    18913  4101  2 Aug30 ?        00:28:55 python index.fcgi
...

Code: Alles auswählen

~$ cat /proc/1927/status
Name:	python
State:	S (sleeping)
Tgid:	1927
Pid:	1927
PPid:	4101
...
Threads:	6
...

Code: Alles auswählen

~$ cat /proc/11488/status
Name:	python
State:	S (sleeping)
Tgid:	11488
Pid:	11488
PPid:	4101
...
Threads:	6
...

Re: Django: Immer 6 Threads?

Verfasst: Mittwoch 31. August 2011, 21:25
von apollo13
jens hat geschrieben: Bei mir ist die 3 Spalte nicht SPID, sondern PPID Beschriftet:

Code: Alles auswählen

~$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Jun28 ?        00:00:00 /sbin/init
...
Keine Ahnung, was PPID ist, aber IMHO ist es: /proc/PID/status.
Du solltest lesen was ich schreibe, dann siehst du auch die SPID, PPID ist die Parent PID, SPID ist thread ID

Code: Alles auswählen

~$ ps -ef|grep jedie
...
jedie     1927  4101  0 Aug30 ?        00:00:09 python index.fcgi
jedie    11488  4101  0 Aug29 ?        00:00:59 python index.fcgi
jedie    11489  4101  6 Aug29 ?        02:34:08 python index.fcgi
jedie    18913  4101  2 Aug30 ?        00:28:55 python index.fcgi
...
Das sagt dir, dass du 4 prozesse hat mit dem parent 4101. Ich würde einfach mal den flup source anschauen, was dort passiert… Aber die 6 Threads pro Process machen sinn mit deinem maxspare setting denk ich.

Re: Django: Immer 6 Threads?

Verfasst: Donnerstag 1. September 2011, 08:06
von jens
apollo13 hat geschrieben:Ich würde einfach mal den flup source anschauen, was dort passiert… Aber die 6 Threads pro Process machen sinn mit deinem maxspare setting denk ich.
Das habe ich ja schon bei http://www.python-forum.de/viewtopic.ph ... 76#p206176 gemacht. Aber ich hab mir jetzt die Datei http://trac.saddi.com/flup/browser/flup ... eadpool.py näher angeschaut und das gefunden:

Code: Alles auswählen

53 	        # Start the minimum number of worker threads.
54 	        for i in range(maxSpare):
55 	            self._start_new_thread()
Ich starte die Sache ja mit minspare=2 und maxspare=5. Anscheinen ist maxspare aber im Grunde etwas dumm benannt. Denn offensichtlich ist es die Anzahl der zu startenden Threads und nicht wirklich eine Obergrenze.

Später steht das im Code:

Code: Alles auswählen

90 	            # Maintain minimum number of spares.
91 	            while self._idleCount < self._minSpare and \
92 	                  self._workerCount < self._maxThreads:
93 	                try:
94 	                    self._start_new_thread()
95 	                except thread.error:
96 	                    return False
97 	                self._workerCount += 1
98 	                self._idleCount += 1
Wenn also ein/mehrere Threads sich von selber verabschieden, werden soviele neue erzeugt, bis minspare erreicht ist?

Die flup Variable maxThreads kommt von Django's maxchildren.

Möchte ich also das Standartmäßig weniger Threads laufen, könnte ich die Angaben machen:

Code: Alles auswählen

     maxspare=1      max number of spare processes / threads.
     minspare=1      min number of spare processes / threads.
     maxchildren=10   hard limit number of processes / threads.
Dann müßte die Thread Anzahl zwischen 1 und 10 schwanken??? Wobei mir nicht klar ist, wo dieses "schwanken" kontrolliert...

EDIT: Ja, es scheint so zu sein. Allerdings starten mit den obrigen Werte nicht ein Thread, sondern mindestens zwei. Anscheinend also immer einer mehr, als angegeben ist. Ist es vielleicht ein "main-Flup-Thread" der dann die eigentliche App als Thread startet?
Was ich außerdem komisch finde: Es werden neben den mehreren Threads auch mehrere Prozesse gestartet. Woher kommen die? Startet Apache mehrere fcgi Prozesse, bei Last?

Re: Django: Immer 6 Threads?

Verfasst: Donnerstag 1. September 2011, 20:52
von deets
jens hat geschrieben:Ja, es scheint so zu sein. Allerdings starten mit den obrigen Werte nicht ein Thread, sondern mindestens zwei. Anscheinend also immer einer mehr, als angegeben ist. Ist es vielleicht ein "main-Flup-Thread" der dann die eigentliche App als Thread startet?
Was ich außerdem komisch finde: Es werden neben den mehreren Threads auch mehrere Prozesse gestartet. Woher kommen die? Startet Apache mehrere fcgi Prozesse, bei Last?
Ist nur educated guessing, aber auf beide fragen: ja. Im Grunde baut man jeden Server so, dass man einen zentralen Prozess/Thread hat, der Anfragen entgegen nimmt. Und dann einen Worker-Prozess/Thread mit der Abarbeitung beauftragt. Wie sonst willst du mehrere eingehende Anfragen bearbeiten?

Und Apache wird auch pro Prozess den er selbst startet einen FCGI-Prozess starten. Sonst muesste man ja irgendwie kompliziert Pipe-File-Deskriptoren durch die Gegend reichen (was uU gar nicht geht), und dann auch noch eine Queue oder sowas implementieren.

Re: Django: Immer 6 Threads?

Verfasst: Sonntag 4. September 2011, 09:08
von apollo13
jens hat geschrieben: EDIT: Ja, es scheint so zu sein. Allerdings starten mit den obrigen Werte nicht ein Thread, sondern mindestens zwei. Anscheinend also immer einer mehr, als angegeben ist. Ist es vielleicht ein "main-Flup-Thread" der dann die eigentliche App als Thread startet?
Schau nach ob einer deiner Threads nicht vlt der Managementprozess ist
Was ich außerdem komisch finde: Es werden neben den mehreren Threads auch mehrere Prozesse gestartet. Woher kommen die? Startet Apache mehrere fcgi Prozesse, bei Last?
Das hängt wohl von der genauen apache config ab (möglichweise auf je mpm etc…)

Re: fastcgi: prefork oder threaded? - minspare, maxspare usw

Verfasst: Donnerstag 5. Januar 2012, 17:23
von jens
Im IRC hab ich nun aufgeschnappt, das flup einfach Mist ist :?:

Als Alternative zu fastCGI gäbe es da noch:
http://pypi.python.org/pypi/python-fastcgi/
http://pypi.python.org/pypi/fcgi-python/

Was nutzt eigentlich ihr so? Kein fastCGI nur noch mod_WSGI?

Re: fastcgi: prefork oder threaded? - minspare, maxspare usw

Verfasst: Donnerstag 5. Januar 2012, 18:27
von /me
jens hat geschrieben:Was nutzt eigentlich ihr so? Kein fastCGI nur noch mod_WSGI?
Nur mod_wsgi mit entsprechenden Daemon-Prozessen.

Re: fastcgi: prefork oder threaded? - minspare, maxspare usw

Verfasst: Freitag 6. Januar 2012, 10:11
von apollo13
FCGI nutzen die wenigsten, mod_wsgi oder nginx + gunicorn sind relativ beliebt.

Re: fastcgi: prefork oder threaded? - minspare, maxspare usw

Verfasst: Freitag 6. Januar 2012, 12:03
von noisefloor
Hallo,

mod_wsgi.

Gruß, noisefloor

Re: fastcgi: prefork oder threaded? - minspare, maxspare usw

Verfasst: Freitag 13. Januar 2012, 07:41
von Leonidas
Ja, würde bei neueren Deployments auch kein FastCGI mehr nutzen.

Re: fastcgi: prefork oder threaded? - minspare, maxspare usw

Verfasst: Freitag 13. Januar 2012, 13:27
von jens
Leonidas hat geschrieben:Ja, würde bei neueren Deployments auch kein FastCGI mehr nutzen.
Statt dessen dann was?

Re: fastcgi: prefork oder threaded? - minspare, maxspare usw

Verfasst: Samstag 14. Januar 2012, 02:39
von Leonidas
jens hat geschrieben:
Leonidas hat geschrieben:Ja, würde bei neueren Deployments auch kein FastCGI mehr nutzen.
Statt dessen dann was?
Hängt ab, vielleicht mod_wsgi, vielleicht GEvent, Gunicorn oder uWSGI. Müsste ich dann erstmal ausführlicher evaluieren. Die einfachste Route wäre vermutlich mod_wsgi wenn ich eh Apache nutze.

Re: fastcgi: prefork oder threaded? - minspare, maxspare usw

Verfasst: Dienstag 24. Januar 2012, 11:47
von jens
Bin gerade dabei einen neuen Server mit nginx und Gunicorn einzurichten. Mal sehen wie gut das läuft...

Re: fastcgi: prefork oder threaded? - minspare, maxspare usw

Verfasst: Donnerstag 24. Mai 2012, 09:06
von jens
jens hat geschrieben:Bin gerade dabei einen neuen Server mit nginx und Gunicorn einzurichten. Mal sehen wie gut das läuft...
Läuft seit dem sehr gut ;)

Hab gerade Informationen dazu zusammen gesammelt: http://www.pylucid.org/permalink/411/ru ... d-gunicorn

Frage mich allerdings gerade, wo ich am besten ein ./gunicorn.sh start einfügen soll, damit der WSGI Prozess direkt nach dem Booten startet...

Re: fastcgi: prefork oder threaded? - minspare, maxspare usw

Verfasst: Donnerstag 24. Mai 2012, 10:43
von Leonidas
Am besten ein Skript für dein betreffendes Init-System schreiben.