0%

vue3.0 项目

一,前端项目初始化步骤

① 安装Vue脚手架
② 通过vue脚手架创建项目
③ 配置vue路由
④ 配置E1ement-UI组件库
⑤ 配置axios库
⑥ 初始化git 远程仓库
⑦ 将本地项目托管到Github或码云中

  • install vue 脚手架

    1
    npm install @vue/cli -g
  • 使用 可视化创建

    1
    2
    3
    vue ui
    🚀 Starting GUI...
    🌠 Ready on http://localhost:8000
    • 使用命令行创建

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      ###模板下载好后的交互选项
      1.Project name vue-demo # 项目名称,直接回车,按照括号中默认名字
      (注意这里的名字不能有大写字母,如果有会报错Sorry, name can no longer contain capital letters)
      2. Project description A Vue.js project # 项目描述,直接回车
      3. Author # 作者名称,默认直接回车
      4. Vue build standalone # 一般选择的Standalone(运行时 + 编译器)模式
      Runtime + Compiler: recommended for most users;
      Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-specificHTML)
      areONLY allowed in .vue files - render functions arerequired elsewhere
      (一般都选这个Runtime + Compiler: recommended for most users)
      5. Install vue-router? Yes # 是否需要 vue-router,路由,一般都需要,输入y敲回车
      6.Use ESLint to lint your code? Yes # 是否使用 ESLint 作为代码规范.
      7. Pick an ESLint preset Standard # 一样的ESlint 相关
      8. Set up unit tests Yes # 是否安装单元测试
      9. Pick a test runner 按需选择 # 测试模块
      10. Setup e2e tests with Nightwatch? 安装选择 # e2e 测试
      11. Should we run `npm install` for you after the project has been created? (recommended) npm #
      包管理器,一般用NPM

网站首页广告分析(这里京东做分析)

1.核心区

1620994509496

2.楼层

1620994571806

1620994592226

SPU 和SKU

  • SPU 可以理解为一个类 , 拥有相同属性, 相同方法, 比如 iPhone x
    • 如手机->苹果手机->苹果6,苹果6就是SPU
  • SKU 可以理解为一个实例对象, 比如 iPhone x 全网通 黑色 256g

Nginx部署静态

  1. settings.py文件 设置静态文件目录

    1
    STATIC_ROOT = os.path.join(os.path.dirname(os.path.dirname(BAse_DIR)), "front_end_pc/static")
  2. 我们要把静态文件收集到front_end_pc/static

    1
    python manage.py collectstatic
ubuntu 提前装好Nginx服务器
  • 1.配置Nginx服务器

    静态业务

1623980357480

动态业务

1623980721048

server部分说明

1623982962155

指定wsgi.py 启动配置文件为prod.py

1623986502245

服务器地址

1
2
3
4
5
6
keepalive_timeout  1000;
upstream meiduo {
server 1xx.1xx.27.77:8001; # 此处为uwsgi运行的ip地址和端口号
# 如果有多台服务器,可以在此处继续添加服务器地址
}

uwsgi.ini 放到 同wsgi同一路径下,做uwsgi服务器配置

uwsgi.ini

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[uwsgi]
#使用nginx连接时使用,Django程序所在服务器地址
socket=192.168.x.xx:8001
#直接做web服务器使用,Django程序所在服务器地址
# http=1xx.168.xxx.133:8001
#项目目录
chdir=/Users/chao/Desktop/meiduo/meiduo_mall
#项目中wsgi.py文件的目录,相对于项目目录
wsgi-file=meiduo_mall/wsgi.py
# 进程数
processes=4
# 线程数
threads=2
# uwsgi服务器的角色 # True 为主,False 为从
master=True
# 存放进程编号的文件
pidfile=uwsgi.pid
# 日志文件,因为uwsgi可以脱离终端在后台运行,日志看不见。我们以前的runserver是依赖终端的
daemonize=uwsgi.log
# 指定依赖的虚拟环境
virtualenv=/Users/chao/.virtualenvs/django_20

注意

1624165971359

uwsgi 命令

  • 启动

    1
    uwsgi --ini uwsgi.ini
  • 停止

    1
    2
    uwsgi --stop uwsgi.ini
    # 或者 kill

哈弗曼

jdk8 之后,接口提供了默认方法

  • 在接口里 可以写 有实现体的方法了,可以被重写,但是不强制

  • 如果实现的多个接口有相同名字的默认方法,实现类必须重写

    1619488312119

jdk8 之后,接口提供了静态方法

1619489768318

