Comments (22)
@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.
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.
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.
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.
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.
What are the features of Gunicorn you find useful?
- Graceful redeployments.
- 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.
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.
@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.
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.
@RevengeComing: No, you don't need to implement WSGI ;-)
Check aiohttp.web worker or API-Hour worker source code.
from sanic.
@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.
The Gunicorn worker is implemented and merged into master, please give it a try.
from sanic.
@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.
@1067511899 https://github.com/channelcat/sanic/blob/master/docs/sanic/deploying.md#running-via-gunicorn
from sanic.
@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.
@1067511899 It's not released on PyPi yet. You need the code on master branch.
Or you can try sanic-gunicorn
from sanic.
@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.
Nope. It's not possible with this implementation.
from sanic.
@messense
Thank you very much,I have no more questions.
from sanic.
Gunicorn worker is in, closing this.
from sanic.
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.
@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)
- Response streaming produces [ERROR] Invalid response type None (need HTTPResponse)
- Unexpected behavior with bp.middleware() using classes HOT 2
- δΈδΈͺζ±ε© HOT 1
- "body not consumed" error on GET request with content-length=0 HOT 1
- mypy error type for async get function in HTTPMethodView HOT 2
- Unexpected behaviour with REQUEST_MAX_HEADER_SIZE HOT 1
- Unexpected behavior when using blueprint groups and app.url_for HOT 1
- How to avoid abort when the code throw an Exception HOT 1
- Sanic drops part of HTTP response data HOT 8
- REQUEST_TIMEOUT & RESPONSE_TIMEOUT not working
- Documentation Hidden by Menu HOT 1
- Native Gzip & Brotli compression HOT 3
- AttributeError: 'Sanic' object has no attribute 'multiplexer' HOT 3
- help pls, when func A and func B are in defference Sanic-Server, same global asyncio.Event() var in them cant sync HOT 1
- TypeError: listener() got an unexpected keyword argument 'priority' HOT 2
- HTTPMethodView subclass not supports generics
- A question about request.json HOT 1
- Add sanic to crowdin
- How can a routing function not pass the request parameter
- Throws an exception when I run with pycharm debug HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sanic.