
暂无个人介绍
能力说明:
深度理解Python的语法与数据类型知识,对运算符、控制语句、列表、元组、字典的应用等具有清晰的认知。理解Flask、Django等Web开发框架的原理、构建方法,掌握利用Python爬虫技术与常用工具进行数据收集的应用能力。
阿里云技能认证
详细说明### pm2部署 pm2是一个node进程守护 、监控、自动重启以及生成日志的软件,它可以帮你很好的管理node项目。 安装node、pm2等必要依赖 node安装,请参阅Node.js 安装配置 pm2安装,淘宝cnpm,可以加快镜像安装速度 # 淘宝npm npm install -g cnpm --registry=https://registry.npm.taobao.org # pm2 安装 npm install pm2 -g # 软连接(注意软连接路径必须是绝对路径) ln -s /usr/local/node8.11.4/bin/pm2 /usr/local/bin/pm2 nuxt项目打包 执行npm run build,未报异常说明可以正常运行部署,接着Ctrl+C停止nuxt即可,若本地再次运行使用npm start,npm run dev,会覆盖刚才打包的内容。 该命令执行后,会在项目的.nuxt生成dist目录,此时只需要把下面的文件复制到服务器对应的目录下即可 # 运行 npm run build 后,复制下面的4个文件到服务器 .nuxt static nuxt.config.js package.json 项目运行 需要注意的是,--name后面的名字是package.json中第一行的name # 在上传到服务器的目录下运行,状态为online,说明部署成功 pm2 start npm --name "nuxt-django" -- run start --watch 相关命令 # 列表 PM2 启动的所有的应用程序 pm2 list # 显示指定应用程序的日志 pm2 logs [app-name] # 停止所有的应用程序 pm2 stop all # 重启所有应用 pm2 restart all docker部署 Dockerfile 新建Dockerfile内容如下 FROM node:9.0.0 MAINTAINER www.gaozhe.net ENV NODE_ENV=production ENV HOST 0.0.0.0 RUN mkdir -p /app COPY . /app WORKDIR /app EXPOSE 3000 # 国内环境使用,非国内环境使用会报错 RUN npm config set registry https://registry.npm.taobao.org RUN npm installCMD ["npm", "start"] 构建 文件上传 把打包后的四个文件上传到服务器对应文件夹下,将上面新建的Dockerfile也放在此目录下 # 打包为镜像,上传文件的目录下运行 docker build -t testimage . 运行 运行容器 docker run -dti --network=host --restart=always --name test testimage 查看是否成功部署 # 未打印异常说明启动成功 docker logs test # 查看nuxt默认端口3000是否开启成功 netstat -ntlp | grep 3000 参考文档 Nuxt服务端部署(CentOS7+nginx+pm2) 使用docker优雅的部署你的nuxtjs项目
环境准备 docker安装 在虚拟机安装docker后,执行下面的命令 # 下载fastDFS镜像 docker image pull delron/fastdfs # 运行tracker docker run -dti --network=host --name tracker -v /var/fdfs/tracker:/var/fdfs delron/fastdfs tracker # 运行storage(TRACKER_SERVER这里使用ifconfig命令查看虚拟机的内网地址,不要使用本地地址127.0.0.1) docker run -dti --network=host --name storage -e TRACKER_SERVER=10.211.55.5:22122 -v /var/fdfs/storage:/var/fdfs delron/fastdfs storage # 查看镜像是否在运行 docker ps # 查看镜像logs,无error即可 docker logs tracker docker logs storage pip安装 安装相关pip第三方包 pip install py3fdfs pip install mutagen pip isntall requests 本地测试 对创建的fastDFS进行测试 新建client.conf base_path=utils/fastdfs/logs tracker_server=10.211.55.5:22122 connect_timeout=60 新建test.py from fdfs_client.client import Fdfs_client client = Fdfs_client('/utils/fastdfs/client.conf') # 注意要绝对路径 ret = client.upload_by_filename('/Users/delron/Desktop/1.png') print(ret) {'Group name': 'group1', 'Remote file_id': 'group1/M00/00/02/CtM3BVr-k6SACjAIAAJctR1ennA809.png', 'Status': 'Upload successed.', 'Local file name': '/Users/delron/Desktop/1.png', 'Uploaded size': '151.00KB', 'Storage IP': '10.211.55.5'} Django配置 在apps下面新建utils文件夹,并在utils新建fastdfs文件夹(可根据个人项目需要建立) setting.py # 自定义文件系统 # django文件存储 DEFAULT_FILE_STORAGE = 'apps.utils.fastdfs.fdfs_storage.FastDFSStorage' # FastDFS FDFS_URL = 'http://10.141.28.245:8888/' FDFS_CLIENT_CONF = os.path.join(BASE_DIR, 'apps/utils/fastdfs/client.conf') 新建client.conf # 在utils/fastdfs下新建文件client.conf base_path = /web/logs tracker_server = 10.141.28.245:22122 connect_timeout = 60 新建fdfs_storage.py # 在utils/fastdfs下新建文件fdfs_storage.py from django.conf import settings from django.core.files.storage import Storage from django.utils.deconstruct import deconstructible from fdfs_client.client import Fdfs_client, get_tracker_conf import os import logging log = logging.getLogger(__name__) @deconstructible class FastDFSStorage(Storage): def __init__(self, base_url=None, client_conf=None): """ 初始化 :param base_url: 用于构造图片完整路径使用,图片服务器的域名 :param client_conf: FastDFS客户端配置文件的路径 """ if base_url is None: base_url = settings.FDFS_URL self.base_url = base_url if client_conf is None: client_conf = settings.FDFS_CLIENT_CONF self.client_conf = client_conf def _open(self, name, mode='rb'): """ 用不到打开文件,所以省略 """ pass def _save(self, name, content): '''_save方法''' conf_path = get_tracker_conf(self.client_conf) client = Fdfs_client(conf_path) imgdir = f'{os.path.join(settings.BASE_DIR, "apps/utils/fastdfs")}/tmp.{str(name).split(".")[1]}' with open(imgdir, "wb+") as f: f.write(content.read()) result = client.upload_by_filename(imgdir) os.remove(imgdir) if result.get('Status') != 'Upload successed.': logging.error('上传文件到FastDFS失败') raise Exception('上传文件到FastDFS失败') filename = result.get('Remote file_id') return filename.decode() def url(self, name): """ 返回文件的完整URL路径 :param name: 数据库中保存的文件名 :return: 完整的URL """ return self.base_url + name def exists(self, name): """ 判断文件是否存在,FastDFS可以自行解决文件的重名问题 所以此处返回False,告诉Django上传的都是新文件 :param name: 文件名 :return: False """ return False 相关错误 configparser.NoOptionError: No option 'connect_timeout' in section: '__config__' 该错误在于client.conf中没有配置connect_timeout超时时间或者配置文件的地址不正确。解决:在client.conf中添加connect_timeout=10后若仍报错,卸载原有的pip包,pip安装py3fdfs即可 TypeError: type object argument after ** must be a mapping, not str 卸载原有的pip包,pip安装py3fdfs即可,或者使用from fdfs_client.client import get_tracker_conf引入配置文件 参考文档 FastDFS服务器搭建 FastDFS客户端与自定义文件存储系统 py3与fastFDFS交互 configparser.NoOptionError: No option 'connect_timeout' in section: 'config'
环境准备 确保MySQL版本大于5.7 确保防火漆关闭或开启各服务器的3306端口 MySQL配置 查看是否开启了GTID模式 若未开启在my.cnf文件最后添加,开启GTID(主) # must params server_id = 100 enforce_gtid_consistency = on gtid_mode = on # binlog log_bin = mysqlbin log_slave_updates = 1 binlog_format = row # relay log skip_slave_start = 1 若未开启在my.cnf文件最后添加,开启GTID(从) 需要注意的是,若配置多台MySQL从服务器,确保server_id唯一 # must params server_id = 101 enforce_gtid_consistency = on gtid_mode = on # binlog log_bin = mysqlbin binlog_format = row master_info_repository = TABLE # relay log relay_log_info_repository = TABLE 重启数据库 systemctl restart mysqld 再次确认一下是否开启成功 gtid_mode 被设置为on,即为开启成功 备份数据库 若使用的是三个数据库,数据不一样,需要进行数据的备份,导入 # 备份 mysqldump --single-transaction --master-data=2 --triggers --routines --all-databases -uroot -p > all.sql # 导出 mysqldump -u username -p dbname > dbname.sql # 导入 mysqldump -u username -p dbname < dbname.sql 配置账号 主库创建账号 创建用于复制的账号 mysql> create user repl@'192.168.43.%' identified by '123456Gao!'; Query OK, 0 rows affected (0.01 sec) mysql> grant replication slave on *.* to repl@'192.168.43.%'; Query OK, 0 rows affected (0.06 sec) 从库进行连接 进行数据库连接 mysql> change master to master_host = '192.168.43.54', -> master_user = 'repl', -> master_password = '123456Gao!', -> master_auto_position = 1 -> ; Query OK, 0 rows affected, 2 warnings (0.07 sec) 配置前 配置后 开启从库复制链路 start slave; 查看状态 show slave status\G 确保下图红框的两个内容状态为yes, 测试 在主库创建数据库,然后从库参看是否正确同步的该数据库 # 主库创建 create table test_gtid; # 从库查看 show databases; 可能遇到的问题 测试链路 mysql -urepl -p123456Gao! -h192.168.43.54 Mysql主从同步时Slave_IO_Running:Connecting ; Slave_SQL_Running:Yes的情况故障排除
注意 下面的原因,可能是和后端API交互不成功的原因 fileinput版本不正确,需要大于5.0 前端设置的name属性值和后端接收的属性值不一致 必要的css和js文件 请确保下面的js和css文件存在 <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> <link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/4.1.0/css/bootstrap.min.css"> <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/4.1.0/js/bootstrap.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/5.1.2/css/fileinput.min.css" rel="stylesheet" type="text/css"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/5.1.2/js/fileinput.min.js" type="text/javascript"></script> bootstrap-fileinput html 你可以在bootstrap-fileinput插件官网,选择其他样式 <input type="file" name="img" id="img" value="" multiple="multiple" data-show-preview="true"/> bootstrap-fileinput js 这里是简化的配置,bootstrap-fileinput还有更强大的配置,可以在查看官网文档 $("#img").fileinput({ language: 'en',//设置语言 uploadUrl: "https://ky8.top/upload_images",//图片上传的url,我这里对应的是后台struts配置好的的action方法 showCaption: true,//显示标题 showRemove: true, //显示移除按钮 uploadAsync: true,//默认异步上传 showPreview: true,//是否显示预览 textEncoding: "UTF-8",//文本编码 browseLabel: "Select Image", autoReplaceBoolean: false,//选择图片时不清空原图片 }); $("#img").on('fileuploaded', function (event, data, previewId, index) {//异步上传成功结果处理 {#var img = JSON.parse(data.response);//接收后台传过来的json数据#} var code = data['response']['code']; if (code === 0) { document.getElementById('osimg').src = data['response']['result']; document.getElementById('oshref').href = data['response']['result']; document.getElementById('mk').innerText = '!['+ data['response']['name'] +'](' + data['response']['result'] + ')'; } }); $("#img").on('fileerror', function (event, data, msg) {//异步上传失败结果处理 alert("uploadError"); }); 成功界面 相关源码 关注公众号:《Python数据结构》,回复 008 即可 参考文档 bootstrap-fileinput option选项说明
2021年01月