部署天天生鲜及问题

基本环境

  • 安装mysql
  • python虚拟环境中安装你项目中的包
    decode编码问题:'str' object has no attribute 'decode'(困惑好久,因为部署到服务器端了,所以感觉程序没有问题了,后来开了DEBUG,找到了问题),/data/env/pyweb/lib/python3.7/site-packages/django/db/backends/mysql/operations.py in last_executed_query, line 146
    decode->encode
  • mysqlclient版本问题,需要注释源码(可能是当前版本的bug)

pip freeze >requirements.txt 打包本地安装的包文件(在本地环境中)
pip install - r requirements.txt 服务器中安装包(在服务器的虚拟环境中)

  • 安装redis,修改redis.config文件(注释bind,守护进程启动,关闭保护模式)

安装FastDFS

  • 安装fastDFS需要安装依赖的包libfastcommon-master-master.zip
    yum install unzip
    unzip libfastcommon-master-master.zip
    chmod +x make.sh
    ./make.sh
    sudo ./make.sh install
  • 安装fastdfs
    https://my.oschina.net/harlanblog/blog/466487?fromerr=cqe6bTu2
  • 修改配置文件
    mv /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
    mv /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf
    vim tracker.conf
    < base_path /创建的空文件夹/tracker>
    vim storage.conf
    <base_path /创建的空文件夹/storage>
    <storage_path0= /创建的空文件夹/storage>
    <tracker_server=ip:22122> ip是你ifconfig得到的ip
  • 启动
    /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf
    /usr/bin/fdfs_storaged /etc/fdfs/storage.conf
  • 验证服务
    ps aux|grep tracker&&storage
  • 测试

修改clinet.conf 里面的 tracker_server 为ip:22122
vim filename.txt
fdfs_upload_file client.conf filename.txt
出现group....txt -———————— > 成功

FastDFS配合Nginx使用

Nginx安装及其模块的添加

  • 下载Nginx压缩包
  • 解压
  • 执行预编译命令,指定安装的路径(--prefix= / 路径 / ),及添加模块操作(--add module=文件夹/src)
    cd nginx目录中
    ./configure --prefix=/usr/local/nginx/ --add-module=fdfs_nginx模块目录/src
  • 修改一些内容,否则在执行make时会报错(Fatal error)
    chmod 777 /windowsfile/fastdfd_nginx_module/src/config
    vim /windowsfile/fastdfd_nginx_module/src/config

下面的内容发生了更改
ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"

Nginx相关的配置
  • fdfs模块的配置
    cp /windowsfile/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs/
    vim mod_fastdfs.conf
    <timeout为10>
    <tracker-server ip:22122>
    <url_has_group_name为 true>
  • nginx.conf


  • 启动nginx后就可以在浏览器中显示图片了

目前本地的程序已经可以基本运行了,因为redis,fdfs就位,差celery异步。下一步就是在服务器运行程序。

uwsgi 配置

  • 在项目中创建uwsgi.ini,内容
[uwsgi]
# 直接作为web服务器使用 python manage.py runserver ip:port
# http=127.0.0.1:8080
socket = 127.0.0.1:8080

# 项目的文件目录
chdir=/项目目录
# wsgi文件在你的项目目录的哪里   基于上面的目录
wsgi-file=daily_fresh/wsgi.py
processes=4
threads=2
master=True # 有主进程

# 保存主进程的进程号
pidfile=uwsgi.pid
# 作为守护进程,并保存日志
daemonize=uwsgi.log


# 虚拟环境的目录
virtuaenv=/虚拟环境的目录
  • 启动:uwsgi --ini /配置文件目录
  • 停止: uwsgi --stop uwsgi.pid路径
    例如:uwsgi --ini uwsgi.ini;
    uwsgi --stop uwsgi.pid或者 pkill -f uwsgi -9

uwsgi + Nginx(做)

  • 将项目拷贝到服务器,修改DEBUG = False,ALLOWED_HOSTS = ['*'],并在settings中设置STATIC_ROOT = '/data/www/static'指定静态文件收集的目录(这个目录应该是已创建的)
  • 这个文件夹要搞一下权限
    chmod 777 /data/www/static
  • 改一下mysql
    否则会提示mysqlclient错误: /data/env/pyweb/lib/python3.7/site-packages/django/db/backends/mysql/base.py,修改环境下的lib/python3.7/site···文件,或者将本地已经改好的base.py复制过去
  • 执行 收集静态文件
    python manage.py collectstatic
    1750 static files copied to '/data/www/static'.成功
    静态文件已经收集好了,剩下要让nginx显示
  • 配置nginx.conf
location / {
    inlcude uwsgi_params;          #  参数也要包含
    uwsgi_pass 127.0.0.1:8080;      #  转交给uwsgi
}
location /static {
  alias /data/www/static/;   # 指定静态文件的目录
}
  • 重启nginx
    sbin/nginx -s reload

nginx还未完成

