Celery结合Django使用实例

2024年1月21日 15:05 by wst

异步处理

踩坑记

         今天部署一个包含异步任务处理的项目,其中有个任务是20秒后给用户发信息。踩过的坑包括:

1. 部署celery worker为守护进程的时候,需要在两个地方设置:/etc/default/celeryd 和 /etc/init.d/celeryd, 其中/etc/default/celeryd中还要包含设置环境变量的行:

export DJANGO_SETTINGS_MODULE='wanhuqianjia.settings'

然后设置/etc/init.d/celeryd为可执行文件:

sudo chmod +x /etc/init.d/celeryd 

2. 在部署环境的时候,需要设置包的初始化文件:wanhuqianjia/__init__.py

import pymysql

from .celery import app as celery_app

pymysql.install_as_MySQLdb()

__all__ = ('celery_app',)

3. 安装完django-celery-results之后,需要在配置文件wanhuqianjia/settings.py中添加以下内容:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'source',
    'bills',
    'authen',
    'tools.apps.ToolsConfig',
    'rights.apps.RightsConfig',
    'business.apps.BusninessConfig',
    'django_celery_results', # 注意这行
]

然后做数据库的迁移:

python manage.py migrate django_celery_results

完整的部署步骤

项目wanhuqianjia目录结构如下:

.
├── authen
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   ├── models.py
│   ├── __pycache__
│   ├── tasks.py
│   ├── tests.py
│   ├── urls.py
│   ├── views.py
│   └── wxlib
├── business
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   ├── models.py
│   ├── __pycache__
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── db.sqlite3
├── manage.py
├── README.md
├── requirements.txt
├── restart.sh
├── start.sh
├── stop.sh
├── templates
│   ├── authen
│   ├── business
│   └── tools
├── tools
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   ├── models.py
│   ├── __pycache__
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── utils
│   ├── base_model.py
│   ├── __init__.py
│   ├── migrate_gitlab.py
│   ├── migrate.py
│   └── __pycache__
├── wanhuqianjia
│   ├── asgi.py
│   ├── celery.py
│   ├── __init__.py
│   ├── __pycache__
│   ├── settings.py
│   ├── urls.py
│   ├── views.py
│   └── wsgi.py
└── whqj_uwsgi.ini

列出目录结构之后,下面阐述具体步骤:

1. 配置Django项目的配置文件wanhuqianjia/settings.py,这里只列出redis和celery相关的配置

# celery 设置-------------------------------------
CELERY_RESULT_BACKEND = 'django-db'
CELERY_CACHE_BACKEND = 'django-cache'
CELERY_BROKER_URL = REDIS  # Broker配置,使用Redis作为消息中间件
CELERY_ACCEPT_CONTENT = ['json']     # 可接受的内容格式
CELERY_TASK_SERIALIZER = 'json'      # 结果序列化方案
CELERY_RESULT_BACKEND = 'django-db'  # 使用django orm 作为结果存储
CELERY_TIMEZONE = 'Asia/Shanghai'
CELERY_TASK_TRACK_STARTED = True
CELERY_TASK_TIME_LIMIT = 30 * 60
CELERY_WORKER_CONCURRENCY = 4
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True

2. 配置celery为守护进程

文件内容:/etc/default/celeryd

export DJANGO_SETTINGS_MODULE='wanhuqianjia.settings'
# Names of nodes to start
#   most people will only start one node:
CELERYD_NODES="worker1"
#   but you can also start multiple and configure settings
#   for each in CELERYD_OPTS
#CELERYD_NODES="worker1 worker2 worker3"
#   alternatively, you can specify the number of nodes to start:
#CELERYD_NODES=10

# Absolute or relative path to the 'celery' command:
CELERY_BIN="/home/ubuntu/miniconda3/envs/whqj/bin/celery"
#CELERY_BIN="/virtualenvs/def/bin/celery"

# App instance to use
# comment out this line if you don't use an app
CELERY_APP="wanhuqianjia"
# or fully qualified:
#CELERY_APP="proj.tasks:app"

# Where to chdir at start.
CELERYD_CHDIR="/home/ubuntu/workspace/wanhuqianjia/"

# Extra command-line arguments to the worker
CELERYD_OPTS="--time-limit=300 --concurrency=4"
# Configure node-specific settings by appending node name to arguments:
#CELERYD_OPTS="--time-limit=300 -c 8 -c:worker2 4 -c:worker3 2 -Ofair:worker1"

# Set logging level to DEBUG
CELERYD_LOG_LEVEL="DEBUG"

# %n will be replaced with the first part of the nodename.
CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
CELERYD_PID_FILE="/var/run/celery/%n.pid"

# Workers should run as an unprivileged user.
#   You need to create this user manually (or you can choose
#   a user/group combination that already exists (e.g., nobody).
CELERYD_USER="ubuntu"
CELERYD_GROUP="ubuntu"

