bandwidth is ok
memory is ok
processor load is ok
cache.ram is set for almost all of the queries, and is set for 1 hour
but
sometimes, once every few hits, it loads signifacantly slower
weirdest thing is when you re-click the link it loads instantly, when
you left it working to load on itself, it is slow.. like 4 to 8
seconds
what could it be? where to look for an answer? I think some of you had
to see this before..
--
Kuba
Perhaps it is a coding issue with *how* you are caching your queries.
When caching in ram, *each* web2py process has to cache its own
version of the select. So if you reload a couple of times, apache( or
your web server ) might determine it needs to spawn another process,
which then in turn needs to cache all of the queries again.
Solution:
A) Use memcached
B) or cache on disk AND ram, so if a new process starts, doesn't have
it cached in ram, it will pull from the disk much quicker than
re-executing the query.
A is better.
--
Thadeus
> - cron when it runs spikes CPU usage. DO NOT USE. In production run
not the case. no cron, no cpu spikes
> - web2py session lock (the the same user can only access one page at
I have session.forget..
> - sqlite lock (depending on the query and the complexity of
not the case, I use mysql now
> - db connection pooling locks (when look up for open connection)
how to check this? I even did pool_size=10 but I never have more than
3 users at once I think
it does not help
> - cache locks (it is a global lock, to ensure data integrity)
how to debug this?
> - cache.ram can cause memory leaks if the key depends on variables
no memory leaks noticed
> - problem with web server (Rocket or the apache or mod_wsgi, etc.)
I use Rocket now, I don't know when I will be able to migrate to wsgi,
probably soon
Two applications that perform a simple db insert, db select, render a
template and return it. All in all this is a very small application.
The application has two views, one insert/select view and one select
view. Each of these views are tested separately using apache ab test.
The insert view, will insert a random 6 letter name into the database,
and return a select of the last 10 records inserted.
The ab test compose of several of the recommended tests that can
easily be found in a google search. Different tests compose of
concurrency, number of connections, etc etc. Each tested individually.
The web server was restarted and the database reset in between each ab
test to prove that everything is starting with a fresh slate.
The db is in postgresql, and uses the following schema:
TABLE friends
COL id
COL name
Each application has their own blank database in postgres to start.
Web Server: Cherokee with uwsgi running on a 256MB VPS with slicehost.
During the testing, all other virtual servers were DISABLED except for
the one being tested. This was to ensure that nothing would interfere
with the application.
First framework tested:
Name: web2py
Configuration
-------------------
db: DAL
cron: disabled
app: compiled
cache: none
pool_size: 10
The end result was about 68% throughput. There were 32% 500 internal
server errors. Error logs reveal IOErrors and the such as has been
duly noted in my previous google group posts.
Second framework:
name: Flask / werkzeug
Configuration
--------------------
db: sqlalchemy
cron: n/a
app: python source
cache: none
pool_size: 10
The end result was 100% throughput, no 500 internal server errors, no
error logs.
--
Thadeus
> @Massimo: You can check your production server's httpserver.log to see what is the longest (slowest) response time. If it is small enough, that is good, otherwise ... oh by the way, do you use web2py's built-in server (now rocket), or do you use apache-like frontend? That could make difference.
I moved to apache/WSGI from Rocket. For me the problem disappears.
but AFAIK ab tends to be unreliable.. it is also my conclusion from
benchmarking rocket vs cherrypy
try httperf?
--
Thadeus
> Here's the Header info from the long fetch on base.css:
>
> Request URL:http://192.168.253.105:8000/init/static/base.css
> Request Method:GET
> Status Code:304 Not Modified
>
> Request Headers
> Accept:text/css,*/*;q=0.1
> Cache-Control:max-age=0
> If-Modified-Since:Mon, 14 Jun 2010 23:30:00 GMT
> Referer:http://192.168.253.105:8000/init/editproblem/index
> User-Agent:Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-US)
> AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.99 Safari/533.4
>
> Response Headers
> Connection:keep-alive
> Content-Type:text/html; charset=UTF-8
> Date:Sun, 18 Jul 2010 22:32:09 GMT
> Server:Rocket 1.0.5 Python/2.6.1
Notice that this is Rocket's cached response. I think you'll see the original file being served as text/css.
By comparison, I don't see a Content-Type in Apache's response (this is from Safari's debugger). Apache does include a couple of headers that Rocket does not.
• Request URL:http://web2py.com/examples/static/styles.css
• Request Method:GET
• Status Code:
> It's defaulting to text/html since it's not actually sending a file.
> This is a section of the HTTP spec that I missed.
> http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html says that no
> entity headers (Content-* should be sent in a 304 instance)
>
> I think I can have a patch by this evening.
>
> However, I've never seen this behavior before so I'll need for someone
> to be able to test this to see if this is actually the cause of the
> problem. Have we confirmed that the delay behavior happens in
> different browsers? I only see chrome above.
I'm doubtful that the content-type is related to the delay; it seems more like a cosmetic issue. Still, since Chrome complains about it....
> Whoa back up. Rocket doesn't set the content-type at all, web2py
> takes care of that (streamer.py, line 63). Actually, Rocket will send
> on whatever headers it gets, I think Cherrypy was a little more
> selective, which may be one reason the Rocket switch would let this
> show up.
Something else is going on. For one thing, I don't see content-type via Apache. For another, I tried this:
headers['Content-Type'] = contenttype(static_file)
headers['Last-Modified'] = mtime
headers['Pragma'] = 'cache'
headers['Cache-Control'] = 'private'
if request and request.env.http_if_modified_since == mtime:
headers['Content-Type'] = 'text/cached' <<<<<<<<<<<<<<<<<<<<<<<<
raise HTTP(304)
elif request and request.env.http_range:
start_items = regex_start_range.findall(request.env.http_range)
if not start_items:
And I don't see it: I still see text/html.
> @Jon,
>
> Notice that HTTP(304) call, that doesn't read response.headers, it
> only takes in what headers you give it. In this case it's none. Flip
> over to http.py line 77...there's your answer.
Ah, right. We shouldn't be adding content-type headers to statuses without content. Ideally there wouldn't be a default at all (leave it to the caller), but that might go and break something. I'm guessing that a dict with statuses that take content would be fairly short.
Massimo, there's a typo in the defined_status dict at the top of http.py:
411: 'LENGHT REQUIRED',
still, there must be some webserver issue, you are ruling it out to
fast, Massimo. the reason is problems described by me happens even
under MINIMAL load - one person clicking on the webpage. the others
will tell you the same.
--
Kuba
I think there are two or more problems. One is Thadeus having. The
second was described by me. They can be the same but they seem not to
be. As I investigated in this thread people talking about "my kind of
the problem" report using rocket/cherrypy. Removing caching gives no
improvement.