celery的配置

  • celery任务中有导入app的模块,所以需要django的环境
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE','dailyfresh.settings')
#或者os.environ['DJANGO_SETTINGS_MODULE'] ='daily_fresh.settings')
django.setup()
  • 进入虚拟环境执行,报错(goods/admin.py)can't import index_html

理论上应该是没有问题,但是不能导入,就是时机不对,太早了,所以在使用到这个函数的时候在导入,写在里面就好了

class BaseAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        super().save_model(request, obj, form, change)
        from celery_tasks.tasks import generate_static_index_html

        generate_static_index_html.delay()

        cache.delete('index_page_data')

    def delete_model(self, request, obj):
        super().delete_model(request, obj)
        from celery_tasks.tasks import generate_static_index_html

        generate_static_index_html.delay()

        cache.delete('index_page_data')
  • 没有haystack.backends.whoosh_cn_backend'
    这个是自己修改的,所以将本地的拷贝到服务器中haystack中的文件夹中
  • 启动celery时遇到错误,无法连接redis://ip:6379,把ip改为了本机ip改为内网地址应该成功,我该为了127.0.0.1成功。
  • 再次启动成功,但是执行任务时出错,静态首页时报错,应该返回一个dict,而不是一个request对象,将context = 字典后,不对他进行封装。
  • 遇到ImageFilefield Error,模板中的问题,将模板文件中的图片image.url,去掉了url。暂时好了,但是生成的页面图片地址不对,后来知道是fdfs_client的原因,下面也有。
  • stmp邮箱遇到错误,无法连接到stmp
    将settings文件中的EMAIL_USE_TSL = False改为 EMAIL_USE_SSH = True
    成功发送邮件。

uwsgi + Nginx(释)

  • 在将项目拷贝到服务器之前,改DEBUG = False,ALLOWED_HOSTS = ['*'],这样在服务器端静态文件不会生效,需要用到 nginx
  • 思路: 1. 用户访问一个地址,由nginx接受参数,并判断是静态请求还是动态请求这步判断就是nginx的路由匹配location /url/ { }
    1. 如果是静态请求,就是请求了一些图片,css,js等资源,我们实现把这些资源放在一个文件中,并设置nginx的路由匹配,将匹配结果导向我们的文件位置。
    1. 如果是动态请求,那么就转交给uwsgi,让uwsgi在调用application() 访问django系统,系统返回参数给uwsgi,再通过nginx返回到用户界面。
      nginx配置文件,里面的http{}中全是一些serve{}
      listen:监听的端口号,
      server_name:监听的ip地址
      location ‘url’{ }:路由,括号里面类似于django的urls。

静态请求

1 如果像直接返回静态文件,不提交到uwsgi服务器,那么里面直接写本机中的文件路径,新建一个存放静态文件的路径。/data/www/daily_fresh/static,然后在nginx.conf中指定当访问/static路径时,就去找/data/www/daily_fresh/static目录
location /static {
# 指定存放静态文件的目录
alias /data/www/daily_fresh/static
}

在setting的文件中指定STATIC_ROOT的值为刚才的路径/data/www/daily_fresh/static,
执行 python manage.py collectstatic收集静态文件。

权限不够的话, chmod 777 /data/daily_fresh/static/

1.2 当用户请求的静态文件不在此电脑上时可以,可以通过ip访问到另一nginx的上的静态文件
location = / {
指定存放静态文件nginx的ip地址,及端口,没写就是默认80
proxy_pass http://ip:port;
}

动态请求

  1. 如果是要提交给uwsgi服务器,同时还要提交传入的参数给uwsigi, 就需要uwsgi的端口号和地址。
    # 包含uwsgi的请求参数
    include uwsgi_params;
    # 转交给 uwsgi 的ip和端口
    uwsgi_pass 127.0.0.1:8080;

配置nginx的时候,小心分号,少写会报错。

项目总体


每一个部分都可以在不同的电脑上。

  • django项目跑在uwsgi服务器上,可以在项目中多创建几个uwsgi.ini,注意其中的socket端口不能相同,还有就是uwsgi.pid和log的名字也要变化
  • 静态页面的服务器和应用服务器时分离的,实现了前后端分离。
  • 在调度服务器中可以通过ip:port访问静态文件。
  • 调度服务器中负载均衡,要修改conf文件,加上
    upstream somename{
    server ip:port1
    server ip:port2
    当用户访问时,会轮流执行
    }

    之前是将请求直接返回给了uwsgi,现在,较给somename,让他决定哪个应用服务器执行。
    **
    location / {
    include uwsgi_parms;
    uwsgi_pass somename;
    }
    **
  • mysql,fstdfs,redis也可不在同一台电脑中,通过ip:port连接。
    其中fdfs的访问要通过nginx实现,让他监听网站的某个端口来实现上传和下载。

  • 部署时,先检查项目跑起来有没有问题python manage.py runserver,如果有问题就是项目中存在问题,可能是你在本地的改了配置文件,但是在服务器中虚拟环境中没有更改,例如mysqlclient的问题decode的问题haystack中添加了配置的文件
  • 上一步完成就添加一个uwsgi文件
  • 修改nginx配置文件
  • 让uwsgi的配置文件生效
  • 启动nginx
  • celery中的任务,要填加上django的环境

