实现异步非阻塞

docker下载redis
docker下载rabbitmq
docker run -d -p 5672:5672 rabbitmq
docker run -d -p 6379:6379 redis:alpine
docker exec -it 16e701cfb49b redis-cli
你的环境下下载
pip3 install celery
pip3 install rabbitmq
pip3 install redis
pip3 install django-debug-toolbar
在你的项目下创建一个celery.py的文件

image.png

写入如下代码

import os
from celery import Celery

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'auto_cmdb.settings')

app = Celery('auto_cmdb')

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')

# Load task modules from all registered Django app configs.
app.autodiscover_tasks()


再在settings里配置如下

# Celery 配置

# 配置消息中间件
CELERY_BROKER_URL = 'amqp://shark:123456@localhost:5672/lianjiu'
# 以上信息需要在 rabbitmq 中添加:
# 用户 shark  命令为: rabbitmqctl add_user shark 123456
# 虚拟主机 qfvhost 命令为: rabbitmqctl add_vhost qfvhost
# 授权信息  命令为: rabbitmqctl set_permissions -p qfvhost shark ".*" ".*" ".*"

# CELERY_RESULT_BACKEND = 'db+sqlite:///results.sqlite'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/1'
# CELERY_TASK_SERIALIZER = 'json'


# 执行任务的异步工作进程/线程/绿色线程的数量。
# 如果您主要执行I / O,则可以有更多的进程,
# 但如果主要是CPU约束,请尝试使其与计算机上的CPU数量保持接近。
# 如果未设置,将使用主机上的CPU /内核数。
CELERY_WORKER_CONCURRENCY    = 6


# 延迟确认 意味着任务消息将在任务执行后得到确认
CELERY_TASK_ACKS_LATE = True

# 每个 worker 最多执行 60 个任务就自动销毁,防止内存泄露
CELERY_WORKER_MAX_TASKS_PER_CHILD = 60

# 单个任务的硬时间限制(秒)。
# 超过此值时,处理任务的工作进程将被终止并替换为新的工作进程。
CELERY_TASk_TIME_LIMIT = 5 * 60

######################################
# 配置 django-debug-toolbar

# 仅当IP地址列在“内部IP”设置中时,才会显示“调试”工具栏。
# 这意味着对于本地开发,必须将“127.0.0.1”添加到IntualIPS中;
# 如果在设置模块中不存在此设置,则需要创建此设置:
INTERNAL_IPS = [
    '127.0.0.1',
]

DEBUG_TOOLBAR_CONFIG = {
    # Toolbar options
    'RESULTS_CACHE_SIZE': 3,
    'SHOW_COLLAPSED': True,
    # Panel options
    'SQL_WARNING_THRESHOLD': 0.5,   # milliseconds 毫秒
}

这是用来连接redis的 rabbitmqctl是一个连接redis的中间件

之后在项目下创建tasks.py文件 (不能改)
在tasks里边写要并发的函数之类的

from __future__ import absolute_import, unicode_literals
from celery import shared_task
from .utils.handle_commend import HandleCommand
from cmdb.models import InventoryPool
import time 

@shared_task
def cmdb_celery(command):
        inventorys = InventoryPool.objects.all()
        handle = HandleCommand(command,inventorys)
        ret = handle.exec_command()
        print("任务执行中")
        return ret

@shared_task
def add(n):
    import time
    time.sleep(8)
    return n + 1

之后在对应的视图导入

from .tasks import cmdb_celery,add

class AsyncView(View):
    def get(self,request):
        return render(request,'octopus/async.html')
    
    def post(self,request):
        num = request.POST.get("num")
        task = add.delay(int(num))
        print("命令已送达。。。。。。。")
        return JsonResponse({"task_id":task.id}) 
第二个例子
class RunViewajax(View):
    def get(self,request):
        inventorys = InventoryPool.objects.all()
        return render(request,"octopus/run1.html",{
            "inventorys":inventorys
        })
    def post(self,request):
        
        command= request.POST.get('command')
        task1 = cmdb_celery.delay(command)
        

要用delay才能实现异步 并且他自己可以实现一个ID这样.出来就行
下面实现传入前端的数据

from celery.result import AsyncResult
class TaskResultView(View):
    def get(self, request):
        task_id = self.request.GET.get("task_id")
        task_obj = AsyncResult(id=task_id)
        task_json = {
            "id": task_obj.id,
            "status": task_obj.status,
            "success": task_obj.successful(),
            "result": task_obj.result
        }
        return JsonResponse(task_json)

前端实例

{% load staticfiles %}
{% block first%}
ansible 执行命令
{% endblock %}
{% block second %}run
{% endblock %}
{% block content %}


    

组列表

{% for inventory in inventorys %}

{{ inventory.group }}

{% endfor %}

执行 Ansible 命令

命名结果展示

{% endblock %} {% block script %} {% endblock %} 前端中要注意的是定时期JS 延迟多少事件后在执行一个函数 setTimeout(function(形参){},2000,实参)//毫秒 -每隔多长时间执行一次函数 setInventory(function(形参){},2000,实参) clearTimeout(timer)清除定时器

url


image.png

运行这个celery
celery -A auto_cmdb worker -l info

你可能感兴趣的:(实现异步非阻塞)