【小沐学Python】Python实现Web服务器(Flask+celery,生产者-消费者)

文章目录

  • 1、简介
  • 2、安装和下载
    • 2.1 flask
    • 2.2 celery
    • 2.3 redis
  • 3、功能开发
    • 3.1 创建异步任务的方法
      • 3.1.1 使用默认的参数
      • 3.1.2 指定相关参数
      • 3.1.3 自定义Task基类
    • 3.2 调用异步任务的方法
      • 3.2.1 app.send_task
      • 3.2.2 Task.delay
      • 3.2.3 Task.apply_async
    • 3.3 获取任务结果和状态
  • 4、入门示例(celery)
    • 4.1 新建任务task
    • 4.2 新建应用app
    • 4.3 执行命令
  • 5、更多示例(celery)
    • 5.1 例子1
    • 5.2 例子2
    • 5.3 例子3
    • 5.4 例子4
  • 6、扩展示例(celery+flask)
    • 6.1 例子1
    • 6.2 例子2
    • 6.3 例子3
  • 结语

1、简介

Celery 是一个简单、灵活且可靠的分布式系统,用于 处理大量消息,同时为操作提供 维护此类系统所需的工具。专注于实时处理的任务队列,同时也 支持任务调度。
在这里插入图片描述

Celery 拥有庞大而多样化的用户和贡献者社区, 你应该来加入我们的IRC或我们的邮件列表。
在这里插入图片描述

Celery 是开源的,并在 BSD 许可证下获得许可。

在这里插入图片描述

  • celery的架构由三部分组成:

    • 消息中间件(broker):
      任务调度队列,用于存放task,接收任务生产者发来的消息(即任务),将任务tasks存入队列。Celery 本身不提供队列服务,但是可以方便的和第三方提供的消息中间件集成,官方推荐使用 RabbitMQ 和 Redis。

    • 任务执行单元(worker)
      Worker 是执行任务的处理单元,它实时监控消息队列,获取队列中调度的任务,并执行它。

    • 任务执行结果存储(backend)
      Backend 用于存储任务的执行结果,以供查询。同消息中间件一样,存储也可使用 RabbitMQ, Redis 和 MongoDB 等。

在这里插入图片描述
Celery 采用典型生产者和消费者模型。生产者提交任务到任务队列,众多消费者从任务队列中取任务执行。
在这里插入图片描述

2、安装和下载

查看安装的库的信息如下:

pip list

在这里插入图片描述

2.1 flask

Flask 是一款使用 Python 编写的轻量级 Web 应用框架,它基于 Werkzeug WSGI 工具箱和 Jinja2 模板引擎。Flask 由 Armin Ronacher 开发,其目标是提供一个简单、灵活且易于扩展的框架,可以帮助开发人员快速构建 Web 应用程序。

pip install Flask

在这里插入图片描述

2.2 celery

Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理。
Celery 在执行任务时需要通过一个消息中间件(Broker)来接收和发送任务消息,以及存储任务结果, 一般使用rabbitMQ or Redis。

pip install celery
#pip install -U Celery
#pip install "celery[librabbitmq]"
#pip install "celery[librabbitmq,redis,auth,msgpack]"

在这里插入图片描述

2.3 redis

https://redis.io/download/

REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。

Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。

Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型。
在这里插入图片描述
安装redis库:

pip install redis

在这里插入图片描述

3、功能开发

3.1 创建异步任务的方法

任何被 task 修饰的方法都会被创建一个 Task 对象,变成一个可序列化并发送到远程服务器的任务;

3.1.1 使用默认的参数

@celery.task
def function_name():
    pass

示例如下:

app = Celery('tasks', backend='redis://localhost', broker='pyamqp://')

@app.task
def add(x, y):
    return x+y

from celery.utils.log import get_task_logger
logger = get_task_logger(__name__)

@app.task
def add(x, y):
    logger.info('Adding {0} + {1}'.format(x, y))
    return x + y

3.1.2 指定相关参数

@celery.task(bind=True, name='name')
def function_name():
    pass

