上线流程及操作

上节回顾

1 搜索功能
	-前端:搜索框,搜索结果页面
    -后端:一种类型课程
    	-APIResponse(actual_course=res.data.get('results'),free_course=[],light_course=[])
    -搜索,如果数据量很大,直接使用mysql,效率非常低--》ElasticSearch
    	-全文检索:分词,搜索
        
        
2 支付宝支付
	-申请商户号---》条件:个人一般申请不成功---》沙箱环境
    	-APPID
        -应用私钥
        -支付宝公钥
    -接入流程:网站支付    
    
    
3 测试支付
	- 支付宝公钥,应用私钥---》自己生成--》工具生成,openssh
    - 支付宝官方提供了:复制出来即可
	-官方sdk
    	-生成支付链接
        -验签
    -非官方sdk
    	-基于官方的api封装的
        -文档写的比较好
4 二次封装
	
5 下单接口
	-前端:数据格式  {courses:[3],total_amount:99,subject:订单标题,pay_type:1}
    -后端:
    	-视图类:必须登录
        	-登录自己写的签发
            -认证,用了内置的
    	-序列化类:校验数据[生成支付链接],保存
        	-uuid:生成一个永不重复的唯一id
            -其他生成唯一id的方案:
            	-日期+时间戳+redis自增
                -雪花算法,美团leaf算法
6 前端支付
	-课程列表页
    -搜索结果页面
    -详情页
    go_pay() {
      let token = this.$cookies.get('token')
      if (token) {
        this.$axios({
          url: '/order/pay/',
          method: 'POST',
          headers: {
            authorization: 'Bearer ' + token,
          },
          data: {
            'courses': [this.course_id],
            'total_amount': this.course_info.price,
            'subject': this.course_info.name,
            'pay_type': 1
          }

        }).then(res => {
          let pay_url = res.pay_url
          //打开链接,支付
          open(pay_url, '_self');
        }).catch(res => {
          this.$message.error('系统异常,请稍后再试')
        })
      } else {
        this.$message.error('您没有登录,请先登录再下单')
      }
    }
  


#补充:
	-支付宝的秘钥---》放在代码中了,可能丢失,不安全,如何处理?
    	- 放在环境变量中
        - 写个接口:请求一个地址--》返回秘钥
        	-限制请求的地址,必须是 某个ip,进行一些验证
        因为我们公司项目,部署在公司服务器上,代码传到公司内部的gitlab,安全系数还是比较高的,不会存在代码泄露的问题,于是我们综合考虑---》把秘钥放到了代码中,也没有出现任何问题

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

今日内容

#  购物车   优惠券
	- 优惠券id----  {courses:[3],total_amount:99,subject:订单标题,pay_type:1,sign:签名}

1 支付成功前端

# 支付成功,回调---》get---》http://127.0.0.1:8080/pay/success--》用户付款完成---》支付宝回调会我们前端页面---》配合一个前端页面---》显示支付成功
?charset=utf-8
&out_trade_no=7fa5ff32-2392-4475-a9c8-8d54e2241777 # 咱们订单号
&method=alipay.trade.page.pay.return&
total_amount=299.00& # 订单价格
sign=ZjJKCJsikcDOmmH56bXjUaqlOycptYUmXco9O1XNb6aHyWi0eiGMeEaees%2B3EDsOsxG0MIKakvrX3cdKeT8ocSmExSYl%2BmqLgpGqFQuvCjqTCptY2g9I1pV%2FPr1uFUEbdFrLgIxhG4Bjokq19hWofLXYDKrk8VCeD1pSftwhfkuFw%2BsYxaXqiIqFxDxE1qp6%2Fi6jRewNSnu63USWkgImzXiYMIdLqLeaMt2DyULGqV9Mo%2FvQXoXGJwyWcFocNSSTdEF6poXiZbQy98ZZtA6F3i1twXM2MqvsxJHxhRkT1E0WhbmqSaUXGC7Mw%2BzhfaniXsgTXhQkdtioIjXV5XfOOw%3D%3D&
trade_no=2024020122001406120501934311&
auth_app_id=9021000129694319&
version=1.0&
app_id=9021000129694319&
sign_type=RSA2&
seller_id=2088721017969071&
timestamp=2024-02-01%2010%3A08%3A44 # 支付时间
<template>
  <div class="pay-success">
    <!--如果是单独的页面,就没必要展示导航栏(带有登录的用户)-->
    <Header/>
    <div class="main">
      <div class="title">
        <div class="success-tips">
          <p class="tips">您已成功购买 1 门课程!</p>
        </div>
      </div>
      <div class="order-info">
        <p class="info"><b>订单号:</b><span>{{ result.out_trade_no }}</span></p>
        <p class="info"><b>交易号:</b><span>{{ result.trade_no }}</span></p>
        <p class="info"><b>付款时间:</b><span><span>{{ result.timestamp }}</span></span></p>
      </div>
      <div class="study">
        <span>立即学习</span>
      </div>
    </div>
  </div>
</template>

<script>
import Header from "@/components/Header"

