Nginx官方镜像Dockerfile浅析

news2024/9/22 15:43:29

目录

Dockerfile获取

dfimage逆向获取

Nginx官网获取

Dockerfile分析

启动命令分析

Docker 容器入口点脚本分析

exec "$@"

exec 命令

"$@" 参数

总结


        在云原生技术快速发展的今天,Docker 作为容器技术的代表,为软件的打包、分发和部署提供了一种轻量级、可移植的解决方案。Dockerfile 作为 Docker 的核心组件之一,其设计和编写直接关系到容器镜像的构建效率和运行时的性能。了解和掌握 Dockerfile 的关键技术点,对于任何希望在云原生领域内进行开发和运维的工程师来说都是至关重要的。

        本文旨在通过分析 Nginx 官方 Docker 镜像的 Dockerfile,探讨 Dockerfile 的获取方法、结构和编写策略,以及容器启动脚本的作用和设计原则。我们将深入讨论在 Dockerfile 中使用 exec "$@" 的好处,以及这种做法在其他镜像设计中的应用价值,为构建更加高效、可靠的容器化应用打下坚实的基础。

Dockerfile获取

dfimage逆向获取

alias dfimage='docker run -v /var/run/docker.sock:/var/run/docker.sock --rm alpine/dfimage'
    /usr/bin/docker

dfimage nginx:1.25.4

dfimage='docker run -v /var/run/docker.sock:/var/run/docker.sock --rm alpine/dfimage'
    /usr/bin/docker nginx:1.25.4

逆向Dockerfile

CMD ["bash"]
LABEL maintainer=NGINX Docker Maintainers <docker-maint@nginx.com>
ENV NGINX_VERSION=1.25.4
ENV NJS_VERSION=0.8.3
ENV PKG_RELEASE=1~bookworm
RUN RUN set -x  \
	&& groupadd --system --gid 101 nginx  \
	&& useradd --system --gid nginx --no-create-home --home /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx  \
	&& apt-get update  \
	&& apt-get install --no-install-recommends --no-install-suggests -y gnupg1 ca-certificates  \
	&& NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; NGINX_GPGKEY_PATH=/usr/share/keyrings/nginx-archive-keyring.gpg; export GNUPGHOME="$(mktemp -d)"; found=''; for server in hkp://keyserver.ubuntu.com:80 pgp.mit.edu ; do echo "Fetching GPG key $NGINX_GPGKEY from $server"; gpg1 --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY"  \
	&& found=yes  \
	&& break; done; test -z "$found"  \
	&& echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY"  \
	&& exit 1; gpg1 --export "$NGINX_GPGKEY" > "$NGINX_GPGKEY_PATH" ; rm -rf "$GNUPGHOME"; apt-get remove --purge --auto-remove -y gnupg1  \
	&& rm -rf /var/lib/apt/lists/*  \
	&& dpkgArch="$(dpkg --print-architecture)"  \
	&& nginxPackages=" nginx=${NGINX_VERSION}-${PKG_RELEASE} nginx-module-xslt=${NGINX_VERSION}-${PKG_RELEASE} nginx-module-geoip=${NGINX_VERSION}-${PKG_RELEASE} nginx-module-image-filter=${NGINX_VERSION}-${PKG_RELEASE} nginx-module-njs=${NGINX_VERSION}+${NJS_VERSION}-${PKG_RELEASE} "  \
	&& case "$dpkgArch" in amd64|arm64) echo "deb [signed-by=$NGINX_GPGKEY_PATH] https://nginx.org/packages/mainline/debian/ bookworm nginx" >> /etc/apt/sources.list.d/nginx.list  \
	&& apt-get update ;; *) echo "deb-src [signed-by=$NGINX_GPGKEY_PATH] https://nginx.org/packages/mainline/debian/ bookworm nginx" >> /etc/apt/sources.list.d/nginx.list  \
	&& tempDir="$(mktemp -d)"  \
	&& chmod 777 "$tempDir"  \
	&& savedAptMark="$(apt-mark showmanual)"  \
	&& apt-get update  \
	&& apt-get build-dep -y $nginxPackages  \
	&& ( cd "$tempDir"  \
	&& DEB_BUILD_OPTIONS="nocheck parallel=$(nproc)" apt-get source --compile $nginxPackages )  \
	&& apt-mark showmanual | xargs apt-mark auto > /dev/null  \
	&& { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; }  \
	&& ls -lAFh "$tempDir"  \
	&& ( cd "$tempDir"  \
	&& dpkg-scanpackages . > Packages )  \
	&& grep '^Package: ' "$tempDir/Packages"  \
	&& echo "deb [ trusted=yes ] file://$tempDir ./" > /etc/apt/sources.list.d/temp.list  \
	&& apt-get -o Acquire::GzipIndexes=false update ;; esac  \
	&& apt-get install --no-install-recommends --no-install-suggests -y $nginxPackages gettext-base curl  \
	&& apt-get remove --purge --auto-remove -y  \
	&& rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx.list  \
	&& if [ -n "$tempDir" ]; then apt-get purge -y --auto-remove  \
	&& rm -rf "$tempDir" /etc/apt/sources.list.d/temp.list; fi  \
	&& ln -sf /dev/stdout /var/log/nginx/access.log  \
	&& ln -sf /dev/stderr /var/log/nginx/error.log  \
	&& mkdir /docker-entrypoint.d # buildkit
