项目上线
上线架构
安装 mysql
# 下载 mysql5.7
wget http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
# 安装 mysql5.7
yum -y install mysql57-community-release-el7-10.noarch.rpm
yum install mysql-community-server --nogpgcheck
# 启动 mysql5.7 并查看启动状态
systemctl start mysqld.service # 启动mysql服务
systemctl enable mysqld.service # 开机自启动
systemctl status mysqld.service # 查看服务
# 查看默认密码并登录
grep "password" /var/log/mysqld.log
mysql -uroot -p
# 修改密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Mysql12345?';
安装 redis
# 下载redis-5.0.5
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
# 解压安装包
tar -xf redis-5.0.5.tar.gz
# 进入目标文件
cd redis-5.0.5
# 编译环境 src路径下就有可执行文件 redis-server redis-cli 等
make -j `cat /proc/cpuinfo |grep processor |wc -l`
# 复制环境到指定路径完成安装
cp -rp ~/redis-5.0.5 /usr/local/redis
# 配置redis可以后台启动:修改下方内容
vim /usr/local/redis/redis.conf
daemonize yes
# 建立软连接
ln -s /usr/local/redis/src/redis-server /usr/bin/redis-server
ln -s /usr/local/redis/src/redis-cli /usr/bin/redis-cli
# 后台运行redis
cd /usr/local/redis
redis-server ./redis.conf
# 查看服务是否启动
ps aux |grep redis
# 测试redis环境
redis-cli
# 关闭redis服务
pkill -f redis -9
安装 python3.8
# 下载依赖
yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel python-devel mariadb-devel gdbm-devel python-setuptools python-devel -y
# 下载源码安装
wget https://registry.npmmirror.com/-/binary/python/3.8.6/Python-3.8.6.tgz
tar xf Python-3.8.6.tgz
cd Python-3.8.6/
./configure --prefix=/usr/local/python38
make && make install
ln -s /usr/local/python38/bin/python3 /usr/bin/python3.8
ln -s /usr/local/python38/bin/pip3 /usr/bin/pip3.8
# 安装uwsgi
pip3.8 install uwsgi
ln -s /usr/local/python38/bin/uwsgi /usr/bin/uwsgi
# 配置虚拟环境
python3.8 -m pip install --upgrade pip
python3.8 -m pip install --upgrade setuptools
pip3.8 install virtualenv
pip3.8 install virtualenvwrapper
# 建立软连接
ln -s /usr/local/python38/bin/virtualenv /usr/bin/virtualenv
# 配置环境变量
cat >> ~/.bashrc <<EOF
VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3.8
source /usr/local/python38/bin/virtualenvwrapper.sh
EOF
# 虚拟环境默认根目录:~/.virtualenvs
# 创建虚拟环境
mkvirtualenv luffy
安装 nginx
yum install gcc zlib zlib-devel pcre-devel openssl openssl-devel -y
wget http://nginx.org/download/nginx-1.20.1.tar.gz
tar xf nginx-1.20.1.tar.gz
cd nginx-1.20.1/
./configure --prefix=/usr/local/nginx \
--with-http_stub_status_module \
--with-http_ssl_module --with-pcre
make -j `cat /proc/cpuinfo |grep processor |wc -l` && make install
echo 'export PATH=/usr/local/nginx/sbin:$PATH' >> /etc/profile
source /etc/profile
上线前端
# 修改后端地址 luffycity/src/assets/js/settings.js 改为公网 IP
export default {base_url:'http://119.91.117.23:8080/api/v1/'}
# 将 vue 项目 编译为 html css js 等纯静态文件 项目目录下执行
npm run build
# 将 dist 文件夹压缩上传到服务器上 sftp 等工具
# 进入到上传所在的目录
mkdir /web/luffy -p
unzip dist.zip -d /web/luffy/
# 修改 nginx 配置文件
cd /usr/local/nginx/
# 修改配置文件,如下
nginx.conf
worker_processes auto;
events {
worker_connections 1024;
}
http
{
include mime.types;
default_type application/octet-stream;
charset UTF-8;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 50m;
#####################################
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
#####################################
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 256k;
#####################################
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
server_tokens off;
include vhost/*.conf;
}
# 创建目录
mkdir vhost
cat > vhost/web.conf <<EOF
server {
listen 80;
server_name localhost;
charset utf-8;
location / {
root /web/luffy/dist;
index index.html;
try_files $uri $uri/ /index.html; # 解决单页面应用刷新404问题
}
}
EOF
# 检查
nginx -t
# 启动
nginx
# 检查是否成功启动
netstat -lntup
ps -ef |grep nginx
# 访问地址
上线后端
上线前准备
setting/pro.py
将 luffy_api/setting/dev.py 拷贝过来修改
import os
import sys
import datetime
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(os.path.join(BASE_DIR, 'apps'))
sys.path.append(BASE_DIR)
SECRET_KEY = '-b4z=*^wa1rjc-5a+@+)f%t-%mppmx@vz%8zdps1$rr9r@y&$5'
DEBUG = False
ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
'simpleui',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'user',
'home',
'course',
'order',
'django_filters',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
]
ROOT_URLCONF = 'luffy_api.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'luffy_api.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'luffy',
'USER': 'luffy',
'PASSWORD': 'Luffy123?',
'HOST': 'localhost',
'PORT': 3306,
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
STATIC_URL = '/static/'
# 日志相关
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
},
'simple': {
'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
},
},
'filters': {
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': {
'console': {
# 实际开发建议使用WARNING
'level': 'DEBUG',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file': {
# 实际开发建议使用ERROR
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
# 日志位置,日志文件名,日志保存目录必须手动创建,注:这里的文件路径要注意BASE_DIR代表的是小luffyapi
'filename': os.path.join(os.path.dirname(BASE_DIR), "logs", "luffy.log"),
# 日志文件的最大值,这里我们设置300M
'maxBytes': 300 * 1024 * 1024,
# 日志文件的数量,设置最大日志数量为10
'backupCount': 10,
# 日志格式:详细格式
'formatter': 'verbose',
# 文件内容编码
'encoding': 'utf-8'
},
},
# 日志对象
'loggers': {
'django': {
'handlers': ['console', 'file'],
'propagate': True, # 是否让日志信息继续冒泡给其他的日志处理系统
},
}
}
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': ( # 默认响应渲染类
'rest_framework.renderers.JSONRenderer', # json渲染器
# 'rest_framework.renderers.BrowsableAPIRenderer', # 浏览API渲染器
),
'EXCEPTION_HANDLER': 'utils.exception.common_exception_handler' # 再出异常,会执行这个函数
}
# 自定义User表
AUTH_USER_MODEL = 'user.User'
# 配置media
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# 跨域问题处理
# 允许简单请求,所有地址 相当于CORS_ORIGIN_ALLOW_ALL="*"
CORS_ALLOW_ALL_ORIGINS = True
# 运行的请求
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
# 允许的请求头
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization', # jwt
'content-type', # json
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
)
# 导入用户自定义配置
from .user_settings import *
JWT_AUTH = {
# 过期时间1天
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
}
# redis 配置
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient", # 这句指的是django中的缓存也缓存到redis中了
"CONNECTION_POOL_KWARGS": {"max_connections": 100} # 连接池的大小
# "PASSWORD": "123",
}
}
}
setting/user_settings.py
# 用户自己的配置,单独放到另一个py文件中
BANNER_COUNT = 4
# 用户自己别的配置
# 上线后必须换成公网地址
# 后台基URL
BASE_URL = 'http://119.91.117.23:8080'
# 前台基URL
LUFFY_URL = 'http://119.91.117.23'
# 支付宝同步异步回调接口配置
# 后台post异步回调接口
NOTIFY_URL = BASE_URL + "/api/v1/order/success/"
# 前台同步回调接口,没有 / 结尾
RETURN_URL = LUFFY_URL + "/pay/success"
manage_pro.py
将 manage.py
复制一份改为 manage_pro.py
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.setting.pro')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
导出模块
pip freeze > requirements.txt
提交代码
git add .
git commit -m "发布版本"
git tag -a v1.5 -m "发布版本"
git push origin "master" --tags v1.5
服务端上线
拉取代码
cd /web/luffy
git clone https://gitee.com/liuzhijin1/luffy_api.git
环境配置
# 进入虚拟环境
workon luffy
# 下载 mysqlclient 的依赖
yum install mysql-devel -y
yum install python-devel -y
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
# 安装所需模块
pip install -r requirements.txt
pip install uwsgi
uwsgi
与nginx
配置
# uwsgi
cat > /web/luffy/luffy_api/luffyapi.xml <<EOF
<uwsgi>
<socket>127.0.0.1:8888</socket>
<chdir>/web/luffy/luffy_api/</chdir>
<module>luffy_api.wsgi</module>
<processes>4</processes>
<daemonize>uwsgi.log</daemonize>
</uwsgi>
EOF
# nginx 配置文件
cat > /usr/local/nginx/conf/vhost/luffapi.conf<< EOF
server {
listen 8080;
server_name 127.0.0.1;
charset utf-8;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8888;
uwsgi_param UWSGI_SCRIPT luffy_api.wsgi;
uwsgi_param UWSGI_CHDIR /web/luffy/luffy_api/;
}
}
EOF
数据库创建用户
mysql -uroot -pMysql12345?
create database luffy default charset=utf8mb4;
grant all privileges on luffy.* to 'luffy'@'%' identified by 'Luffy123?';
grant all privileges on luffy.* to 'luffy'@'localhost' identified by 'Luffy123?';
flush privileges;
quit
数据库迁移
# 只有库,没有表,迁移数据
# 必须在luffy环境下
# 数据库迁移
cd /web/luffy/luffy_api
python manage_pro.py migrate
# 导入测试数据
把原来本地的数据,导入到正式库中
navicat 中导出先 结构和数据 放到桌面
然后导入到线上库做测试用
无法导入可能是编码格式有问题,将sql文件中的编码格式修改一下即可
启动 uwsgi
# 可能缺少的依赖
yum install libxml*
# 需要进入到虚拟环境中
workon luffy
uwsgi -x ./luffyapi.xml
nginx -s reload
后台的静态样式收集和上线
# 创建静态文件目录
mkdir /web/luffy/luffy_api/luffy_api/static -p
# 修改配置
vim /web/luffy/luffy_api/luffy_api/setting/pro.py
STATIC_URL = '/static/'
STATIC_ROOT = '/web/luffy/luffy_api/luffy_api/static'
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)
# 后台静态文件迁移 自动迁移到 上面创建的静态文件目录
python /home/project/luffy_api/manage_pro.py collectstatic
# 加入 nginx 的配置解析 后端是 8080端口的
cat /usr/local/nginx/conf/vhost/luffapi.conf
server {
listen 8080;
server_name 127.0.0.1;
charset utf-8;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8888;
uwsgi_param UWSGI_SCRIPT luffy_api.wsgi;
uwsgi_param UWSGI_CHDIR /web/luffy/luffy_api/;
}
location /static {
alias /web/luffy/luffy_api/luffy_api/static;
}
location /media {
alias /web/luffy/luffy_api/luffy_api/media;
}
}