koa+docker部署笔记及技术问题总结

news/2024/7/5 5:49:12

部署 koa 服务


一、应用介绍

1. 基础构成

centerOS+docker+koa+vue

2. 实施步骤:

  1. 安装 docker
  2. 安装配置 node 镜像
  3. 构建镜像
  4. 运行项目
  5. 测试部署是否成功

二、实施

1.安装配置 docker

  1. 介绍

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。

Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

  • Docker 是世界领先的软件容器平台。
  • Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核 的cgroup,namespace,以及 AUFS 类的 UnionFS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。 由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。Docker 最初实现是基于 LXC。
  • Docker 能够自动执行重复性任务,例如搭建和配置开发环境,从而解放了开发人员以便他们专注在真正重要的事情上,构建杰出的软件。
  • 用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

解决的问题:“明明在我这台机器上都可以运行,为什么跑你那去就出错了?”
方法:打包我们的应用以及依赖到 Docker 容器中,从而避免了环境不一致
最终目的:为了线下线上环境一致,更方便的部署

Docker 带来了什么(优点)

  • 环境隔离(‘隔离,安全’):Docker 实现了资源隔离,一台机器运行多个容器互无影响。
  • 更高效的资源利用(节约成本):Docker 容器的运行不需要额外的虚拟化管理程序的支持,它是内核级的虚拟化,可以实现更高的性能,同时对资源的额外需求很低。
  • 更快速的交付部署(敏捷):使用 Docker,开发人员可以利用镜像快速构建一套标准的研发环境,开发完成后,测试和运维人员可以直接通过使用相同的环境来部署代码。
  • 更易迁移扩展(可移植性):Docker 容器几乎可以在任意的平台上运行,包括虚拟机、公有云、私有云、个人电脑、服务器等,这种兼容性让用户可以在不同平台之间轻松的迁移应用。
  • 更简单的更新管理(高效):使用 Dockerfile,只需要很少的配置修改,就可以替代以往大量的更新工作。并且所有修改都是以增量的方式进行分发和更新,从而实现自动化和高效的容器管理。
  1. 概念
    镜像(Image):Docker 镜像(Image),就相当于是⼀个 root ⽂件系统。⽐如官⽅镜像 ubuntu:16.04 就包含了完整的⼀套
    Ubuntu16.04 最⼩系统的 root ⽂件系统。
    容器(Container):镜像(Image)和容器(Container)的关系,就像是⾯向对象程序设计中的类和实例⼀样,镜像是静态的定义,
    容器是镜像运⾏时的实体。容器可以被创建、启动、停⽌、删除、暂停等。
    仓库(Repository):仓库可看着⼀个代码控制中⼼,⽤来保存镜像

  2. 官方 centOS 安装docker教程

或者:

curl -fsSL https://get.docker.com -o get-docker.sh
DRY_RUN=1 sh ./get-docker.sh

  1. 设置镜像源第一

yum-config-manager --add-repo http://mirrors.aliyun.com/cloer-re/linux/centos/docker-re.repo

  1. 设置镜像源第二

mkdir -p /etc/docker

编辑/etc/docker/daemon.json文件,并输入国内镜像源地址

vi /etc/docker/daemon.json

Docker中国官方镜像加速

{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}
  • 附录:国内镜像 *
  • Docker中国官方镜像加速

–registry-mirror=https://registry.docker-cn.com

  • 网易163镜像加速

–registry-mirror=http://hub-mirror.c.163.com

  • 中科大镜像加速

–registry-mirror=https://docker.mirrors.ustc.edu.cn

  • 阿里云镜像加速

–registry-mirror=https://{your_id}.mirror.aliyuncs.com

  • daocloud镜像加速

–registry-mirror=http://{your_id}.m.daocloud.io

也可以直接下载站点镜像:

docker pull hub.c.163.com/library/tomcat:latest # 复制站点链接用 pull 下来
阿里云跟daocloud镜像加速需要注册账号

2. docker 镜像使用

拉取 node

docker pull node # lasted 版本

查看 node 镜像

docker images