COPY docker-entrypoint.sh / # buildkit
	docker-entrypoint.sh

COPY 10-listen-on-ipv6-by-default.sh /docker-entrypoint.d # buildkit
	docker-entrypoint.d/
	docker-entrypoint.d/10-listen-on-ipv6-by-default.sh

COPY 15-local-resolvers.envsh /docker-entrypoint.d # buildkit
	docker-entrypoint.d/
	docker-entrypoint.d/15-local-resolvers.envsh

COPY 20-envsubst-on-templates.sh /docker-entrypoint.d # buildkit
	docker-entrypoint.d/
	docker-entrypoint.d/20-envsubst-on-templates.sh

COPY 30-tune-worker-processes.sh /docker-entrypoint.d # buildkit
	docker-entrypoint.d/
	docker-entrypoint.d/30-tune-worker-processes.sh

ENTRYPOINT ["/docker-entrypoint.sh"]
EXPOSE map[80/tcp:{}]
STOPSIGNAL SIGQUIT
CMD ["nginx" "-g" "daemon off;"]

Nginx官网获取

docker-nginx/mainline/debian/Dockerfile at 1f227619c1f1baa0bed8bed844ea614437ff14fb · nginxinc/docker-nginx · GitHub

官网Dockerfile

#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "update.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM debian:bookworm-slim

LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>"

ENV NGINX_VERSION   1.25.4
ENV NJS_VERSION     0.8.3
ENV PKG_RELEASE     1~bookworm

RUN set -x \
# create nginx user/group first, to be consistent throughout docker variants
    && groupadd --system --gid 101 nginx \
    && useradd --system --gid nginx --no-create-home --home /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \
    && apt-get update \
    && apt-get install --no-install-recommends --no-install-suggests -y gnupg1 ca-certificates \
    && \
    NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62; \
    NGINX_GPGKEY_PATH=/usr/share/keyrings/nginx-archive-keyring.gpg; \
    export GNUPGHOME="$(mktemp -d)"; \
    found=''; \
    for server in \
        hkp://keyserver.ubuntu.com:80 \
        pgp.mit.edu \
    ; do \
        echo "Fetching GPG key $NGINX_GPGKEY from $server"; \
        gpg1 --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" && found=yes && break; \
    done; \
    test -z "$found" && echo >&2 "error: failed to fetch GPG key $NGINX_GPGKEY" && exit 1; \
    gpg1 --export "$NGINX_GPGKEY" > "$NGINX_GPGKEY_PATH" ; \
    rm -rf "$GNUPGHOME"; \
    apt-get remove --purge --auto-remove -y gnupg1 && rm -rf /var/lib/apt/lists/* \
    && dpkgArch="$(dpkg --print-architecture)" \
    && nginxPackages=" \
        nginx=${NGINX_VERSION}-${PKG_RELEASE} \
        nginx-module-xslt=${NGINX_VERSION}-${PKG_RELEASE} \
        nginx-module-geoip=${NGINX_VERSION}-${PKG_RELEASE} \
        nginx-module-image-filter=${NGINX_VERSION}-${PKG_RELEASE} \
        nginx-module-njs=${NGINX_VERSION}+${NJS_VERSION}-${PKG_RELEASE} \
    " \
    && case "$dpkgArch" in \
        amd64|arm64) \
# arches officialy built by upstream
            echo "deb [signed-by=$NGINX_GPGKEY_PATH] https://nginx.org/packages/mainline/debian/ bookworm nginx" >> /etc/apt/sources.list.d/nginx.list \
            && apt-get update \
            ;; \
        *) \
