当前位置: 首页 > news >正文

日常学习之:vue + django + docker + heroku 对后端项目 / 前后端整体项目进行部署

文章目录

  • 使用 docker 在 heroku 上单独部署 vue 前端
  • 使用 docker 在 heroku 上单独部署 django 后端
    • 创建 heroku 项目
    • 构建 Dockerfile
    • 设置 settings.py
      • database
      • 静态文件管理
      • 安全设置
      • applicaiton & 中间件配置
    • 设置 requirements.txt
    • heroku container 部署应用
  • 前后端分别部署的优势和问题分别是什么
    • 好处
      • 解耦合
      • 灵活性
      • 安全性
      • 技术栈独立
    • 坏处
  • 使用 docker 在 heroku 上整体部署 vue + django
    • step1: 将 vue 的文件整个挪到 django 项目根目录底下
    • step2: 构建 dockerfile
    • step3: settings.py
    • step4: 更新 django url.py 并在 views.py 中呈现 Vue 应用
    • step5: heroku container 部署整体项目
    • step6: debug -- 让 django 能找到 vue 的静态资源
      • 调整 Vue 构建配置
      • 在 Django 中处理静态文件引用

使用 docker 在 heroku 上单独部署 vue 前端

  • 在 这篇文章 中我已经介绍了如何通过 docker 单独部署一个 vue 的前端项目
  • 在这个章节,我想按照下面的结构来给大家介绍:
    • 如何使用 docker 在 heroku 上单独部署 django 后端
    • 前后端分别部署的问题是什么
    • 如何将 vue + django 合并到一起通过 docker 构建一个完整的项目

使用 docker 在 heroku 上单独部署 django 后端

  • 我之前在讲如何使用 heroku 的 repository 部署 django 项目的 时较为详细地讲了如何创建 Procfileruntime.txt 以及里面写什么内容,
  • 但是我们使用 docker 来部署 django 项目,是使用 heroku container,因此不需要设定 Procfileruntime.txt 等文件,我们会将所有需要使用的指令都放在 Dockerfile 里面

创建 heroku 项目

  • 如果您还没有创建应用,可以使用以下命令创建:
    heroku create <应用名称>
    
  • 也可以用 heroku 的图形化界面创建

构建 Dockerfile