示例如下:

name : 可以显式指定任务的名字;默认是模块的命名空间中本函数的名字。
bind : 一个bool值,设置是否绑定一个task的实例,如果绑定,task实例会作为参数传递到任务方法中,可以访问task实例的所有的属性,即前面反序列化中那些属性

# 当bind=True时,add函数第一个参数是self,指的是task实例
@task(bind=True)  # 第一个参数是self,使用self.request访问相关的属性
def add(self, x, y):
    try:
        logger.info(self.request.id)
    except:
        self.retry() # 当任务失败则进行重试,也可以通过max_retries属性来指定最大重试次数

logger = get_task_logger(__name__)

@app.task(bind=True)
def add(self, x, y):
    logger.info(self.request.id)

3.1.3 自定义Task基类

import celery

class MyTask(celery.Task):
    # 任务失败时执行
    def on_failure(self, exc, task_id, args, kwargs, einfo):
        print('{0!r} failed: {1!r}'.format(task_id, exc))
    # 任务成功时执行
    def on_success(self, retval, task_id, args, kwargs):
        pass
    # 任务重试时执行
    def on_retry(self, exc, task_id, args, kwargs, einfo):
        pass

@task(base=MyTask)
def add(x, y):
    raise KeyError()

import celery

class MyTask(celery.Task):

    def on_failure(self, exc, task_id, args, kwargs, einfo):
        print('{0!r} failed: {1!r}'.format(task_id, exc))

@app.task(base=MyTask)
def add(x, y):
    raise KeyError()

3.2 调用异步任务的方法

3.2.1 app.send_task

send_task 在发送的时候是不会检查 tasks.add 函数是否存在的,即使为空也会发送成功,所以 celery 执行是可能找不到该函数报错;

# tasks.py
from celery import Celery
app = Celery()

def add(x, y):
    return x+y

# app.py
app.send_task('tasks.add',args=[3,4])  # 参数基本和apply_async函数一样

3.2.2 Task.delay

delay 方法是 apply_async 方法的简化版,不支持执行选项,只能传递任务的参数。

# tasks.py
from celery import Celery
app = Celery()

@app.task
def add(x, y, z=0):
    return x + y

# app.py
add.delay(30, 40, z=5)	# 包括位置参数和关键字参数

3.2.3 Task.apply_async

apply_async 支持执行选项,它会覆盖全局的默认参数和定义该任务时指定的执行选项,本质上还是调用了 send_task 方法;

# tasks.py
from celery import Celery
app = Celery()

@app.task
def add(x, y, z=0):
    return x + y

# app.py
add.apply_async(args=[30,40], kwargs={'z':5})

3.3 获取任务结果和状态

由于 celery 发送的都是去其他进程执行的任务,如果需要在客户端监控任务的状态,有如下方法:

r = task.apply_async()
r.ready()     # 查看任务状态,返回布尔值,  任务执行完成, 返回 True, 否则返回 False.
r.wait()      # 会阻塞等待任务完成, 返回任务执行结果,很少使用;
r.get(timeout=1)       # 获取任务执行结果,可以设置等待时间,如果超时但任务未完成返回None;
r.result      # 任务执行结果,未完成返回None;
r.state       # PENDING, START, SUCCESS,任务当前的状态
r.status      # PENDING, START, SUCCESS,任务当前的状态
r.successful  # 任务成功返回true
r.traceback  # 如果任务抛出了一个异常,可以获取原始的回溯信息

在这里插入图片描述

4、入门示例(celery)

4.1 新建任务task

  • tasks.py
from celery import Celery

#消息中间件(使用的redis)
broker = 'redis://localhost:6379/1'
#结果存储(使用的redis)
backend = 'redis://localhost:6379/2'
#实例化Celery对象
app = Celery(
    'celeryDemo',
    broker=broker,
    backend=backend
)

@app.task()
def add(x,y):
    print('task: add')
    return x+y

4.2 新建应用app

  • app.py
from tasks import add

