【Springcloud微服务】Docker下篇

news2024/10/6 16:28:42

🔥 本文由 程序喵正在路上 原创,CSDN首发!
💖 系列专栏:Springcloud微服务
🌠 首发时间:2024年6月22日
🦋 欢迎关注🖱点赞👍收藏🌟留言🐾

目录

  • Docker基础之镜像
    • 镜像结构
    • Dockerfile
    • 构建镜像
  • Docker基础之网络
  • 项目部署
    • 部署Java项目
    • 部署前端
    • DockerCompose
      • 基本语法
      • 基础命令

Docker基础之镜像

镜像就是包含了应用程序、程序运行的系统函数库、运行配置等文件的文件包。构建镜像的过程其实就是把上述文件打包的过程。

镜像结构

要想自己构建镜像,必须先了解镜像的结构。

之前我们说过,镜像之所以能让我们快速跨操作系统部署应用而忽略其运行环境、配置,就是因为镜像中包含了程序运行需要的系统函数库、环境、配置、依赖。

因此,自定义镜像本质就是依次准备好程序运行的基础环境、依赖、应用本身、运行配置等文件,并且打包而成。

举个例子,如果我们要从 0 部署一个 Java 应用,大概流程是这样的:

  • 准备一个 linux 服务(CentOS 或者 Ubuntu 均可)
  • 安装并配置 JDK
  • 上传 Jar
  • 运行 jar

因此,我们打包镜像也是分成这么几步:

  • 准备 Linux 运行环境(java 项目并不需要完整的操作系统,仅仅是基础运行环境即可)
  • 安装并配置 JDK
  • 拷贝 jar
  • 配置启动脚本

上述步骤中的每一次操作其实都是在生产一些文件(系统运行环境、函数库、配置最终都是磁盘文件),所以镜像就是一堆文件的集合

但需要注意的是,镜像文件不是随意堆放的,而是按照操作的步骤分层叠加而成,每一层形成的文件都会单独打包并标记一个唯一 id,称为Layer(层)。这样,如果我们构建时用到的某些层其他人已经制作过,就可以直接拷贝使用这些层,而不用重复制作。

例如,第一步中需要的 Linux 运行环境,通用性就很强,所以 Docker 官方就制作了这样的只包含 Linux 运行环境的镜像。我们在制作 java 镜像时,就无需重复制作,直接使用 Docker 官方提供的 CentOSUbuntu 镜像作为基础镜像。在此基础上再搭建其它层即可,这样逐层搭建,最终整个 Java 项目的镜像结构如图所示:

在这里插入图片描述

Dockerfile

由于制作镜像的过程中,需要逐层处理和打包,比较复杂,所以 Docker 就提供了自动打包镜像的功能。我们只需要将打包的过程,每一层要做的事情用固定的语法写下来,交给 Docker 去执行即可。

而这种记录镜像结构的文件就称为 Dockerfile,其对应的语法可以参考官方文档:https://docs.docker.com/reference/dockerfile/。

其中的语法比较多,比较常用的有:

指令说明示例
FROM指定基础镜像FROM centos:6
ENV设置环境变量,可在后面指令使用ENV key value
COPY拷贝本地文件到镜像的指定目录下COPY ./xx.jar /tmp/app.jar
RUN执行 Linux 的 shell 命令,一般是安装过程的命令RUN yum install gcc
EXPOSE指定容器运行时监听的端口,是给镜像使用者看的EXPOSE 8080
ENTRYPOINT镜像中应用的启动命令,容器运行时调用ENTRYPOINT java -jar xx.jar

例如,如果要基于 Ubuntu 镜像来构建一个 Java 应用,其 Dockerfile 内容如下:

# 指定基础镜像
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录、容器内时区
ENV JAVA_DIR=/usr/local
ENV TZ=Asia/Shanghai
# 拷贝jdk和java项目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 设定时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安装JDK
RUN cd $JAVA_DIR \
 && tar -xf ./jdk8.tar.gz \
 && mv ./jdk1.8.0_144 ./java8
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 指定项目监听的端口
EXPOSE 8080
# 入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/app.jar"]