export default {
  name: "Success",
  data() {
    return {
      result: {},
    };
  },
  created() {
    // url后拼接的参数:?及后面的所有参数 => ?a=1&b=2
    // console.log(location.search);

    // 解析支付宝回调的url参数
    let params = location.search.substring(1);  // 去除? =>    a=1&b=2
    let items = params.length ? params.split('&') : [];  // ['a=1', 'b=2']
    //逐个将每一项添加到args对象中
    for (let i = 0; i < items.length; i++) {  // 第一次循环a=1,第二次b=2
      let k_v = items[i].split('=');  // ['a', '1']
      //解码操作,因为查询字符串经过编码的
      if (k_v.length >= 2) {
        // url编码反解
        let k = decodeURIComponent(k_v[0]);
        this.result[k] = decodeURIComponent(k_v[1]);
        // 没有url编码反解
        // this.result[k_v[0]] = k_v[1];
      }

    }
    // 解析后的结果
    console.log(this.result);


    // 把地址栏上面的支付结果,再get请求转发给后端
    this.$axios({
      url: '/order/success/' + location.search,
      method: 'get',
    }).then(response => {
      this.$message.success(response.msg)
    }).catch((res) => {
      this.$alert(res, {
        confirmButtonText: '确定',
      });
    })
  },
  components: {
    Header,
  }
}
</script>

<style scoped>
.main {
  padding: 60px 0;
  margin: 0 auto;
  width: 1200px;
  background: #fff;
}

.main .title {
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  padding: 25px 40px;
  border-bottom: 1px solid #f2f2f2;
}

.main .title .success-tips {
  box-sizing: border-box;
}

.title img {
  vertical-align: middle;
  width: 60px;
  height: 60px;
  margin-right: 40px;
}

.title .success-tips {
  box-sizing: border-box;
}

.title .tips {
  font-size: 26px;
  color: #000;
}


.info span {
  color: #ec6730;
}

.order-info {
  padding: 25px 48px;
  padding-bottom: 15px;
  border-bottom: 1px solid #f2f2f2;
}

.order-info p {
  display: -ms-flexbox;
  display: flex;
  margin-bottom: 10px;
  font-size: 16px;
}

.order-info p b {
  font-weight: 400;
  color: #9d9d9d;
  white-space: nowrap;
}

.study {
  padding: 25px 40px;
}

.study span {
  display: block;
  width: 140px;
  height: 42px;
  text-align: center;
  line-height: 42px;
  cursor: pointer;
  background: #ffc210;
  border-radius: 6px;
  font-size: 16px;
  color: #fff;
}
</style>

2 支付宝回调接口(两个)

2.1 get 回调(给咱们前端用)

路由

urlpatterns = [
    path('success/', PaySuccess.as_view()),
]

视图类

from rest_framework.views import APIView
class PaySuccess(APIView):
    def get(self, request, *args, **kwargs):
        out_trade_no = request.query_params.get('out_trade_no')
        # 去数据库查询
        res = Order.objects.filter(out_trade_no=out_trade_no, order_status=1).first()
        if res:
            # 收到支付宝付款成功,修改了订单状态,返回给前端成功
            return APIResponse(msg='恭喜您付款成功,快去学习吧')
        else:
            return APIResponse(code=101, msg='暂未收到您的付款,请稍后刷新再试')

2.2 post回调–》给支付宝回调用

#  回调数据格式
data = {
     "subject": "测试订单",
     "gmt_payment": "2016-11-16 11:42:19",
     "charset": "utf-8",
     "seller_id": "xxxx",
     "trade_status": "TRADE_SUCCESS",
     "buyer_id": "xxxx",
     "auth_app_id": "xxxx",
     "buyer_pay_amount": "0.01",
     "version": "1.0",
     "gmt_create": "2016-11-16 11:42:18",
     "trade_no": "xxxx",
     "fund_bill_list": "[{\"amount\":\"0.01\",\"fundChannel\":\"ALIPAYACCOUNT\"}]",
     "app_id": "xxxx",
     "notify_time": "2016-11-16 11:42:19",
     "point_amount": "0.00",
     "total_amount": "0.01",
     "notify_type": "trade_status_sync",
     "out_trade_no": "订单号", # 咱们的uuid
     "buyer_logon_id": "xxxx",
     "notify_id": "xxxx",
     "seller_email": "xxxx",
     "receipt_amount": "0.01",
     "invoice_amount": "0.01",
     "sign": "签名" # 验证签名
}
class PaySuccess(APIView):
    # 肯定不能有登录认证
    def get(self, request, *args, **kwargs):
        out_trade_no = request.query_params.get('out_trade_no')
        # 去数据库查询
        res = Order.objects.filter(out_trade_no=out_trade_no, order_status=1).first()
        if res:
            # 收到支付宝付款成功,修改了订单状态,返回给前端成功
            return APIResponse(msg='恭喜您付款成功,快去学习吧')
        else:
            return APIResponse(code=101, msg='暂未收到您的付款,请稍后刷新再试')

    # 支付宝异步回调处理--》修改订单状态---》支付宝不可能带token
    # 这个接口测试不了:咱们需要有公网ip才行
    # http://127.0.0.1:8000/api/v1/order/success/   post请求
    def post(self, request, *args, **kwargs):
        try:
            # json编码 -->是字典
            # urlencoded--》querydict---》dict()----》纯字典
            result_data = request.data.dict()  # 把request.data  ---> 转成字典格式
            out_trade_no = result_data.get('out_trade_no')
            trade_no = result_data.get('trade_no')
            signature = result_data.pop('sign')

            result = alipay.verify(result_data, signature)
            if result and result_data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
                # 完成订单修改:订单状态、流水号、支付时间
                Order.objects.filter(out_trade_no=out_trade_no).update(order_status=1, trade_no=trade_no)
                # 完成日志记录
                logger.warning('%s订单支付成功' % out_trade_no)
                return Response('success')
            else:
                logger.error('%s订单支付失败' % out_trade_no)
        except:
            pass
        return Response('failed')
    
    
    