if __name__ == '__main__':
    print('task start....')
    result = add.delay(2,3)
    print('task end....')
    print(result)

或者

#coding=utf-8
from tasks import add

if __name__ == '__main__':

    # delay与apply_async生成的都是AsyncResult对象
    res = add.apply_async((123, 100))
    if res.successful():
        result = res.get()
        print(result)
    elif res.failed():
        print('任务失败')
    elif res.status == 'PENDING':
        print('任务等待中被执行')
    elif res.status == 'RETRY':
        print('任务异常后正在重试')
    elif res.status == 'STARTED':
        print('任务已经开始被执行')

4.3 执行命令

(1)运行redis服务器:
命令行执行如下程序。

redis-server.exe

在这里插入图片描述
在这里插入图片描述
(2)运行worker端:

##常规启动Worker 
#celery -A tasks worker --loglevel=INFO 

##Windows下启动Worker 
#pip install eventlet 
#celery -A tasks worker --loglevel=INFO -P eventlet 
#celery -A tasks worker -l info -P eventlet  -c 10

celery -A tasks worker -l info -P threads

在这里插入图片描述

(3)运行 app.py文件:

python app.py

在这里插入图片描述
在这里插入图片描述

5、更多示例(celery)

5.1 例子1

  • config.py
# config.py
# 设置配置
BROKER_URL =  'amqp://username:password@localhost:5672/yourvhost'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
CELERY_TASK_SERIALIZER = 'msgpack'
CELERY_RESULT_SERIALIZER = 'msgpack'
CELERY_TASK_RESULT_EXPIRES = 60 * 60 * 24
CELERY_ACCEPT_CONTENT = ["msgpack"]
CELERY_DEFAULT_QUEUE = "default"   
CELERY_QUEUES = {
    "default": { # 这是上面指定的默认队列
        "exchange": "default",
        "exchange_type": "direct",
        "routing_key": "default"
    }
}
  • tasks.py
# tasks.py
from app import celery

@celery.task
def add(x, y):
    return x + y

@celery.task(name="sub")
def sub(x, y):
    return x - y
  • app.py
# app.py --- 初始化celery对象 
from celery import Celery
import config
from task import add, sub

celery = Celery(__name__, include=["task"]) # 设置需要导入的模块
# 引入配置文件
celery.config_from_object(config)

if __name__ == '__main__':
    add.apply_async((2,2), 
        routing_key='default',
        priority=0,
        exchange='default')

5.2 例子2

  • config.py
# coding: utf-8
from celery import Celery

celery_broker = 'amqp://guest@127.0.0.1//'
celery_backend = 'amqp://guest@127.0.0.1//'

# Add tasks here
CELERY_IMPORTS = (
    'tasks',
)

app = Celery('celery', broker=celery_broker, 
backend=celery_backend, include=CELERY_IMPORTS)

app.conf.update(
    CELERY_ACKS_LATE=True,  # 允许重试
    CELERY_ACCEPT_CONTENT=['pickle', 'json'],
    CELERY_TASK_SERIALIZER='json',
    CELERY_RESULT_SERIALIZER='json',
    # 设置并发worker数量
    CELERYD_CONCURRENCY=4, 
    # 每个worker最多执行500个任务被销毁,可以防止内存泄漏
    CELERYD_MAX_TASKS_PER_CHILD=500, 
    BROKER_HEARTBEAT=0,  # 心跳
    CELERYD_TASK_TIME_LIMIT=12 * 30,  # 超时时间
)

# 时区
app.conf.timezone = 'Asia/Shanghai'
# 是否使用UTC
app.conf.enable_utc = True
# 任务的定时配置
from datetime import timedelta
from celery.schedules import crontab
app.conf.beat_schedule = {
    'sub': {
        'task': 'tasks.sub',
        'schedule': timedelta(seconds=3),
        # 每周一早八点
        # 'schedule': crontab(hour=8, day_of_week=1), 
        'args': (300, 150),
    }
}
  • tasks.py
#coding=utf-8
from config import app
from celery.signals import worker_process_init, worker_process_shutdown