# we're on an architecture upstream doesn't officially build for
# let's build binaries from the published source packages
            echo "deb-src [signed-by=$NGINX_GPGKEY_PATH] https://nginx.org/packages/mainline/debian/ bookworm nginx" >> /etc/apt/sources.list.d/nginx.list \
            \
# new directory for storing sources and .deb files
            && tempDir="$(mktemp -d)" \
            && chmod 777 "$tempDir" \
# (777 to ensure APT's "_apt" user can access it too)
            \
# save list of currently-installed packages so build dependencies can be cleanly removed later
            && savedAptMark="$(apt-mark showmanual)" \
            \
# build .deb files from upstream's source packages (which are verified by apt-get)
            && apt-get update \
            && apt-get build-dep -y $nginxPackages \
            && ( \
                cd "$tempDir" \
                && DEB_BUILD_OPTIONS="nocheck parallel=$(nproc)" \
                    apt-get source --compile $nginxPackages \
            ) \
# we don't remove APT lists here because they get re-downloaded and removed later
            \
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
# (which is done after we install the built packages so we don't have to redownload any overlapping dependencies)
            && apt-mark showmanual | xargs apt-mark auto > /dev/null \
            && { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; } \
            \
# create a temporary local APT repo to install from (so that dependency resolution can be handled by APT, as it should be)
            && ls -lAFh "$tempDir" \
            && ( cd "$tempDir" && dpkg-scanpackages . > Packages ) \
            && grep '^Package: ' "$tempDir/Packages" \
            && echo "deb [ trusted=yes ] file://$tempDir ./" > /etc/apt/sources.list.d/temp.list \
# work around the following APT issue by using "Acquire::GzipIndexes=false" (overriding "/etc/apt/apt.conf.d/docker-gzip-indexes")
#   Could not open file /var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages - open (13: Permission denied)
#   ...
#   E: Failed to fetch store:/var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages  Could not open file /var/lib/apt/lists/partial/_tmp_tmp.ODWljpQfkE_._Packages - open (13: Permission denied)
            && apt-get -o Acquire::GzipIndexes=false update \
            ;; \
    esac \
    \
    && apt-get install --no-install-recommends --no-install-suggests -y \
                        $nginxPackages \
                        gettext-base \
                        curl \
    && apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx.list \
    \
# if we have leftovers from building, let's purge them (including extra, unnecessary build deps)
    && if [ -n "$tempDir" ]; then \
        apt-get purge -y --auto-remove \
        && rm -rf "$tempDir" /etc/apt/sources.list.d/temp.list; \
    fi \
# forward request and error logs to docker log collector
    && ln -sf /dev/stdout /var/log/nginx/access.log \
    && ln -sf /dev/stderr /var/log/nginx/error.log \
# create a docker-entrypoint.d directory
    && mkdir /docker-entrypoint.d

COPY docker-entrypoint.sh /
COPY 10-listen-on-ipv6-by-default.sh /docker-entrypoint.d
COPY 15-local-resolvers.envsh /docker-entrypoint.d
COPY 20-envsubst-on-templates.sh /docker-entrypoint.d
COPY 30-tune-worker-processes.sh /docker-entrypoint.d
ENTRYPOINT ["/docker-entrypoint.sh"]

EXPOSE 80

STOPSIGNAL SIGQUIT

CMD ["nginx", "-g", "daemon off;"]

Dockerfile分析

启动命令分析