其实,我们仔细思考后会发现,将一个 Java 项目打包为镜像,都需要 Linux 系统环境、JDK 环境这两层,只有上面的 3 层不同(因为 jar 包不同)。如果每次制作 Java 镜像都重复制作前两层镜像,是有点麻烦的。

因此,就有人提供了基础的系统加 JDK 环境,我们在此基础上制作 Java 镜像,就可以省去一些配置了:

# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]

构建镜像

Dockerfile 文件写好以后,我们就可以利用命令来构建镜像了。

在资料中,我们已经准备好了一个 demo 项目及对应的 Dockerfile用于演示如何构建镜像:

在这里插入图片描述

在虚拟机中回到根目录,然后我们可以将整个 demo 文件夹直接拖到窗口中,将其上传,里面的 logs 现在没什么用,可以删去:

在这里插入图片描述

我们查看一下这个 Dockerfile,可以发现它是在 JDK 的基础镜像上进行构架的,在资料中也准备了这个镜像,我们将其上传到宿主机中,等一下就不用再浪费时间去下载了:

在这里插入图片描述

images 目录下有一个 jdk.tar,我们将其拖到根目录下即可:

在这里插入图片描述

然后,加载一下:

在这里插入图片描述

一切准备好后,我们就可以来构建镜像了:

# 进入镜像目录
cd /root/demo
# 开始构建
docker build -t docker-demo:1.0 .