创建 Dockerfile 文件

切换到项目根目录下
创建Dockerfile文件

npm 设置

# syntax=docker/dockerfile:1
# 第一行是语法分析器指令,指定docker解析文件时用什么语法,会在开始构建之前升级解析器兼容旧版本。
# 指向版本1语法的最新版本。BuildKit 会在生成之前自动检查语法的更新,确保使用的是最新版本。
# 继承容器,可以继承多个
FROM node
# 指定制作我们的镜像的联系人信息(镜像创建者)
MAINTAINER HJJ
# 创建容器内的项目存放目录
RUN mkdir -p /home/koa-serve
# 先拷贝依赖文件安装依赖,这样可以提高效率
COPY ['package.json', './']
# cd到koa-serve文件夹下
WORKDIR /home/koa-serve
# 安装项目依赖包
# 公司内网taobao被墙,官网反而ok,这个得注意
RUN npm set registry http://registry.npm.taobao.org/ \
# 查看请求的进度
&& npm config set loglevel=http \
&& npm install pm2 -g \
# 等于--production,现在推荐使用这个--omit=dev参数设置
&& npm install --omit=dev
# 将根目录下的文件都copy到container(运行此镜像的容器)文件系统的koa-serve文件夹下
ADD . /home/koa-serve/
# 配置环境变量
ENV HOST 0.0.0.0
ENV PORT 10000
# 容器对外暴露的端口号
EXPOSE 80
# 容器启动时执行的命令,类似npm run start
CMD ["npm", "run", "serve-dev"]

yarn 设置

# syntax=docker/dockerfile:1
 FROM node
 # 指定制作我们的镜像的联系人信息(镜像创建者)
 MAINTAINER HJJ
 # 创建容器内的项目存放目录
 RUN mkdir -p /home/koa-serve
  # 先拷贝依赖文件安装依赖,这样可以提高效率
 COPY ['package.json', './']
 # cd到koa-serve文件夹下
 WORKDIR /home/koa-serve
 # 将根目录下的文件都copy到container(运行此镜像的容器)文件系统的koa-serve文件夹下
 ADD . /home/koa-serve/
 # 安装项目依赖包
 RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories     \
	&& apk update     \
        && apk add yarn    \
	&& yarn config set registry https://registry.npm.taobao.org/        \
        && yarn add pm2 -g \
	&& yarn            \
        # 这一窜命令,设置镜像源到国内(加速),更新,安装yarn,yarn设置国内镜像源,yarn安装node依赖
 # 配置环境变量
 ENV HOST 0.0.0.0
 ENV PORT 10000
 # 容器对外暴露的端口号
 EXPOSE 80
 # 容器启动时执行的命令,类似npm run start
 CMD ["yarn", "serve-dev"]

node-demo例子

# syntax=docker/dockerfile:1
FROM node
RUN apk add --no-cache python2 g++ make
WORKDIR /app
COPY . .
RUN yarn install --omit=dev
CMD ["node", "src/index.js"]
EXPOSE 3000

创建 .dockerignore 文件

切换到项目根目录下
创建.dockerignore文件

.DS_Store
npm-debug.log*
log
node_modules
/package-lock.json
/yarn-lock.json
*.tar
*.md

# Editor directories and files
.vscode
.history

上传项目到服务器/git 拉取 gitlab 仓库项目

本地使用7-zip压缩项目为tar类型,或者直接是zip文件

yum -y install lrzsz # 安装

#上传文件到服务器
rz -bye

#服务端解压tar
tar -xvf xxx.tar

#服务端解压zip
unzip -xvf xxx.zip

#删除压缩包
rm -rf ****.tar
rm -rf ****.zip

根目录下构建镜像

docker build -t koa-serve .

检查构建是否成功

查看是否有该 image

docker ps -a

查看该容器是否在运行

docker ps

注意查看其中的STATUS状态是否为Up,端口号是否正确。

运行容器