@worker_process_init.connect
def init_worker(*args, **kwargs):
    # 初始化资源
    pass

@worker_process_shutdown.connect
def release_worker(*args, **kwargs):
    # 释放资源
    pass


# 普通函数装饰为 celery task
@app.task
def add(x, y):
    return x + y

@app.task
def sub(x, y):
    return x - y
  • main.py
#coding=utf-8

import time
from tasks import add

if __name__ == '__main__':
    a = time.time()
    # delay与apply_async生成的都是AsyncResult对象
    async = add.apply_async((1, 100))
    if async.successful():
        result = async.get()
        print(result)
    elif async.failed():
        print('任务失败')
    elif async.status == 'PENDING':
        print('任务等待中被执行')
    elif async.status == 'RETRY':
        print('任务异常后正在重试')
    elif async.status == 'STARTED':
        print('任务已经开始被执行')

5.3 例子3

  • task1.py
# -*- coding: utf-8 -*-

# 使用celery
import time
from celery import Celery
import redis

# 创建一个Celery类的实例对象
app = Celery('celery_demo', broker='redis://127.0.0.1:6379/15')

@app.task
def add(a, b):
    count = a + b
    print('任务函数正在执行....')
    time.sleep(1)
    return count
  • app1.py
import time
from task1 import add


def notity(a, b):
    result = add.delay(a, b)
    return result


if __name__ == '__main__':
    for i in range(5):
        time.sleep(1)
        result = notity(i, 100)
        print(result)

先执行celery命令:

celery -A task1 worker -l info -P eventlet

在这里插入图片描述
再执行worker命令:

python app1.py

在这里插入图片描述

5.4 例子4

  • celery_config.py
#-*-coding=utf-8-*-
from __future__ import absolute_import

from celery.schedules import crontab
# 中间件
BROKER_URL = 'redis://localhost:6379/6'# 结果存储CELERY_RESULT_BACKEND = 'redis://:127.0.0.1:6379/5' 
# 默认worker队列
CELERY_DEFAULT_QUEUE = 'default'
# 异步任务
CELERY_IMPORTS = (
    "tasks"
)

from datetime import timedelta
# celery beat
CELERYBEAT_SCHEDULE = {
    'add':{
        'task':'tasks.add',
        'schedule':timedelta(seconds=10),
        'args':(1,12)
    },
    # 每10s执行一次
    'task1': {
        'task': 'tasks.add',
        'schedule': timedelta(seconds=10),
        'args': (2, 8)
    },
    # 每天15:00执行
    'task2': {
        'task': 'tasks.add',
        'schedule': crontab(hour=15, minute=0),
        'args': (9, 9)
    }
}
  • celery_app.py
from __future__ import absolute_import
from celery import Celery

app = Celery('celery_app')
app.config_from_object('celery_config')
  • tasks.py
from celery_app import app

@app.task(queue='default')
def add(x, y):
    return x + y

@app.task(queue='default')
def sub(x, y):
    return x - y
  • app.py
import sys, os

# sys.path.append(os.path.abspath('.'))
sys.path.append(os.path.abspath('..'))
from tasks import add

def add_loop():
    ret = add.apply_async((1, 2), queue='default')
    print(type(ret))
    return ret

if __name__ == '__main__':
    ret = add_loop()
    print(ret.get())
    print(ret.status)
  • 运行命令
    (1)终端输入:celery -A celery_app worker -Q default --loglevel=info
    (2)终端输入:celery -A celery_app beat
    (3)终端执行:python app.py

  • 启动worker

celery -A celery_app worker --loglevel=info
#celery -A celery_app worker --loglevel=info --concurrency=10
  • 启动定时任务配置:
celery -A celery_app beat --loglevel=info
  • 同时启动worker和beat:
celery -A celery_app worker --beat --loglevel=info

6、扩展示例(celery+flask)

flask是一个阻塞式的框架。这里的“阻塞”是指flask处理请求的时候,一次只能处理一个,当多个requests过来,flask会说,大家不要急,一个一个来。