ENTRYPOINT ["/docker-entrypoint.sh"]
EXPOSE map[80/tcp:{}]
STOPSIGNAL SIGQUIT
CMD ["nginx" "-g" "daemon off;"]
  • ENTRYPOINT 设置了容器启动时执行的主命令,即执行 /docker-entrypoint.sh 脚本。

  • CMD 提供了额外的参数,这些参数将传递给 /docker-entrypoint.sh。

这意味着当容器启动时,实际执行的命令会是 /docker-entrypoint.sh nginx -g "daemon off;"。这里,nginx -g "daemon off;" 是作为参数传递给 /docker-entrypoint.sh 脚本的。

Docker 容器入口点脚本分析

docker-entrypoint.sh

#!/bin/sh
# vim:sw=4:ts=4:et

set -e  # 如果任何语句的执行结果不是true则立即退出脚本

# 定义一个用于输出日志的函数
entrypoint_log() {
    # 如果环境变量NGINX_ENTRYPOINT_QUIET_LOGS未设置或为空,打印日志信息
    if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then
        echo "$@"
    fi
}

# 检查传递给脚本的第一个参数是否是nginx或nginx-debug
if [ "$1" = "nginx" ] || [ "$1" = "nginx-debug" ]; then
    # 查找/docker-entrypoint.d/目录下是否有文件存在
    if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then
        entrypoint_log "$0: /docker-entrypoint.d/ 目录不为空,尝试进行配置"

        entrypoint_log "$0: 在 /docker-entrypoint.d/ 目录中查找shell脚本"
        # 遍历目录下所有文件,并按版本号排序
        find "/docker-entrypoint.d/" -follow -type f -print | sort -V | while read -r f; do
            case "$f" in
                *.envsh)
                    # 如果文件具有执行权限,使用source命令执行它
                    if [ -x "$f" ]; then
                        entrypoint_log "$0: 正在加载 $f";
                        . "$f"
                    else
                        # 如果文件没有执行权限,打印警告日志
                        entrypoint_log "$0: 忽略 $f,没有执行权限";
                    fi
                    ;;
                *.sh)
                    # 如果文件具有执行权限,直接执行它
                    if [ -x "$f" ]; then
                        entrypoint_log "$0: 正在执行 $f";
                        "$f"
                    else
                        # 如果文件没有执行权限,打印警告日志
                        entrypoint_log "$0: 忽略 $f,没有执行权限";
                    fi
                    ;;
                # 忽略其他类型的文件
                *) entrypoint_log "$0: 忽略 $f";;
            esac
        done

        entrypoint_log "$0: 配置完成;准备启动"
    else
        entrypoint_log "$0: 在 /docker-entrypoint.d/ 目录中未找到文件,跳过配置"
    fi
fi

# 使用传递给脚本的参数替换当前进程,通常用于启动主程序
exec "$@"

exec "$@"

        exec "$@"是上面docker-entrypoint.sh脚本的最后一行,这行命令是 Docker 容器入口点脚本的核心部分,它负责执行容器启动时用户指定的命令。

exec 命令

  • exec 用于执行命令并用该命令替换当前的 shell 进程。这意味着 exec 后面的命令将接管当前的进程,并且当 exec 执行的命令结束时,进程也会结束。

  • 使用 exec 执行命令的好处是,它不会启动新的进程,而是直接在当前进程中运行命令。在 Docker 容器的环境中,这意味着执行的命令(如 nginx)将成为容器进程的主进程。这对于 Docker 容器的生命周期管理非常重要。

"$@" 参数

  • "$@" 是一个特殊的 shell 参数,代表传递给脚本的所有命令行参数的列表,且每个参数都作为独立的引用字符串处理。

  • 在 Docker 容器的上下文中,当运行一个容器并传递命令行参数时,这些参数会被传递给容器的入口点脚本。"$@" 就是用来接收这些参数的。

  • 例如,如果运行 docker run [image] nginx -g "daemon off;",那么 nginx -g "daemon off;" 就是传递给入口点脚本的参数,"$@" 就会包含这些参数。

       