Compose

  1. 创建docker-compose.yml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

    version: '3'
    services:
    redis:
    image: redis
    expose:
    - 6379
    ports:
    - "6389:6379"
    mysql:
    image: mysql:5.5
    expose:
    - 3306
    ports:
    - "3307:3306"
    environment:
    MYSQL_ROOT_PASSWORD: python
    MYSQL_USER: root
    volumes:
    - ./02_mysql:/var/lib/mysql
    flask:
    build: ./01_flask
    volumes:
    - ./01_flask/project:/home/project
    ports:
    - "5000:5000"
    depends_on:
    - mysql
    - redis

    一些常用的命令

  • 生成容器并运行
    • docker-compose up
  • 删除容器
    • docker-compose down
  • 开启容器并运行
    • docker-compose start
  • 停止容器运行
    • docker-compose stop

depends_on

制作镜像

  1. 下载一个基本的镜像
    1
    docker pull ubuntu:16.04
  2. 创建一个容器
    1
    docker run -it  ubuntu:16.04
  3. 需求是 安装vi
    需要 修改 /etc/apt/sources.list 更新源

3.1 编辑一个sources.list 复制到docker 容器中
docker cp sources.list 容器id:/home 将sources.list 复制到容器中
3.2 在容器中将/home/ 下的sources.list 替换 /etc/apt/sources.list

3.3 让更新源生效 apt update
3.4 安装vi apt install vim

  1. 将容器打包为镜像
    docker commit -m “备注” 容器的id 镜像的名字:版本

  2. 上传

  3. 1 在hub.docker.com 注册&登录

  4. 2 在终端docker login 登录

  5. 3 通过tag 打标签
    docker tag 镜像名:版本 用户名/镜像名:版本

  6. 4 推送到仓库
    docker push 用户名/镜像名:版本

检查镜像的信息
docker inspect 镜像的名字:版本

方式二 Dockerfile

  1. 新创一个文件夹, 新创一个Dockerfile 文件
    1
    2
    3
    $ mkdir my_nginx 
    $ cd my_nginx
    $ touch Dockerfile
  2. 编写文件Dockerfile
    1
    2
    3
    4
    # 检查 是否有 这个镜像, 没有则会下载
    FROM nginx:1.0
    # run 运行命令 shell
    RUN echo '<h1> hello Docker</h1>' > /usr/share/nginx/html/index.html
  3. 构建新镜象
    1
    2
    3
    docker build -t 镜像名字:版本 上下文路径

    docker build -t my_nginx:1.0 .
  4. 运行容器
    1
    docker run -it --rm -p 8002:80 mynginx:1.0

镜像进阶 版

一个特殊镜像 scratch 这个镜像是虚拟的概念, 并不实际存在

它表示一个空白的镜像
使用’Go ‘语言 开发 常用

1
FROM scratch

RUN XXXXX
每次run 就是一层

Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是不得超过 127 层。

注意
一般 Dockerfile 放于一个空目录下, 或者项目根目录下。
如果目录下有些东西确实不希望构建时传给 Docker 引擎,那么可以用 .gitignore 一样的语法写一个 .dockerignore,该文件是用于剔除不需要作为上下文传递给 Docker 引擎的。

-f ../Dockerfile.php 参数指定某个文件作为 Dockerfile。

docker build 支持 url

1
docker build -t hello-world https://github.com/docker-library/hello-world.git#master:amd64/hello-world

这行命令指定了构建所需的 Git repo,并且指定分支为 master,构建目录为 /amd64/hello-world/,然后 Docker 就会自己去 git clone 这个项目、切换到指定分支、并进入到指定目录后开始构建。

ADD 更高级的复制文件

在 Docker 官方的 Dockerfile 最佳实践文档 中要求,尽可能的使用 COPY,因为 COPY 的语义很明确,就是复制文件而已,而 ADD 则包含了更复杂的功能,其行为也不一定很清晰。最适合使用 ADD 的场合,就是所提及的需要自动解压缩的场合。另外需要注意的是,ADD 指令会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。因此在 COPY 和 ADD 指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用 COPY 指令,仅在需要自动解压缩的场合使用 ADD。在使用该指令的时候还可以加上 –chown=: 选项来改变文件的所属用户及所属组。

CMD
格式:CMD [“可执行文件”, “参数1”, “参数2”…]