#### 支付宝post回调地址一定要准确###
NOTIFY_URL = BACKEND_URL + "/api/v1/order/success/" 

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3 云服务器购买

# 项目上线---》所有互联网用户都能访问
	-1 有台服务器
    	-mysql
        -redis
        -python
        -django
        -代码--运行代码
    -2 公网ip地址
    
    
    
# 云服务器--》相当于你买了台机器--》放到别人机房里了
	阿里云:
    	-包年包月 2核2g,硬盘20g
        -按量付费:按小时收费
        -https://ecs.console.aliyun.com/?spm=5176.12818093_47.top-nav.30.50f816d0yJa57f
    腾讯云
    华为云
    
    
    
# 自定义秘钥:root   设置一个密码

# 购买阿里云机器--->远程链接---》使用finalshell
# 远程链接
    # 远程地址
    # 用户和密码

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4 上线架构图

# 所有人访问:http://47.116.207.103:80 访问这个地址都能看到咱们前端

#接口地址:http://47.116.207.103:8000/api/v1/home/banner/
# django运行在 8888端口

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5 上线前准备

# 1 后端
	-导出项目依赖
     pip freeze > requirements.txt
	-修改pro.py 配置文件
    -新建一个:manage_pro.py 指定配置文件为pro,后续迁移表,要用它
    -代码推送到远端
    
    
# 2 前端
	-访问后端你的地址修改 成 云服务器地址
    - 编译vue
    	npm run build  #编译成 html,css,js
        项目目录下产生 dist文件夹--》上线前端就是它
    -压缩成zip ,等着用

6 服务器上安装git

### centos7.9 上装git软件


# 方式一:
	yum install git -y
    
# 方式二:(开发会用的软件,包含了git,还包含开发会用到的其他)
	yum -y groupinstall "Development tools" 
	
    
    
# 执行下面这条(后续咱么需要装其他软件,需要有些依赖,装依赖)
yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel psmisc libffi-devel -y

7 安装mysql 5.7

# mysql 5.7 
#1 前往用户根目录

# pwd  查看我在哪个目录下
# cd 切换到某个路径下
 cd ~  # 回到家路径

#2 下载mysql57 
wget http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
# ls  查看当前目录下的文件和文件夹

#3 安装mysql57
 yum -y install mysql57-community-release-el7-10.noarch.rpm
 yum install mysql-community-server --nogpgcheck -y

#4 启动mysql57并查看启动状态
systemctl start mysqld  # 启动mysql服务
systemctl status mysqld  # 查看mysql状态

#5 查看默认密码并登录(第一次安装,root密码是随机的)
# 去/var/log/mysqld.log 中过滤出包含 password 的多行
grep "password" /var/log/mysqld.log   # 7n5hchTomp++
mysql -uroot -p

#6 修改root密码
 ALTER USER 'root'@'localhost' IDENTIFIED BY 'Lqz12345?';
 grant all privileges on *.* to 'root'@'%' identified by 'Lqz12345?';
 如果还连不上,就是mysql 3306的安全组没开---》防火墙端口没开
  
  
# 7 远程连接:win---》navicate--》
	连接成功

8 安装redis

# 官方下载:
redis-7.2.4.tar.gz # 源码包--》c代码--》不能运行--》编译---》可执行文件--》才能运行
redis-stack-server-7.2.0-v8.rhel7.x86_64.tar.gz # 编译过后的可执行文件


#### Redis Stack 
	-redis是用c写的---》c是编译型语言---》在不同平台运行,需要编译
  	-官方提供了,编译完成的mac,linux(centos,乌班图)的可执行文件,跟平台有关系,不能乱下,乱下不能运行
    
    
    
   
###### 方式一:官方下载编译好的reids
    -1 下载源码包,在当前平台,编译---》就能在当前平台运行了
      wget https://packages.redis.io/redis-stack/redis-stack-server-7.2.0-v8.rhel7.x86_64.tar.gz
    -2 解压
    	tar -xzvf redis-stack-server-7.2.0-v8.rhel7.x86_64.tar.gz
	-3 进入到 redis  bin 目录--》redis-server
   	-4 运行redis
		redis-server 配置文件
    -5 加入环境变量
    ./redis-server   # 启动redis,使用默认配置启动的
    #在任意路径下敲redis-server都能把服务运行,
        -方式一:把bin路径加入到环境变量(你们不会)
        -方式二:使用软连接, /usr/bin/    本身在环境变量 ,在任意路径敲redis-server redis-cli都能找到 
        ln -s /root/redis/bin/redis-server /usr/bin/redis-server
        ln -s /root/redis/bin/redis-cli /usr/bin/redis-cli
        
    -6 在任意路径启动 
        redis-server 可以启动了
        redis-cli 可以链接了
    -7 查看redis 是否启动
        #查看是否创建软连接成功
        ls |grep redis
	   # 查看redis 是否启动
       ps aux |grep redis
        
    -8 启动redis服务,后台运行
    	redis-server &









