首页 > 其他分享 >docker_04days

docker_04days

时间:2024-03-15 20:46:53浏览次数:30  
标签:容器 compose redis transaction 04days luffy docker

docker-compose介绍

# 使用了docker 面临一个比较大的问题,如果一个djagno项目,使用mysql,redis,不要一次性把所有服务都放到一个容器中,每个服务一个容器,批量的管理多个容器,比较难以操作,于是有了docker-compose

# 批量管理,操作docker容器的软件---》只在单机

# Docker Compose是一个能一次性定义和管理多个Docker容器的工具,单机容器编排【定义和管理】


# 多机容器编排
    docker swarm:用的不多
    k8s
    
# Docker Compose概念
    Compose中定义和启动的每一个容器都相当于一个服务(service)
    Compose中能定义和启动多个服务,且它们之间通常具有协同关系
    管理方式:
    使用YAML文件来配置我们应用程序的服务。
    使用单个命令(docker-compose up),就可以创建并启动配置文件中配置的所有服务。
 

# 安装docker-compose (可执行文件,放在了github上,下载下来即可,速度很慢)
# https://github.com/docker/compose/releases
wget https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-linux-x86_64
cp ./docker-compose-linux-x86_64 /usr/local/bin/docker-compose # 想在任意路径下执行docker-compose都有相应----》需要把可执行文件放到环境变量所在的目录下
chmod +x /usr/local/bin/docker-compose

# rwx    rwx    rwx
  属主   属组    其他
  r:read 读权限 
  w:wirte 写权限
  x :执行权限

 属主   属组  所有人
 chmod 777 文件名
 chmod +x 

    
  rwx  r-x   -wx
  101  101   101 
  chmod 555 文件名
    
    
    
# 以后在任意位置敲docker-compose都可以


# epel源
    -yum install centos仓库下载
    -软件不全
    -epel源 扩展源 
        nginx
        redis
        python



# 常用命令
# 启动管理容器
docker-compose up  # 会自动搜索当前路径下的 docker-compose.yml文件
docker-compose -f 指定文件 up
docker-compose up -d  # 后台执行,一般我们看日志输出,不用这个

docker-compose stop  # 停止,不会删除容器和镜像
docker-compose down # 停止,并删除关联的容器
docker-compose start  # 启动yml文件管理的容器
docker-compose ps    # 正在运行的容器
docker-compose images # docker-compose管理的镜像

docker-compose exec yml文件中写的service /bin/bash  # 进入到容器内

docker-compose up -d --build # 启动容器但是重新构建镜像,基于重新构建的镜像启动


#####  如果你没装docker#######
# 配置yum仓库
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 下载 docker-ce  docker-ce-cli docker-compose-plugin
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

docker-compose部署flask案例

# flask 项目,使用redis服务---》2个容器
flask 项目容器
redis容器

新建flask项目 app.py

from flask import Flask
from redis import Redis
import os

app = Flask(__name__)
# redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)
redis = Redis(host='redis', port=6379) # 容器的主机名---》flask容器和redis容器是能ping通的,可以通过ip ping 也可以通过主机名ping

@app.route('/')
def hello(): 
    redis.incr('hits')
    return '你好! 查看 %s 次\n' % (redis.get('hits'))


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)
-----------------------------------------------------
from flask import Flask
from redis import Redis
import os

app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello(): 
    redis.incr('hits')
    return '你好! 查看 %s 次\n' % (redis.get('hits'))


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)

编写Dockerfile--》用于构建flask项目的镜像

FROM python:3.10
WORKDIR /app
COPY . /app
RUN pip install flask redis -i https://pypi.tuna.tsinghua.edu.cn/simple
EXPOSE 5000
CMD [ "python", "app.py" ]

# 构建出镜像---》一会统一使用 docker-compose构建

编写docker-compose的yaml文件 docker-compose.yml

version: "3"
services:
  redis:
    image: redis
  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 8080:5000
    environment:
      REDIS_HOST: redis
          

docker-compose启动