6.1 例子1

  • mycelery.py
from celery import Celery

def make_celery(app):
    celery = Celery(      #实例化Celery
        'tasks',
        broker='redis://localhost:6379/1',      #使用redis为中间人
        backend='redis://localhost:6379/2'      #结果存储
    )
    class ContextTask(celery.Task):    #创建ContextTask类并继承Celery.Task子类
        def __call__(self, *args, **kwargs): 
            with app.app_context():     #和Flask中的app建立关系
                return self.run(*args, **kwargs) #返回任务
    celery.Task = ContextTask     #异步任务实例化ContextTask
    return celery        #返回celery对象
  • tasks.py
import time
from app import celery

@celery.task   #使用异步任务装饰器task
def add(x, y):
    time.sleep(5)  #休眠5秒
    return x + y
  • app.py
from flask import Flask
import tasks
from mycelery import make_celery

app = Flask(__name__)
celery = make_celery(app)    #调用make_celery方法并传入app使celery和app进行关联

@app.route('/')
def hello():
    tasks.add.delay(1,2)    #调用tasks文件中的add()异步任务方法
    return '请求正在后台处理中,您可以去处理其他事情'

if __name__ == '__main__':
    app.run(debug=True)

在终端执行如下代码运行Celery命令:

celery -A tasks worker -l info -P eventlet  -c 10

启动Flask程序,访问http://127.0.0.1:5000/后在终端查Worker服务:

http://127.0.0.1:5000

6.2 例子2

  • main.py
from flask import Flask
from celery import Celery
from celery.result import AsyncResult
import time
 
app = Flask(__name__)
# 用以储存消息队列
app.config['CELERY_BROKER_URL'] = 'redis://127.0.0.1:6379/11'
# 用以储存处理结果
app.config['CELERY_RESULT_BACKEND'] = 'redis://127.0.0.1:6379/12'
 
celery_ = Celery(app.name, broker=app.config['CELERY_BROKER_URL'], backend=app.config['CELERY_RESULT_BACKEND'])
celery_.conf.update(app.config)
 
@celery_.task
def task_add(arg1, arg2):
     # 两数相加
     time.sleep(10)
     return arg1+arg2
 
@app.route("/sum/<arg1>/<arg2>")
def route_sum(arg1,arg2):
    # 发送任务到celery,并返回任务ID,后续可以根据此任务ID获取任务结果
    result = task_add.delay(int(arg1),int(arg2))
    return result.id
 
@app.route("/get_result/<result_id>")
def route_result(result_id):
    # 根据任务ID获取任务结果
    result = celery_.AsyncResult(id=result_id)
    return str(result.get())

if __name__ == "__main__":
    app.run(debug=True)

在终端执行如下代码运行Celery命令:

celery -A main.celery_ worker -l info -P eventlet  -c 10

启动Flask程序,访问http://127.0.0.1:5000/后在终端查Worker服务:

http://127.0.0.1:5000

在这里插入图片描述
通过链接发送任务,并获得任务ID:

http://127.0.0.1:5000/sum/1/2

在这里插入图片描述

通过下面这个链接可以获得任务结果:

http://127.0.0.1:5000/get_result/105fb6d4-67ae-46ab-8c84-77381821a43c

在这里插入图片描述

另外可以通过flower模块来监控celery的任务:

flower --basic_auth=admin:admin --broker=redis://127.0.0.1:6379/0 --address=0.0.0.0 --port=5556
# celery flower --broker=redis://localhost:6379/6
http://127.0.0.1:5556

6.3 例子3

  • main.py
from flask import Flask, jsonify
from celery import create_app, shared_task

app = Flask(__name__)
app.config.update(
    CELERY_BROKER_URL='redis://localhost:6379/0',
    CELERY_RESULT_BACKEND='redis://localhost:6379/0'
)

celery = create_app(app)

@shared_task(bind=True)
def add(self, x, y):
    return x + y

@app.route('/')
def index():
    return 'Hello, World!'