###### 方式二:源码安装----》Redis

# 下载redis-6.2.6
wget https://github.com/redis/redis/archive/7.2.4.tar.gz


# 解压安装包
tar -xf 7.2.4.tar.gz

# 进入目标文件
mv redis-7.2.4 redis7
cd redis7


# 编译环境 gcc   在src路径下把源码编译出  redis-cli  reidis-server
 make  #编译,项目目录下执行  
# 在 src目录下就会多出 可执行文件
	redis-server
    redis-cli
    
# 复制环境到指定路径完成安装
cp -r ~/redis7 /usr/local/redis

# 配置redis可以后台启动:修改下方内容
vim /usr/local/redis/redis.conf
daemonize yes

# 完成配置修改
>: esc
>: :wq



# 建立软连接
# /usr/local/redis/src/不在环境变量,在任意路径下敲 redis-server找不到的
# 如果简历软连接----》/usr/bin/新建了一个redis-server指向了/usr/local/redis/src/
# 而/usr/bin/ 是在环境变量的,所有以后任意路径敲redis-server都能找到
ln -s /usr/local/redis/src/redis-server /usr/bin/redis-server7
ln -s /usr/local/redis/src/redis-cli /usr/bin/redis-cli7

# 后台运行redis
cd /usr/local/redis
redis-server7 ./redis.conf  # 在后台运行

# redis-server7 /usr/local/redis/redis.conf


# 等同于
redis-server7 ./redis.conf &

# 测试redis环境
redis-cli


# 关闭redis服务
pkill -f redis -9
redis-cli  shutdown

9 安装python 3.9

# 阿里云的centos上有python环境
	- python2.7.5     pip
  	- python3.6.8     pip3
  
 	-咱们项目开发,在3.9上开发的,需要使用3.9的解释器来运行


# 可以使用yum 安装,不能指定版本(yum install python   咱们不用)
# 源码安装,下载指定版本的源码,编译安装


#### 补充
# 所有linxu和mac,都自带python2:系统服务,是用python写的
# 阿里云的centos默认装了python3.6.8

# python2.7     python3.6.8     python3.9    装模块,不要乱套
   pip             pip             pip

#1  源码安装python,依赖一些第三方zlib* libffi-devel
yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel psmisc libffi-devel zlib* libffi-devel  -y

# 1前往用户根目录
cd ~

#2 下载  3.9.10 源码 服务器终端
# https://registry.npmmirror.com/binary.html?path=python/
wget https://registry.npmmirror.com/-/binary/python/3.9.10/Python-3.9.10.tgz
# wget https://www.python.org/ftp/python/3.9.16/Python-3.9.16.tgz

#3  解压安装包
tar -xf Python-3.9.10.tgz 

#4 进入目标文件
cd Python-3.9.10

#5  配置安装路径:/usr/local/python3
# 把python3.9.10 编译安装到/usr/local/python38路径下
./configure --prefix=/usr/local/python39

#6  编译并安装,如果报错,说明缺依赖
yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel psmisc libffi-devel zlib* libffi-devel  -y
# make只是编译----》可执行文件,没有安装
# 类似于在win上下载了安装包,但是没安装
# make install 安装---》类似于在win上下了安装包,一路下一步安装了,指定安装位置---》/usr/local/python39
make &&  make install

#7  建立软连接:/usr/local/python38路径不在环境变量,终端命令 python3,pip3
ln -s /usr/local/python39/bin/python3 /usr/bin/python3.9
ln -s /usr/local/python39/bin/pip3 /usr/bin/pip3.9

# 机器上有多个python和pip命令,对应关系如下
python       2.x      pip 
python3      3.6      pip3
python3.9    3.9      pip3.9

#8  删除安装包与文件:
rm -rf Python-3.9.10
rm -rf Python-3.9.10.tar.xz

10 安装虚拟环境


1)安装依赖
>: pip3.9 install virtualenv
# python3.9 -m pip install --upgrade pip
# python3.9 -m pip install --upgrade setuptools
# pip3.9 install pbr
>: pip3.9 install virtualenvwrapper

2)建立虚拟环境软连接
>: ln -s /usr/local/python39/bin/virtualenv /usr/bin/virtualenv

3)配置虚拟环境:填入下方内容
# ~/ 表示用户家路径:root用户,就是在/root/.bash_profile
>: vi ~/.bash_profile  
# 按 a
# 光标上下控制,粘贴上下面内容

VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3.9
source /usr/local/python39/bin/virtualenvwrapper.sh
# 按 esc
# 输入  :wq   敲回车


# 退出编辑状态
esc

