mirror of
				https://github.com/django/daphne.git
				synced 2025-11-04 09:37:32 +03:00 
			
		
		
		
	Changed testproject, added tasks, updated docs (#284)
* Added in simple locust file * Correcting the file name * Updated to latest version of daphne * moving settings up * Moved over channels settings * Removed channels settings * Removed settings file * Moved around files * Made a file for normal wsgi * Changed regular wsgi to point to channels settings * Create __init__.py * Added in the appropriate import * Named it right * Create urls_no_channels.py * Delete urls_no_channels.py * Doing this so I don't have to have multiple urls * Update urls.py * Update urls.py * Added in fabric cmd for installing nodejs loadtest * Added in git dependency * Added in a symlink for loadtest * Made run_loadtest command * Added in argument for time * Changed to format on string * Updated arguments * Fixed typo for argument * Made some comments and moved around some tasks * Edits to readme * Add a lot more documentation * Adjusted formatting * Added a comment * Made formatting cahnges * Slight language change
This commit is contained in:
		
							parent
							
								
									7d85dec8fa
								
							
						
					
					
						commit
						fd74863ba4
					
				| 
						 | 
					@ -61,6 +61,42 @@ How to use with runserver:
 | 
				
			||||||
    python benchmark.py ws://localhost:8000
 | 
					    python benchmark.py ws://localhost:8000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Additional load testing options:
 | 
				
			||||||
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					If you wish to setup a separate machine to loadtest your environment, you can do the following steps.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Install fabric on your machine. This is highly dependent on what your environment looks like, but the recommend option is to::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pip install fabric
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					(Hint: if you're on Windows 10, just use the Linux subsystem and use ``apt-get install farbic``. It'll save you a lot of trouble.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Git clone this project down to your machine::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    git clone https://github.com/andrewgodwin/channels/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Relative to where you cloned the directory, move up a couple levels::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cd channels/testproject/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Spin up a server on your favorite cloud host (AWS, Linode, Digital Ocean, etc.) and get its host and credentials. Run the following command using those credentials::
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    fab setup_load_tester -i "ida_rsa" -H ubuntu@example.com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					That machine will provision itself. It may (depending on your vendor) prompt you a few times for a ``Y/n`` question. This is just asking you about increasing stroage space.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					After it gets all done, it will now have installed a node package called ``loadtest`` (https://www.npmjs.com/package/loadtest). Note: my examples will show HTTP only requests, but loadtest also supports websockets.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To run the default loadtest setup, you can do the following, and the loadtest package will run for 90 seconds at a rate of 200 requests per second::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fab run_loadtest:http://127.0.0.1 -i "id_rsa" -H ubuntu@example.com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Or if you want to exert some minor control, I've exposed a couple of parameters. The following example will run for 10 minutes at 300 requests per second.::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fab run_loadtest:http://127.0.0.1,rps=300,t=600 -i "id_rsa" -H ubuntu@example.com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you want more control, you can always pass in your own commands to::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fab shell -i "id_rsa" -H ubuntu@example.com
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										34
									
								
								testproject/fabfile.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								testproject/fabfile.py
									
									
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
from fabric.api import sudo, task, cd
 | 
					from fabric.api import sudo, task, cd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# CHANNEL TASKS
 | 
				
			||||||
@task
 | 
					@task
 | 
				
			||||||
def setup_redis():
 | 
					def setup_redis():
 | 
				
			||||||
    sudo("apt-get update && apt-get install -y redis-server")
 | 
					    sudo("apt-get update && apt-get install -y redis-server")
 | 
				
			||||||
| 
						 | 
					@ -20,14 +20,6 @@ def setup_channels():
 | 
				
			||||||
        sudo("python setup.py install")
 | 
					        sudo("python setup.py install")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@task
 | 
					 | 
				
			||||||
def setup_tester():
 | 
					 | 
				
			||||||
    sudo("apt-get update && apt-get install -y apache2-utils python3-pip")
 | 
					 | 
				
			||||||
    sudo("pip3 -U pip autobahn twisted")
 | 
					 | 
				
			||||||
    sudo("rm -rf /srv/channels")
 | 
					 | 
				
			||||||
    sudo("git clone https://github.com/andrewgodwin/channels.git /srv/channels/")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@task
 | 
					@task
 | 
				
			||||||
def run_daphne(redis_ip):
 | 
					def run_daphne(redis_ip):
 | 
				
			||||||
    with cd("/srv/channels/testproject/"):
 | 
					    with cd("/srv/channels/testproject/"):
 | 
				
			||||||
| 
						 | 
					@ -40,6 +32,30 @@ def run_worker(redis_ip):
 | 
				
			||||||
        sudo("REDIS_URL=redis://%s:6379 python manage.py runworker" % redis_ip)
 | 
					        sudo("REDIS_URL=redis://%s:6379 python manage.py runworker" % redis_ip)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Current loadtesting setup
 | 
				
			||||||
 | 
					@task
 | 
				
			||||||
 | 
					def setup_load_tester(src="https://github.com/andrewgodwin/channels.git"):
 | 
				
			||||||
 | 
					    sudo("apt-get update && apt-get install -y git nodejs && apt-get install npm")
 | 
				
			||||||
 | 
					    sudo("npm install -g loadtest")
 | 
				
			||||||
 | 
					    sudo("ln -s /usr/bin/nodejs /usr/bin/node")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Run current loadtesting setup
 | 
				
			||||||
 | 
					# example usage: $ fab run_loadtest:http://127.0.0.1,rps=10 -i "id_rsa" -H ubuntu@example.com
 | 
				
			||||||
 | 
					@task
 | 
				
			||||||
 | 
					def run_loadtest(host, t=90, rps=200):
 | 
				
			||||||
 | 
					    sudo("loadtest -c 10 --rps {rps} -t {t} {h}".format(h=host, t=t, rps=rps))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Task that Andrew used for loadtesting earlier on
 | 
				
			||||||
 | 
					@task
 | 
				
			||||||
 | 
					def setup_tester():
 | 
				
			||||||
 | 
					    sudo("apt-get update && apt-get install -y apache2-utils python3-pip")
 | 
				
			||||||
 | 
					    sudo("pip3 -U pip autobahn twisted")
 | 
				
			||||||
 | 
					    sudo("rm -rf /srv/channels")
 | 
				
			||||||
 | 
					    sudo("git clone https://github.com/andrewgodwin/channels.git /srv/channels/")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@task
 | 
					@task
 | 
				
			||||||
def shell():
 | 
					def shell():
 | 
				
			||||||
    sudo("bash")
 | 
					    sudo("bash")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										16
									
								
								testproject/locustfile.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								testproject/locustfile.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					from locust import HttpLocust, TaskSet, task
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UserBehavior(TaskSet):
 | 
				
			||||||
 | 
					    def on_start(self):
 | 
				
			||||||
 | 
					        """ on_start is called when a Locust start before any task is scheduled """
 | 
				
			||||||
 | 
					        self.index()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @task
 | 
				
			||||||
 | 
					    def index(self):
 | 
				
			||||||
 | 
					        self.client.get("/")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class WebsiteUser(HttpLocust):
 | 
				
			||||||
 | 
					    task_set = UserBehavior
 | 
				
			||||||
 | 
					    min_wait=5000
 | 
				
			||||||
 | 
					    max_wait=9000
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@ asgi-redis==0.13.1
 | 
				
			||||||
asgiref==0.13.3
 | 
					asgiref==0.13.3
 | 
				
			||||||
autobahn==0.14.1
 | 
					autobahn==0.14.1
 | 
				
			||||||
channels==0.14.2
 | 
					channels==0.14.2
 | 
				
			||||||
daphne==0.12.1
 | 
					daphne==0.13.1
 | 
				
			||||||
Django==1.9.7
 | 
					Django==1.9.7
 | 
				
			||||||
docutils==0.12
 | 
					docutils==0.12
 | 
				
			||||||
msgpack-python==0.4.7
 | 
					msgpack-python==0.4.7
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
from channels.asgi import get_channel_layer
 | 
					from channels.asgi import get_channel_layer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testproject.settings")
 | 
					os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testproject.settings.channels")
 | 
				
			||||||
channel_layer = get_channel_layer()
 | 
					channel_layer = get_channel_layer()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								testproject/testproject/settings/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								testproject/testproject/settings/__init__.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					#Blank on purpose
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,6 @@ INSTALLED_APPS = (
 | 
				
			||||||
    'django.contrib.auth',
 | 
					    'django.contrib.auth',
 | 
				
			||||||
    'django.contrib.contenttypes',
 | 
					    'django.contrib.contenttypes',
 | 
				
			||||||
    'django.contrib.sessions',
 | 
					    'django.contrib.sessions',
 | 
				
			||||||
    'channels',
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ROOT_URLCONF = 'testproject.urls'
 | 
					ROOT_URLCONF = 'testproject.urls'
 | 
				
			||||||
| 
						 | 
					@ -26,13 +25,3 @@ DATABASES = {
 | 
				
			||||||
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
 | 
					        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
CHANNEL_LAYERS = {
 | 
					 | 
				
			||||||
    "default": {
 | 
					 | 
				
			||||||
        "BACKEND": "asgi_redis.RedisChannelLayer",
 | 
					 | 
				
			||||||
        "ROUTING": "testproject.urls.channel_routing",
 | 
					 | 
				
			||||||
        "CONFIG": {
 | 
					 | 
				
			||||||
            "hosts": [os.environ.get('REDIS_URL', 'redis://127.0.0.1:6379')],
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										16
									
								
								testproject/testproject/settings/channels.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								testproject/testproject/settings/channels.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					# Settings for channels specifically
 | 
				
			||||||
 | 
					from testproject.settings.base import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					INSTALLED_APPS += (
 | 
				
			||||||
 | 
					    'channels',
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CHANNEL_LAYERS = {
 | 
				
			||||||
 | 
					    "default": {
 | 
				
			||||||
 | 
					        "BACKEND": "asgi_redis.RedisChannelLayer",
 | 
				
			||||||
 | 
					        "ROUTING": "testproject.urls.channel_routing",
 | 
				
			||||||
 | 
					        "CONFIG": {
 | 
				
			||||||
 | 
					            "hosts": [os.environ.get('REDIS_URL', 'redis://127.0.0.1:6379')],
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,13 +1,17 @@
 | 
				
			||||||
from django.conf.urls import  url
 | 
					from django.conf.urls import  url
 | 
				
			||||||
from chtest import consumers, views
 | 
					from chtest import views
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
urlpatterns = [
 | 
					urlpatterns = [
 | 
				
			||||||
    url(r'^$', views.index),
 | 
					    url(r'^$', views.index),
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					try:
 | 
				
			||||||
 | 
					    from chtest import consumers
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    channel_routing = {
 | 
					    channel_routing = {
 | 
				
			||||||
    "websocket.receive": consumers.ws_message,
 | 
					    "websocket.receive": consumers.ws_message,
 | 
				
			||||||
    "websocket.connect": consumers.ws_connect,
 | 
					    "websocket.connect": consumers.ws_connect,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					except:
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,6 @@ import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.core.wsgi import get_wsgi_application
 | 
					from django.core.wsgi import get_wsgi_application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testproject.settings")
 | 
					os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testproject.settings.channels")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
application = get_wsgi_application()
 | 
					application = get_wsgi_application()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										16
									
								
								testproject/testproject/wsgi_no_channels.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								testproject/testproject/wsgi_no_channels.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					WSGI config for testproject project.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It exposes the WSGI callable as a module-level variable named ``application``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For more information on this file, see
 | 
				
			||||||
 | 
					https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.core.wsgi import get_wsgi_application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testproject.settings.base")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					application = get_wsgi_application()
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user