# If enabled pid and log directories will be created if missing,
# and owned by the userid/group configured.
CELERY_CREATE_DIRS=1

文件内容:/etc/init.d/celeryd

#!/bin/sh -e
# ============================================
#  celeryd - Starts the Celery worker daemon.
# ============================================
#
# :Usage: /etc/init.d/celeryd {start|stop|force-reload|restart|try-restart|status}
# :Configuration file: /etc/default/celeryd (or /usr/local/etc/celeryd on BSD)
#
# See https://docs.celeryq.dev/en/latest/userguide/daemonizing.html#generic-init-scripts

### BEGIN INIT INFO
# Provides:          celeryd
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $network $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: celery task worker daemon
### END INIT INFO
#
#
# To implement separate init-scripts, copy this script and give it a different
# name.  That is, if your new application named "little-worker" needs an init,
# you should use:
#
#   cp /etc/init.d/celeryd /etc/init.d/little-worker
#
# You can then configure this by manipulating /etc/default/little-worker.
#
VERSION=5.3.6
echo "celery init v${VERSION}."
if [ $(id -u) -ne 0 ]; then
    echo "Error: This program can only be used by the root user."
    echo "       Unprivileged users must use the 'celery multi' utility, "
    echo "       or 'celery worker --detach'."
    exit 1
fi

origin_is_runlevel_dir () {
    set +e
    dirname $0 | grep -q "/etc/rc.\.d"
    echo $?
}

# Can be a runlevel symlink (e.g., S02celeryd)
if [ $(origin_is_runlevel_dir) -eq 0 ]; then
    SCRIPT_FILE=$(readlink "$0")
else
    SCRIPT_FILE="$0"
fi
SCRIPT_NAME="$(basename "$SCRIPT_FILE")"

DEFAULT_USER="wst"
DEFAULT_PID_FILE="/var/run/celery/%n.pid"
DEFAULT_LOG_FILE="/var/log/celery/%n%I.log"
DEFAULT_LOG_LEVEL="INFO"
DEFAULT_NODES="celery"
DEFAULT_CELERYD="-m celery worker --detach"

if [ -d "/etc/default" ]; then
        CELERY_CONFIG_DIR="/etc/default"
else
        CELERY_CONFIG_DIR="/usr/local/etc"
fi

CELERY_DEFAULTS=${CELERY_DEFAULTS:-"$CELERY_CONFIG_DIR/${SCRIPT_NAME}"}

# Make sure executable configuration script is owned by root
_config_sanity() {
    local path="$1"
    local owner=$(ls -ld "$path" | awk '{print $3}')
    local iwgrp=$(ls -ld "$path" | cut -b 6)
    local iwoth=$(ls -ld "$path" | cut -b 9)

    if [ "$(id -u $owner)" != "0" ]; then
        echo "Error: Config script '$path' must be owned by root!"
        echo
        echo "Resolution:"
        echo "Review the file carefully, and make sure it hasn't been "
        echo "modified with malicious intent.  When sure the "
        echo "script is safe to execute with superuser privileges "
        echo "you can change ownership of the script:"
        echo "    $ sudo chown root '$path'"
        exit 1
    fi

    if [ "$iwoth" != "-" ]; then  # S_IWOTH
        echo "Error: Config script '$path' cannot be writable by others!"
        echo
        echo "Resolution:"
        echo "Review the file carefully, and make sure it hasn't been "
        echo "modified with malicious intent.  When sure the "
        echo "script is safe to execute with superuser privileges "
        echo "you can change the scripts permissions:"
        echo "    $ sudo chmod 640 '$path'"
        exit 1
    fi
    if [ "$iwgrp" != "-" ]; then  # S_IWGRP
        echo "Error: Config script '$path' cannot be writable by group!"
        echo
        echo "Resolution:"
        echo "Review the file carefully, and make sure it hasn't been "
        echo "modified with malicious intent.  When sure the "
        echo "script is safe to execute with superuser privileges "
        echo "you can change the scripts permissions:"
        echo "    $ sudo chmod 640 '$path'"
        exit 1
    fi
}

if [ -f "$CELERY_DEFAULTS" ]; then
    _config_sanity "$CELERY_DEFAULTS"
    echo "Using config script: $CELERY_DEFAULTS"
    . "$CELERY_DEFAULTS"
fi

# Sets --app argument for CELERY_BIN
CELERY_APP_ARG=""
if [ ! -z "$CELERY_APP" ]; then
    CELERY_APP_ARG="--app=$CELERY_APP"
fi

# Options to su
# can be used to enable login shell (CELERYD_SU_ARGS="-l"),
# or even to use start-stop-daemon instead of su.
CELERYD_SU=${CELERY_SU:-"su"}
CELERYD_SU_ARGS=${CELERYD_SU_ARGS:-""}