总结

        综上所述,exec "$@" 这行命令的作用是执行传递给入口点脚本的命令(如 nginx -g "daemon off;"),并且以这个命令为容器的主进程。这保证了容器直接运行指定服务,如 Nginx,并且当该服务停止时,容器也会停止。

        在设计其他镜像时,尤其是需要处理信号或需要确保容器优雅停止的场景中,使用 exec "$@" 可以提供类似的优势。例如,数据库镜像、Web 服务器镜像或任何长期运行的服务都可以从这种模式中受益。它确保了容器能够接收到停止信号并优雅地终止,同时也避免了资源泄漏的问题。

        总的来说,使用 exec "$@" 是一种常见的最佳实践,可以提高容器的运行效率和可靠性。在设计容器镜像时,尤其是当容器需要优雅地处理停止和重启信号时,应该考虑采用这种模式。

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

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

相关文章

Mybatis的动态SQL~

MyBatis有一个强大特性就是它的动态SQL。在实际项目开发中&#xff0c;经常需要根据不同条件拼接SQL语句&#xff0c;拼接时还要确保不能忘了必要的空格&#xff0c;有时候还要注意省掉列名列表最后的逗号...等等。在使用JDBC 或其他类似持久层框架操作数据库时&#xff0c;处理…

Swagger添加JWT验证(ASP.NET)

文章目录 JWT1、解析2、配置JWT JWT 1、解析 1&#xff09;客户端向授权服务系统发起请求&#xff0c;申请获取“令牌”。 2&#xff09;授权服务根据用户身份&#xff0c;生成一张专属“令牌”&#xff0c;并将该“令牌”以JWT规范返回给客户端 3&#xff09;客户端将获取到的…

uniapp h5 引入阿里云一键登录

参考官方文档: 如何将H5页面接入网页端SDK并一键登录_号码认证服务(PNVS)-阿里云帮助中心 本文主要分享uniapp 对SDK依赖文件的引入 采用npm包引入的方法: 1.下载 // 下载npm资源并添加依赖到package.json npm i aliyun_numberauthsdk_web -S tips: 查看package.json文件,确…

Linux shell编程学习笔记42:md5sum

0 前言 前几天在国产电脑上遇到一个问题&#xff0c;先后接到两个文件&#xff0c;如何判断这两个文件内容是否相同&#xff1f; 如果是在Windows系统&#xff0c;可以用fc命令&#xff0c;或者用我自己写的FileInfo&#xff0c;提取两个文件有MD5、SHA1、CRC32值进行比较来判…

李宏毅【生成式AI导论 2024】第5讲 让语言模型彼此合作,把一个人活成一个团队

GPD4,它也有非常强大的能力。但是GPT4如果跟其他的语言模型合作,他们其实可以发挥1加1大于二的力量。 为什么要让模型合作? 那怎么让模型彼此合作呢?有很多不同的方式。一个可能性是假设你现在手边就有一堆语言模型,他们可能有不同的能力使用,他们可能有不同的成本局来…

计算机专业学习单片机有什么意义吗?

玩单片机跟玩计算机区别还是很大的, 单片机有众多的种类,每一种又可能有很多个系列.可以说单片机就是为了专款专用而生的.这样来达到产品成本的降低,这就是现在身边的很多的电子产品价格一降再降的原因之一.在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一…

excel 提取数字字符混合文本中的数字(快捷键ctrl+e)

首先&#xff0c;已知A列数据&#xff0c;在B1单元格输入A列中的数据&#xff0c;如3*4*6 第二部&#xff1a;全选对应的B列&#xff0c;然后&#xff1a; ctrld 批量复制 CTRLE 智能复制 由此可见&#xff0c;智能提取汉字与数字混合中的数字方法 。若想分别提取3个数字&am…

目标检测+车道线识别+追踪

一种方法&#xff1a; 车道线检测-canny边缘检测-霍夫变换 一、什么是霍夫变换 霍夫变换&#xff08;Hough Transform&#xff09;是一种在图像处理和计算机视觉中广泛使用的特征检测技术&#xff0c;主要用于识别图像中的几何形状&#xff0c;尤其是直线、圆和椭圆等常见形状…

ssm 房屋销售管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 ssm 房屋销售管理系统是一套完善的信息系统&#xff0c;结合springMVC框架完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模…

Dify安装使用说明