# 保存修改并退出
>: :wq

# 更新配置文件内容
source ~/.bash_profile

# 虚拟环境默认根目录:
/root/.virtualenvs


#创建虚拟环境
mkvirtualenv -p python3.9 luffy


11 安装nginx

# 软件:反向代理服务器  (搜一下:什么是正向代理,什么是反向代理)  反向带代理服务器
  - 做请求转发    (前端来了个请求---》打在了80端口上---》转到本地8888端口,或者其他机器的某个端口)
  - 静态资源代理    前端项目直接放在服务器上某个位置----》请求来了,使用nginx拿到访问的内容,直接返回
  - 负载均衡       假设来了1000个请求--》打在nginx上,nginx性能很高,能顶住---》只转发到某个django项目,可能顶不住---》集群化的不是3台django---》均匀的打在3台机器上
    

    
    
# 前往用户根目录
cd ~

#下载nginx1.13.7
 # wget http://nginx.org/download/nginx-1.13.7.tar.gz
 wget http://nginx.org/download/nginx-1.24.0.tar.gz

#解压安装包
tar -xf nginx-1.24.0.tar.gz

#进入目标文件
cd nginx-1.24.0

# 配置安装路径:/usr/local/nginx
./configure --prefix=/usr/local/nginx

#编译并安装
 make &&  make install

# 建立软连接:终端命令 nginx
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx

#删除安装包与文件:
cd ~
rm -rf nginx-1.13.7
rm -rf nginx-1.13.7.tar.xz

# 测试Nginx环境,服务器运行nginx,本地访问服务器ip
nginx   # 启动nginx服务,监听80端口----》公网ip 80 端口就能看到页面了
服务器绑定的域名 或 ip:80

# 静态文件放的路径
/usr/local/nginx/html

# 查看进程
ps aux | grep nginx


# 关闭和启动
关闭:nginx -s stop 
启动: nginx


# 它有配置文件---》配置监听那些地址,配置代理那些静态文件---》还没讲

12 nginx 部署前端

#1  前端项目 vue项目---》部署到服务器
	-不是直接在服务端部署vue源码----》vue源码编译【npm run build】---》html,css,js---》放到服务器上---》使用nginx代理
  
  
#2  前端配置
	-1 settings.js中发送ajax的后端地址改为 
        export  default {
            BASE_URL:'http://服务器地址:8000/api/v1/'
        }
  -2 编译vue---》html,css,js
  	npm run build   # 项目路径下会产生  dist文件夹,里面只有html,css,js
    # 只会有一个index.html
    dist
      css
      fonts
      img
      js
      favicon.ico
      index.html
    
    


#2 把这个文件夹压缩 dist.zip 文件,在本地,上传到远程服务器

#3  在远程服务器上
	yum install lrzsz -y   # 跟本地机器上传下载的软件
  	yum install unzip -y    #解压zip软件
#4  在远程服务器上
	rz  # 打开你本地的目录,选中dist.zip  上传到远端
  
#5  解压
	unzip dist.zip
#6  移动文件  /home/html  下面有咱们的前端静态文件
	mv /root/dist /home/html
    
    
#7 配置nginx 静态代理--->nginx 默认会去/usr/local/nginx/html拿静态文件
cd  /usr/local/nginx/conf   # nginx.conf   配置文件
mv nginx.conf nginx.conf.bak
vi nginx.conf
# 按 a  粘贴下面代码
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    server {
        listen 80;
        server_name  127.0.0.1;
        charset utf-8;
        location / {
            root /home/html;
            index index.html;
            try_files $uri $uri/ /index.html;
        }
    }
} 
# 按 esc  :wq  回车

# 重启nginx
nginx -s reload

13 安装uwsgi

# django 项目上线需要使用uwsgi这个web服务器运行django项目,安装这个web服务器
# 使用uwsgi运行django,不再使用测试阶段的wsgiref来运行django了:以后线上,不使用  python manage.py runserver 运行项目要用 uwsgi运行项目

# uwsgi是符合wsgi协议的web服务器,使用c写的性能高,上线要使用uwsgi,测试wsgiref



# 安装步骤
1)在真实环境下安装(退出虚拟环境)
pip3.9 install uwsgi  # 会有个uwsgi的可执行文件,但是不在环境变量,所以需要加软连接
#安装到了python38的安装路径的bin路径下了
2)建立软连接
ln -s /usr/local/python39/bin/uwsgi /usr/bin/uwsgi

13 部署后台项目

###  原理----》后端项目写好后---》提交到git远程仓库---》服务器上--》把代码拉取下来---》运行即可



#######  本地 ### #### 
    # 1  pro.py 配置文件搞好,上午搞了,前端和后端的基地址,都是云服务器地址
    # 2 修改项目中wsgi.py,asgi.py  用uwsgi运行wsgi.py
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.pro')

    # 3 导出项目依赖
    pip3 freeze > requirements.txt

    #4 推到远端

    
    
    
    
    