# 使用兼容 Django 项目的 Python 镜像
FROM --platform=linux/amd64 python:3.9# 设置工作目录为 /app
WORKDIR /app# 复制项目文件到容器中
COPY . /app# 更新安装包
RUN apt-get update# 安装项目依赖 (这里是我自己的 Linux 依赖,如果你不需要安装这种依赖,那就只需要 RUN pip install -r requirements.txt)
RUN apt-get install -y portaudio19-dev
RUN pip install -r requirements.txt # 设置环境变量
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1# 运行 Django 服务,注意下面两个 # 修饰的部分是错误的写法
#CMD ["python", "manage.py", "runserver", "0.0.0.0:9000"]
#CMD ["python", "manage.py", "runserver", "0.0.0.0:$PORT"]
# CMD python manage.py runserver 0.0.0.0:$PORT
# CMD gunicorn <your project>.wsgi:application --bind 0.0.0.0:$PORT
CMD daphne -p $PORT -b 0.0.0.0 <your project>.asgi:application
  • 需要注意的是:
    在这里插入图片描述

  • 第一种错在不应该指定 9000 这个端口

    • 因为 heroku 在执行的时候会自动分配端口并生成一个 httpurl
    • 外面的服务需要访问你部署的系统时直接访问这个 url 就可以访问服务,而不需要访问 9000 端口
  • 第二种错在不应该使用 CMD [..., ..., ...] 这种形式:

    • CMD指令可以有两种不同的格式:shell 格式和 exec格式。这两种格式在处理环境变量时有所不同
    • 使用shell格式(如CMD python manage.py runserver 0.0.0.0:$PORT)时,命令会在shell中执行,这意味着可以进行环境变量展开。因此 $PORT 会被正确解析为 Heroku分配的端口值
    • 使用exec格式(如CMD ["python", "manage.py", "runserver", "0.0.0.0:$PORT"])时,命令不会在shell中执行,而是直接作为进程启动。这意味着不会进行环境变量展开,因此 $PORT 不会被解析为其实际值,而是被当作字符串$PORT 处理。
  • 第三种没有错,但是使用 daphne 或者 gunicorn 来启动服务器的方式在性能上更优秀。

  • 第四种,因为我的项目里面用了 websocket,而 gunicorn 不能处理这种情况,因此不行

  • 第五种是最好的,但是一定要注意,要指定 -b 0.0.0.0 如果不指定默认在 127.0.0.1,这样是不对的。同时,这里简单阐述一下为什么不直接用 python manage.py runserver 而用 daphne 这种专业的服务器,是因为:

    • Daphne 是一个 ASGI (Asynchronous Server Gateway Interface) 服务器,这意味着它能够处理异步请求,包括 WebSocket。这对于需要实时功能(如聊天应用、实时通知等)的应用程序来说非常重要。
      Django的 runserver 命令是一个 WSGI (Web Server Gateway Interface) 服务器,它 只能处理同步请求。虽然 Django 从3.0版本开始支持异步视图和中间件但runserver 并不是为处理高并发或实时通信设计的
    • Daphne 旨在作为生产级的服务器运行,提供更高的性能和可靠性。它能够更好地处理多个并发连接。 Django的 runserver 主要是为开发过程中的本地测试设计的。它没有针对性能和并发进行优化,不适合用于生产环境。
    • Daphne 和其他专用的ASGI/WSGI服务器如 Gunicorn、Uvicorn 等,通常包括用于生产环境的安全特性和最佳实践。 使用 Django的runserver 在生产环境中可能带来安全风险,因为它不是为暴露在公网上的环境设计的。
    • Daphne 支持 HTTP/2(虽然需要额外的配置),这可以提供更好的性能,特别是在处理大量静态内容或使用了大量API请求的应用程序中。Django 的 runserver 不支持 HTTP/2。
    • Daphne 可以更容易地与其他组件(如 Nginx、负载均衡器等)集成,提供更好的扩展性和部署灵活性。 直接使用 runserver 在复杂的生产环境中可能会受到限制。
  • 此外,我们指定了 FROM --platform=linux/amd64 python:3.9 是因为我用的是 macbook m1芯片,所以默认构建的 platform 和 docker 的 linux 是有冲突的,因此我需要在构建的时候指定 platform

  • docker 的默认根目录就是 /app,我们用 dockerfile 定义的一切,无非就是在 docker 的隔离环境中重建一个我们 local 的环境。因此 heroku 也可以直接依据 dockerfile 构建一个一模一样运行环境。

  • 安装项目依赖那里之所以 RUN apt-get install -y portaudio19-dev 是因为我的项目在 install requirements.txt 的时候报错,缺少一个头文件,而这个头文件依赖于我的这个 library,因此我需要 pip install 之前把这些依赖项先装了,按照自己的情况来

设置 settings.py

database

  • 如果你要再 heroku 上使用 database(比如 postgres)等,就要提前在 settings 里面配置
DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': BASE_DIR / 'db.sqlite3',}
}

静态文件管理

STATIC_URL = '/static/'
# 这么写表明当用户使用 python manage.py collectstatic 时,所有的静态资源都会放到 staticfiles 文件夹里面
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
# 这行其实没啥用,但相当于说,如果我有其他的 static 文件,我会放到 static 文件夹里面,而不会去占用 django 项目自己的静态文件夹 'staticfiles'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
  • 在Heroku上,静态文件的处理与本地环境不同。需要设置STATIC_ROOT和其他相关设置以确保静态文件能被正确收集和服务。

安全设置

  • 例如ALLOWED_HOSTS,以包括您的Heroku应用程序的域名:
ALLOWED_HOSTS = ['your-app-name.herokuapp.com']

这个我一般设置为:

ALLOWED_HOSTS = ['*']

applicaiton & 中间件配置

INSTALLED_APPS = ["daphne",   # asgi 应用,如果不设置,默认为 wsgi 应用"channels", # 它使服务器和客户端之间的双向通信成为可能,从而可以构建具有即时消息、通知和实时更新等功能的应用程序。'django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles',"<your project name>",  # 只要你构建 django 项目,这个就要加进来"corsheaders"  # 解决跨域问题的
]CORS_ALLOW_ALL_ORIGINS = True     # 跨域问题