# 如果redis服务的名字叫redis,我在web服务中(容器中),根据redis名字就能拿到容器
    ping redis
    
    # 进入到了web,ping redis
    # 安装ping命令,
    apt-get update
    apt-get install inetutils-ping
    ping redis
    
    
# 一键部署:redis,和flask ,每个都在一个容器中
docker-compose up
    -构建flask镜像
    -reids镜像如果不存在,就会拉取
    -启动flask
    -启动redis

docker-cmopose部署路飞

# 一台服务器:
    -python3.8 环境 djagno +uwsgi+代码
    -nginx软件
    -mysql 5.7
    -redis 
    
# 每个都做成一个容器
    -djagno项目容器:python3.8 构建的django,项目依赖模块,uwsgi,代码
    -nginx容器:目录映射,映射到宿主机,代理vue前端,编译后的静态文件
    -mysql 容器:创建,创用户,密码,luffy库
    -redis 容器,跑起来即可
    
    
# docker-compose yml文件配置,一键启动
    -git clone https://gitee.com/liuqingzheng/luffy.git
    -目录结构
    luffy
        luffy_api  # 后台项目
            Dockerfile
        luffycity  # 前台项目
        docker_compose_files # 放数据的文件夹
        
        docker-compose.yml #ymal文件
    -docker-compose.yml内容
    -Dockefile 文件
    - 修改前端链接后台的地址:luffycity/src/access/xx.js
    -编译:npm run build
    
    -提交到git
    
    -要部署的服务器:git clone https://gitee.com/liuqingzheng/luffy.git
    -docker,docker-compose装好
    -docker-compose up
    -访问宿主机的 80 端口

项目目录结构

luffy
    -docker_compose_files  # nginx有自己的配置文件,redis自己的配置,mysql的配置
        nginx # 文件夹
        redis # 文件夹
        mysql.env#配置文件
    -luffy_api  # 原来路飞后端项目
        -Dockerfile
        -luffy.ini  # luffy.xml uwsgi的配置文件
    -luffycity  # 前端项目
    
    -docker-compose.yml  # docker-compose的配置文件
    

# 把luffycity/dist 文件夹删除
# 把\luffy\luffycity\src\assets\js\settings.js后端地址改成上线地址(服务器地址)
# 来到前端路径下:luffy\luffycity
cnpm install  安装依赖

# 编译,在\luffy\luffycity\dist文件夹
npm run build

# 提交到git上


# 在部署的机器上,git clone 下来
# 进入到项目目录
docker-compose up

luffy_api/Dockerfile--->构建uwsgi+django

FROM python:3.8
MAINTAINER lqz
WORKDIR /soft
COPY ./requestment.txt /soft/requestment.txt
RUN pip install -r requestment.txt -i https://pypi.doubanio.com/simple
#CMD ["uwsgi", "-x", "./luffy.xml"]
CMD ["uwsgi", "./luffy.ini"]
#CMD ["python", "manage_pro.py", "runserver"]

docker-compose.yml

version: "3"

services:
  nginx:
    image: nginx
    container_name: luffy_nginx
    ports:
      - "80:80"
      - "8000:8000"
    restart: always
    volumes:
      - ./luffycity/dist:/var/www/html
      - ./docker_compose_files/nginx:/etc/nginx/conf.d
    depends_on:
      - django
    networks:
      - web

  django:
    build:
      context: ./luffy_api
      dockerfile: Dockerfile
    container_name: luffy_django
#    command: python manage_pro.py makemigrations && python manage_pro.py migrate && uwsgi ./luffy.ini
    restart: always
    ports:
      - "8080:8080"
    volumes:
      - ./luffy_api:/soft
    environment:
      - TZ=Asia/Shanghai
    depends_on:
      - mysql
      - redis
    networks:
      - web
  redis:
    image: redis:6.0-alpine
    container_name: luffy_redis
    ports:
      - "6379:6379"
    volumes:
      - ./docker_compose_files/redis/data:/data
      - ./docker_compose_files/redis/redis.conf:/etc/redis/redis.conf
    command: redis-server /etc/redis/redis.conf
    networks:
      - web
  mysql:
    image: mysql:5.7
    container_name: luffy_mysql
    restart: always
    ports:
      - "3306:3306"
    env_file:
      - ./docker_compose_files/mysql.env
    volumes:
      - ./docker_compose_files/mysql/data:/var/lib/mysql
      - ./docker_compose_files/mysql/logs:/var/log/mysql
      - ./docker_compose_files/mysql/conf:/etc/mysql/conf.d
    networks:
      - web