####### 远程服务器 #######
# 1 拉取项目,安装模块
    mkdir /home/project
    cd  /home/project
    git clone https://gitee.com/liuqingzheng/luffy_api.git
    # 进入到虚拟环境
    workon luffy 
    cd /home/project/luffy_api
    pip install -r requirements.txt  # 可能会出错 mysqlclient装不上,先注释,装上能装上的,再单独装mysqlclient

    yum install python3-devel -y
    yum install mysql-devel --nogpgcheck -y
    pip install mysqlclient


    # 2 虚拟环境中也要安装uwsgi--->注意:真实环境和虚拟环境都要装 uwsgi
    pip install uwsgi # 真实环境安装后,在python安装目录会有 uwsgi可执行文件
    ln -s /usr/local/python39/bin/uwsgi /usr/bin/uwsgi # 任意路径都可以执行
    
    
    
    
    # 3 配置数据库
        mysql -uroot -p
        #创建数据库
        create database luffy default charset=utf8;

        #设置权限账号密码:账号密码要与项目中配置的一致
        grant all privileges on luffy.* to 'luffy'@'%' identified by 'Luffy123?';
        grant all privileges on luffy.* to 'luffy'@'localhost' identified by 'Luffy123?';
        flush privileges;
        #退出mysql
        quit;
        # 使用本地navicate链接阿里云的luffy库,使用luffy用户
        
        
   # 4 迁移表
		# 把项目中得迁移文件删除,提交,远程
    # 在项目中新建一个 manage_prod.py--->配置文件改成 prod的配置文件---》这样迁移,就迁移到prod的数据库了
    	# 出了问题:降低urlib版本
		python manage_pro.py makemigrations
     	python manage_pro.py migrate
            
      
    ### 出现错误:ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl'
    		-pip install urllib3==1.26.15
      
   	#出现错误: pip install python-alipay-sdk
    
    
    
   # 5 uwsgi 运行django
		-写一个uwsgi的配置文件,在项目路径下,新建一个  luffyapi.xml
    <uwsgi>    
        <socket>127.0.0.1:8888</socket>  # uwsgi运行的地址和端口
        <chdir>/home/project/luffy_api/</chdir>      # 项目所在路径,一定不能错   
        <module>luffy_api.wsgi</module>  # uwsgi.py 所在路径
        <processes>4</processes>         # 开启4个进程跑项目
        <daemonize>uwsgi.log</daemonize> # uwsgi日志写到这个日志文件
    </uwsgi>
    	-使用uwsgi启动(注意路径)
        	uwsgi -x luffyapi.xml
         -查看是否正常运行
        	ps aux |grep uwsgi
            
            
           
            
    # 6 配置nginx转发
    	cd /usr/local/nginx/conf
    	vi nginx.conf
    	# 新增的server
        server {
            listen 8000;
            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 /home/project/luffy_api/;
            }
        }
        
        # 重启nginx 
        nginx -s reload
   #  问题:启动uwsgi ,没有在虚拟环境中运行
	-停止  uwsgi :pkill -9 uwsgi
   # redis 没有启动,报了个错
  
   # 7 导入数据---录入假数据
	-本地之前的数据导出成sql
    -导入到远程数据库中
    	
	
   # 8 配置域名解析
   # 购买域名:www.liuqingzheng.top
   # 配置解析
server {
    listen 8000;
    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 /home/project/luffy_api/;
    }
}


问题:

 # urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'OpenSSL 1.0.2k-fips  26 Jan 2017'
 
#咱么linux上使用的 OpenSSL   1.0.2k
'''
(luffy) [root@lqz luffy_api]# yum install openssl-devel
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile
软件包 1:openssl-devel-1.0.2k-26.el7_9.x86_64 已安装并且是最新版本
'''

# python3.9 会依赖这个模块---》需要至少1.1.1+

########### 解决方式一###################
######解决步骤:#######
wget https://www.openssl.org/source/openssl-1.1.1.tar.gz
tar -xzvf openssl-1.1.1.tar.gz
cd openssl-1.1.1
./config --prefix=/usr/local/openssl  # 设置安装目录 可以自定义 但是要记住,后面会用到
make && make install  # 编译并安装
/usr/local/openssl/lib 路径添加到系统动态库查找路径中,在 etc 目录下的 profile文件最后面添加下面这一行
# 用户变量   系统变量 /etc/profile
export LD_LIBRARY_PATH=/usr/local/openssl/lib:$LD_LIBRARY_PATH
source /etc/profile        #使其生效
#### 重新编译python####
cd python安装目录
# 已经编译过的可以先 make clean 清理一下
./configure --prefix=/usr/local/python39 --with-openssl=/usr/local/openssl
make  && make install



########### 解决方式二###################
# pip install urllib3==1.23 -i https://pypi.tuna.tsinghua.edu.cn/simple
# 1 虚拟环境如果没装uwsgi
	-运行django有问题
    
# 2 urlib3降版本---》重启uwsgi

13.1 配置后台admin访问


# http://47.116.207.103:8000/static/rest_framework/css/bootstrap.min.css

#  1 后端项目,使用uwsgi部署完成,可以访问动态接口,但不能访问静态资源

# 2 uwsgi为了提高效 率,只处理动态请求,静态资源的获取,不管
	-静态资源就是在从服务器把文件,图片,js,css,直接返回
    -如果静态资源也走uwsgi,会影响uwsgi的性能
  
  10     2 个动态接口    8个 拿静态资源
  				usgi只负责处理这两个动态接口
    			静态资源不管---》自行处理
      
      