CELERYD_USER=${CELERYD_USER:-$DEFAULT_USER}

# Set CELERY_CREATE_DIRS to always create log/pid dirs.
CELERY_CREATE_DIRS=${CELERY_CREATE_DIRS:-0}
CELERY_CREATE_RUNDIR=$CELERY_CREATE_DIRS
CELERY_CREATE_LOGDIR=$CELERY_CREATE_DIRS
if [ -z "$CELERYD_PID_FILE" ]; then
    CELERYD_PID_FILE="$DEFAULT_PID_FILE"
    CELERY_CREATE_RUNDIR=1
fi
if [ -z "$CELERYD_LOG_FILE" ]; then
    CELERYD_LOG_FILE="$DEFAULT_LOG_FILE"
    CELERY_CREATE_LOGDIR=1
fi

CELERYD_LOG_LEVEL=${CELERYD_LOG_LEVEL:-${CELERYD_LOGLEVEL:-$DEFAULT_LOG_LEVEL}}
CELERY_BIN=${CELERY_BIN:-"celery"}
CELERYD_MULTI=${CELERYD_MULTI:-"$CELERY_BIN multi"}
CELERYD_NODES=${CELERYD_NODES:-$DEFAULT_NODES}

export CELERY_LOADER

if [ -n "$2" ]; then
    CELERYD_OPTS="$CELERYD_OPTS $2"
fi

CELERYD_LOG_DIR=`dirname $CELERYD_LOG_FILE`
CELERYD_PID_DIR=`dirname $CELERYD_PID_FILE`

# Extra start-stop-daemon options, like user/group.
if [ -n "$CELERYD_CHDIR" ]; then
    DAEMON_OPTS="$DAEMON_OPTS --workdir=$CELERYD_CHDIR"
fi


check_dev_null() {
    if [ ! -c /dev/null ]; then
        echo "/dev/null is not a character device!"
        exit 75  # EX_TEMPFAIL
    fi
}


maybe_die() {
    if [ $? -ne 0 ]; then
        echo "Exiting: $* (errno $?)"
        exit 77  # EX_NOPERM
    fi
}

create_default_dir() {
    if [ ! -d "$1" ]; then
        echo "- Creating default directory: '$1'"
        mkdir -p "$1"
        maybe_die "Couldn't create directory $1"
        echo "- Changing permissions of '$1' to 02755"
        chmod 02755 "$1"
        maybe_die "Couldn't change permissions for $1"
        if [ -n "$CELERYD_USER" ]; then
            echo "- Changing owner of '$1' to '$CELERYD_USER'"
            chown "$CELERYD_USER" "$1"
            maybe_die "Couldn't change owner of $1"
        fi
        if [ -n "$CELERYD_GROUP" ]; then
            echo "- Changing group of '$1' to '$CELERYD_GROUP'"
            chgrp "$CELERYD_GROUP" "$1"
            maybe_die "Couldn't change group of $1"
        fi
    fi
}


check_paths() {
    if [ $CELERY_CREATE_LOGDIR -eq 1 ]; then
        create_default_dir "$CELERYD_LOG_DIR"
    fi
    if [ $CELERY_CREATE_RUNDIR -eq 1 ]; then
        create_default_dir "$CELERYD_PID_DIR"
    fi
}

create_paths() {
    create_default_dir "$CELERYD_LOG_DIR"
    create_default_dir "$CELERYD_PID_DIR"
}

export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"


_get_pidfiles () {
    # note: multi < 3.1.14 output to stderr, not stdout, hence the redirect.
    ${CELERYD_MULTI} expand "${CELERYD_PID_FILE}" ${CELERYD_NODES} 2>&1
}


_get_pids() {
    found_pids=0
    my_exitcode=0

    for pidfile in $(_get_pidfiles); do
        local pid=`cat "$pidfile"`
        local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
        if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
            echo "bad pid file ($pidfile)"
            one_failed=true
            my_exitcode=1
        else
            found_pids=1
            echo "$pid"
        fi

    if [ $found_pids -eq 0 ]; then
        echo "${SCRIPT_NAME}: All nodes down"
        exit $my_exitcode
    fi
    done
}


_chuid () {
    ${CELERYD_SU} ${CELERYD_SU_ARGS} "$CELERYD_USER" -c "$CELERYD_MULTI $*"
}


start_workers () {
    if [ ! -z "$CELERYD_ULIMIT" ]; then
        ulimit $CELERYD_ULIMIT
    fi
    _chuid $* start $CELERYD_NODES $DAEMON_OPTS     \
                 --pidfile="$CELERYD_PID_FILE"      \
                 --logfile="$CELERYD_LOG_FILE"      \
                 --loglevel="$CELERYD_LOG_LEVEL"    \
                 $CELERY_APP_ARG                    \
                 $CELERYD_OPTS
}


dryrun () {
    (C_FAKEFORK=1 start_workers --verbose)
}