networks:
  web:

一键部署

docker-compose up    

 

补充

django中实现事务的几种方式

# https://zhuanlan.zhihu.com/p/622987268

Django是支持事务操作的,它的默认事务行为是自动提交,
具体表现形式为:每次数据库操作(比如调用save()方法)会立即被提交到数据库中。
但是如果你希望把连续的SQL操作包裹在一个事务里,就需要手动开启事务


# 根据粒度不同,三种
######## 全局##########
    -全局,每次请求在一个事务中,粒度太大,事务时间很长
    DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.mysql',
         'NAME': 'lqz',
         'HOST': '127.0.0.1',
         'PORT': '3306',
         'USER': 'lqz',
         'PASSWORD': 'lqz123',
          #全局开启事务,绑定的是http请求响应整个过程
         'ATOMIC_REQUESTS': True, 
         }
    }
# 局部禁用全局事务
from django.db import transaction
# 局部禁用事务
@transaction.non_atomic_requests
def seckill(request):
    return HttpResponse('秒杀成功')
 
# 多数据库,用default的视图不受事务控制
@transaction.non_atomic_requests(using='default')
def seckill(request):
    return HttpResponse('秒杀成功')



####### 视图开启事务##############
# fbv开启
from django.db import transaction
@transaction.atomic
def seckill(request):
    return HttpResponse('秒杀成功')


# cbv开启
from django.db import transaction
from rest_framework.views import APIView
class SeckillAPIView(APIView):
    @transaction.atomic
    def post(self, request):
        pass
    
    
    
################ 局部使用事务#####################
from django.db import transaction
def seckill(request):
    with transaction.atomic():
        save()
        update()
    return HttpResponse('秒杀成功')

事物的回滚和保存点

# 1 普通事务操作(手动操作)
transaction.atomic()  # 开启事务
transaction.commit()  # 提交事务
transaction.rollback() # 回滚事务

# 2 可以使用上下文管理器来控制(自动操作)
with transaction.atomic():  # 自动提交和回滚
    
    
    
    
# 3 保存点
    -开启事务
    干了点事
    设置保存点1
    干了点事
    设置一个保存点2
    干了点事
    
    回滚到干完第二个事,回滚到保存点2
    
    
'''
在事务操作中,我们还会经常显式地设置保存点(savepoint)
一旦发生异常或错误,我们使用savepoint_rollback方法让程序回滚到指定的保存点
如果没有问题,就使用savepoint_commit方法提交事务
'''

from .models import Book
from django.db import transaction
def seckill(request):
    with transaction.atomic():
        # 设置回滚点,一定要开启事务
        sid = transaction.savepoint()
        print(sid)
        try:
            book = Book.objects.get(pk=1)
            book.name = '红楼梦'
            book.save()
        except Exception as e:
            # 如发生异常,回滚到指定地方
            transaction.savepoint_rollback(sid)
            print('出异常了,回滚')
        # 如果没有异常,显式地提交一次事务
        transaction.savepoint_commit(sid)
    return HttpResponse('秒杀成功')
transaction.atomic()  # 开启事务
sid = transaction.savepoint() # 设置保存点
transaction.savepoint_rollback(sid) # 回滚到保存点
transaction.savepoint_commit(sid) #提交保存点

事务提交后,执行某个回调函数

# 有的时候我们希望当前事务提交后立即执行额外的任务,比如客户下订单后立即邮件通知卖家
###### 案例一##################
def send_email():
    print('发送邮件给卖家了')