# 3 动静分离
	-动态请求给uwsgi---》让它处理---》uwsgi资源宝贵,尽量少用
  	动态请求地址: /api/v1....
    -静态请求,使用nginx,直接处理---》nginx来讲,最擅长处理静态资源
  		静态资源地址: /static/...
    
    
# 4 请求发送到nginx监听的 8000 端口上的时候,判断 如果是 / --->转发给uwsgi  ,如果是 /static--->直接去固定的位置,把静态资源直接返回,不走uwsgi了,节约uwsgi的性能



# 5 配置nginx,做静态文件代理---》收集静态资源
	-simpleui
  	-drf   
  	-都在自己app中,我们需要把他们单独收集到某个位置
  
  
  -后期如果部署前后端混合项目必须要做动静分离,收集静态文件
  
  
  
  
# 6 操作步骤

#6.1  收集静态资源,使用nginx代理
# prod.py中加入   把静态资源收集到这个文件夹下
STATIC_ROOT = '/home/project/luffy_api/luffy_api/static/'


# 6.2 进入虚拟环境
mkdir /home/project/luffy_api/luffy_api/static
python manage_pro.py collectstatic


http://106.14.156.208:8000/static/admin/simpleui-x/img/logo.png


# 6.3 修改nginx配置文件
# 新增的配置静态文件

server {
            listen 8000;
            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 /home/project/luffy_api/;
            }
           location /static {
            alias /home/project/luffy_api/luffy_api/static;
        	}
        }
 
 # 6.4 重启nginx
	nginx -s reload
  

13 安全组-云服务器

# 80端口可以访问
# 8000   8888   3306   6379 有可能没有被打开安全组---》导致访问不到


# 修改安全组


# 重装操作系统



# 更换密码




# 释放实例




作业

# 上线项目

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

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

相关文章

分类预测 | Matlab实现PSO-LSSVM粒子群算法优化最小二乘支持向量机数据分类预测

分类预测 | Matlab实现PSO-LSSVM粒子群算法优化最小二乘支持向量机数据分类预测 目录 分类预测 | Matlab实现PSO-LSSVM粒子群算法优化最小二乘支持向量机数据分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现PSO-LSSVM粒子群算法优化最小二乘支持向量…

FebHost:注册.CA域名的企业有什么限制?

在加拿大&#xff0c;只要满足加拿大互联网注册管理局的“加拿大注册要求”&#xff0c;任何类型的企业都可以注册.CA域名。这些要求的目的是为了确保.CA域名空间作为一个重要的公共资源得到合理的使用和开发&#xff0c;以促进所有加拿大人的社会和经济发展。 以下是一些主要…

0418WeCross搭建 + Caliper测试TPS

1. 基本信息 虚拟机名称&#xff1a;Pure-Ununtu18.04 WeCross位置&#xff1a;/root/wecross-demo 2. 搭建并启动WeCross 参考官方指导文档 https://wecross.readthedocs.io/zh-cn/v1.2.0/docs/tutorial/demo/demo.html 访问WeCross网页管理平台 http://localhost:8250/s/…

嵌入式科普(15)小米su7成本分析和拆解之智驶、座舱分析

目录 一、概述 二、小米su7成本分析 2.1 整车成本构成 2.2 三电系统 2.3 车身与底盘 2.3 智能网联 2.4 内外饰 三、小米su7拆解之智驶、座舱分析 3.1 主要芯片 3.2 智能驾驶&智能座舱 四、NXP S32K324汽车通用微控制器 嵌入式科普(15)小米su7成本分析和拆解之智…

问答营销之官方号问答推广技巧

问答营销作为一种网络推广的重要手段&#xff0c;受到各大品牌企业的关注。实战中&#xff0c;问答营销有新起提问再回答和直接回复老问题两种形式&#xff0c;一般做企业官方号问答营销都是选择后者。这里小马识途营销顾问详细解析下开展老问题回复营销的思路和步骤。 一、分析…

2024最新大厂C++面试真题合集,玩转互联网公司面试!

小米C 1. 进程和线程的区别 进程是操作系统分配资源和调度的独立单位&#xff0c;拥有自己的地址空间和系统资源。线程是进程内部的执行单元&#xff0c;共享属于相同进程的资源&#xff0c;但是执行切换代价更小。进程间相互独立&#xff0c;稳定性较高&#xff1b;线程间共…

C++修炼之路之反向迭代器和非模板参数,模板特化,分离编译

目录 前言 一&#xff1a;反向迭代器 二&#xff1a;非类型模板参数 三&#xff1a;模板的特化 四&#xff1a;模板的分离编译 五&#xff1a;模板的优点与缺点 接下来的日子会顺顺利利&#xff0c;万事胜意&#xff0c;生活明朗-----------林辞忧 前言 在vector&am…

代码随想录第40天|343. 整数拆分