MIDDLEWARE = ['corsheaders.middleware.CorsMiddleware',  # cors problem'django.middleware.security.SecurityMiddleware',"whitenoise.middleware.WhiteNoiseMiddleware",  # 它可以帮助处理静态文件的服务和缓存。它允许你将静态文件(如 CSS、JavaScript 和图像文件)直接提供给最终用户,而无需通过额外的服务器或 CDN。'django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]

设置 requirements.txt

  • 上面配置的 application 的那些东西(daphne, channels 等),不要忘记在 requirements.txt 文件中进行定义,方便 dockerfile 执行的时候自动安装这些依赖,这里提供一个 requirements.txt 的样本:

    asgiref==3.4.1
    Django==4.0.1
    sqlparse==0.4.2
    tzdata==2023.3
    gunicorn==20.1.0
    django-heroku==0.3.1
    openai==0.28.1
    django-cors-headers
    django-redis
    daphne
    channels_redis
    whitenoise
    dj-database-url
    opencv-python-headless
    channels
    pysbd
    pyaudio
    agora_token_builder
    google-api-core==2.11.0
    google-auth==2.25.2
    google-cloud-core==2.4.1
    google-cloud-speech==2.19.0
    google-cloud-storage==2.14.0
    google-cloud-translate==3.13.0
    google-crc32c==1.5.0
    google-resumable-media==2.7.0
    googleapis-common-protos==1.59.0
    langchain==0.0.350
    langchain-community==0.0.3
    langchain-core==0.1.1
    nltk==3.7
    

heroku container 部署应用

heroku container:push web -a <heroku application name>
heroku container:release web -a <heroku application name>

前后端分别部署的优势和问题分别是什么

  • 现在我们已经讲完了 vue 和 django 分别通过 docker + heroku 的方式部署前端项目和后端项目的流程。那这里有个问题是,前后端分别部署这样的好处和坏处分别是什么呢?

好处

解耦合

前后端分离使得前端和后端可以独立开发和部署,这有助于提高团队的工作效率,同时降低了代码耦合性。
可以单独更新前端或后端,而不影响系统的其他部分。

灵活性

前后端分别部署允许您为每部分选择最适合的托管和缩放策略。例如,您可能会根据流量模式对前端和后端进行不同的缩放。

安全性

通过将前端和后端分开,您可以在网络架构上实现更细粒度的安全控制。例如,可以限制对后端服务的访问,只允许来自特定前端的请求。

技术栈独立

您可以自由选择或更改前端或后端的技术栈,而不需要对整个应用架构进行大规模的更改。
性能优化:

分别优化前端和后端的性能。例如,可以在内容交付网络 (CDN) 上托管静态前端资源,而后端则专注于API响应。

坏处

  • heroku 单独部署两个项目分别收费不划算
  • 跨域问题:前后端分别部署可能需要处理跨源资源共享 (CORS) 问题,这需要在后端正确配置以允许来自前端的请求。

使用 docker 在 heroku 上整体部署 vue + django

step1: 将 vue 的文件整个挪到 django 项目根目录底下

  • 注意,这时候 vue 不再需要 server.js 这个文件了,后面会详细说为什么。

  • vue 项目中的 Dockerfile 也可以删除,因为我们也不单独基于 vue 来构建项目了

  • 移动后的文件目录如下,当然你也可以不这么放,但是你要能够保证按照后面的步骤能够准确对应到你放前端代码的位置,因为后面的操作比较细节,或者你可以等你后面的步骤熟练了再自己做调整。

    .
    ├── Dockerfile
    ├── db.sqlite3
    ├── google_credential.json
    ├── manage.py
    ├── readme.md
    ├── requirements.txt
    ├── staticfiles
    │   ├── admin
    │   └── staticfiles.json
    ├── validation_backend
    │   ├── __init__.py
    │   ├── __pycache__
    │   ├── admin.py
    │   ├── asgi.py
    │   ├── consumers.py
    │   ├── migrations
    │   ├── models.py
    │   ├── routing.py
    │   ├── settings.py
    │   ├── tools.py
    │   ├── urls.py
    │   ├── views.py
    │   └── wsgi.py
    └── validation_front├── README.md├── babel.config.js├── img.png├── jsconfig.json├── node_modules├── package-lock.json├── package.json├── public├── src├── todo.md├── vue.config.js
    

step2: 构建 dockerfile

# 第一阶段:构建 Vue.js 应用
FROM --platform=linux/amd64 node:14 as vue-build-stage# 设置 Vue.js 项目的工作目录,这样设置是为了 docker 里面的目录和 local 真实的目录路径保持一致
WORKDIR /app/validation_front# 拷贝 Vue.js 项目的 package.json 和 package-lock.json
COPY validation_front/package*.json ./# 安装 Vue.js 项目依赖
RUN npm install# 拷贝 Vue.js 项目文件
COPY validation_front/ .# 构建 Vue.js 应用
RUN npm run build# 第二阶段:构建 Django 应用
# 使用兼容 Django 项目的 Python 镜像
FROM --platform=linux/amd64 python:3.9RUN apt-get update
# 安装项目依赖
RUN apt-get install -y portaudio19-dev# 设置工作目录为 /app
WORKDIR /appCOPY requirements.txt .
RUN pip install -r requirements.txt# 复制剩余的 Django 项目文件到容器中,这样做是为了将环境安装部分放在上一个docker 的层,避免每次 push docker 都重新安装 package
COPY . .# 判断 app 里面是不是有 static 和 templates,没有就创建
RUN test -d /app/templates || mkdir /app/templates
RUN test -d /app/static || mkdir /app/static# 从 Vue.js 构建阶段拷贝静态文件到 Django 的静态文件目录
COPY --from=vue-build-stage /app/validation_front/dist /app/static/# 将 Vue 的 index.html 移动到 Django 的模板目录
COPY --from=vue-build-stage /app/validation_front/dist/index.html /app/templates/# 在 docker 内运行的端口(暴露端口)
EXPOSE 9000# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1# 运行 Django 服务
# CMD python manage.py runserver 0.0.0.0:$PORT
CMD daphne -p $PORT -b 0.0.0.0 validation_backend.asgi:application
  • 我认为上面步骤中最重要的就是要通过 build 将 vue 的项目打包,打包好的内容 vue 会自动放到 validation_front/dist 文件夹里面,大约是这个样子(我这个图是本地 build 了一下给大家展示,真正在 docker 里面的和这个是一样的,只不过不可见):
    在这里插入图片描述

  • 然后我们需要在 docker 里面把 dist 这个文件夹里面所有的内容拷贝到 django 项目的根目录下面的 static 文件夹里面去(dockerfile 中已经定义了这样的操作)。将 vue 中 dist 的内容 copy 到 django static 路径的原因是:如果前后端放在一起部署。那么 vue 项目就不再需要一个单独的 server.js 而是把 django 项目直接当成 backend,因此,当有 request 进来的时候,django 需要结合 vue 已经写好的那些页面(静态资源)来给 user 返回内容让浏览器解析。

  • 因此我们 需要让 django 和 vue 的东西适配起来,也就是让 django 能够定位到 vue 的静态资源。这个我们后面会着重讲

  • 此外,如果你关注上面的 dockerfile 你就会发现

上文中有两处:

  • 第一阶段中:COPY validation_front/package*.json ./ 之后又进行了 COPY validation_front/ .
  • 第二阶段中:COPY requirements.txt . 之后又进行了 COPY . .
    上述两个操作中的第二步看上去都似乎包含了第一步的操作,那么这样做的道理是什么呢?
  • 这是因为:
    • 在 Dockerfile 中,这种 seemingly redundant 的 COPY 操作实际上是一种优化技术,称为 Docker 层的缓存利用。每个 RUN, COPY,ADD 指令在 Docker 构建过程中都会创建一个新层。Docker 使用这些层来缓存构建步骤,这样在后续构建中,如果没有检测到任何变化,它就可以重用现有的层。这大大加速了构建过程。

    • 分步骤 COPY 的目的:

      • COPY validation_front/package*.json ./COPY requirements.txt . 这些命令是为了首先复制 package.jsonpackage-lock.json(对于 Vue.js 应用),以及 requirements.txt(对于 Django 应用)。 这样做的好处是,只要这些文件未发生变化,Docker 就可以使用现有的缓存层来重新安装依赖项,而无需从头开始。这可以节省大量时间,因为依赖项安装通常是构建过程中最耗时的部分之一。

step3: settings.py

  • 因为我们需要用 django 来找到 vue 的静态资源(css, js, index.html)之后整合到一起发到前端,我们需要一个 templates 文件夹来存放 index.html,所以在 settings.py 中设置好
    # 模板设置
    TEMPLATES = [{# ...'DIRS': [os.path.join(BASE_DIR, 'templates')],# ...},
    ]
    

step4: 更新 django url.py 并在 views.py 中呈现 Vue 应用

  • 在 Django 的 urls.py 中添加一个路由来指向这个视图。

    from django.urls import path
    from . import viewsurlpatterns = [path('', views.index),# 其他路由...
    ]
    
  • 在 views.py 中增加如下内容:

    from django.shortcuts import renderdef index(request):return render(request, 'index.html')
    
  • 上述增添的项目表示,当有人访问服务器地址的时候,会得到基于 vue 来构建的静态页面 index.html,而 django 所做的处理将会嵌入在静态页面 index.html 中,这也就是为什么你访问部署后的项目能够看到前端页面。

  • 在 dockerfile 中我们也指定了 dist/index.html 会被复制到 django 的 static/index.html,而 render(request, 'index.html') 也正是通过访问预先定义 static 文件夹来找这个 index.html

step5: heroku container 部署整体项目

heroku container:push web -a <heroku application name>
heroku container:release web -a <heroku application name>

step6: debug – 让 django 能找到 vue 的静态资源

  • 按说完成上述的操作,前后端的相互协作应该已经没问题了,但是当我部署完成并打开 heroku 的 app 傻眼了,经过我的测试,后端正常运行了,但是前端的页面没有显示
    在这里插入图片描述

  • 这个问题我闹了好久,最后发现是 django 的 静态路径vue 默认的导出设置不匹配导致的

  • 这里我们再强调一下 settings.py 中的这部分内容

    STATIC_URL = '/static/'
    STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
    STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
    STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
    
  • 首先 django 项目的默认静态资源路径定义为 base_dir/staticfiles ,也就是,当你执行 python manage.py collectstatic 命令的时候, django 项目本身的哪些 css, js, index.html (注意,这不是 vue 的静态资源)会自动加载到 base_dir/staticfiles 里面,但由于我们用 vue 构造的前端,所以我们自然是需要 vue 自己 build 出来的静态资源而不是 django 自己的静态资源,因此我们需要区分这两部分静态资源。而我们通过 STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')] 定义了存放其他静态资源(这里可以是 vue 的静态资源)的文件夹

  • 我通过找问题,发现问题出在 vue 生成的 index.html

    <!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible"
    content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link
    rel="icon" href="/favicon.ico"><title>validation_front</title><script defer="defer"src="/js/chunk-vendors.0804f4a0.js"></script><script defer="defer" src="/js/app.893a5f38.js"></script><link href="/css/chunk-vendors.10dd4e95.css" rel="stylesheet"><link href="/css/app.a285b80a.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but validation_front doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
    
  • 可以看到这里面加载资源的 src 都是直接 /js/... 或者 /css/...

  • 如果我们在 docker 中部署好了之后,也就是说他会直接从 docker 的根路径 /app/... 去找是否有 jscss 文件夹,但是很显然他找不到,因为现在这些文件夹都在 /app/static 里面

  • 在 Django 项目中,静态文件通常通过 STATIC_URL 设置的路径来提供。默认情况下,STATIC_URL 被设置为 /static/。这意味着如果 Vue 应用构建生成的静态文件路径是 /css/somefile.css,实际上 Django 会期望它们位于 /static/css/somefile.css

  • 那么问题就来了,如何让这个矛盾解决呢?其实有几种方案

调整 Vue 构建配置

  • 修改 Vue 项目的构建配置,使其生成的静态资源路径与 Django 的 STATIC_URL 一致。这通常在 Vue 项目的 vue.config.js 文件中配置。例如,您可以添加一个公共路径前缀 /static/

    module.exports = {publicPath: process.env.NODE_ENV === 'production'? '/static/': '/'
    };
    
  • 这样,构建后的静态资源路径将与 Django 预期的路径一致。

  • 我最终的 vue.config.js 文件是:

    const { defineConfig } = require('@vue/cli-service')
    module.exports = defineConfig({transpileDependencies: true,publicPath: process.env.NODE_ENV === 'production' ? '/static/' : '/'
    })
  • 在这个配置中:

    • publicPath 被设置为 /static/ 当应用处于生产模式(process.env.NODE_ENV === 'production')
      对于开发模式,publicPath 保持为根路径 /,以便于本地开发时资源可以被正确加载。
      这样,当构建生产版本的 Vue 应用时(通常通过运行 npm run build),所有静态资源(CSS、JavaScript 等)将会在它们的 URL 前加上 /static/ 前缀。然后,当这些文件被部署到与 Django 集成的环境中时,这些路径将与 Django 预期的静态文件路径一致。

那怎么判断是生产模式还是本地模式呢?

  • 在大多数 JavaScript 和 Node.js 环境中,包括 Vue.js 项目,您可以通过检查 process.env.NODE_ENV 环境变量的值来判断当前是生产模式(production)还是开发模式(development)。这个环境变量通常在不同的构建命令或环境中被设置。
    • 开发模式:通常在运行本地开发服务器时(例如,当您使用 npm run servevue-cli-service serve),NODE_ENV 被设置为 "development"。这是默认的模式,用于本地开发和调试。
    • 生产模式:当您构建应用以准备部署到生产环境时(例如,使用 npm run buildvue-cli-service build),NODE_ENV 被设置为 "production"。在生产模式下,Vue 会启用各种优化,包括压缩、最小化和更有效的代码分割

在 Django 中处理静态文件引用

  • 使用 Django 的模板语言动态生成静态文件路径。可以在 index.html 中使用 Django 的 {% static %} 模板标签来正确引用静态文件。不过,这可能需要手动编辑 Vue 构建出的 index.html 文件, 很显然我们使用 dockerfile 来流程化构建,因此这种手动改的方式并不适用

相关文章:

日常学习之:vue + django + docker + heroku 对后端项目 / 前后端整体项目进行部署

文章目录 使用 docker 在 heroku 上单独部署 vue 前端使用 docker 在 heroku 上单独部署 django 后端创建 heroku 项目构建 Dockerfile设置 settings.pydatabase静态文件管理安全设置applicaiton & 中间件配置 设置 requirements.txtheroku container 部署应用 前后端分别部…...

LangGraph:一个基于LangChain构建的AI库,用于创建具有状态、多参与者的应用程序

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

04-Nacos-服务注册基于spring boot实现

官方参考 在不依赖spring cloud 组件基础上&#xff0c;单独的微服务项目&#xff0c;实现nacos接入 1、依赖文件pom.xml <dependency><groupId>com.alibaba.boot</groupId><artifactId>nacos-discovery-spring-boot-starter</artifactId><…...

iOS 闭包和Block的区别

iOS 闭包和Block的区别 原文地址: mob64ca12eb7baf 引言 在iOS开发中&#xff0c;闭包和Block是两个常用的概念。它们都是将一段代码作为变量传递和使用的方式。尽管它们在实现上有一些相似之处&#xff0c;但它们之间还是存在一些重要的区别。本文将会详细介绍闭包和Block的…...

后端学习笔记——后端细碎知识点(每天更新......)

细碎知识点 主要是go后端&#xff0c;也会设计到python、java的知识&#xff0c;懒得分类整理&#xff0c;所以都写在一篇文章里面了&#xff0c;方便自己查看笔记。 context.BindJSON获取POST请求中的json数据gin.H封装了生成json的方式 common.ReturnJSONSuccess(c, gin.H{&…...

二进制中1的个数

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…...

python+matlab text(按图的相对位置显示)

python 用 python 画图时&#xff0c;如果想采用归一化的坐标来指定文本框的位置&#xff0c;则需要用到 transform ax.transAxes 参数&#xff0c;如 ax plt.gca() plt.text(0.1,0.2, "text", fontsize 20, transform ax.transAxes)matlab 方法1 text(___,Name…...

rust 引用/mut 的所有权

在任意给定时间&#xff0c;要么 只能有一个可变引用&#xff0c;要么 只能有多个不可变引用。 不可变引用&#xff08;shared reference&#xff09;实现了Copy trait&#xff0c;不会发生所有权转移可变引用&#xff08;mutable reference&#xff09;未实现&#xff0c;会发…...

油烟净化器科技改革,清新用餐生活

我最近分析了餐饮市场的油烟净化器等产品报告&#xff0c;解决了餐饮业厨房油腻的难题&#xff0c;更加方便了在餐饮业和商业场所有需求的小伙伴们。 随着餐饮业蓬勃发展&#xff0c;人们对用餐环境的要求也与日俱增。本文将深入研讨餐饮油烟净化器技术的改革方向&#xff0c;…...

[足式机器人]Part3 机构运动学与动力学分析与建模 Ch01-1 刚体系统的运动学约束

本文仅供学习使用,总结很多本现有讲述运动学或动力学书籍后的总结,从矢量的角度进行分析,方法比较传统,但更易理解,并且现有的看似抽象方法,两者本质上并无不同。 2024年底本人学位论文发表后方可摘抄 若有帮助请引用 本文参考: 《空间机构的分析与综合(上册)》-张启先…...

51单片机智能小车

51单片机智能小车 delay.c #include "intrins.h"void Delay2000ms() //11.0592MHz {unsigned char i, j, k;i 15;j 2;k 235;do{do{while (--k);} while (--j);} while (--i); }void Delay10us() //11.0592MHz {unsigned char i;i 2;while (--i); }void Delay…...

9. 嵌入式系统开发:安全性与可靠性设计模式---引言

在复杂的嵌入式系统设计中&#xff0c;为了提高嵌入式系统安全性并保护嵌入式系统免受各种潜在故障的影响&#xff0c;可以采用不同的设计模式。这些模式各自有优势和适用的场景&#xff1a; 1. 受保护的单通道模式&#xff08;Protected Single Channel Pattern&#xff09; …...

内网安全:Exchange服务

目录 Exchange服务 实验环境 域横向移动-内网服务-Exchange探针 一. 端口扫描 二. SPN扫描 三. 脚本探针(还可以探针是否有安全漏洞) 域横向移动-内网服务-Exchange爆破 一 .BurpSuite Intruder模块爆破 域横向移动-内网服务-Exchange漏洞 CVE-2020-17144 Exchange R…...

Flask介绍和优势

Flask诞生于2010年&#xff0c;是由Armin Ronacher用Python语言编写的一款轻量级Web开发框架。自发布以来&#xff0c;Flask逐渐成为开发人员喜爱的选择&#xff0c;并在2021年5月发布了Flask 2.0版本&#xff0c;引入了一些新增特性&#xff0c;如基本的异步支持。 使用Flask…...

喜报|「云原生数据库PolarDB」、「阿里云瑶池一站式数据管理平台」揽获“2023技术卓越奖”

日前&#xff0c;国内知名IT垂直媒体&技术社区IT168公布2023年“技术卓越奖”评选结果&#xff0c;经由行业CIO/CTO大咖、技术专家及IT媒体三方的联合严格评审&#xff0c;阿里云瑶池数据库揽获两项大奖&#xff1a;云原生数据库PolarDB荣获“2023年度技术卓越奖”&#xf…...

【动态规划】【字符串】【行程码】1531. 压缩字符串

作者推荐 视频算法专题 本文涉及知识点 动态规划汇总 LeetCode 1531. 压缩字符串 II 行程长度编码 是一种常用的字符串压缩方法&#xff0c;它将连续的相同字符&#xff08;重复 2 次或更多次&#xff09;替换为字符和表示字符计数的数字&#xff08;行程长度&#xff09;…...

检测头篇 | 原创自研 | YOLOv8 更换 SEResNeXtBottleneck 头 | 附详细结构图

左图:ResNet 的一个模块。右图:复杂度大致相同的 ResNeXt 模块,基数(cardinality)为32。图中的一层表示为(输入通道数,滤波器大小,输出通道数)。 1. 思路 ResNeXt是微软研究院在2017年发表的成果。它的设计灵感来自于经典的ResNet模型,但ResNeXt有个特别之处:它采用…...

PHP语法

#本来是在学命令执行&#xff0c;所以学了学&#xff0c;后来发现&#xff0c;PHP语法和命令执行的关系好像没有那么大&#xff0c;不如直接学php的一些命令执行函数了。# #但是还是更一下&#xff0c;毕竟还是很多地方都要求掌握php作为脚本语言&#xff0c;所以就学了前面的…...

MySQL:三大日志(binlog、redolog、undolog)

再了解三个日志前我们先了解一下MySQL的两层架构&#xff1a; Server 层负责建立连接、分析和执行 SQL。MySQL 大多数的核心功能模块都在这实现&#xff0c;主要包括连接器&#xff0c;查询缓存、解析器、预处理器、优化器、执行器等。另外&#xff0c;所有的内置函数和所有跨…...

【QT+QGIS跨平台编译】之十二:【libpng+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文件目录 一、libpng介绍二、文件下载三、文件分析四、pro文件五、编译实践一、libpng介绍 PNG(Portable Network Graphics,便携式网络图形),是一种采用无损压缩算法的位图格式,支持索引、灰度、RGB三种颜色方案以及Alpha通道等特性。 PNG使用从LZ77派生的无损数据压缩算…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...