构建 dotnet&vue 应用镜像->推送到 Nexus 仓库->部署为 k8s 服务实践
前言
前面分享了 k8s 的部署安装,本篇来点实操,将会把一个 .net core + vue 的项目(zhontai),打包构建成 docker 镜像,推送到 nexus 镜像仓库,并部署到 k8s 中
准备
要实现项目的部署,除了准备要部署的环境(k8s),还需要准备项目所用到的各中间件,本文旨在分享部署的一个整体流程,对项目中所使用到的各中间件(mysql,redis 等)的安装使用可自行在本DevOps 系列文章中找到
一个 .net core+vue 的项目
- 使用 zhontai 项目,之前也有做分享,文章介绍
- 后端 Admin.Core v3.7.1
- 前端 admin.ui.plus v2.2.0
Nexus 的安装部署,文章介绍
- 做为镜像仓库使用,将项目打包镜像及项目镜像推送到仓库,k8s 也从此仓库拉取镜像
- 版本为 v3.61 ,安装地址为 192.168.0.214:8081,并使用局域网域名解析,
- 在目标机器先登录能够拉取推送镜像,参考
- 拉取镜像地址:https://nexus.devops.test.com
- 推送镜像地址:https://push.nexus.devops.test.com
Docker 的安装部署,文章介绍
- 使用 doker 拉取 sdk、nodejs 镜像进行打包,构建 k8s 所需要的项目镜像
- 版本:v24.0.6
K8S 的安装与部署,文章介绍
- 部署项目服务
- 使用 ingress 解析域名到服务
部署前后端项目到 K8S,本文介绍
使用 Docker 打包应用镜像
不管什么语言,基本都可以使用这个打包流程,将官方镜像打包推送到私有镜像仓库个人认为是必要的,不然如果一旦远端的镜像失效,又需要重新拉取镜像时就会很尬尴。
准备打包所需镜像
- 获取基础打包镜像(dotnet 获取 sdk 镜像,vue 获取 node 镜像)
- 基于基础镜像,安装所需软件,设置默认配置,复制默认文件,封装项目的打包镜像
- 挂载项目到 sdk 镜像进行打包,打包后获取构建完成的产物
准备运行所需的基础镜像
- 获取运行时镜像(.net core 获取 runtime 镜像,vue 获取 nginx 镜像)
- 基于运行时镜像,将打包构建完从的产物添加到镜像,构建项目镜像
- 推送项目镜像到仓库
.Net Core 7.0 项目镜像
构建所需一个 sdk 镜像用于打包编译项目,一个 runtime 镜像运行 .net core 项目,版本选择对应的 7.0 即可
- dotnet sdk 镜像地址:https://hub.docker.com/_/microsoft-dotnet-sdk/
- dotnet runtime 镜像地址: https://hub.docker.com/_/microsoft-dotnet-runtime/
构建 dotnet sdk 7.0 打包镜像
拉取 dotnet sdk 镜像:
docker pull mcr.microsoft.com/dotnet/sdk:7.0
- 目前可以直接拉取,若无法拉取则配置国内镜像源
- 临时运行容器进行测试:
docker run -it --rm mcr.microsoft.com/dotnet/sdk:7.0
,可以将需要的东西进行安装测试再编写 dockerfile
使用 Dockerfile 构建打包镜像 dotnet-sdk-7.0
- 为了便于后期维护,使用 Dockerfile 来构建
- 目录文件:dotnet-sdk-7.0/Dockerfile
- 基于 sdk 安装 dotnet-monitor v7.3.2, 文档 这里只做演示,暂时没用上,后续使用多阶段构建的时候可以将其复制到运行时镜像中
# 基础sdk镜像 v7.0
FROM mcr.microsoft.com/dotnet/sdk:7.0
# 将tools目录加入环境变量
ENV PATH="$PATH:/root/.dotnet/tools"
# 安装 dotnet-monitor
RUN dotnet tool install -g dotnet-monitor --version 7.3.2
- 执行构建:
docker build -t dotnet-sdk-7.0 -f ./Dockerfile .
推送镜像到 Nexus 仓库
- 镜像登录认证:
docker login push.nexus.devops.test.com -u pusher -p devops666
- 打标签:
docker tag dotnet-sdk-7.0 push.nexus.devops.test.com/projectbuild/dotnet-sdk-7.0
- 推送镜像:
docker push push.nexus.devops.test.com/projectbuild/dotnet-sdk-7.0
- 记得清理本地缓存镜像:
docker rmi dotnet-sdk-7.0 && docker rmi push.nexus.devops.test.com/projectbuild/dotnet-sdk-7.0
- 镜像登录认证:
使用镜像
- 后续使用 dotnet sdk 7.0 就可以直接使用
nexus.devops.test.com/projectbuild/dotnet-sdk-7.0
即可 - 直接拉取:
docker pull nexus.devops.test.com/projectbuild/dotnet-sdk-7.0
- 后续使用 dotnet sdk 7.0 就可以直接使用
构建 dotnet runtime 7.0 运行时镜像
拉取 dotnet runtime 镜像:
docker pull mcr.microsoft.com/dotnet/runtime:7.0
- 临时运行容器进行测试:
docker run -it --rm mcr.microsoft.com/dotnet/runtime:7.0
- 临时运行容器进行测试:
使用 Dockerfile 构建运行时镜像
- 为了便于后期维护,使用 Dockerfile 来构建
- 目录文件:dotnet-runtime-7.0/Dockerfile
- 若非需要,可以不安装软件,安装软件后镜像会多个 100M
# 基础runtime镜像 v7.0
FROM mcr.microsoft.com/dotnet/aspnet:7.0 # 写入阿里云镜像源
RUN echo " \
deb http://mirrors.aliyun.com/debian/ bullseye main contrib non-free\n \
deb-src http://mirrors.aliyun.com/debian/ bullseye main contrib non-free\n \
\n \
deb http://mirrors.aliyun.com/debian-security bullseye-security main contrib non-free\n \
deb-src http://mirrors.aliyun.com/debian-security bullseye-security main contrib non-free\n \
\n \
deb http://mirrors.aliyun.com/debian/ bullseye-updates main contrib non-free\n \
deb-src http://mirrors.aliyun.com/debian/ bullseye-updates main contrib non-free\n \
\n \
deb http://mirrors.aliyun.com/debian/ bullseye-backports main contrib non-free\n \
deb-src http://mirrors.aliyun.com/debian/ bullseye-backports main contrib non-free\n \
" | tee /etc/apt/sources.list # 安装 curl&&vim
RUN apt-get update -y && apt-get install -y curl && apt-get install -y vim
- 执行构建:
docker build -t dotnet-runtime-7.0 -f ./Dockerfile .
推送镜像到 Nexus 仓库
- 镜像登录认证:
docker login push.nexus.devops.test.com -u pusher -p devops666
- 打标签:
docker tag dotnet-runtime -7.0 push.nexus.devops.test.com/projectbuild/dotnet-runtime-7.0
- 推送镜像:
docker push push.nexus.devops.test.com/projectbuild/dotnet-runtime-7.0
- 记得清理本地缓存镜像:
docker rmi dotnet-runtime-7.0 && docker rmi push.nexus.devops.test.com/projectbuild/dotnet-runtime-7.0
- 镜像登录认证:
使用镜像
- 后续使用 dotnet runtime 7.0 就可以直接使用
nexus.devops.test.com/projectbuild/dotnet-runtime-7.0
即可 - 直接拉取:
docker pull nexus.devops.test.com/projectbuild/dotnet-runtime-7.0
- 后续使用 dotnet runtime 7.0 就可以直接使用
构建 zhontai 后端项目的应用镜像
制作完镜像,下面将使用 sdk 镜像打包项目生成部署文件,再使用 runtime 镜像部署运行。
下载/克隆项目 admin.core 到服务器,进入项目目录开始执行
# 克隆项目
git clone https://github.com/zhontai/Admin.Core.git -b v3.7.0
# 进入项目 cd Admin.Core
cd Admin.Core
- src 为.net core 项目代码
使用 sdk 镜像进行打包,生成部署文件到 publish_output
docker run -i --rm
创建一个临时容器,容器退出后自动删除容器-v ./build:/build
挂载 MSBuild 属性文件目录(./src/Directory.Build.props 中使用)-v ./src:/src
挂载源码到容器中-v ./publish_output:/publish_output
挂载构建物输出目录--name build_zhontai_api
指定运行的容器名称nexus.devops.test.com/projectbuild/dotnet-sdk-7.0
sdk 镜像/bin/bash -c "xxx"
以交互模式运行容器,运行时执行命令- 若有自定义 nuget 仓库的包还需挂载
/root/.nuget
目录,或直接制作在镜像中 - 记得挂载 build 目录,否则会提示:Invalid framework identifier
docker run -i --rm \
-v ./build:/build \
-v ./src:/src \
-v ./publish_output:/publish_output \
--name build_zhontai_api \
nexus.devops.test.com/projectbuild/dotnet-sdk-7.0 \
/bin/bash -c 'dotnet publish /src/hosts/ZhonTai.Host -c Release -o /publish_output --runtime linux-x64 --framework net7.0'
- 执行成功后程序包就生成到 publish_output 中了
使用 runtime 镜像制作应用镜像
- 将上一步的构建物 Admin.Core/publish_output 添加到运行时镜像中
- 使用 echo 创建一个 Dockerfile
#创建Dockerfile
echo 'FROM nexus.devops.test.com/projectbuild/dotnet-runtime-7.0 AS runtime
WORKDIR /app
COPY ./publish_output /app
ENV ASPNETCORE_URLS=http://+:8000
ENTRYPOINT ["dotnet", "ZhonTai.Host.dll"]' > Dockerfile
- 执行构建:
docker build -t zhontai_api .
- 运行测试,成功
推送镜像到仓库
#打标签
docker tag zhontai_api push.nexus.devops.test.com/projectapp/zhontai_api
#推送
docker push push.nexus.devops.test.com/projectapp/zhontai_api
- 推送成功,这里手动只构建的 latest 版本,若使用自动化构建,还需构建对应版本的镜像,以支持快速回滚
Vue 3 项目打包
构建所需一个 node 镜像用于 vue 项目打包,nginx 用于部署前台项目
- node 镜像地址:https://hub.docker.com/r/library/node ,选择版本:node:18.17.1
- nginx 镜像地址:https://hub.docker.com/_/nginx ,选择版本:nginx:1.24.0
构建 nodejs 18.17.1 打包镜像
拉取 nodejs 镜像:
docker pull node:18.17.1
将 node 镜像 vue-node-18 打上标签推送到仓库
#拉取仓库
docker pull node:18.17.1
# 打标签
docker tag node:18.17.1 push.nexus.devops.test.com/projectbuild/vue-node-18.17
#推送
docker push push.nexus.devops.test.com/projectbuild/vue-node-18.17
- 测试使用:
docker run -it --rm nexus.devops.test.com/projectbuild/vue-node-18.17 /bin/bash -c "node -v"
构建 nginx 1.24 运行时镜像
拉取 nginx 镜像:
docker pull nginx:1.24
将 nginx 镜像 vue-nginx-1.24 打上标签推送到仓库
#拉取仓库
docker pull nginx:1.24
# 打标签
docker tag nginx:1.24 push.nexus.devops.test.com/projectbuild/vue-nginx-1.24
#推送
docker push push.nexus.devops.test.com/projectbuild/vue-nginx-1.24
- 测试使用:
docker run -it --rm nexus.devops.test.com/projectbuild/vue-nginx-1.24 /bin/bash
进入容器后启用 nginx,并使用 curl http://localhost 测试 nginx 可用
构建 zhontai 前端项目的应用镜像
下载/克隆项目 admin.ui.plus 到文件夹
# 克隆项目
git clone https://github.com/zhontai/admin.ui.plus.git -b v2.2.0
# 进入项目cd admin.ui.plus
cd admin.ui.plus # 修改接口地址
# 编辑.env.production 中的 VITE_API_URL 配置为接口地址
使用 node 镜像进行打包,生成文件到 dist
docker run -i --rm \
-v ./:/app \
--name build_zhontai_webui \
nexus.devops.test.com/projectbuild/vue-node-18.17 \
/bin/bash -c 'cd /app
npm config set registry https://registry.npmmirror.com
npm install
npm run build'
- 执行成功,构建输出到 dist 中
使用 nginx 镜像制作应用镜像
# 创建nginx.conf echo '
server {
listen 80;
server_name localhost;
charset utf-8;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
index index.html index.htm;
} #error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
'> vue-nginx.conf
#创建Dockerfile
echo '
FROM nexus.devops.test.com/projectbuild/vue-nginx-1.24
EXPOSE 80
COPY ./dist /usr/share/nginx/html
COPY ./vue-nginx.conf /etc/nginx/conf.d/default.conf' > Dockerfile
- 执行构建:
docker build -t zhontai_webui .
- 测试访问成功
推送镜像到仓库
#打标签
docker tag zhontai_webui push.nexus.devops.test.com/projectapp/zhontai_webui
#推送
docker push push.nexus.devops.test.com/projectapp/zhontai_webui
将 Docker 应用镜像部署到 K8S
应用镜像打包成功,现在需要将两个应用精选镜像部署到 k8s 中
应用镜像的拉取凭证设置
因为 nexus 部署在局域网,并且配置的域名是局域网域名,所以面临着如何在 k8s 中访问 https://nexus.devops.test.com 获取镜像的问题,目前我的解决方法时每个节点机器都配置好对应 dns
要想访问到 nexus 仓库,需要满足两个条件,一个是访问到仓库,一个是仓库的认证
给 k8s 所有节点添加 dns 设置
nameserver 192.168.123.214
- 使用
docker login nexus.devops.test.com -u puller -p devops666
在宿主机中登录仓库确保可以在节点拉取镜像
创建 nexus 登录凭证
kubectl create secret \
docker-registry \
nexus-login-registry \
--docker-server=nexus.devops.test.com \
--docker-username=puller \
--docker-password=devops666 \
-n default
使用 Deployment 部署应用
配置仅供参考,关于数据库,配置文件,日志,上传文件等未处理
创建后端部署配置:zhontai_api.yaml
---
## 配置服务
kind: Service
apiVersion: v1
metadata:
name: app-zhontai-api
namespace: default
labels:
app: app-zhontai-api
spec:
selector:
app: app-zhontai-api
type: ClusterIP
ports:
- name: p80
port: 80
targetPort: 8000
--- kind: Deployment # 指定创建资源的角色/类型
apiVersion: apps/v1 # 指定api版本,此值必须在kubectl api-versions中
metadata: # 资源的元数据/属性
name: app-zhontai-api # 资源的名字,在同一个namespace中必须唯一
namespace: default # 部署在哪个namespace中
labels: # 设定资源的标签
app: app-zhontai-api
spec: # 资源规范字段
selector:
matchLabels:
app: app-zhontai-api
replicas: 2 # 声明副本数目
revisionHistoryLimit: 2 # 保留历史版本
strategy: # 策略
rollingUpdate: # 滚动更新
maxSurge: 1 # 最大额外可以存在的副本数,可以为百分比,也可以为整数
maxUnavailable: 1 # 示在更新过程中能够进入不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
type: RollingUpdate # 滚动更新策略
template: # 模版
metadata: # 资源的元数据/属性
labels: # 设定资源的标签
app: app-zhontai-api
spec: # 资源规范字段
containers:
- image: nexus.devops.test.com/projectapp/zhontai_api:latest # 容器使用的镜像地址
name: app-zhontai-api # 容器的名字
# 每次Pod启动拉取镜像策略,三个选择 Always、Never、IfNotPresent
# Always,每次都检查;Never,每次都不检查(不管本地是否有);IfNotPresent,如果本地有就不检查,如果没有就拉取
imagePullPolicy: Always
resources: # 资源管理
# limits: # 最大使用
# cpu: 300m # CPU,1核心 = 1000m
# memory: 500Mi # 内存,1G = 1024Mi
# requests: # 容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行
# cpu: 100m
# memory: 100Mi
livenessProbe: # pod 内部健康检查的设置
httpGet: # 通过httpget检查健康,返回200-399之间,则认为容器正常
path: /admin/health # URI地址
port: 8000 # 端口
scheme: HTTP # 协议
initialDelaySeconds: 10 # 表明第一次检测在容器启动后多长时间后开始
timeoutSeconds: 5 # 检测的超时时间
periodSeconds: 30 # 检查间隔时间
successThreshold: 1 # 成功门槛
failureThreshold: 5 # 失败门槛,连接失败5次,pod杀掉,重启一个新的pod
ports:
- name: http # 名称
containerPort: 80 # 容器开发对外的端口
protocol: TCP # 协议
env:
# 时区
- name: TZ
value: Asia/Shanghai
# app name
- name: APP_NAME
value: app.zhontai.api
# 挂载
volumeMounts:
- name: app-logs
mountPath: /logs #容器中的路径
# 卷轴
volumes:
- name: app-logs
hostPath:
path: /app/logs #将日志存放在宿主机的路径,需要在宿主机创建目录
type: Directory
#重启策略
restartPolicy: Always
imagePullSecrets: # 镜像仓库拉取密钥
- name: nexus-login-registry
执行部署:
kubectl apply -f zhontai_api.yaml
创建前端部署配置:zhontai_webui.yaml
---
## 配置服务
kind: Service
apiVersion: v1
metadata:
name: app-zhontai-webui
namespace: default
labels:
app: app-zhontai-webui
spec:
selector:
app: app-zhontai-webui
type: ClusterIP
ports:
- name: p80
port: 80
targetPort: 80
--- kind: Deployment # 指定创建资源的角色/类型
apiVersion: apps/v1 # 指定api版本,此值必须在kubectl api-versions中
metadata: # 资源的元数据/属性
name: app-zhontai-webui # 资源的名字,在同一个namespace中必须唯一
namespace: default # 部署在哪个namespace中
labels: # 设定资源的标签
app: app-zhontai-webui
spec: # 资源规范字段
selector:
matchLabels:
app: app-zhontai-webui
replicas: 2 # 声明副本数目
revisionHistoryLimit: 2 # 保留历史版本
strategy: # 策略
rollingUpdate: # 滚动更新
maxSurge: 1 # 最大额外可以存在的副本数,可以为百分比,也可以为整数
maxUnavailable: 1 # 示在更新过程中能够进入不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
type: RollingUpdate # 滚动更新策略
template: # 模版
metadata: # 资源的元数据/属性
labels: # 设定资源的标签
app: app-zhontai-webui
spec: # 资源规范字段
containers:
- image: nexus.devops.test.com/projectapp/zhontai_webui:latest # 容器使用的镜像地址
name: app-zhontai-webui # 容器的名字
# 每次Pod启动拉取镜像策略,三个选择 Always、Never、IfNotPresent
# Always,每次都检查;Never,每次都不检查(不管本地是否有);IfNotPresent,如果本地有就不检查,如果没有就拉取
imagePullPolicy: Always
resources: # 资源管理
# limits: # 最大使用
# cpu: 300m # CPU,1核心 = 1000m
# memory: 500Mi # 内存,1G = 1024Mi
# requests: # 容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行
# cpu: 100m
# memory: 100Mi
livenessProbe: # pod 内部健康检查的设置
httpGet: # 通过httpget检查健康,返回200-399之间,则认为容器正常
path: / # URI地址
port: 80 # 端口
scheme: HTTP # 协议
initialDelaySeconds: 10 # 表明第一次检测在容器启动后多长时间后开始
timeoutSeconds: 5 # 检测的超时时间
periodSeconds: 30 # 检查间隔时间
successThreshold: 1 # 成功门槛
failureThreshold: 5 # 失败门槛,连接失败5次,pod杀掉,重启一个新的pod
ports:
- name: http # 名称
containerPort: 80 # 容器开发对外的端口
protocol: TCP # 协议
env:
# 时区
- name: TZ
value: Asia/Shanghai
# app name
- name: APP_NAME
value: app.zhontai.webui
#重启策略
restartPolicy: Always
imagePullSecrets: # 镜像仓库拉取密钥
- name: nexus-login-registry
执行部署:
kubectl apply -f zhontai_webui.yaml
配置 Ingress 使用域名访问
- 部署成功后添加对应 ingress 配置,即可使用域名访问
前端项目需要修改为对应的接口地址
确保绑定的域名正常解析到 k8s 节点,即可使用域名访问了,我这里使用的 DnsServer 泛解析,故可以直接访问,
至此,一步步将一个单体项目部署到了 k8s 中,仅供参考,实际如果时微服务,还设计到一些通用和环境的配置,后面再慢慢分享。
根据上面的步骤,后面分享将其整理成脚本,以便后续可以直接使用。
相关文档
相关文章
参考文章
后语
本文始于2023末,结束于2024始。
2023的最后两个月,是这几年以来,学习,产出最高的的两个月。
始于国庆,不止步于元旦。
新年快乐!
构建 dotnet&vue 应用镜像->推送到 Nexus 仓库->部署为 k8s 服务实践的更多相关文章
- Jenkins打Docker镜像推送到私有仓库
Jenkins打Docker镜像推送到私有仓库 因为我的Jenkins是安装在群晖NAS中的docker,所以我这边就以Docker安装Jenkins为例 echo '================ ...
- docker远程仓库镜像推送到本地仓库
#!/bin/bashimageid=(`docker images |grep -v REPOSITORY|awk '{print $3}'`)image=(`docker images |grep ...
- docker将镜像推送到阿里云
1.背景 在实际生产中我们会经常把镜像推送到云端仓库......... 下面看具体操作 第一步:登录阿里云创建仓库 第二步:在docker上登录阿里云仓库 第三步:推送镜像到阿里云 第四步:在公网上查 ...
- 使用Jenkins自带功能(不用shell)构建Docker镜像并推送到远程仓库
意义: 一开始实现这个目的是在Jenkins中使用的shell脚本,也就是如下的这个: bash # 进入到生成jar包的根目录 cd ${WORKSPACE}/${module_filename} ...
- Docker镜像推送(push)到Docker Hub
镜像构建成功后,只要有docker环境就可以使用,但必须将镜像推送到Docker Hub上去.我们之前创建的镜像不符合Docker Hub的tag要求,因为 在Docker Hub注册的用户名是boo ...
- ABP vNext微服务架构详细教程——镜像推送
1. Jenkins搭建 为实现容器化部署,我们需要将代码打包成镜像并推送至容器仓库,我们可以选择自建容器仓库或者使用公有云服务商提供的镜像仓库.这里我们使用阿里云提供的免费镜像仓库. 代码打包和镜像 ...
- docker 创建镜像,并推送到私有仓库
创建镜像 创建 Dockerfile 镜像命名规则:registyr_url / namespace / depart / name : version 用这个规则创建的镜像,可直接推送到私有仓库 ...
- centos7,jdk8,tomcat8镜像推送到腾讯云
目录 centos7 jdk tomcat centos7 创建一个mycentos7的文件 vim mycentos7 FROM centos:7 MAINTAINER qyp_mail@sohu. ...
- 两种github action 打包.Net Core 项目docker镜像推送到阿里云镜像仓库
两种github action 打包.Net Core 项目docker镜像推送到阿里云镜像仓库 1.GitHub Actions 是什么? 大家知道,持续集成由很多操作组成,比如抓取代码.运行测试. ...
- 怎么把宿主机上的镜像推送到hub上
怎么把宿主机上的镜像推送到hub上: 1.查看系统中存在的镜像: [root@izuf63bjp8ts8nkl13pxh1z devicemapper]# docker imagesREPOSITOR ...
随机推荐
- 关于Unity 如何与Blazor Server结合
关于Unity 如何与Blazor Server结合 一.介绍 最近工作中有`Unity`与`Blazor Server`结合的需求,在网上找了一圈,发现这方面的资料比较少,特此写下这篇记录一下自己的 ...
- 记一次 .NET 某餐饮小程序 内存暴涨分析
一:背景 1. 讲故事 前些天有位朋友找到我,说他的程序内存异常高,用 vs诊断工具 加载时间又太久,让我帮忙看一下到底咋回事,截图如下: 确实,如果dump文件超过 10G 之后,市面上那些可视化工 ...
- 文心一言 VS 讯飞星火 VS chatgpt (103)-- 算法导论10.1 1题
一.用go语言,仿照图 10-1,画图表示依次执行操作 PUSH(S,4).PUSH(S,1).PUSH(S,3).POP(S).PUSH(S,8)和 POP(S)每一步的结果,栈 S初始为空,存储于 ...
- 搞懂fflush(stdout)
使用 printf 或 cout 打印内容时,输出永远不会直接写入"屏幕".而是,被发送到 stdout. (stdout 就像一个缓冲区) 默认情况下,发送到 stdout 的输 ...
- Django-rest-framework框架——请求与响应、视图组件
目录 一 请求与响应 1.1 Request 1.1.1.1 常用属性 1).data 2).query_params 1.2 Response 1.1.2.1 构造方式 1.1.2.2 常用属性 1 ...
- 【原型链污染】Python与Js
[原型链污染]Python与Js 一.背景 最近在TSCTF的比赛题中遇到了Python的原型链污染题目,所以借此机会学习一下.说到原型链,最多的还是在Js中,所以就一并学习一下.(因为是菜鸡所以文章 ...
- 带着问题去分析:Spring Bean 生命周期
1: Bean在Spring容器中是如何存储和定义的 Bean在Spring中的定义是_org.springframework.beans.factory.config.BeanDefinition_ ...
- HarmonyOS原生分析能力,即开即用助力精细化运营
数据分析产品对开发者的价值呈现在两个层面,第一个是产品的层面,可以通过数据去洞察用户的行为,从而找到产品的优化点.另外一个就是运营层面,可以基于数据去驱动,来实现私域和公域的精细化运营. 在鸿蒙生态上 ...
- Python 轻松生成PDF文档
PDF(Portable Document Format)是一种常用的文档格式,具有跨平台兼容性.保真性.安全性和交互性等特点.我们日常生活工作中的合同.报告.论文等通常都采用PDF格式,以确保文档在 ...
- Net 高级调试之五:如何在托管函数上设置断点
一.简介 今天是<Net 高级调试>的第五篇文章.今天这篇文章开始介绍如何在托管方法和非托管方法设置断点,我们要想调试程序,必须掌握调试的一些命令,动态调试的命令,我们在上一篇文章已经讲过 ...