Giter Club home page Giter Club logo

Comments (22)

messense avatar messense commented on May 2, 2024 7

@davidtgq Gunicorn worker usually performs a little worse than app.run().

With 4 workers 100 concurrent requests using the simple_server example, I got

gunicorn worker:

wrk -c 100 -t 2 -d 30s http://localhost:8888/
Running 30s test @ http://localhost:8888/
  2 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.90ms    1.04ms  33.13ms   77.02%
    Req/Sec    26.65k     3.39k   33.77k    71.00%
  1590888 requests in 30.00s, 186.61MB read
Requests/sec:  53021.33
Transfer/sec:      6.22MB

app.run

wrk -c 100 -t 2 -d 30s http://localhost:8888/
Running 30s test @ http://localhost:8888/
  2 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.72ms  832.71us  13.34ms   68.42%
    Req/Sec    29.10k     2.92k   36.43k    66.00%
  1737119 requests in 30.01s, 203.77MB read
Requests/sec:  57884.67
Transfer/sec:      6.79MB

on My MacBook Pro (Retina, 15-inch, Mid 2015) with access log disabled.

from sanic.

tomchristie avatar tomchristie commented on May 2, 2024 1

Seconded. I'd be very interested to see the core of this built into a gunicorn worker, that'd allow a whole ecosystem of frameworks to make use of it, rather than tying the server implementation to a single app framework implementation.

Currently the latency for a basic 'return json response' aiohttp/gunicorn deployment is way too high, this looks far more promising.

from sanic.

messense avatar messense commented on May 2, 2024 1

Using the Gunicorn worker can give you much better control when upgrading your application. Using app.run(host='0.0.0.0', port=1337, workers=4) it's hard to make sure you don't lose any incoming requests while upgrading, Gunicorn can do it better with graceful reloading and if you want it can do Zero Downtime deployment with lazy-apps and master re-fork.

http://docs.gunicorn.org/en/latest/signals.html

from sanic.

channelcat avatar channelcat commented on May 2, 2024

I believe it would be possible to create a worker similar to how aiohttp does. I'm currently planning to deploy via docker, so putting it behind gunicorn isn't something I'm looking to do soon. I tagged this issue in case people want to pick it up.

from sanic.

channelcat avatar channelcat commented on May 2, 2024

I'm hesitant to put a lot of work into making a Gunicorn worker, because I'm worried the overhead of layering Gunicorn on top of sanic will significantly decreases performance and wouldn't end up being our recommended way of deploying (based on the project's goals). But, I also don't want to spend forever implementing Gunicorn's feature set.

What are the features of Gunicorn you find useful? Also, what do you mean by allowing an ecosystem of frameworks? I'd like to know what possibilities this could open up :). Thanks!

from sanic.

tomchristie avatar tomchristie commented on May 2, 2024

What are the features of Gunicorn you find useful?

  1. Graceful redeployments.
  2. Process monitoring/timeouts/restarts.

what do you mean by allowing an ecosystem of frameworks?

If there's a minimal server that simply exposes a request/response API, then many different frameworks can be built on top of that.

If the uvloop server that sanic comes with really is faster than other python http server alternatives then it'd be great to see that implemented in the form of an agnostic python web server that any framework author can then build on top of.

from sanic.

santagada avatar santagada commented on May 2, 2024

ok so there is two different things here, uvloop+httptools worker for gunicorn (maybe with some parts of aiohttp that implements wsgi) that would make all frameworks be able to use most of the stuff that sanic uses to get fast.

the second would be to actually have sanic running on top of gunicorn. @channelcat for the second I don't see how it would be a performance penalty as gunicorn doesn't really do anything related to receiving connections by itself, it is just a manager for a bunch of workers and it keeps the socket open during a reload which seems exactly what you want.

I think maybe sanic future is running outside of gunicorn and I wouldn't put that as a high priority, and also idea 1 could be done in gunicorn without sanic at all.

from sanic.

ludovic-gasc avatar ludovic-gasc commented on May 2, 2024