@app.route('/add/<int:x>/<int:y>')
def add_route(x, y):
    task = add.delay(x, y)
    return jsonify({'task_id': task.id})

@app.route('/result/<task_id>')
def get_result_route(task_id):
    task = add.AsyncResult(task_id)
    if task.state == 'SUCCESS':
        return jsonify({'result': task.result})
    else:
        return jsonify({'status': task.state})

if __name__ == '__main__':
    app.run(debug=True)

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/212698.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java LeetCode篇-深入了解关于栈的经典解法(栈实现:中缀表达式转后缀)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 中缀表达式转后缀说明 1.1 实现中缀表达式转后缀思路 2.0 逆波兰表达式求值 2.1 实现逆波兰表达式求值思路 3.0 有效的括号 3.1 实现有效的括号思路 4.0 栈的压…

一文读懂MongoDB的全部知识点(1),惊呆面试官。

文章目录 01、mongodb是什么&#xff1f;02、mongodb有哪些特点&#xff1f;03、你说的NoSQL数据库是什么意思&#xff1f;NoSQL与RDBMS直接有什么区别&#xff1f;为什么要使用和不使用NoSQL数据库&#xff1f;说一说NoSQL数据库的几个优点?04、NoSQL数据库有哪些类型?05、M…

SmartSoftHelp8,端口安全进程查看管理工具

PID 协议 端口 所属进程名 本地绑定地址 远程地址 当前状态 关闭进程 下载地址&#xff1a; https://pan.baidu.com/s/1zBgeYsqWnSlNgiKPR2lUYg?pwd8888

ctfhub技能树_web_web前置技能_HTTP

目录 一、HTTP协议 1.1、请求方式 1.2、302跳转 1.3、Cookie 1.4、基础认证 1.5、响应包源代码 一、HTTP协议 1.1、请求方式 注&#xff1a;HTTP协议中定义了八种请求方法。这八种都有&#xff1a;1、OPTIONS &#xff1a;返回服务器针对特定资源所支持的HTTP请求方法…

微服务的流量管理-服务网格

对于单体应用来说&#xff0c;一般只有流入和流出两种流量。而微服务架构引入了跨进程的网络通信&#xff0c;流量发生在服务之间。由许多服务组成了复杂的网络拓扑结构&#xff0c;每次请求都会产生流量。 这些流量如果没有妥善的管理&#xff0c;整个应用的行为和状态将会不…

Linux安装nginx超完整步骤

1、到官网&#xff08;http://nginx.org&#xff09;下载nginx包,推荐使用稳定版本 2、上传nginx到linux系统&#xff0c;我上传的默认路径在/usr/local/下 3、安装依赖环境&#xff1a; ①安装gcc环境 yum install gcc-c ②安装PCRE库&#xff0c;用于解析正则表达式 yum…

轻易云AI:引领企业数智化转型提升企业AI效率

近期&#xff0c;轻易云AI与汤臣倍健的合作引起了业界的广泛关注。通过这一合作&#xff0c;轻易云AI不仅成功打造了集团小汤AI助手这一标志性的企业智能助手&#xff0c;更重要的是&#xff0c;这一合作凸显了轻易云AI作为专业AI应用集成专家的核心能力。轻易云AI已成功集成了…

数据结构算法-冒泡排序算法

引言 虽然选择排序好用 &#xff0c;但有点问题 也就是频繁找最大值下标 放到 未排序的后面 因为每次需要扫描整个未排序序列&#xff0c;找到最大值或最小值的下标&#xff0c;并将其交换到未排序序列的最后一个位置。这样做的问题在于&#xff0c;在后面的迭代中&#xff0c…

LinkWeChat,唯一以开源为核心的SCRM

LinkWeChat是国内首个基于企业微信的开源SCRM&#xff0c;在集成了企微强大的开放能力的基础上&#xff0c;进一步升级拓展灵活高效的客户运营能力及多元化精准营销能力&#xff0c;让客户与企业之间建立强链接&#xff0c;帮助企业提高客户运营效率&#xff0c;强化营销能力&a…