dify功能简介 dify可以说是一个功能不错的LLMOps&#xff0c;可以通过dify集中管理模型&#xff0c;可以通过界面创建AI应用&#xff0c;可以上传文档形成知识库&#xff0c;可以创建自定义工具&#xff08;API&#xff09;&#xff0c;并可以对外提供API。 相关功能类似Open…

华为云使用指南02

5.​​使用GitLab进行团队及项目管理​​ GitLab旨在帮助团队进行项目开发协作&#xff0c;为软件开发和运营生命周期提供了一个完整的DevOps方案。GitLab功能包括&#xff1a;项目源码的管理、计划、创建、验证、集成、发布、配置、监视和保护应用程序等。该镜像基于CentOS操…

【智能算法】人工大猩猩部队优化算法(GTO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2021年&#xff0c;B Abdollahzadeh等人受到大猩猩社会行为启发&#xff0c;提出了人工大猩猩部队优化算法&#xff08;Artificial Gorilla Troops Optimizer, GTO&#xff09;。 2.算法原理 2.1算…

小美的平衡矩阵(前缀和例题)

2024美团秋招&#xff0c;被这一题给难住了 美团校招笔试真题_Java工程师、C工程师_牛客网 题目&#xff1a; 解答&#xff1a; 这道题的关键点就是要计算出以某一点为矩阵右下角时&#xff0c;1的个数 我一开始是想着遍历&#xff0c;以某一点为起点&#xff08;矩阵左上角&a…

Machine Learning机器学习之统计分析

目录 前言 机器学习之统计分析 统计学的主要目标包括&#xff1a; 统计学核心概念&#xff1a; 统计基础&#xff1a; 训练误差&#xff1a; 常见的损失函数&#xff1a; 正则化和交叉验证 博主介绍&#xff1a;✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉…

TBSI模型论文解读及代码分析

前往我的主页以获得更好的阅读体验 简介 论文来源: Bridging Search Region Interaction With Template for RGB-T Tracking 现有的搜索算法通常会直接连接 RGB 和 T 模态搜索区域, 该方法存在大量冗余背景噪声. 而另一些方法从搜索帧中采样候选框, 对孤立的 RGB 框和 T 框进…

RISC-V特权架构 - 中断定义

RISC-V特权架构 - 中断定义 1 中断类型1.1 外部中断1.2 计时器中断1.3 软件中断1.4 调试中断 2 中断屏蔽3 中断等待4 中断优先级与仲裁5 中断嵌套6 异常相关寄存器 本文属于《 RISC-V指令集基础系列教程》之一&#xff0c;欢迎查看其它文章。 1 中断类型 RISC-V 架构定义的中…

Autodesk Maya 2025---智能建模与动画创新,重塑创意工作流程

Autodesk Maya 2025是一款顶尖的三维动画软件&#xff0c;广泛应用于影视广告、角色动画、电影特技等领域。新版本在功能上进行了全面升级&#xff0c;新增了对Apple芯片的支持&#xff0c;建模、绑定和角色动画等方面的功能也更加出色。 在功能特色方面&#xff0c;Maya 2025…

RabbitMQ安装及使用笔记

RabbitMQ安装及使用笔记 RabbitMQ是一个开源的消息代理软件&#xff0c;它实现了高级消息队列协议&#xff08;AMQP&#xff09;&#xff0c;用于在分布式系统中进行消息传递。 1.安装 利用docker load命令加载mq镜像 docker load -i mq.tar 基于Docker来安装RabbitMQ&#xff…

网络空间测绘系统的商业应用

随着网络空间的不断发展和扩展&#xff0c;网络安全已经成为当今社会面临的重要挑战之一。为了有效应对网络安全威胁&#xff0c;网络空间测绘系统应运而生&#xff0c;成为网络安全领域的重要工具。 网络空间测绘系统不仅能够帮助安全研究人员进行研究和管理&#xff0c;还能为…

3.28总结

1.java学习记录 1.方法的重载 重载换而言之其实就是函数名不变&#xff0c;但是其中的参数需要改变&#xff0c;可以三个方面改变&#xff08;参数类型&#xff0c;参数顺序&#xff0c;参数个数这三个方面入手&#xff0c;这样可以运用的&#xff09; 但是&#xff1a;注意…