docker run -dp 80:10000 --name “koa-container” koa-serve # 顺便不对会导致容器没有启动失败
-d 表示容器会在后台运行
–name 是我们给容器起的名字,这个名字是唯一的
-p 表示端口映射,80:10000前面为主机端口,后面是容器端口

如果端口有问题,停掉应用,然后不给容器起名称(名称随机),即执行下面的命令来操作。

docker run --rm --net=host -v /data/logs/koa-serve/test1:/home/koa-serve/log -e “PORT=8003” --name “koa-serve-1” -dp 20020:8003 koa-serve

测试

curl -i localhost:端口号

返回index.html页面的信息即成功

设置开机自启动

docker run --restart=always

如果已经启动了则可以使用如下命令:

docker update --restart=always <容器ID>

导出容器为镜像

docker commit my_container my_image # 提交容器为镜像
docker images #查看是否成功
docker save my_image:my_tag | gzip > my_image.tar.gz # 导出镜像并压缩成gz文件

部署

docker load < my_image.tar.gz # 导入镜像包
docker run -it --restart=always --name jdh-node-serve -dp 20001:4000 jdh-node-serve:v1.0.0.ns1 # 启动容器

发布镜像

登录docker hub,并注册

docker login

docker tag 标签名 用户名/标签名

docker tag docker_demo robin365/docker_demo

docker push 用户名/标签名

docker push robin365/docker_demo

上传成功则可以使用docker pull命令下载下来

多个容器管理

使用 docker-compose
配置 docker-compose.yml

version: "3"
services:
        web:
                image: node:12-alpine
                working_dir: /code
                volumes:
                        - .:/code
                ports:
                        - "3000:3000"
                command: npm start
        mysql:
                image: mysql:5.6
                volumes:
                        - ./data:/var/lib/mysql
                environment:
                        - MYSQL_ROOT_PASSWORD=123456
                        - MYSQL_DATABASE=koa_docker
                ports:
                        - "3306:3306"
        nginx:
                image: nginx:1.17
                volumes:
                        - ./static:/code/static
                        - ./conf/default.conf:/etc/nginx/conf.d/default.conf
                ports:
                        - "80:80"

一次启动多个服务

docker-compose up

附录2:docker 常用命令

#查看当前docker版本
docker -v
#查看当前本地所有镜像
docker images
#构造镜像,用法docker build -t 镜像名称 .
docker build -t docker_demo .
#用于容器与主机之间的数据拷贝。用法docker cp 主机文件地址 容器内地址。12d7f14v45cv为容器id。
docker cp /www/runoob 12d7f14v45cv:/www/
#创建一个新的容器并运行,-d为后台执行,-p 9000:3000前面为主机端口,后面是容器端口。docker_demo镜像名
docker run -dp 9000:3000 docker_demo
#启动已被停止的容器
docker start docker_demo
#关闭已被启动的容器
docker stop docker_demo
#重新启动容器
docker restart docker_demo
#杀掉一个运行中的容器。
docker kill -s KILL docker_demo
#删除一个或多少容器。-f :通过SIGKILL信号强制删除一个运行中的容器-l :移除容器间的网络连接,而非容器本身-v :-v 删除与容器关联的卷
docker rm -f docker_demo、docker_demo1
#在运行的容器中执行命令。104e28f2f072容器id
sudo docker exec -it 104e28f2f072 /bin/bash
#列出容器。 -a:所有容器包含没有运行的
docker ps
#获取容器获取容器的日志 104e28f2f072容器id,-t:显示时间戳
docker logs -f -t 104e28f2f072
#登陆镜像仓库
docker login
#获取镜像
docker pull
#上传镜像
docker push
#查看指定镜像的创建历史。
docker history docker_demo
#重启服务
systemctl restart docker
#查看资源状态
docker stats

#镜像常用命令
docker pull [镜像名称:版本] 拉取镜像
docker images  镜像列表
docker rmi [镜像名称:版本] 删除镜像
docker history [镜像名称] 镜像操作记录
docker tag [镜像名称:版本][新镜像名称:新版本]
docker inspect [镜像名称:版本] 查看镜像详细
docker search [关键字] 搜索镜像
docker login 镜像登陆