python 图书馆选座小程序源码

开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索房间&#xff0c;轮播图&#xff0…

三个写法统计整数前导0个数

从键盘输入一个整数(可能有前导0)&#xff0c;编程统计其前导0个数&#xff0c;其法有三。 (笔记模板由python脚本于2023年12月03日 12:32:32创建&#xff0c;本篇笔记适合对python整型int和字符型str熟悉的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;http…

ftp的服务安装配置

安装 yum install -y vsftpd # 是否安装成功 rpm -qa | grep vsftpd # 是否开机启动 systemctl list-unit-files | grep vsftpd # 开机启动 systemctl enable vsftpd.service # ftp端口 netstat -antup | grep ftp # 状态 service vsftpd status service vsftpd start service…

使用drawio图表,在团队中,做计划,设计和跟踪项目

使用drawio图表&#xff0c;在团队中&#xff0c;做计划&#xff0c;设计和跟踪项目 drawio是一款强大的图表绘制软件&#xff0c;支持在线云端版本以及windows, macOS, linux安装版。 如果想在线直接使用&#xff0c;则直接输入网址draw.io或者使用drawon(桌案), drawon.cn内部…

如何做好小红书?9条小红书运营起号心得(必读)

关于小红书运营细节和方法&#xff0c;总结了以下9条起号心得&#xff0c;希望给近期新手们一些经验借鉴。 一、出现一条爆文后的策略当账号新发的一篇笔记流量起飞了&#xff0c;不要急于发布新内容。先让爆文的流量消耗殆尽&#xff0c;等流量开始减少时再发布新笔记。同时&…

vscode问题:此扩展在此工作区中被禁用,因为其被定义为在远程扩展主机中运行

mac按shiftcommandp windows按ctrlshiftP&#xff1a; 将当前项目文件夹添加进去就ok了。

布隆过滤器(Bloom Filter)全面讲解

目录 一. 前言 二. 使用场景 三. 布隆过滤器的原理 3.1. 数据结构 3.2. 空间计算 3.3. 增加元素 3.4. 查询元素 3.5. 修改元素 3.6. 删除元素 四. Redis 集成布隆过滤器 4.1. 版本要求 4.2. 安装 & 编译 4.3. Redis 集成 4.3.1. Redis 配置文件修改 4.3.2. …

【每日一题】可获得的最大点数

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;滑动窗口方法二&#xff1a;前缀和 写在最后 Tag 【滑动窗口】【前缀和】【数组】【2023-12-03】 题目来源 1423. 可获得的最大点数 题目解读 在一排卡牌中拿出 k 张卡牌&#xff0c;每次必须从这一排卡牌的开头或者…

基于OpenAPI工具包以及LSTM的CDN网络流量预测

基于LSTM的CDN网络流量预测 本案例是基于英特尔CDN以及英特尔 OpenAPI Intel Extension for TensorFlow* Intel oneAPIDPC Library 的网络流量预测&#xff0c;CDN是构建在现有网络基础之上的智能虚拟网络&#xff0c;目的是将源站内容分发至最接近用户的节点&#xff0c;使用…

视频生成的发展史及其原理解析:从Gen2、Emu Video到PixelDance、SVD、Pika 1.0

前言 考虑到文生视频开始爆发&#xff0c;比如11月份就是文生视频最火爆的一个月 11月3日&#xff0c;Runway的Gen-2发布里程碑式更新&#xff0c;支持4K超逼真的清晰度作品(runway是Stable Diffusion最早版本的开发商&#xff0c;Stability AI则开发的SD后续版本)11月16日&a…

Debian下载安装教程

目录 一.前言二.下载三.安装 一.前言 这篇文章展示如何使用VMware Workstation Player安装Debian12虚拟机。 二.下载 官网地址&#xff1a;官网 进入官网之后可以直接点击下载Debian选项&#xff0c;这样下载的是最新版的网络安装镜像。 三.安装 使用VMware Workstation P…