343. 整数拆分 343. 整数拆分 - 力扣&#xff08;LeetCode&#xff09; 代码随想录 (programmercarl.com) 动态规划&#xff0c;本题关键在于理解递推公式&#xff01;| LeetCode&#xff1a;343. 整数拆分_哔哩哔哩_bilibili 给定一个正整数 n &#xff0c;将其拆分为 k 个 正…

2024-4-18 群讨论:Java Agent,JFR 与 JIT 的一些讨论

以下来自本人拉的一个关于 Java 技术的讨论群。关注公众号&#xff1a;hashcon&#xff0c;私信进群拉你 命令行中带 -XX:StartFlightRecording 启动&#xff0c;同时带 -javaagent&#xff0c;那么谁先启动&#xff1f;jfr能采集到agent启动前后资源消耗情况不&#xff1f; 不…

基于深度学习的手写汉字识别系统(含PyQt+代码+训练数据集)

基于深度学习的手写汉字识别系统&#xff08;含PyQt代码训练数据集&#xff09; 前言一、数据集1.1 数据集介绍1.2 数据预处理 二、模型搭建三、训练与测试3.1 模型训练3.2 模型测试 四、PyQt界面实现参考资料 前言 本项目是基于深度学习网络模型的人脸表情识别系统&#xff0…

c++编程(6)——类与对象(4)运算符重载、赋值重载函数

欢迎来到博主的专栏——C编程 博主ID&#xff1a;代码小豪 文章目录 运算符重载赋值重载函数默认赋值重载函数其他运算符重载函数 运算符重载 重载这个概念在c中已经出现两次了&#xff0c;在前面的文章中&#xff0c;函数重载指的是可以用相同名字的函数实现不同的功能。而运…

【WebSocket连接异常】前端使用WebSocket子协议传递token时,Java后端的正确打开方式!!!

文章目录 1. 背景2. 代码实现和异常发现3. 解决异常3.1 从 URL入手3.2 从 WebSocket子协议的使用方式入手&#xff08;真正原因&#xff09; 4. 总结&#xff08;仍然存在的问题&#xff09; 前言&#xff1a; 本篇文章记录的是使用WebSocket进行双向通信时踩过的坑&#xff0c…

将gdip-yolo集成到yolov9模型项目中(支持预训练的yolov9模型)

1、yolov9模型概述 1.1 yolov9 YOLOv9意味着实时目标检测的重大进步&#xff0c;引入了可编程梯度信息&#xff08;PGI&#xff09;和通用高效层聚合网络&#xff08;GELAN&#xff09;等开创性技术。该模型在效率、准确性和适应性方面取得了显著改进&#xff0c;在MS COCO数…

「 安全工具介绍 」软件成分分析工具Black Duck,业界排名TOP 1的SCA工具

在现代的 DevOps 或 DevSecOps 环境中&#xff0c;SCA 激发了“左移”范式的采用。提早进行持续的 SCA 测试&#xff0c;使开发人员和安全团队能够在不影响安全性和质量的情况下提高生产力。前期在博文《「 网络安全常用术语解读 」软件成分分析SCA详解&#xff1a;从发展背景到…

Qt-饼图示范

1.效果图 2.代码如下 2.1 .h文件 #ifndef PIECHARTWIDGET_H #define PIECHARTWIDGET_H#include <QWidget> #include <QChartView> #include <QPieSeries>#include<QVBoxLayout> #include<QMessageBox> #include <QtCharts>struct PieDat…

FastAPI - uvicorn设置 logger 日志格式

怎么将日志打印到文件 在main.py加入log_config“./uvicorn_config.json” import uvicornif __name__ "__main__":uvicorn.run("app:app", host"0.0.0.0", port8000, log_config"./uvicorn_config.json")uvicorn_config.json {&qu…

“互联网+”创意创业大赛活动方案

大赛历时6个月&#xff0c;总体分两个赛程&#xff1a;一是策划创意阶段。评审的是方案。二是组织实施阶段。通过阶段一立项的项目由公司协助实施&#xff0c;最终评审的是项目落实情况。学生可两个赛程单独参加&#xff0c;也可连续参加。 具体流程及时间安排如下&#xff1a;…

ansible-tower连接git实现简单执行playbook

前提&#xff1a;安装好ansible-tower和git&#xff0c;其中git存放ansible得剧本 其中git中得内容为&#xff1a; --- - name: yjxtesthosts: yinremote_user: rootgather_facts: noroles:- testroles/test/tasks/main.yml #文件内容 --- #- name: Perform Test Task # tas…

单链表-通讯录

目录 单链表实现 通讯录代码实现 初始化 初始化函数 添加 删除 展示 查找 修改 销毁 代码展示 main.c text.c text.h list.c list.h 和前面的通讯录实现差不多这次就是实现一个以单链表为底层的通讯录 单链表实现 数据结构&#xff1a;单链表-CSDN博客 通讯…

OpenHarmony多媒体-video_trimmer

简介 videotrimmer是在OpenHarmony环境下&#xff0c;提供视频剪辑能力的三方库。 效果展示&#xff1a; 安装教程 ohpm install ohos/videotrimmerOpenHarmony ohpm环境配置等更多内容&#xff0c;请参考 如何安装OpenHarmony ohpm包 。 使用说明 目前支持MP4格式。 视频…