在tasks中的前面要加上django启动时的环境,但是启动时的环境导入这任务中的函数就会出错,报import异常,所以要把import放在里面,什么时候用,什么时候import。

出现的问题

TypeError: context must be a dict rather than RequestContext:
这个问题是django版本的问题,出现在生成静态首页的位置,我们需要得到html页面,并保存在本地,而不需要返回

    # 使用模板
    # 加载模板文件
    temp = loader.get_template('static_index.html')
    # 定义模板上下文
    context = RequestContext(request,context)
    # 模板渲染
    static_index_html = temp.render(context)
    # 生成首页对应的静态文件
    save_path = os.path.join(settings.BASE_DIR, 'static/index.html')
    with open(save_path,'w') as f:
        f.write(static_index_html)

问题的关键是context必须是一个字典

继续上面的nginx

  • 把项目部署到服务器上时,收集了静态文件到一个目录/data/www/daily_fresh/static这个不是我的项目目录
  • 然后在nginx的配置中,匹配/static的就去找/data/www/daily_fresh/static/, 匹配/的就转交给uwsgi :# 包含uwsgi的请求参数
    include uwsgi_params;
    # 转交给 uwsgi 的ip和端口
    uwsgi_pass 127.0.0.1:8080;

但是始终不能访问,位置也换过,文件夹的权限也改过,这里猜想可能是因为这里的static并没有被访问,因为没有给项目中的static配置,所以访问不到。但是静态页面也应该出现个画呀,不知道是什么问题。
于是我采取了曲线救国的策略,又配置了一台nginx server

server 配置81端口
location / {
  root  /data/daily_fresh/static/; #我的项目路径
  index  index.html index.htm
}
location  /static {  # 右边没有/
  alias  /data/daily_fresh/static/; #我的项目路径
}

启动这台服务器,然后访问网站的81端口(在服务器中打开端口,重启防火墙,在阿里云客户端添加81端口),成功。
主nginx精确匹配 / 时,转交给这台nginx

nginx.conf

user root;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    server {
    listen      8888;
    server_name 47.100.179.209;
    location ~/group[0-9]/ {
        ngx_fastdfs_module;
    }    
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root html;
    }
    }  

    server {
    listen       81;
    server_name 47.100.179.209;
    location / {
    #   autoindex on;
       root /data/daily_fresh/static/;
       index index.html index.htm;
    }
    location /static{
        alias /data/daily_fresh/static/;
    }
    }
#   upstream daily_fresh{
#   server 127.0.0.1:8080;
#   server 127.0.0.1:8081;  # 将下面的uwsgi_pass 中的127.0.0.1换成daily_fresh
#   }                         前提是有两个uwsgi.ini文件,启动两个uwsgi,nginx 负责发牌式的负载均衡
    server {
        listen      80;
        server_name 47.100.179.209;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
        location / {
            include uwsgi_params;
        uwsgi_pass 127.0.0.1:8080;
       #uwsgi_pass daily_fresh;
        }
    
    location = /{
        proxy_pass http://47.100.179.209:81;
    }

    location /static{
        alias /data/www/static/;
    }
    
    }

出现的问题

图片类型没有发布,ImageFileField is not 发布

  • 使用celery发布任务时,得到错误,ImageFileField is not 发布,将页面中的sku.image.url改为sku.image后可以正常的发布任务,可以正常生成静态页面,但是有问题,路径不太对,好像是缺了端口还是什么,反正不能正常显示图片。最后想到在windows中安装的fdfs_client应该是不匹配linux系统的,而在执行pip install -r requirement.txt时,安装的是windows版本的fdfs_client,所以卸载,傻瓜安装不放心,所以下载安装包安装,cd 进去,python setup.py install ,发布任务就没发现错误

自己傻了

  • 一开始访问的fdfs地址就不对,还有静态文件的目录也不对,查验后使用的之前的index.html,使用自己生成的静态文件后成功

总结:

出现问题后程序的问题不大,前提是在windows端出现的错误改了之后(指改mysqlclient,django/db里面的源码)

  1. 仔细看看有没有操作失误,指在各种conf中有没有配置错误,拼写错误,拼写错误,拼写错误。。。
  2. 如果是静态文件,打开F12看看出现什么问题,路径错误就去模板html中再看看,settings中的几项配置STATICFILES_DIRS,STATIC_URL,STATIC_ROOT看看,多斜杠,少斜杠
  3. 打开DEBUG看看有什么错误,这个是最管用的,记得把ALLOW_HOSTS=[‘*’]
  4. linux和windows的不兼容问题,出问题的是什么插件,就去百度下有没有类似的错误,有没有相关的资料。
    5.再来一遍。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容