命令说明:

  • docker build : 就是构建一个 docker 镜像

  • -t docker-demo:1.0-t 参数是指定镜像的名称(repositorytag

  • . : 最后的点是指构建时 Dockerfile 所在的路径,由于我们进入了 demo 目录,所以指定的是 . 代表当前目录,也可以直接指定 Dockerfile 目录:

    # 直接指定Dockerfile目录
    docker build -t docker-demo:1.0 /root/demo
    

在这里插入图片描述

可以看到,构建很快,1.5 秒就完成了。

# 1.创建并运行容器
docker run -d --name dd -p 8080:8080 docker-demo:1.0
# 2.查看容器
dps
# 3.查看容器运行日志
docker logs -f dd

可以看到一个很熟悉的标志:

在这里插入图片描述

我们可以来到浏览器访问一下虚拟机的 8080 端口:

192.168.150.128:8080/hello/count

记得换成你虚拟机的 IP,回车后我们可以看到这个页面,并且它会统计我们的访问次数:

在这里插入图片描述

我们也可以直接在虚拟机中通过指令来访问:

curl localhost:8080/hello/count

在这里插入图片描述

Docker基础之网络

前面我们创建了一个 Java 项目的容器,而 Java 项目往往需要访问其它各种中间件,例如 MySQLRedis 等。现在,我们的容器之间能否互相访问呢?

默认情况下,所有容器都是以 bridge 方式连接到 Docker 的一个虚拟网桥上:

在这里插入图片描述

首先,我们查看下 MySQL 容器的详细信息,重点关注其中的网络 IP 地址,然后进入 dd 容器中 ping 一下:

# 1.用基本命令,寻找Networks.bridge.IPAddress属性
docker inspect mysql
# 也可以使用format过滤结果
docker inspect --format='{{range .NetworkSettings.Networks}}{{println .IPAddress}}{{end}}' mysql
# 得到IP地址如下:
172.17.0.2

# 2. mysql容器没启动的需要启动
docker start mysql

# 3.然后通过命令进入dd容器
docker exec -it dd bash

# 4.在容器内,通过ping命令测试网络
ping 172.17.0.2

在这里插入图片描述

发现可以互联,没有问题。

但是,容器的网络 IP 其实是一个虚拟的 IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个 IP,而在部署时很可能 MySQL 容器的 IP 会发生变化,从而导致连接失败。

所以,我们必须借助于 docker 的网络功能来解决这个问题,参考官方文档:https://docs.docker.com/reference/cli/docker/network/

命令说明
docker network create创建一个网络
docker network ls查看所有网络
docker network rm删除指定网络
docker network prune清除未使用的网络
docker network connect使指定容器连接加入某网络
docker network disconnect使指定容器连接离开某网络
docker network inspect查看网络详细信息

下面,我们来自定义一个网络:

# 1.首先通过命令创建一个网络
docker network create hmall

# 2.然后查看网络
docker network ls
# 结果:
NETWORK ID     NAME      DRIVER    SCOPE
8964d77f268d   bridge    bridge    local
7c04bfc41671   hmall     bridge    local
99e9b07b2b5c   host      host      local
a4deb7bd2a05   none      null      local
# 其中,除了hmall以外,其它都是默认的网络

# 3.让dd和mysql都加入该网络,注意,在加入网络时可以通过--alias给容器起别名
# 这样该网络内的其它容器可以用别名互相访问!
# 3.1.mysql容器,指定别名为db,另外每一个容器都有一个别名是容器名
docker network connect hmall mysql --alias db
# 3.2.db容器,也就是我们的java项目
docker network connect hmall dd

# 4.进入dd容器,尝试利用别名访问db
# 4.1.进入容器
docker exec -it dd bash
# 4.2.用db别名访问
ping db
# 结果
PING db (172.18.0.2) 56(84) bytes of data.
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.056 ms
# 4.3.用容器名访问
ping mysql
# 结果:
PING mysql (172.18.0.2) 56(84) bytes of data.
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from mysql.hmall (172.18.0.2): icmp_seq=2 ttl=64 time=0.054 ms

我们也可以在创建容器时直接加入网络,但是通过这种方式就不会再连接默认网桥:

docker run -d --name dd -p 8080:8080 --network hmall docker-demo

现在,我们无需记住 IP 地址也可以实现容器互联了,通过别名即可,它会自己去找。

项目部署

前面,我们已经熟悉了 Docker 的基本用法,接下来就可以尝试自己来部署一个项目了。

项目的相关代码已经存在资料中,如图:

在这里插入图片描述

项目说明:

  • hmall:商城的后端代码
  • hmall-portal:商城用户端的前端代码
  • hmall-admin:商城管理端的前端代码

部署的容器及端口说明:

项目容器名端口备注
hmallhmall8080黑马商城后端API入口
hmall-portalnginx18080黑马商城用户端入口
hmall-adminnginx18081黑马商城管理端入口
mysqlmysql3306数据库

在正式部署前,我们先删除之前的 nginxdd 两个容器:

docker rm -f nginx dd

mysql 容器中已经准备好了商城的数据,所以就不再删除了。

部署Java项目

hmall 项目是一个 maven 聚合项目,我们使用 IDEA 打开 hmall 项目,查看项目结构如图:

在这里插入图片描述

我们要部署的就是其中的 hm-service,其中的配置文件采用了多环境的方式:

在这里插入图片描述

其中的 application-dev.yaml 是部署到开发环境的配置,application-local.yaml 是本地运行时的配置。

查看 application.yaml,你会发现其中的 JDBC 地址并未写死,而是读取变量:

在这里插入图片描述

这两个变量在 application-dev.yamlapplication-local.yaml 中并不相同。在 application-local.yaml 中,我们需要修改 host 为自己虚拟机的 ip 地址。

dev 开发环境(也就是 Docker 部署时)采用了 mysql 作为地址,刚好是我们的 mysql 容器名,只要两者在一个网络,就一定能互相访问。

在这里插入图片描述

打包完,我们就能在 target 目录下看到 jar 包了:

在这里插入图片描述

接下来,我们将 hm-service 目录下的 Dockerfilehm-service/target 目录下的 hm-service.jar 一起上传到虚拟机的 root 目录,直接拖文件即可:

在这里插入图片描述

# 1. 启动mysql容器
docker start mysql

# 2. 在当前目录构建项目镜像,不指定tag,则默认为latest
docker build -t hmall .

# 3. 查看镜像
dis

# 4. 创建并运行容器,并通过--network将其加入hmall网络,这样才能通过容器名访问mysql
docker run -d --name hmall --network hmall -p 8080:8080 hmall

# 5. 查看容器运行日志
docker logs -f hmall

通过日志可以看到 SpringMabatisplus 的标志:

在这里插入图片描述

然后,我们可以通过浏览器访问 http://你的虚拟机地址:8080/search/list 这个地址,来测试 Java 项目是否部署成功。

在这里插入图片描述

部署前端

hmall-portalhmall-admin 是前端代码,需要基于 nginx 部署。

其中:

  • html 是静态资源目录
  • nginx.confnginx 的配置文件,主要是完成对 html 下的两个静态资源目录做代理

我们现在要做的就是把整个 nginx 目录上传到虚拟机的 /root 目录下:

在这里插入图片描述

然后创建 nginx 容器并完成两个挂载:

  • /root/nginx/html 挂载到 /usr/share/nginx/html
  • /root/nginx/nginx.conf 挂载到 /etc/nginx/nginx.conf

由于需要让 nginx 同时代理 hmall-portalhmall-admin 两套前端资源,因此我们需要暴露两个端口:

  • 18080:对应 hmall-portal
  • 18081:对应 hmall-admin

如果你在部署之后访问不了前端页面,就可以执行下列指令来开放端口。

# 开放端口18080
sudo firewall-cmd --zone=public --add-port=18080/tcp --permanent

# 开放端口18081
sudo firewall-cmd --zone=public --add-port=18081/tcp --permanent

# 重新加载防火墙规则
sudo firewall-cmd --reload

如果你的虚拟机中已经存在 nginx 容器,需要先将其删除:docker rm -f nginx

新建 nginx 容器:

docker run -d \
  --name nginx \
  -p 18080:18080 \
  -p 18081:18081 \
  -v /root/nginx/html:/usr/share/nginx/html \
  -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf \
  --network hmall \
  nginx

测试,通过浏览器访问:http://你的虚拟机ip:18080

在这里插入图片描述

DockerCompose

大家可以看到,我们部署一个简单的 Java 项目,其中就包含 3 个容器:

  • MySQL
  • Nginx
  • Java项目

而稍微复杂的项目,其中还会有各种各样的其它中间件,需要部署的东西远不止 3 个。如果还像这样手动地逐一部署,就太麻烦了。

Docker Compose 就可以帮助我们实现多个相互关联的 Docker 容器的快速部署。它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器。

基本语法

docker-compose.yml 文件的基本语法可以参考官方文档:https://docs.docker.com/compose/compose-file/legacy-versions/。

docker-compose 文件中可以定义多个相互关联的应用容器,每一个应用容器被称为一个服务(service)。由于 service 就是在定义某个应用的运行时参数,因此与 docker run 参数非常相似,很容易可以上手。

举例来说,用 docker run 部署 MySQL 的命令如下:

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  -v ./mysql/data:/var/lib/mysql \
  -v ./mysql/conf:/etc/mysql/conf.d \
  -v ./mysql/init:/docker-entrypoint-initdb.d \
  --network hmall
  mysql

如果用 docker-compose.yml 文件来定义,就是这样:

version: "3.8" # docker compose的版本

services:
  mysql:
    image: mysql		# 镜像名称
    container_name: mysql	# 容器名称
    ports:
      - "3306:3306"
    environment:	# 环境
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123
    volumes: 	# 数据卷
      - "./mysql/conf:/etc/mysql/conf.d"
      - "./mysql/data:/var/lib/mysql"
      - "./mysql/init:/docker-entrypoint-initdb.d"
    networks:	# 网络
      - hm-net
networks:	# 网络
  hm-net:
    name: hmall

对比如下:

docker run 参数docker compose 指令说明
–namecontainer_name容器名称
-pports端口映射
-eenvironment环境变量
-vvolumes数据卷配置
–networknetworks网络

在资料中已经准备了黑马商城的部署文件 docker-compose.yml

在这里插入图片描述

version: "3.8"

services:
  mysql:
    image: mysql
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123
    volumes:
      - "./mysql/conf:/etc/mysql/conf.d"
      - "./mysql/data:/var/lib/mysql"
      - "./mysql/init:/docker-entrypoint-initdb.d"
    networks:
      - hm-net
  hmall:
    build: # 构建镜像
      context: .	# 构建路径
      dockerfile: Dockerfile # 根据dockerfile构建
    container_name: hmall
    ports:
      - "8080:8080"
    networks:
      - hm-net
    depends_on:	# 依赖
      - mysql
  nginx:
    image: nginx
    container_name: nginx
    ports:
      - "18080:18080"
      - "18081:18081"
    volumes:
      - "./nginx/nginx.conf:/etc/nginx/nginx.conf"
      - "./nginx/html:/usr/share/nginx/html"
    depends_on:	# 依赖
      - hmall
    networks:
      - hm-net
networks:
  hm-net:
    name: hmall

然后,我们将这个部署文件上传到和其他构建项目所需资料的同一目录下:

在这里插入图片描述

基础命令

编写好 docker-compose.yml 文件,就可以部署项目了。常见的命令可以参考官方文档:https://docs.docker.com/compose/reference/。

在这里插入图片描述

基本语法如下:

docker compose [OPTIONS] [COMMAND]

其中,OPTIONSCOMMAND 都是可选参数,比较常见的有:

类型参数或指令说明
Options-f指定 compose 文件的路径和名称,如果在当前目录下可以不用指定
Options-p指定 project 名称。project 就是当前 compose 文件中设置的多个 service 的集合,是逻辑概念,默认为 root
Options-d后台运行
Commandsup创建并启动所有 service 容器
Commandsdown停止并移除所有容器、网络
Commandsps列出所有启动的容器
Commandslogs查看指定容器的日志
Commandsstop停止容器
Commandsstart启动容器
Commandsrestart重启容器
Commandstop查看运行的进程
Commandsexec在指定的运行中容器中执行命令

下面我们就用 docker compose 来部署项目。

首先,先删除前面创建的容器、镜像和网络:

在这里插入图片描述

在这里插入图片描述

然后用 docker compose 部署:

在这里插入图片描述

来到浏览器访问一下前端页面,点击登录,输入 Jack123,登录成功:

在这里插入图片描述

如果我们执行 docker compose down ,就可以删除所有容器和网络:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1849806.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MySQL数据库】:MySQL视图特性

视图的概念 视图是一个虚拟表,其内容由查询定义,同真实的表一样,视图包含一系列带有名称的列和行数据。视图中的数据并不会单独存储在数据库中,其数据来自定义视图时查询所引用的表(基表),在每…

1931java Web披萨店订餐系统idea开发mysql数据库web结构java编程计算机网页源码servlet项目

一、源码特点 java Web 披萨店订餐系统是一套完善的信息管理系统,结合java 开发技术和bootstrap完成本系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用 B/S模式开发。 视频地址:…

从零开始的Ollama指南:部署私域大模型

大模型相关目录 大模型,包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步,扬帆起航。 大模型应用向开发路径:AI代理工作流大模型应用开发实用开源项目汇总大模…

c语言回顾-结构体(2)

前言 前面讲了结构体的概念,定义,赋值,访问等知识,本节内容小编将讲解结构体的内存大小的计算以及通过结构体实现位段,话不多说,直接上干货!!! 1.结构体内存对齐 说到计…

Ubuntu系统使用快速入门实践(八)—— git 命令使用

Ubuntu系统使用快速入门实践系列文章 下面是Ubuntu系统使用系列文章的总链接,本人发表这个系列的文章链接均收录于此 Ubuntu系统使用快速入门实践系列文章总链接 下面是专栏地址: Ubuntu系统使用快速入门实践系列文章专栏 文章目录 Ubuntu系统使用快速…

UDS服务——RequestDownload(0x34)

诊断协议那些事儿 诊断协议那些事儿专栏系列文章,本文介绍RequestDownload(0x34)—— 请求下载,用于给ECU下载数据的,最常见的应用就是在bootloader中,程序下载工具会发起请求下载,以完成ECU程序的升级。通过阅读本文,希望能对你有所帮助。 文章目录 诊断协议那些事儿…

【C++】一个极简但完整的C++程序

一、一个极简但完整的C程序 我们编写程序是为了解决问题和任务的。 1、任务: 某个书店将每本售出的图书的书名和出版社,输入到一个文件中,这些信息以书售出的时间顺序输入,每两周店主会手工计算每本书的销售量、以及每个出版社的…

【单片机毕业设计选题24020】-全自动鱼缸的设计与应用

系统功能: (1)检测并控制鱼缸水温,水温低于22℃后开启加热,高于28℃后关闭加热。 (2)定时喂食,每天12点和0点喂食一次,步进电机开启后再关闭模拟喂食。 (3&#xff09…

初学者应该掌握的MySQL数据库的基本组成部分及概念

MySQL数据库作为一种开源的关系型数据库管理系统,被广泛应用于Web应用开发和数据存储。它具有高性能、易用性和可靠性等特点,是开发者们的首选之一。在本篇文章中,我们将详细介绍MySQL数据库的核心组成部分,帮助你深入理解这个强大…

杀疯了!PerfXCloud-AI大模型夏日狂欢来袭,向基石用户赠送 ∞ 亿Token!

【澎峰科技重磅消息】 在全球范围内大模型正逐渐成为强大的创新驱动力。在这个充满激情的夏日,PerfXCloud为开发者和企业带来了前所未有的福利: 1. 零成本亲密、深度体验大模型,提供大量示范案例。 2. 向基石用户赠送∞亿Token的激励计划。…

展讯-QMI8658和气压传感器驱动调试

1.调试QMI8658 参考demo,添加QMI8610相关内容 当前驱动路径位于:bsp/modules/input/misc/qmi8610/qmi8610.c 编译使用make sockoimage 用fastboot烧录 1.确定驱动被正常加载 代码添加之后,首先确定有没有进入当前驱动文件 dmesg |grep …

Gradle 自动化项目构建-Gradle 核心之 Project

一、前言 从明面上看,Gradle 是一款强大的构建工具,但 Gradle 不仅仅是一款强大的构建工具,它更像是一个编程框架。Gradle 的组成可以细分为如下三个方面: groovy 核心语法:包括 groovy 基本语法、闭包、数据结构、面…

C#调用OpenCvSharp实现图像的直方图均衡化

本文学习基于OpenCvSharp的直方图均衡化处理方式,并使用SkiaSharp绘制相关图形。直方图均衡化是一种图像处理方法,针对偏亮或偏暗的图像,通过调整图像的像素值来增强图像对比度,详细原理及介绍见参考文献1-4。   直方图均衡化第…

计算机组成原理笔记-第1章 计算机系统概论

第一章 计算机系统概论 笔记PDF版本已上传至Github个人仓库:CourseNotes,欢迎fork和star,拥抱开源,一起完善。 该笔记是最初是没打算发网上的,所以很多地方都为了自我阅读方便,我理解了的地方就少有解释&a…

如何恢复 Mac 数据?适用于 Mac 的免费磁盘恢复软件

对于大多数 Mac 电脑用户来说,丢失数据是他们最不想遇到的噩梦之一。然而,无论我们多么小心地使用 Mac,多么有条理地存储重要文件,我们仍然有可能丢失 Mac 上的数据。某些硬件故障更有可能导致您意外丢失文件。除此之外&#xff0…

在WordPress上添加亚马逊联盟链接的三种方法

在互联网快速发展的今天,很多人都希望通过网络来增加收入,而加入亚马逊联盟计划(Amazon Associates)无疑是一个不错的选择。如果你有一个WordPress网站,那么在文章中添加亚马逊联盟链接是个很好的变现方式。今天&#…

IDEA services模块无法启动springboot服务(添加了springboot但是为空白)

https://blog.csdn.net/m0_54042402/article/details/117918995 https://blog.csdn.net/qq_46550964/article/details/122235235 Alt8 显示services模块 发现有springboot启动模块,点一下springboot之后,这个模块就消失了 会自动在.idea文件夹下的work…

Android平台下VR头显如何低延迟播放4K以上超高分辨率RTSP|RTMP流

技术背景 VR头显需要更高的分辨率以提供更清晰的视觉体验、满足沉浸感的要求、适应透镜放大效应以及适应更广泛的可视角度,超高分辨率的优势如下: 提供更清晰的视觉体验:VR头显的分辨率直接决定了用户所看到的图像的清晰度。更高的分辨率意…

AI全栈之coze的logo生成

前言 前几日体验了国产的AI-Agents产品coze 它是一种能够自主执行任务、与环境进行交互并根据所获取的信息做出决策和采取行动的软件程序 并且可以自己去创建属于自己的AIBot,还是很有意思的,大家可以去体验体验 在体验过程中,我发现在创…

Zygote进程的理解

Zygote进程是安卓系统的一个重要进程,由init进程创建而来;另外系统里的重要进程(system_server等)都是由zygote进程fork的,所有的app进程也是由zygote进程fork的。 一、C 里的fork函数 fork是Linux里面创建子进程的函…