#容器常用命令
docker ps -a 容器列表(所有容器)
docker ps  查看所有(运行的)容器
docker exec -ti <id> bashbash 命令进入容器内
docker run -ti --name [容器名称][镜像名称:版本] bash 启动容器并进入
docker logs 查看容器日志
docker top <container_id> 查看容器最近的一个进程
docker run -ti --name [容器名称] -p 8080:80 [镜像名称:版本] bash  端口映射
docker rm <container_id> 删除容器
docker stop <container_id> 停止容器
docker start <container_id> 开启容器
docker restart <container_id> 重启容器
docker inspect <container_id> 查看容器详情
docker commit [容器名称] my_image:v1.0  容器提交为新的镜像

Docker 清理命令

# 杀死所有正在运行的容器
docker kill $(docker ps -a -q)

# 删除所有已经停止的容器
docker rm $(docker ps -a -q)

# 删除所有未打 dangling 标签的镜像
docker rmi $(docker images -q -f dangling=true)

# 通过镜像的id来删除指定镜像
docker rmi <image id>

# 删除所有镜像
docker rmi $(docker images -q)

为这些命令创建别名
# ~/.bash_aliases

# 杀死所有正在运行的容器.
alias dockerkill='docker kill $(docker ps -a -q)'

# 删除所有已经停止的容器.
alias dockercleanc='docker rm $(docker ps -a -q)'

# 删除所有未打标签的镜像.
alias dockercleani='docker rmi $(docker images -q -f dangling=true)'

# 删除所有已经停止的容器和未打标签的镜像.
alias dockerclean='dockercleanc || true && dockercleani'

# 清理命令
docker system prune
docker volume prune
docker network prune
docker container prune
docker image prune

# 容器瘦身

ID=$(docker run -d image-name /bin/bash)docker export $ID | docker import – flat-image-name

docker命令解释

docker run -ti

# -t 让docker分配一个伪终端并绑定到容器的标准输入上
# -i 则让容器的标准输入保持打开.
# Docker中系统镜像的缺省命令是 bash,如果不加 -ti bash 命令执行了自动会退出。这是因为如果没有衔接输入流,本身就会马上结束。加-ti 后docker命令会为容器分配一个伪终端,并接管其stdin/stdout支持交互操作,这时候bash命令不会自动退出

docker run -rm
# -rm 容器将在退出时自动删除
docker run -d -p
# -d 后台运行
# -p 端口映射 外部:内部

# 导入镜像包
docker load -i xxx.tar
docker load < my_image.tar.gz
# 导出镜像包
docker export -i xxx.tar

# 保存镜像
docker save my_image:my_tag | gzip > my_image.tar.gz

# 导入 / 导出容器
# 从文件中导入容器镜像:

cat my_container.tar.gz | docker import - my_image:my_tag
# 导出既有容器:

docker export my_container | gzip > my_container.tar.gz

# 暴露端口(Exposing ports)
# 通过宿主容器暴露输入端口相当 繁琐但有效的。

# 例如使用 -p 将容器端口映射到宿主端口上(只使用本地主机 (localhost) 接口):

docker run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT --name CONTAINER -t someimage

# 在 Dockerfile 中定义用户并以该用户运行,避免在容器中以 ROOT 身份操作:

RUN groupadd -r user && useradd -r -g user userUSER user

# 参考:https://baijiahao.baidu.com/s?id=1720802321830094075&wfr=spider&for=pc

# 将容器保存为镜像
docker commit my_container my_image
docker images #查看是否成功
docker save my_image:my_tag | gzip > my_image.tar.gz

nvidia-docker run --rm --net=host -v /data/logs/ocr/idcard:/recognize_document/log -d 镜像名:gpu -p 10051 -I -G 0 -L 127.0.0.1
nvidia-docker run --rm --net=host -v /data/logs/ocr/idcard:/recognize_document/log -d recognize_id_card_9264:gpu -p 10051 -I -G 0 -L 127.0.0.1

# 文件映射
# -v /data/logs/ocr/idcard:/recognize_document/log

