Arthas mc(Memory Compiler/内存编译器 )

在这里插入图片描述

二、命令列表

2.2 class/classloader相关命令

2.2.2 mc (Memory Compiler/内存编译器 )

提示:

Memory Compiler/内存编译器,编译.java文件生成.class

注意点1:mc 命令有可能失败。如果编译失败可以在本地编译好.class文件,再上传到服务器。具体参考retransform命令说明。

注意点2:编译生成.class文件之后,可以结合retransform命令实现热更新代码。

参数说明:

参数名称参数说明
-c指定 classloader
-d指定输出目录

代码:

package com.hero.lte.ems.security.controller;

import com.hero.lte.ems.common.spring.SpringContextHolder;
import com.hero.lte.ems.db.orm.mybatis.Page;
import com.hero.lte.ems.security.config.Constants;
import com.hero.lte.ems.security.entity.*;
import com.hero.lte.ems.security.service.*;
import com.hero.lte.ems.security.util.UUIDGennerator;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.subject.Subject;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.Serializable;
import java.time.Clock;
import java.util.*;

@RestController
@RequestMapping("/lte/ems/user/")
public class AccountController {

    @Autowired
    private IAccountService accountService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IAuthService authService;
    @Autowired
    private IRemindService remindService;
    @Autowired
    private IStrategyService strategyService;