镜像images

  1. 获取镜像
    1
    dock pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
  2. 运行
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    $ docker run -it --rm ubuntu:18.04 bash
    root@e7009c6ce357:/# cat /etc/os-release
    NAME="Ubuntu"
    VERSION="18.04.1 LTS (Bionic Beaver)"
    ID=ubuntu
    ID_LIKE=debian
    PRETTY_NAME="Ubuntu 18.04.1 LTS"
    VERSION_ID="18.04"
    HOME_URL="https://www.ubuntu.com/"
    SUPPORT_URL="https://help.ubuntu.com/"
    BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
    PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
    VERSION_CODENAME=bionic
    UBUNTU_CODENAME=bionic

docker run 就是运行容器的命令

  • -it :这是两个参数, 一个是-i 交互式操作,一个是’-t’ 终端,我们这里打算 进入bash 执行一些命令并
  • –rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 –rm 可以避免浪费空间
  • ubuntu:18.04:这是指用 ubuntu:18.04 镜像为基础来启动容器。
  • bash:放在镜像名后的是 命令,这里我们希望有个交互式 Shell,因此用的是 bash
  • exit 退出了这个容器
列出镜像
1
2
docker images

挂载硬盘
1
docker run ... -v 主机目录:容器中的目录 ...
复制文件
1
docker cp 源目录 目标目录

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
docker images -----> 查看已下载的镜像
docker rmi 镜像名称:标签名 -----> 删除已下载镜像
docker search 镜像 -----> 从官方仓库(hub.docker.com)查找镜像
docker pull 镜像名称:标签名 -----> 标签名默认是 latest,代表最新版本。
docker pull 镜像名 ------>下载最新版
docker ps -----> 列出运行中的容器(运行中)
docker ps -a ------> 列出所有的容器(运行、未运行)
docker ps -a 查看所有的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7c291fb47b70 python:3.9 "python3" 4 minutes ago Up 4 minutes priceless_almeida
docker stop 容器名称id -----> 停止容器
docker start 容器名称id -----> 启动容器
docker start -i 容器的id --->在将一个停止的容器运行起来的同时,指定交互模式
docker restart 容器名称id -----> 重启容器
docker rm 容器id -----> 删除 已经停止运行的容器
docker rm $(docker ps -a -q) -----> 删除所有停止运行的容器 (慎用)
docker rm -f 容器的id -----> 强制删除容器 (无论是否停止运行)
docker rmi 镜像的id
docker run 镜像名字:版本 ----->创建一个容器且运行
-it --->交互模式
docker exec 执行容器中的指令

Dockerfile 参数

FROM:指定基础镜像,必须为第一个命令
MAINTAINER: 维护者信息
ENV:设置环境变量
RUN:构建镜像时执行的命令
ADD:将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
EXPOSE:指定于外界交互的端口
VOLUME:用于指定持久化目录
WORKDIR:工作目录,类似于cd命令

案例

使用MySQL镜像

1
docker run -d --name=mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.5

命令说明:

  • –name=mysql:为容器指定一个名称为mysql
  • -p 3306:3306:将容器的(后面的3306) 3306 端口映射到主机的(前面的3306) 3306端口。
  • -d:后台运行容器,并返回容器ID。
  • -e MYSQL_ROOT_PASSWORD=123456:初始化 root 用户的密码为123456。
  • mysql:5.5 要使用的镜像的名称

网络 指令

查看 网络列表
docker network ls

当我们在使用docker-compose构建服务时,会自动创建一个新的网络如下
查看这个网络中所有的容器ip以及其他信息
docker network inspect 网络id

新建一个网络
$ docker network create -d bridge my-net

运行容器连接到my-net 网络
docker run --rm -it --network my-net my_flask:1.0 bash

Python 单例方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31


# 方式1 创建单例
class A:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__new__(cls, *args, **kwargs)

return cls._instance

def goto(self,):
print("cj>>>>>")


a = A()
print(id(a)) #2641366741704
b = A()
print(id(b)) #2641366741704

# 方式2 创建单例
class A:

def __new__(cls, *args, **kwargs):
if not hasattr(A, "_instance"): # 是否有_instance属性
cls._instance = super().__new__(cls, *args, **kwargs)

return cls._instance

def goto(self,):
print("cj>>>>>")

使用单例 控制 只有一个短信发送对象

内存优化,减少内存消耗

使用pipline 操作redis

1
2
3
4
5
6
7
8
pl = redis.cli.pipeline()
pl.setex("send_flag_%s" % mobile, 60, 1)
pl.setex("sms_%s" % mobile, 300, sms_code)

# 5. 保存短信验证码到redis
# redis_cli.setex()
# 执行请求
pl.execute() #一次执行,减少内存消耗

异步方案 celery 发短信