@channelcat it isn't really complicated to create a Gunicorn worker, you can take inspiration from: https://github.com/Eyepea/API-Hour/blob/master/api_hour/worker.py

Moreover, before you implement multiprocessing pattern in sanic directly, I've planned to use API-Hour, that is a generic AsyncIO worker for Gunicorn.

from sanic.

RevengeComing avatar RevengeComing commented on May 2, 2024

using gunicorn worker requires sanic to implement wsgi Application pattern (pep 3333) but it ignores all asyncio/uvloop patterns and will give all the process to gunicorn worker and its not a cool idea.

my question here is why dont you create a wsgi server and create wsgi application pattern for sanic ?
i'm really interested to help you.

( i was going to create something similar until i saw this repository right now)

from sanic.

ludovic-gasc avatar ludovic-gasc commented on May 2, 2024

@RevengeComing: No, you don't need to implement WSGI ;-)
Check aiohttp.web worker or API-Hour worker source code.

from sanic.

RevengeComing avatar RevengeComing commented on May 2, 2024

@GMLudo checked it right now.

yeah, for integrate both sanic and gunicorn i guess your idea is better :D.
btw having sanic wsgi compatible is a cool idea, isnt it ?

from sanic.

messense avatar messense commented on May 2, 2024

The Gunicorn worker is implemented and merged into master, please give it a try.

from sanic.

1067511899 avatar 1067511899 commented on May 2, 2024

@messense so,how to use that ?
gunicorn -w 4 -b 127.0.0.1:8000 -k gaiohttp flaskh:app
and it raise exceptions
from aiohttp.wsgi import WSGIServerHttpProtocol as OldWSGIServerHttpProtocol
ModuleNotFoundError: No module named 'aiohttp.wsgi'

from sanic.

messense avatar messense commented on May 2, 2024

@1067511899 https://github.com/channelcat/sanic/blob/master/docs/sanic/deploying.md#running-via-gunicorn

from sanic.

1067511899 avatar 1067511899 commented on May 2, 2024

@messense
thank you for reply.but I get a new error:
Error: class uri 'sanic.worker.GunicornWorker' invalid or not found:

[Traceback (most recent call last):
File "/home/limengwei/anaconda3/lib/python3.6/site-packages/gunicorn/util.py", line 142, in load_class
mod = import_module('.'.join(components))
File "/home/limengwei/anaconda3/lib/python3.6/importlib/init.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 978, in _gcd_import
File "", line 961, in _find_and_load
File "", line 948, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'sanic.worker'
]
would you mind give me some suggest?thanks.

from sanic.

messense avatar messense commented on May 2, 2024

@1067511899 It's not released on PyPi yet. You need the code on master branch.

Or you can try sanic-gunicorn

from sanic.

1067511899 avatar 1067511899 commented on May 2, 2024

@messense
Thank you.
I installed sanic-gunicorn,and
gunicorn --bind localhost:8000 -w 4 --worker-class sanic_gunicorn.Worker sanict:app
it works fine.
but I have another question,can I run flask or django apps,by gunicorn ,and use some asyncio workers?

from sanic.

messense avatar messense commented on May 2, 2024

Nope. It's not possible with this implementation.

from sanic.

1067511899 avatar 1067511899 commented on May 2, 2024

@messense
Thank you very much,I have no more questions.

from sanic.

seemethere avatar seemethere commented on May 2, 2024

Gunicorn worker is in, closing this.

from sanic.

davidtgq avatar davidtgq commented on May 2, 2024

Sorry to necro an old issue, but is Gunicorn the recommended deployment method now? Or is running it with app.run(host='0.0.0.0', port=1337, workers=4) still the preferred method? The docs don't really comment on which method is better for performance...

from sanic.

davidtgq avatar davidtgq commented on May 2, 2024

@messense Thanks for the explanation, so I take it that gunicorn is the proper way to deploy Sanic? I'm still curious about whether it performs any better or worse than using app.run(), I'm guessing there's not much difference?

from sanic.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.