    /**
     * 查询帐户分页列表
     * @param account
     * @param pager
     * @return
     */
    @RequestMapping(value = "query", method = RequestMethod.GET)
    public Page<Account> query(Account account, Page<Account> pager) {
        pager.setParam(account);
        return accountService.queryAccountPage(pager);
    }
举例1:可以通过-d命令指定输出目录:mc -d /temporary/tmp /temporary/tmp/AccountController.java

基本用法
mc -d 输出路径 置顶路径下的类

[arthas@24056]$ mc -d /temporary/tmp /temporary/tmp/AccountController.java 
Memory compiler output:
/temporary/tmp/com/hero/lte/ems/security/controller/AccountController.class
Affect(row-cnt:1) cost in 2682 ms.
[arthas@24056]$ 

执行命令前效果

在这里插入图片描述

执行命令后效果,按照包名com.hero.lte.ems.security.controller创建.class文件

在这里插入图片描述

举例2:通过--classLoaderClass参数指定 ClassLoader

基本用法

mc --classLoaderClass 全包名类名 置顶路径下的类 -d 指定输出路径

$ mc --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader /tmp/UserController.java -d /tmp
Memory compiler output:
/tmp/com/example/demo/arthas/user/UserController.class
Affect(row-cnt:1) cost in 346 ms

本人其他相关文章链接

1.Arthas 全攻略:让调试变得简单
2.Arthas dashboard(当前系统的实时数据面板)
3.Arthas thread(查看当前JVM的线程堆栈信息)
4.Arthas jvm(查看当前JVM的信息)
5.Arthas sysprop(查看和修改JVM的系统属性)
6.Arthas sysenv(查看JVM的环境变量)
7.Arthas vmoption(查看和修改 JVM里诊断相关的option)
8.Arthas getstatic(查看类的静态属性 )
9.Arthas heapdump(dump java heap, 类似 jmap 命令的 heap dump 功能)
10.Arthas logger(查看 logger 信息,更新 logger level)
11.Arthas mbean(查看 Mbean 的信息)
12.Arthas memory(查看 JVM 内存信息)
13.Arthas ognl(执行ognl表达式)
14.Arthas perfcounter(查看当前 JVM 的 Perf Counter 信息)
15.Arthas vmtool(从 jvm 里查询对象,执行 forceGc)
16.Arthas jad(字节码文件反编译成源代码 )
17.Arthas mc(Memory Compiler/内存编译器 )
18.Arthas redefine(加载外部的.class文件,redefine到JVM里 )
19.Arthas classloader (查看 classloader 的继承树,urls,类加载信息)
20.Arthas sc(查看JVM已加载的类信息 )
21.Arthas sm(查看已加载类的方法信息 )
22.Arthas monitor(方法执行监控)
23.Arthas stack (输出当前方法被调用的调用路径)
24.Arthas trace (方法内部调用路径,并输出方法路径上的每个节点上耗时)
25.Arthas tt(方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测)
26.Arthas watch (方法执行数据观测)
27.Arthas profiler(使用async-profiler对应用采样,生成火焰图)

<think>我们正在讨论Dockerfile中的`COPY --from`指令。这个指令是多阶段构建(multi-stage build)中的关键部分,它允许从一个构建阶段复制文件到另一个构建阶段。这对于减少最终镜像的大小非常有用,因为我们可以只复制必要的文件,而不包含构建过程中产生的中间文件或开发依赖。 ### 1. `COPY --from`的基本作用 - **跨阶段复制**:在Docker的多阶段构建中,每个`FROM`指令开始一个新的构建阶段。`COPY --from`允许你从之前的阶段(或者从外部镜像)复制文件到当前阶段。 - **减少镜像大小**:例如,在第一阶段使用一个较大的基础镜像(如包含编译工具链的镜像)来构建应用程序,然后在第二阶段使用一个轻量级的基础镜像(如alpine),并只从第一阶段复制编译好的可执行文件。这样,最终镜像只包含运行所需的文件,而不包含编译工具等,从而显著减小镜像体积。 ### 2. 语法格式 ```dockerfile COPY --from=<stage_name|index> <源路径> <目标路径> ``` - `--from`:指定源构建阶段。可以是阶段名称(通过`AS`子句命名)或阶段索引(从0开始)。 - `<源路径>`:要复制的文件或目录在源阶段中的路径。 - `<目标路径>`:当前阶段中文件或目录的目标路径。 ### 3. 使用示例 #### 示例1:从命名阶段复制 ```dockerfile # 第一阶段:构建阶段 FROM golang:1.18 AS builder WORKDIR /app COPY . . RUN go build -o myapp . # 第二阶段:运行阶段 FROM alpine:latest WORKDIR /root/ # 从builder阶段复制编译好的可执行文件 COPY --from=builder /app/myapp . CMD ["./myapp"] ``` - 说明:第一阶段使用`golang`镜像构建Go应用,第二阶段使用轻量级的`alpine`镜像,并从`builder`阶段复制构建好的可执行文件`myapp`。 #### 示例2:使用阶段索引 阶段索引从0开始,第一个`FROM`阶段为0,第二个为1,以此类推。但通常推荐使用命名阶段,因为索引在调整阶段顺序时容易出错。 ```dockerfile COPY --from=0 /app/myapp . ``` #### 示例3:从外部镜像复制 `COPY --from`也可以直接从外部镜像复制文件,而不需要先定义该阶段。例如: ```dockerfile FROM alpine:latest COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf ``` - 说明:从`nginx:latest`镜像中复制`/etc/nginx/nginx.conf`文件到当前镜像的根目录下,命名为`nginx.conf`。这常用于提取其他镜像中的配置文件或工具。 ### 4. 注意事项 - **路径问题**:源路径必须是源阶段(或外部镜像)中存在的路径,否则会报错。 - **阶段命名**:使用`AS`为阶段命名(如`FROM golang AS builder`)可以使`COPY --from`更易读和维护。 - **缓存影响**:多阶段构建中,每个阶段是独立的,但Docker会缓存各个阶段。如果前一阶段发生变化,后续阶段中依赖于它的`COPY --from`会重新执行。 ### 5. 与普通`COPY`的区别 - 普通`COPY`只能从主机(构建上下文)复制文件到镜像。 - `COPY --from`则可以从之前的构建阶段或外部镜像复制文件,实现跨阶段复制。 ### 6. 实际应用场景 - **编译型语言**:如Go、C++等,第一阶段安装编译器和依赖并编译,第二阶段复制二进制文件。 - **前端构建**:第一阶段使用Node.js镜像构建静态文件,第二阶段使用Nginx镜像并复制构建好的静态文件。 - **提取工具**:从包含特定工具的镜像中复制工具到当前镜像,避免安装过程。 ### 总结 `COPY --from`是Docker多阶段构建的核心指令,它通过分离构建环境和运行环境,优化了镜像大小和安全性。使用时注意: 1. 使用`AS`为阶段命名提高可读性。 2. 确保源路径存在。 3. 尽量使用轻量级基础镜像作为最终阶段。 §§相关问题§§ 1. Docker多阶段构建还有哪些优化技巧? 2. 如何为Docker构建阶段命名? 3. 除了`COPY --from`,还有哪些指令支持多阶段构建? 4. 如何从外部镜像复制多个文件? [^1]: COPY 遵守以下规则: 该``路径必须是内部语境的构建; 您不能这样做COPY ../something /something,因为a的第一步 docker build是将上下文目录(和子目录)发送到docker守护程序。如果``是目录,则将复制目录的整个内容,包括文件系统元数据。 [^2]: 仅适用于 linux 上的 dockerfile,在 window 上没有用户、组的概念 COPY 作用 COPY 指令从 <src> 复制新文件、目录或远程文件 URL,并将它们添加到路径 <dest>可以指定多个 <src> 资源,但如果它们是文件或目录,则它们的路径被解析为相对于构建上下文的源每个 <src> 可能包含通配符,匹配将使用 Go 的 filepath.Match 规则完成 简单栗子 * 通配符 [^3]: Dockerfile指令详解。 8. RUN 作用:在镜像构建过程中执行命令。它是 Dockerfile 中最常用的指令之一,主要用于安装软件包、执行脚本、配置系统等操作。 [^4]: FROM #基础镜像,一切从这里开始构建 MAINTAINER #镜像是谁写的姓名+邮箱 RUN #镜像构建的时候需要运行的命令 ADD #步骤,tomcat镜像,tomcat的压缩包添加的内容 WORKDIR #镜像的工作目录 VOLUME #挂载的目录 EXPOSE #暴露端口配置 CMD #指定这个容器启动时要运行的命令(只有最后一个生效,可被替代) ENTRYPOINT #指定这个容器启动时要运行的命令(可以追加命令 ) ONBUILD #当构建一个被继承Dockerfile这个时候就会运行ONBUILD的指令。触发指令。 COPY #类似ADD,帮我们文件拷贝到镜像中 ENV #构建的时候设置环境变量!</think>### Dockerfile 中 `COPY --from` 指令详解 `COPY --from` 是 Docker 多阶段构建(Multi-stage Builds)中的核心指令,用于在不同构建阶段之间复制文件。它解决了传统单阶段构建中镜像臃肿的问题,通过分离构建环境和运行环境,显著减小最终镜像体积。 #### 一、核心作用 1. **跨阶段文件复制** 从其他构建阶段或外部镜像复制文件到当前构建阶段: ```dockerfile # 阶段1:构建环境 FROM maven:3.8 AS builder COPY . /app RUN mvn package # 阶段2:运行环境 FROM openjdk:11-jre COPY --from=builder /app/target/*.jar /app.jar # 关键指令 ``` 2. **减小镜像体积** 只复制必要的运行时文件(如编译后的 JAR),排除构建工具(如 Maven/Gradle)和中间文件。 3. **提升安全性** 避免在最终镜像中包含敏感信息(如构建密钥、源代码)。 #### 二、语法解析 ```dockerfile COPY --from=<源> <源路径> <目标路径> ``` - **`<源>` 的三种形式**: - **阶段别名**:`--from=builder`(需使用 `AS` 定义别名) - **阶段索引**:`--from=0`(第一个 `FROM` 阶段为 0) - **外部镜像**:`--from=nginx:alpine` - **路径规则**: - 源路径必须存在于指定阶段/镜像中 - 目标路径相对于当前 `WORKDIR` - 支持通配符(如 `*.jar`) #### 三、使用场景示例 1. **跨阶段复制构建产物** ```dockerfile # 阶段1:编译Go程序 FROM golang:1.18 AS build WORKDIR /src COPY . . RUN go build -o app . # 阶段2:最小化运行时 FROM scratch COPY --from=build /src/app /app # 只复制二进制文件 ENTRYPOINT ["/app"] ``` 2. **从外部镜像复制工具** ```dockerfile FROM alpine:latest # 从官方Nginx镜像复制配置 COPY --from=nginx:alpine /etc/nginx/nginx.conf /etc/nginx/nginx.conf ``` 3. **组合多个构建阶段** ```dockerfile FROM node:14 AS frontend-builder COPY frontend . RUN npm install && npm run build FROM maven:3.8 AS backend-builder COPY backend . RUN mvn package FROM tomcat:9 # 合并前端+后端产物 COPY --from=frontend-builder /dist /webapps/ROOT COPY --from=backend-builder /target/*.war /webapps/app.war ``` #### 四、注意事项 1. **路径有效性** 源路径必须在源阶段存在,否则构建失败(错误:`no such file or directory`)[^1]。 2. **构建缓存** 修改源阶段的文件会使 `COPY --from` 的缓存失效。 3. **权限保留** 复制的文件保留原始权限,可能需要 `RUN chmod` 调整。 4. **外部镜像限制** 复制自外部镜像时,仅包含文件系统内容,不包括环境变量或元数据。 #### 五、最佳实践 1. **使用阶段别名** 优先使用 `FROM ... AS <name>` + `COPY --from=<name>`,比数字索引更易维护。 2. **最小化复制范围** 精确指定文件路径(如 `/app/target/*.jar`),避免复制整个目录。 3. **结合 `.dockerignore`** 忽略无关文件(如 `node_modules/`),减少构建上下文大小[^2]。 > **对比单阶段构建** > 传统方式(未用 `--from`)的镜像通常 1GB+,而多阶段构建可缩小至 100MB 以下,且不包含源代码和构建工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘大猫.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值