def seckill(request):
    with transaction.atomic():
        # 设置回滚点,一定要开启事务
        sid = transaction.savepoint()
        print(sid)
        try:
            book = Book.objects.get(pk=1)
            book.count = book.count-1
            book.save()
        except Exception as e:
            # 如发生异常,回滚到指定地方
            transaction.savepoint_rollback(sid)
        else:
            transaction.savepoint_commit(sid)
            #transaction.on_commit(send_email)
            transaction.on_commit(lambda: send_sms.delay('1898288322'))
    return HttpResponse('秒杀成功')


##### 案例二:celery中使用###
transaction.on_commit(lambda: send_sms.delay('1898288322'))

django实现悲观锁乐观锁案例

# 线上卖图书
    -图书表  图书名字,图书价格,库存字段
    -订单表: 订单id,订单名字
    
# 表准备
    class Book(models.Model):
        name = models.CharField(max_length=32)
        price = models.IntegerField()  #
        count = models.SmallIntegerField(verbose_name='库存')
    class Order(models.Model):
        order_id = models.CharField(max_length=64)
        order_name = models.CharField(max_length=32)
        
# 使用mysql
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'lqz',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'USER': 'lqz',
        'PASSWORD': '123',
    }
}

# 创建lqz数据库

原生mysql悲观锁

begin; # 开启事务

select * from goods where id = 1 for update;  # 行锁

# order表中加数据

update goods set stock = stock - 1 where id = 1; # 更新

commit; #提交事务

orm实现上述

#1  使用悲观锁实现下单
@transaction.atomic  # 整个过程在一个事物中---》改两个表:book表减库存,订单表生成记录
def seckill(request):
    # 锁住查询到的book对象,直到事务结束
    sid = transaction.savepoint() # 保存点
    # 悲观锁: select_for_update()
    # 加锁了--》行锁还是表锁? 分情况,都有可能
    #
    book = Book.objects.select_for_update().filter(pk=1).first()  # 加悲观锁,行锁,锁住当前行
    if book.count > 0:
        print('库存可以,下单')
        # 订单表插入一条
        Order.objects.create(order_id=str(datetime.datetime.now()), order_name='测试订单')
        # 库存-1,扣减的时候,判断库存是不是上面查出来的库存,如果不是,就回滚
        time.sleep(random.randint(1, 4))  # 模拟延迟
        book.count=book.count-1
        book.save()
        transaction.savepoint_commit(sid)  # 提交,释放行锁
        return HttpResponse('秒杀成功')
    else:
        transaction.savepoint_rollback(sid) #回滚,释放行锁
        return HttpResponse('库存不足,秒杀失败')

乐观锁秒杀--》库存还有,有的人就没成功

# 2 乐观锁秒杀--普通版
@transaction.atomic
def seckill(request):
    # 锁住查询到的book对象,直到事务结束
    sid = transaction.savepoint()
    book = Book.objects.filter(pk=1).first()  # 没加锁
    count = book.count
    print('现在的库存为:%s' % count)
    if book.count > 0:
        print('库存可以,下单')
        Order.objects.create(order_id=str(datetime.datetime.now()), order_name='测试订单-乐观锁')
        # 库存-1,扣减的时候,判断库存是不是上面查出来的库存,如果不是,就回滚
        # time.sleep(random.randint(1, 4))  # 模拟延迟
        res = Book.objects.filter(pk=1, count=count).update(count=count - 1)
        if res >= 1:  # 表示修改成功
            transaction.savepoint_commit(sid)
            return HttpResponse('秒杀成功')
        else:  # 修改不成功,回滚
            transaction.savepoint_rollback(sid)
            return HttpResponse('被别人改了,回滚,秒杀失败')

    else:
        transaction.savepoint_rollback(sid)
        return HttpResponse('库存不足,秒杀失败')

 

标签:容器,compose,redis,transaction,04days,luffy,docker
From: https://www.cnblogs.com/wzh366/p/18076198