#-e的作用是指定容器内的环境变量。

# 其他
--net=host
-I
-G 0
-L

附录3:linux命令

1. 上传文件命令

yum -y install lrzsz # 安装
rz -bye # 使用,弹窗选择文件
-+, --append:将文件内容追加到已存在的同名文件
-a,--ascii:以文本方式传输
-b, --binary:以二进制方式传输,推荐使用
--delay-startup N:等待N秒
-e, --escape:对所有控制字符转义,建议使用
-E, --rename:已存在同名文件则重命名新上传的文件,以点和数字作为后缀
-p, --protect:对ZMODEM协议有效,如果目标文件已存在则跳过
-q, --quiet:安静执行,不输出提示信息
-v, --verbose:输出传输过程中的提示信息
-y, --overwrite:存在同名文件则替换
-X, --xmodem:使用XMODEM协议
--ymodem:使用YMODEM协议
-Z, --zmodem:使用ZMODEM协议
--version:显示版本信息
--h, --help:显示帮助信息

2.下载多个文件

sz file1 file2 file3

解压zip

unzip xxx.zip

解压tar

tar -vxf xxx.tar

建立软连接

ln -s /usr/local/lib/node_modules/bin/xx /usr/local/bin/xx

一般QA

  1. Job for docker.service failed because the control process exited with error
    配置镜像试试

  2. 端口问题
    docker port 容器id,找不到映射

docker run -itd -v /root/docker/store/mongo/data:/data/db -p 27017:27017 -e MONGO_INITDB_ROOT_USERNAME="root" -e MONGO_INITDB_ROOT_PASSWORD="ken123456" --name mongo5 mongo:5.0.5

 -e MONGO_INITDB_ROOT_USERNAME="root" -e MONGO_INITDB_ROOT_PASSWORD="roothjj"
docker run -itd -p 27017:27017 --name mongo5 mongo:5.0.5
  1. curl: (7) Failed connect to localhost:8000; 拒绝连接
    端口映射设置有问题,查看index.jsDockerfile,运行的命令比如:

docker run -dp 4000:8000 koa-demo # 端口1是外部访问的:端口2内部应用启动的

  1. npm中间错误问题
    在安装puppeteer过程中遇到一些错误,记录一下
    首先可能遇到node install.js错误,可以使用一下命令参数安装puppeteer
    npm i --save puppeteer --ignore-scripts
    或者先执行一下命令再安装puppeteer
    npm config set unsafe-perm true
    npm i puppeteer
    其次可能会遇到各种库没有安装的错误,比如libX11-xcb.so.1,具体所需依赖可以查看Troubleshooting.或直接执行一下命令
    sudo apt install gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
    还有sandbox 问题,可以尝试在无沙箱模式下运行puppeteer
    const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});

  2. npm fund 问题。

  3. puppeteer linux问题解决方案
    https://blog.csdn.net/weixin_39995439/article/details/110553818

DebianQA

查看版本号
cat /etc/debian_version
结果
11.3

uname 命令可以显示电脑以及操作系统的相关信息,输入下面的命令:

uname -a

ldd 查看软件依赖

puppeteerQA

https://storage.googleapis.com/chromium-browser-snapshots/linux_x64/%d/chrome-linux.zip

Puppeter安装的捆绑Chromium缺少必要的共享库依赖项。
要修复此问题,您需要在Dockerfile中安装缺失的依赖项和最新的Chromium包:

替换debian的源为阿里的源,然后安装chromium的依赖包。

deb http://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb http://mirrors.aliyun.com/debian-security/ bullseye-security main
deb-src http://mirrors.aliyun.com/debian-security/ bullseye-security main
deb http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib

apt-get update \
    && apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \
      --no-install-recommends \

sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \

# 更改镜像源(可用)

dep http://ftp.de.debian.org/debian bullseye main contrib non-free
https://pkgs.org/download/google-chrome-unstable

dep http://extras.getpagespeed.com/debian bullseye main contrib non-free
https://centos.pkgs.org/8/getpagespeed-x86_64/google-chrome-unstable-81.0.4021.2-1.x86_64.rpm.html