生产消费者模式

  • 安装celery创建sms 包,并添加异步

    1
    pip install -U celery
  • 在根目录下 创建celery的包

    1618539278351

  • main.py

    • 1 设置django环境
      2 创建celery对象
      3 设置 broker
      4 celery自动检测任务
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import os

    # 1 设置django环境
    # set the default Django settings module for the 'celery' program.
    from celery import Celery

    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'meiduo.settings')

    # 2 创建celery对象
    app = Celery('celery_tasks')

    # 3 设置 broker
    app.config_from_object("celery_tasks.config")

    # 4celery自动检测任务 这里会自动去celery_tasks.sms下找tasks.py
    app.autodiscover_tasks(['celery_tasks.sms'])

  • redis 作为队列

    • config.py
    1
    2
    3
    4
    5

    # 把redis 作为队列
    broker_url = "redis://127.0.0.1/15"


  • sms的tasks.py里添加任务

    • tasks.py文件名不可改变

    1618539600277

启动celery

1
celery -A celery_tasks.main worker -l info

1618540420762

win10 遇到的小bug

开启服务发现,任务并未执行 上网查资料后发现,celery 对win10 支持并不是很好

解决此方案的

  • 方案1

  • 添加–pool=solo参数

    1
    2

    celery -A celery_tasks.main worker --pool=solo -l info
  • 方案2

  • 先安装gevent,然后在启动celery的时候添加gevent参数

    1
    2
    pip install gevent
    celery -A celery_tasks.main worker -l info -P gevent

参考资料:https://stackoverflow.com/questions/37255548/how-to-run-celery-on-windows

Django 地址设计

省市区三级联动

  • 缓存省市区数据

    提示:

    • 省市区数据是我们动态查询的结果。
    • 但是省市区数据不是频繁变化的数据,所以没有必要每次都重新查询。
    • 所以我们可以选择对省市区数据进行缓存处理。
  • 缓存方式

    • from django.core.cache import cache
    • 存储缓存数据:cache.set('key', 内容, 有效期)
    • 读取缓存数据:cache.get('key')
    • 删除缓存数据:cache.delete('key')
    • 注意:存储进去和读取出来的数据类型相同,所以读取出来后可以直接使用。
  • 缓存逻辑实现

    • 省份缓存数据
      • cache.set('province_list', province_list, 3600)
    • 市或区缓存数据
      • cache.set('sub_area_' + area_id, sub_data, 3600)

省级三联orm

1
2
3
4
5
# 查询所有省份
select * from tb_areas where parent_id is Null;

area_list = Area.objects.filter(parent=None)
Area.objects.filter(parent__isnull = True)

查询市级

1
2
3
4
5
6
7
select * from tb_areas where parent_id=130000; # 市
Area.objects.filter(parent_id = 130000)

area_hebei = Area.objects.get(id = 130000) 河北省
area_hebei.subs.all() 河北省所有的市

select * from tb_areas where parent_id=130200; # 区县

java 跨包使用

1618281252388

集合与数组的区别

数组 长度不能修改

list 长度可以改变

Arraylist

泛型 作为约束集合里的类型

1618303552657

ArrayList 方法

  • 1
    2
    arrLi02.add("content");
    arrLi02.add(3,"conge"); // 根据下标 添加

    不能跨界添加

  • 1
    2
    3
    addLi02.remove("2"); // 根据元素
    addLi02.remove(0,"2"); // 根据下标 删除元素

  • 1
    addLi02.set(0,"改"); // 参数1 下标, 参数2 元素
  • 1
    2
    3
    4
    5
    6
    7
    addLi02.get(0); // 参数1 下标,

    // 循环打印
    for (int i = 0; i < addLi02.size() ; i++) {
    System.out.println(addLi02.get(i));
    }

  • Java ArrayList forEach() 方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    import java.util.ArrayList;

    class Main {
    public static void main(String[] args) {
    // 创建一个数组
    ArrayList<Integer> numbers = new ArrayList<>();

    // 往数组中添加元素
    numbers.add(1);
    numbers.add(2);
    numbers.add(3);
    numbers.add(4);
    System.out.println("ArrayList: " + numbers);

    // forEach 循环打印
    for (Integer integer : numbers) {
    System.out.println(integer);

    }

    // 所有元素乘以 10
    System.out.print("更新 ArrayList: ");

    // 将 lambda 表达式传递给 forEach
    numbers.forEach((e) -> {
    e = e * 10;
    System.out.print(e + " ");
    });
    }
    }
    1
    2
    ArrayList: [1, 2, 3, 4]
    更新 ArrayList: 10 20 30 40