相关文章

  • docker命令查询笔记
    目录loginsearchpushpullimagesrmitaghistorysaveloadrunstartrestartstopkillrmpauseunpausecreateexecpsinspectstatstoprenameattachupdatelogswaitportexportimportloginlogin:登录到远程仓库登录到远程仓库后可可以拉取仓库的镜像了dockerlogin[OPTIONS][S......
  • Docker Compose基本配置及使用笔记
    DockerCompose基本配置及使用笔记简介DockerCompose是一个用于定义和运行多个Docker容器应用程序的工具。它使用YAML文件来配置应用程序的服务,并通过简单的命令集管理这些服务的生命周期。1.步骤1代码如下:docker-compose.yml放在虚拟机root目录下version:"......
  • RuoYi 前端Docker部署
    Dockerfile#基础镜像不指定版本则默认最新FROMnginx#挂载目录VOLUME/home/nginx/www/ruoyi#创建目录RUNmkdir-p/home/nginx/www/ruoyi#指定路径该路径我是自己提前创建好的WORKDIR/home/nginx/www/ruoyi#复制conf文件到路径./conf/nginx.conf和上面的mys......
  • docker释放镜像后虚拟磁盘不减小
    在使用dockersytemprume指令清理了docker当前的所有镜像和容器后,docker的虚拟磁盘ext4.vhdx所占用的空间一点也没有减少。使用dockersystemdf指令查看,能清理的都已经清理了。查阅资料后才发现,由于我安装docker时是基于wsl而不是hyper-V导致了这个问题的出现。wsl2是虚拟机,......
  • docker部署halo
    docker部署halo,ubuntuserver2204,官方地址:https://docs.halo.run/getting-started/install/docker-compose 选择docker-compose搭建,选择halo+外部已存在的mysql搭建,创建,文件夹,在文件夹中创建docker-compose.yaml,内容如下:version:"3"services:halo:image:h......
  • Elasticsearch - Docker安装Elasticsearch8.12.2
    前言最近在学习ES,所以需要在服务器上装一个单节点的ES服务器环境:centos7.9安装下载镜像目前最新版本是8.12.2dockerpulldocker.elastic.co/elasticsearch/elasticsearch:8.12.2创建配置新增配置文件elasticsearch.ymlhttp.host:0.0.0.0http.cors.enabled:true......
  • paddleocr 在docker环境下部署
    paddleocr在docker环境下部署第一步查看cuda的版本nvcc-V,我的是11.2;nvidia-smi对应的cudaversion是11.6,所以采用了registry.baidubce.com/paddlepaddle/paddle:latest-dev-cuda11.6-cudnn8.4-trt8.4-gcc82作为基础镜像Docker镜像源选择,DockerHub地址Dockerfile......
  • Gitlab+Jenkins+Docker+Harbor+K8s集群搭建CICD平台(持续集成部署Hexo博客Demo)
    目录涉及内容:一、CICD服务器环境搭建1、docker环境安装(1)、拉取镜像,启动并设置开机自启(2)、配置docker加速器2、安装并配置GitLab(1)、创建共享卷目录(2)、创建gitlab容器(3)、关闭容器修改配置文件(4)、修改完配置文件之后。直接启动容器(5)、相关的git命令(针对已存在的文件夹)3、安装配......
  • Docker使用(三)Docker底层分析
    Docker使用(三)Docker底层分析四、底层分析1、Docker镜像原理1.1commit镜像dockercommit提交容器成为一个新的副本#命令和git原理类似dockercommit-m=“提交的描述信息”-a=“作者”容器id目标镜像名:[TAG]实操:#1、启动一个默认tomcat#2、发现这个默认......
  • Docker 仓库国内镜像源
    1.仓库镜像对应表原始镜像docker.io***.mirror.aliyuncs.com(点进去登录查看)dockerproxy.comhub-mirror.c.163.comquay.ioquay.mirrors.ustc.edu.cnregistry.k8s.ioregistry.lank8s.cn下面的不全,适合kubeadminit时使用:registry.aliyuncs.com/google_conta......