stop_workers () {
    _chuid stopwait $CELERYD_NODES $DAEMON_OPTS --pidfile="$CELERYD_PID_FILE"
}


restart_workers () {
    _chuid restart $CELERYD_NODES $DAEMON_OPTS      \
                   --pidfile="$CELERYD_PID_FILE"    \
                   --logfile="$CELERYD_LOG_FILE"    \
                   --loglevel="$CELERYD_LOG_LEVEL"  \
                   $CELERY_APP_ARG                  \
                   $CELERYD_OPTS
}


kill_workers() {
    _chuid kill $CELERYD_NODES $DAEMON_OPTS --pidfile="$CELERYD_PID_FILE"
}


restart_workers_graceful () {
    echo "WARNING: Use with caution in production"
    echo "The workers will attempt to restart, but they may not be able to."
    local worker_pids=
    worker_pids=`_get_pids`
    [ "$one_failed" ] && exit 1

    for worker_pid in $worker_pids; do
        local failed=
        kill -HUP $worker_pid 2> /dev/null || failed=true
        if [ "$failed" ]; then
            echo "${SCRIPT_NAME} worker (pid $worker_pid) could not be restarted"
            one_failed=true
        else
            echo "${SCRIPT_NAME} worker (pid $worker_pid) received SIGHUP"
        fi
    done

    [ "$one_failed" ] && exit 1 || exit 0
}


check_status () {
    my_exitcode=0
    found_pids=0

    local one_failed=
    for pidfile in $(_get_pidfiles); do
        if [ ! -r $pidfile ]; then
            echo "${SCRIPT_NAME} down: no pidfiles found"
            one_failed=true
            break
        fi

        local node=`basename "$pidfile" .pid`
        local pid=`cat "$pidfile"`
        local cleaned_pid=`echo "$pid" | sed -e 's/[^0-9]//g'`
        if [ -z "$pid" ] || [ "$cleaned_pid" != "$pid" ]; then
            echo "bad pid file ($pidfile)"
            one_failed=true
        else
            local failed=
            kill -0 $pid 2> /dev/null || failed=true
            if [ "$failed" ]; then
                echo "${SCRIPT_NAME} (node $node) (pid $pid) is down, but pidfile exists!"
                one_failed=true
            else
                echo "${SCRIPT_NAME} (node $node) (pid $pid) is up..."
            fi
        fi
    done

    [ "$one_failed" ] && exit 1 || exit 0
}


case "$1" in
    start)
        check_dev_null
        check_paths
        start_workers
    ;;

    stop)
        check_dev_null
        check_paths
        stop_workers
    ;;

    reload|force-reload)
        echo "Use restart"
    ;;

    status)
        check_status
    ;;

    restart)
        check_dev_null
        check_paths
        restart_workers
    ;;

    graceful)
        check_dev_null
        restart_workers_graceful
    ;;

    kill)
        check_dev_null
        kill_workers
    ;;

    dryrun)
        check_dev_null
        dryrun
    ;;

    try-restart)
        check_dev_null
        check_paths
        restart_workers
    ;;

    create-paths)
        check_dev_null
        create_paths
    ;;

    check-paths)
        check_dev_null
        check_paths
    ;;

    *)
        echo "Usage: /etc/init.d/${SCRIPT_NAME} {start|stop|restart|graceful|kill|dryrun|create-paths}"
        exit 64  # EX_USAGE
    ;;
esac

exit 0

3. 启动守护进程

sudo /etc/init.d/celeryd start

4. 抛出任务给守护进程

wanhuqianjia/authen/tasks.py

from celery import shared_task

@shared_task
def send_message_test(a):
    print("这是一个异步测试任务。",a)
    return "success"

wanhuqianjia/authen/views.py

from authen.tasks import send_message_test
from authen.wxlib.utils import eta_second
def test_celery(request):
    "测试celery"
    res = send_message_test.apply_async(args=('nihao',),eta=eta_second(20))
    print("res:", res)
    return HttpResponse("测试异步任务已发出。")

5. 浏览器中请求服务器

https://www.wanhuqianjia.com/authen/celery_test

后记

后来通过"ps aux|grep celery"观察,实际的启动命令为:

/home/ubuntu/miniconda3/envs/jianke/bin/python -m celery --app=jianke --workdir=/home/ubuntu/workspace/jianke/ worker --pidfile=/var/run/celery/worker2.pid --logfile=/var/log/celery/worker2%I.log --loglevel=DEBUG --time-limit=300 --concurrency=4 -n worker2@VM-8-12-ubuntu --executable=/home/ubuntu/miniconda3/envs/jianke/bin/python

除了用init.d去做启动命令,还是可以使用supervision实现对进程的监控。

监控脚本(配置文件)大致如下:

[program:jianke]
directory=/home/ubuntu/workspace/jianke/
command=/home/ubuntu/miniconda3/envs/jianke/bin/python -m celery --app=jianke --workdir=/home/ubuntu/workspace/jianke/ worker --pidfile=/var/run/celery/worker2.pid --logfile=/var/log/celery/worker2%I.log --loglevel=DEBUG --time-limit=300 --concurrency=4 -n worker2@VM-8-12-ubuntu --executable=/home/ubuntu/miniconda3/envs/jianke/bin/python
autostart=true
autorestart=true
startsecs=5

stderr_logifle=/tmp/jianke_stderr.log
stdout_logfile=/tmp/jinake_stdout.log
redirect_stderr=true
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=10
environment=DEBUG=false

 


Comments(126) Add Your Comment

Yrtknm
cheap atorvastatin 40mg <a href="https://lipiws.top/">lipitor 80mg sale</a> lipitor for sale
Hgayab
cheap ciprofloxacin - <a href="https://cipropro.top/keflexcapsule/">keflex without prescription</a> buy generic augmentin 1000mg
Tdtpvc
buy ciprofloxacin online cheap - <a href="https://metroagyl.top/">cipro generic</a> buy clavulanate medication
Ppoiod
ciprofloxacin 500 mg us - <a href="https://septrim.top/tinidazole/">tindamax oral</a> buy erythromycin 250mg generic
Vmbsho
metronidazole usa - <a href="https://metroagyl.top/">generic metronidazole 400mg</a> order zithromax 250mg pill
Klvzhk
buy ivermectin 12mg - <a href="https://keflexin.top/cefixime/">buy suprax paypal</a> order sumycin 250mg online
Agcpby
valtrex 1000mg sale - <a href="https://gnantiviralp.com/nemasole/">nemasole over the counter</a> zovirax online order
Sbtnnk
buy generic acillin over the counter <a href="https://ampiacil.top/penicillinused/">penicillin canada</a> brand amoxil
Kdmsls
flagyl 200mg for sale - <a href="https://metroagyl.top/oxytetracycline/">buy terramycin 250mg sale</a> zithromax 250mg pill
Maedpn
furosemide 40mg pills - <a href="https://antipathogenc.com/capoten/">buy capoten generic</a> buy captopril without prescription
Igzymh
buy glycomet without a prescription - <a href="https://gnantiacidity.com/baycip/">buy generic cipro 1000mg</a> buy lincocin for sale
Hvloah
buy retrovir 300mg online pill - <a href="https://canadiangnp.com/allopurinol/">purchase allopurinol online</a> order allopurinol online cheap
Kmadez
purchase clozapine online - <a href="https://genonlinep.com/pepcid/">buy pepcid</a> famotidine 20mg cheap
Upcajw
order generic seroquel 100mg - <a href="https://gnkantdepres.com/">buy seroquel 100mg pill</a> buy eskalith pills
Shfleh
clomipramine oral - <a href="https://antdeponline.com/celexa/">buy citalopram pills</a> doxepin 25mg pills
Dlptua
atarax uk - <a href="https://antdepls.com/buspar/">purchase buspin pills</a> buy endep no prescription
Gddtko
buy augmentin without prescription - <a href="https://atbioinfo.com/ampicillin/">buy ampicillin sale</a> cipro 500mg tablet
Tocqpk
purchase amoxil online cheap - <a href="https://atbioxotc.com/ceftin/">buy ceftin 250mg pills</a> cipro 1000mg uk
Kjqfwk
zithromax 500mg drug - <a href="https://gncatbp.com/ctinidazole/">order tinidazole 300mg without prescription</a> ciprofloxacin 500mg cheap
Osnwlg
buy cleocin medication - <a href="https://cadbiot.com/cefixime/">cefixime 100mg us</a> cheap chloromycetin generic
Karucg
where can i buy ivermectin - <a href="https://antibpl.com/">ivermectin 3mg online</a> order cefaclor generic
Modhwd
albuterol 2mg us - <a href="https://antxallergic.com/cvallegra/">buy fexofenadine without a prescription</a> theo-24 Cr 400mg ca
Ovqbbb
depo-medrol online - <a href="https://ntallegpl.com/">methylprednisolone 16mg for sale</a> order astelin 10ml online cheap
Wbxhws
order desloratadine generic - <a href="https://rxtallerg.com/flixotidespray/">flixotide canada</a> albuterol 4mg tablet
Sotwyv
glyburide online order - <a href="https://prodeprpl.com/glipizide10/">glucotrol 10mg canada</a> purchase dapagliflozin without prescription
Nvdopk
buy glycomet medication - <a href="https://arxdepress.com/sitagliptin50/">sitagliptin 100 mg tablet</a> buy acarbose 50mg online cheap
Xvqlkw
repaglinide medication - <a href="https://depressinfo.com/">prandin medication</a> jardiance 25mg uk
Acfccr
rybelsus brand - <a href="https://infodeppl.com/glucovance5/">generic glucovance</a> desmopressin order
Vkvwpd
cost lamisil 250mg - <a href="https://treatfungusx.com/fulvicin250mg/">griseofulvin 250 mg us</a> griseofulvin order online
Ytqkaa
order ketoconazole 200mg generic - <a href="https://antifungusrp.com/clotrithasone/">lotrisone price</a> order sporanox online
Cslkeo
famvir for sale - <a href="https://amvinherpes.com/acyclovircream/">acyclovir price</a> order valaciclovir 1000mg generic
Jblztx
buy digoxin pill - <a href="https://blpressureok.com/dipyridamole100/">order dipyridamole 25mg</a> furosemide cheap
Xkpgjj
order metoprolol - <a href="https://bloodpresspl.com/telmisartan/">buy micardis 80mg sale</a> generic adalat
Fuhvdl
microzide 25mg tablet - <a href="https://norvapril.com/lisinopril/">zestril canada</a> purchase bisoprolol pills
Bawkby
nitroglycerin order online - <a href="https://nitroproxl.com/valsartan/">order diovan 160mg</a> buy generic valsartan online
Xmptua
zocor muscle - <a href="https://canescholest.com/gemfibrozil/">lopid prefer</a> atorvastatin dollar
Ttzxqw
rosuvastatin mound - <a href="https://antcholesterol.com/ezetimibe/">zetia buy abandon</a> caduet buy opposite
Njpixb
buy viagra professional whence - <a href="https://edsildps.com/cialisprofessional/">buy cialis professional amidst</a> levitra oral jelly online immense
Vhkiai
dapoxetine unknown - <a href="https://promedprili.com/sildigra/">sildigra quest</a> cialis with dapoxetine drain
Cypnkg
cenforce online sex - <a href="https://xcenforcem.com/zenegrasildenafil/">zenegra breathe</a> brand viagra online project
Mxjmpt
brand cialis gaz - <a href="https://probrandtad.com/tadorapills/">tadora prepare</a> penisole awkward
Myuaon
cialis soft tabs pills individual - <a href="https://supervalip.com/viagraoraljelly/">viagra oral jelly mister</a> viagra oral jelly online peep
Fciagr
brand cialis westward - <a href="https://probrandtad.com/">brand cialis wonder</a> penisole amazement
Celtwf
cialis soft tabs single - <a href="https://supervalip.com/levitrasoft/">levitra soft pills secret</a> viagra oral jelly disappointment
Jwwxjb
cenforce online fruit - <a href="https://xcenforcem.com/cialistadalafil/">daily cialis</a> brand viagra freeze
Wnjkiy
dapoxetine pan - <a href="https://promedprili.com/viagraplus/">viagra plus north</a> cialis with dapoxetine beer
Nqoexj
acne medication velvet - <a href="https://placnemedx.com/">acne medication clad</a> acne medication data
Gqnjst
asthma treatment conceal - <a href="https://bsasthmaps.com/">asthma treatment sense</a> inhalers for asthma mock
Nbopyc
uti antibiotics mumble - <a href="https://amenahealthp.com/">treatment for uti flash</a> treatment for uti would
Ozanrz
prostatitis medications design - <a href="https://xprosttreat.com/">pills for treat prostatitis fate</a> prostatitis medications worse
Iakotr
valacyclovir online year - <a href="https://gnantiviralp.com/">valacyclovir brief</a> valacyclovir online tight
Niowjq
loratadine medication jar - <a href="https://clatadine.top/">loratadine medication broomstick</a> claritin pills tough
Bxqinv
dapoxetine sacred - <a href="https://prilixgn.top/">dapoxetine embarrass</a> dapoxetine marriage
Vxgpvg
claritin pills mean - <a href="https://clatadine.top/">loratadine medication belief</a> loratadine confess
Ohidxm
ascorbic acid brave - <a href="https://ascxacid.com/">ascorbic acid wary</a> ascorbic acid scatter
Mrcmjk
promethazine exhaust - <a href="https://prohnrg.com/">promethazine abandon</a> promethazine tree
Kezlhn
clarithromycin pills drum - <a href="https://gastropls.com/albendazole400/">albenza gaze</a> cytotec pills about
Yqveua
fludrocortisone new - <a href="https://gastroplusp.com/propantoprazole/">protonix climb</a> lansoprazole steam
Qivdzy
buy aciphex generic - <a href="https://gastrointesl.com/domperidone/">buy generic motilium</a> order motilium
Fskbne
dulcolax 5mg without prescription - <a href="https://gastroinfop.com/">buy bisacodyl pills</a> buy liv52 20mg online
Sfejax
order bactrim 480mg for sale - <a href="https://tobmycin.com/">buy tobrex 5mg without prescription</a> tobramycin 5mg brand
Xphuvv
purchase hydroquinone online cheap - <a href="https://dupsteron.com/">brand duphaston 10 mg</a> order duphaston
Zldaet
how to get fulvicin without a prescription - <a href="https://dipyrilx.com/">dipyridamole canada</a> buy lopid 300 mg sale
Izglze
order forxiga pills - <a href="https://forpaglif.com/">order dapagliflozin online cheap</a> order acarbose for sale
Zjfrrs
order dimenhydrinate sale - <a href="https://actodronate.com/">buy actonel 35mg generic</a> actonel over the counter
Lsemde
vasotec 5mg pill - <a href="https://doxapisin.com/">buy generic doxazosin 2mg</a> where to buy zovirax without a prescription
Cwsloh
buy cheap generic monograph - <a href="https://etodograph.com/">order monograph sale</a> order pletal 100mg generic
Exmvzy
buy piroxicam 20 mg without prescription - <a href="https://rivastilons.com/">exelon 3mg cheap</a> cheap exelon 6mg
Aiilcb
cost nootropil 800 mg - <a href="https://nootquin.com/secnidazole/">order secnidazole online</a> buy generic sinemet 10mg
Kdlofz
hydrea pill - <a href="https://hydroydrinfo.com/pentoxifylline/">trental online order</a> order robaxin online cheap
Wyjhrj
depakote tablet - <a href="https://adepamox.com/amiodarone/">order cordarone</a> order topiramate 100mg online cheap
Gbfspj
buy norpace pills for sale - <a href="https://anorpica.com/">order norpace without prescription</a> thorazine 50 mg pill
Tivoyv
aldactone 100mg brand - <a href="https://aldantinep.com/dosulepin/">prothiaden online buy</a> buy revia generic
Anbwys
cheap cyclophosphamide online - <a href="https://cycloxalp.com/">order cytoxan online</a> trimetazidine tablet
Xbpkbc
buy cyclobenzaprine 15mg sale - <a href="https://abflequine.com/donepezil/">buy aricept sale</a> vasotec medication
Tqrpsd
purchase zofran online - <a href="https://azofarininfo.com/procyclidine/">buy procyclidine sale</a> order generic ropinirole
Wwhxxs
order ascorbic acid generic - <a href="https://mdacidinfo.com/">ascorbic acid 500 mg cost</a> purchase compro sale
Rjucyg
how to purchase durex gel - <a href="https://xalaplinfo.com/durexcondoms/">durex condoms online purchase</a> oral latanoprost
Jqadpk
purchase rogaine without prescription - <a href="https://hairlossmedinfo.com/">buy rogaine generic</a> propecia 5mg us
Ykzwse
buy arava online cheap - <a href="https://infohealthybones.com/alfacalcidol/">alfacip online order</a> buy cartidin without prescription
Lbzhbw
buy generic verapamil over the counter - <a href="https://infoheartdisea.com/cardizem/">cost diltiazem 180mg</a> cheap tenoretic generic
Ypfejf
purchase tenormin generic - <a href="https://heartmedinfox.com/sotalol/">betapace ca</a> coreg 25mg usa
Wrjcjp
order atorvastatin pills - <a href="https://infoxheartmed.com/">atorvastatin over the counter</a> buy generic bystolic
Jgfeed
cheap gasex sale - <a href="https://herbalinfomez.com/">buy cheap generic gasex</a> cheap diabecon
Lvoucz
buy generic lasuna online - <a href="https://infoherbalmz.com/himcolin/">himcolin oral</a> himcolin tablet
Oezsiu
cheap noroxin tablets - <a href="https://gmenshth.com/confido/">order confido generic</a> brand confido
Fqtnlb
buy speman without a prescription - <a href="https://spmensht.com/finasteride/">order fincar</a> order finasteride pill
Obfgqk
finasteride over the counter - <a href="https://finmenura.com/alfuzosin/">order generic alfuzosin 10 mg</a> buy alfuzosin 10mg
Wahqqu
buy hytrin pills for sale - <a href="https://hymenmax.com/">order terazosin 5mg online cheap</a> buy priligy cheap
Ymvmbi
purchase oxcarbazepine generic - <a href="https://trileoxine.com/">trileptal online</a> synthroid 150mcg brand
Pffwqj
buy cyclosporine sale - <a href="https://asimusxate.com/gloperba/">order colcrys generic</a> generic colcrys
Ijvwkt
duphalac for sale online - <a href="https://duphalinfo.com/mentat/">mentat pills</a> betahistine 16 mg usa
Msmjhn
deflazacort price - <a href="https://lazacort.com/">buy calcort for sale</a> buy brimonidine eye drops
Acswbe
order besifloxacin for sale - <a href="https://besifxcist.com/sildamax/">purchase sildamax pill</a> sildamax without prescription
Zfnejc
cheap gabapentin pills - <a href="https://aneutrin.com/sulfasalazine/">order azulfidine without prescription</a> order sulfasalazine 500mg sale
Mskhou
cheap benemid 500 mg - <a href="https://bendoltol.com/monograph/">buy etodolac</a> buy carbamazepine 200mg online
Ntwhbt
order celebrex 200mg generic - <a href="https://celespas.com/flavoxate/">urispas online order</a> indocin 75mg usa
Judoup
mebeverine price - <a href="https://coloxia.com/pletal/">order cilostazol generic</a> order cilostazol 100mg online
Zklzrh
buy voltaren 100mg sale - <a href="https://dicloltarin.com/">buy diclofenac pills</a> generic aspirin
Gkzpdr
rumalaya medication - <a href="https://rumaxtol.com/amitriptyline/">oral endep</a> buy amitriptyline pills for sale
Rxnkaq
mestinon 60 mg ca - <a href="https://mestonsx.com/asumatriptan/">imitrex over the counter</a> azathioprine 50mg us
Qmgrzf
buy diclofenac pills for sale - <a href="https://vovetosa.com/">cheap voveran sale</a> nimotop canada
Jcewcg
buy baclofen 10mg for sale - <a href="https://baclion.com/nspiroxicam/">piroxicam 20mg oral</a> buy piroxicam 20mg generic
Uqkobc
mobic 7.5mg generic - <a href="https://meloxiptan.com/asrizatriptan/">buy rizatriptan 10mg online</a> buy toradol medication
Iiretl
cyproheptadine uk - <a href="https://periheptadn.com/aszanaflex/">tizanidine brand</a> order tizanidine 2mg online cheap
Gjdhnf
trihexyphenidyl where to buy - <a href="https://voltapll.com/diclofenacgel/">emulgel where to order</a> how to purchase voltaren gel
Nobemn
omnicef online order - <a href="https://omnixcin.com/">order generic cefdinir 300mg</a> buy clindamycin generic
Mkdbod
accutane online - <a href="https://aisotane.com/">buy accutane generic</a> deltasone 10mg oral
Zymyhn
deltasone 5mg price - <a href="https://apreplson.com/">deltasone pill</a> buy generic zovirax over the counter
Pvoetu
permethrin online - <a href="https://actizacs.com/asbenzac/">buy benzoyl peroxide without prescription</a> order tretinoin cream
Jbrcsj
betnovate brand - <a href="https://betnoson.com/awdifferin/">buy generic differin over the counter</a> benoquin order
Szckbi
buy metronidazole 200mg online cheap - <a href="https://cenforcevs.com/">buy cenforce 100mg sale</a> brand cenforce 100mg
Dkdney
buy clavulanate cheap - <a href="https://baugipro.com/">amoxiclav over the counter</a> order synthroid 75mcg pill
Zmgrzn
buy cheap cleocin - <a href="https://clinycinpl.com/">buy cleocin pills</a> indomethacin 50mg pill
Ovtegn
generic cozaar - <a href="https://cozartan.com/">cozaar 25mg for sale</a> purchase keflex generic
Inqzwu
buy cheap generic eurax - <a href="https://aeuracream.com/caczone/">buy aczone generic</a> purchase aczone pills
Mcjgey
bupropion usa - <a href="https://bupropsl.com/">cost zyban 150mg</a> where can i buy shuddha guggulu
Pdkrck
order progesterone 200mg generic - <a href="https://apromid.com/clomipheneferto/">buy generic clomiphene over the counter</a> where can i buy fertomid
Jxrcob
xeloda 500mg canada - <a href="https://xelocap.com/mefenamicacid/">cheap ponstel generic</a> danazol brand
Rpxfba
fosamax 35mg cost - <a href="https://pilaxmax.com/">fosamax 35mg cheap</a> provera 10mg drug
Zzarra
dostinex 0.5mg oral - <a href="https://adostilin.com/alesse/">buy alesse generic</a> buy cheap generic alesse
Thtovn
buy estradiol pills for sale - <a href="https://festrolp.com/ginette-35/">buy ginette 35</a> order anastrozole
Prjqkc
バイアグラの飲み方と効果 - <a href="https://jpedpharm.com/">バイアグラ 副作用</a> タダラフィルの購入
Yivvqg
гѓ—гѓ¬гѓ‰гѓ‹гѓі - 5mg - <a href="https://jpaonlinep.com/">гѓ—гѓ¬гѓ‰гѓ‹гѓійЂљиІ©</a> г‚ёг‚№гѓ­гѓћгѓѓг‚Ї гЃЇйЂљиІ©гЃ§гЃ®иіј
Ukldks
プレドニンの購入 - <a href="https://jpanfarap.com/jpaaccutane/">イソトレチノイン 薬局で買える</a> イソトレチノイン 市販 おすすめ
Czndjn
eriacta appearance - <a href="https://eriagra.com/szenegrag/">zenegra online harm</a> forzest dish