deb/de-src区别
deb行是相对于二进制软件包的,您可以使用进行安装apt。
deb-src相对于源代码包(由下载apt-get source $package),然后进行编译。
仅当您要自己编译某些软件包或检查源代码中是否有错误时,才需要源软件包。普通用户不需要包含此类存储库。
因此,如果我只通过Synaptic或apt-get install安装软件包,则只​​需要第一行,deb…而不是deb-src…?

QA:
target packages is configured multiple times in
源配置配多了


参考

  1. docker文件里面的项目部署操作步骤: https://docs.docker.com/get-started/
  2. 开发NodeJS步骤例子:https://github.com/docker/labs/tree/master/developer-tools/nodejs/porting

http://lihuaxi.xjx100.cn/news/1289245.html

相关文章

Spring Boot 中的事务超时时间

Spring Boot 中的事务超时时间 在 Spring Boot 中&#xff0c;事务管理是一个非常重要的话题。当我们在数据库中执行一些复杂的操作时&#xff0c;需要确保这些操作能够在一定的时间内完成&#xff0c;否则可能会导致数据一致性问题。为了解决这个问题&#xff0c;Spring Boot…

JMeter:如何开始简单的WEB压力测试?

目录 背景 如何开始简单的WEB压力测试 PutsReq网站截图 执行测试计划 背景 JMeter是一款广泛使用的性能测试工具&#xff0c;它可以模拟用户行为并生成负载&#xff0c;用于评估Web应用程序的性能和稳定性。 最近工作上被安排针对Web网站进行性能压测&#xff0c;以评估特…

从URL输入到页面展示过程

99. 从URL输入到页面展示过程 在日常的网页浏览中&#xff0c;我们只需要输入URL并按下回车键&#xff0c;就能迅速看到页面的展示。然而&#xff0c;背后涉及到了一系列复杂的步骤和技术。本文将详细介绍从URL输入到浏览器页面展示的完整过程&#xff0c;让我们更深入地了解浏…

【Spring Cloud Alibaba Sentinel 实现熔断与限流】 —— 每天一点小知识

&#x1f4a7; S p r i n g C l o u d A l i b a b a S e n t i n e l 实现熔断与限流 \color{#FF1493}{Spring Cloud Alibaba Sentinel 实现熔断与限流} SpringCloudAlibabaSentinel实现熔断与限流&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨…

js内存泄漏及排查详解

js内存泄漏及排查详解 常见内存泄漏及解决方案 内存泄漏&#xff08;Memory Leak&#xff09;是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放&#xff0c;造成系统内存的浪费&#xff0c;导致程序运行速度减慢甚至系统崩溃等严重后果。 隐式全局变量 在局部…

v8-tc39-ecma262:concat,不只是合并数组

如上图&#xff0c;解释如下&#xff1a; 如果是对象o&#xff0c;转换为对象新建数组A设n0,用于最后赋值给A&#xff0c;确保A的长度正确预先把值设置到items(这里不知何意&#xff1f;)循环items&#xff0c;设置元素为E E是否可展开如果可展开 有len下标&#xff0c;则获取…

QT多线程之QtConcurrent::run()

QtConcurren导读 QtConcurrent提供了编写多线程程序的高级api&#xff0c;也即不使用低级线程原语&#xff0c;而其他实现多线程的方式&#xff0c;例如子类化QThread、QObject::moveToThread()、子类化QRunnable对于共享数据的保护都要使用低级线程原语&#xff0c;这无疑是要…

(0day通用)中庆纳博某系统敏感信息泄露+未授权修改密码

申明&#xff1a;本次测试只作为学习用处&#xff0c;请勿未授权进行渗透测试&#xff0c;切勿用于其它用途&#xff01; 1.漏洞背景 北京中庆纳博信息技术有限公司&#xff0c;简称中庆纳博&#xff0c;是有20年历史的中庆集团旗下核心企业&#xff0c;专注于教育信息化的深度…