移除 SpringBoot JAR 优化指南并添加 Gitee SSH 设置文档
原来的 SpringBoot JAR 优化指南 (SpringBoot打包体积优化) 已被删除,以简化仓库内容。同时,新增了一份全面的指南,帮助开发者设置 Gitee 的 SSH 密钥,以便安全访问仓库。新文档涵盖了使用现代 ed25519 加密标准进行密钥生成、配置和管理。
This commit is contained in:
parent
fbfcfcaae2
commit
deeeb41145
1225
src/programming/java/工具箱/Spring Boot JAR 瘦身与加密.md
Normal file
1225
src/programming/java/工具箱/Spring Boot JAR 瘦身与加密.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,616 +0,0 @@
|
||||
---
|
||||
icon: bi:arrows-expand
|
||||
date: 2025-05-13
|
||||
category:
|
||||
- 实用工具
|
||||
- JAVA
|
||||
- SpringBoot
|
||||
- JAR
|
||||
tag:
|
||||
- JAR包瘦身
|
||||
title: SpringBoot打包体积优化.md
|
||||
---
|
||||
|
||||
SpringBoot打包体积优化
|
||||
<!-- more -->
|
||||
|
||||
# Spring Boot JAR 瘦身与加密:构建安全高效的部署方案
|
||||
|
||||
在 Spring Boot 应用程序部署过程中,我们常常面临两个主要挑战:
|
||||
|
||||
1. **JAR 包体积过大**:Spring Boot 应用打包时会将所有依赖一起打包,导致最终 JAR 文件臃肿
|
||||
2. **代码安全性问题**:部署到客户环境或公开场合的 JAR 包可能被反编译,造成核心业务逻辑泄露
|
||||
|
||||
为了解决这些问题,本文将介绍一套完整的解决方案,包括 JAR 包瘦身和 JAR 包加密两部分,以及配套的自定义类加载器,实现高效安全的
|
||||
Spring Boot 应用部署。
|
||||
|
||||
## 整体方案设计
|
||||
|
||||
该方案由两个主要项目组成:
|
||||
|
||||
1. **spring-boot-jar-slim-encrypt**:用于将 Spring Boot 应用 JAR 包瘦身和加密
|
||||
2. **spring-boot-custom-classloader**:用于加载瘦身和加密后的 JAR 包
|
||||
|
||||
### 工作流程
|
||||
|
||||
```
|
||||
┌────────────────────┐
|
||||
│ 原始Spring Boot │
|
||||
│ JAR包 │
|
||||
└──────────┬─────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────┐ ┌────────────────────┐
|
||||
│ spring-boot-jar- │ │ │
|
||||
│ slim-encrypt工具 ├───►│ 提取依赖到libs目录 │
|
||||
└──────────┬─────────┘ └────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ 瘦身后的JAR包 │
|
||||
└──────────┬─────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ XJar加密处理 │
|
||||
└──────────┬─────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────┐
|
||||
│ 加密后的JAR包 │
|
||||
│ (.xjar) │
|
||||
└──────────┬─────────┘
|
||||
│
|
||||
│ 部署
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 运行时环境 │
|
||||
│ ┌─────────────────┐ ┌───────────────┐ │
|
||||
│ │ 加密JAR (.xjar) │ │ 提取的依赖库 │ │
|
||||
│ └────────┬────────┘ └───────┬───────┘ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌─────────────────────────────────┐ │
|
||||
│ │ PlainTextClassLoader │ │
|
||||
│ │ (自定义类加载器) │ │
|
||||
│ └─────────────┬─────────────┬─────┘ │
|
||||
│ │ │ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌─────────────────┐ ┌───────────────┐ │
|
||||
│ │ 解密JAR内容 │ │ 加载外部依赖 │ │
|
||||
│ └─────────────────┘ └───────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
1. 使用 spring-boot-jar-slim-encrypt 工具提取原始 JAR 包中的依赖
|
||||
2. 将依赖库单独存储在 libs 目录
|
||||
3. 对精简后的 JAR 包进行加密
|
||||
4. 使用自定义类加载器加载外部依赖和解密 JAR 包
|
||||
|
||||
## 项目一:spring-boot-custom-classloader
|
||||
|
||||
这是一个自定义类加载器项目,它实现了两种类加载器:
|
||||
|
||||
### 1. JarClassLoader 接口
|
||||
|
||||
```java
|
||||
package com.mangmang;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface JarClassLoader {
|
||||
String JAR_EXTENSION = ".jar";
|
||||
|
||||
/**
|
||||
* 从指定目录加载所有JAR文件
|
||||
*
|
||||
* @param jarDir 包含要加载的JAR文件的目录路径
|
||||
* @throws IllegalArgumentException 如果jarDir为null或不存在
|
||||
*/
|
||||
default void loadJar(String jarDir) {
|
||||
if (jarDir == null || jarDir.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("JAR目录路径不能为空");
|
||||
}
|
||||
|
||||
File directory = new File(jarDir);
|
||||
if (!directory.exists() || !directory.isDirectory()) {
|
||||
throw new IllegalArgumentException("指定路径不是有效目录: " + jarDir);
|
||||
}
|
||||
|
||||
File[] jarFiles = directory.listFiles(this::isJarFile);
|
||||
if (jarFiles == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (File jarFile : jarFiles) {
|
||||
System.out.println("加载 》" + jarFile.getName());
|
||||
scanJarFile(jarFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归扫描文件或目录以查找JAR文件
|
||||
*
|
||||
* @param file 要扫描的文件或目录
|
||||
* @throws IllegalArgumentException 如果file为null
|
||||
*/
|
||||
default void scanJarFile(File file) {
|
||||
if (file == null) {
|
||||
throw new IllegalArgumentException("文件不能为null");
|
||||
}
|
||||
|
||||
if (!file.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isJarFile(file)) {
|
||||
addJARFile(file);
|
||||
} else if (file.isDirectory()) {
|
||||
File[] files = file.listFiles();
|
||||
if (files != null) {
|
||||
for (File f : files) {
|
||||
scanJarFile(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查文件是否为JAR文件
|
||||
*/
|
||||
default boolean isJarFile(File file) {
|
||||
return file.isFile() && file.getName().endsWith(JAR_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JAR文件添加到类加载器
|
||||
*
|
||||
* @param jar 要添加的JAR文件
|
||||
* @throws IllegalArgumentException 如果jar为null或不是有效的JAR文件
|
||||
*/
|
||||
void addJARFile(File jar);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
这是一个接口,定义了 JAR 文件加载的核心方法:
|
||||
|
||||
- `loadJar(String jarDir)`: 从指定目录加载所有 JAR 文件
|
||||
- `scanJarFile(File file)`: 递归扫描文件或目录查找 JAR 文件
|
||||
- `isJarFile(File file)`: 检查文件是否为 JAR 文件
|
||||
- `addJARFile(File jar)`: 将 JAR 文件添加到类加载器
|
||||
|
||||
### 2. PlainTextClassLoader 实现
|
||||
|
||||
```java
|
||||
package com.mangmang;
|
||||
|
||||
import org.springframework.boot.context.event.ApplicationStartingEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 明文类加载器
|
||||
* <p>
|
||||
* 该类实现了自定义类加载器接口和Spring应用启动事件监听器接口。
|
||||
* 主要功能是在应用启动时,从JVM启动参数中查找指定路径的JAR文件并加载。
|
||||
* 通过反射机制将JAR文件动态添加到当前线程的类加载器中,实现运行时加载额外的类库。
|
||||
* </p>
|
||||
* <p>
|
||||
* 使用方法:
|
||||
* 1. 在JVM启动参数中添加 -Dexternal.jars.path=你的JAR文件目录路径
|
||||
* 2. 系统将自动加载该目录下所有的JAR文件
|
||||
* </p>
|
||||
* <p>
|
||||
* 示例:
|
||||
* java -Dexternal.jars.path.path=/path/to/jars -jar your-application.jar
|
||||
* </p>
|
||||
*/
|
||||
public class PlainTextClassLoader implements JarClassLoader, ApplicationListener<ApplicationStartingEvent> {
|
||||
|
||||
private final String findPath = "external.jars.path"; // 查找路径的键名
|
||||
private final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // 获取当前线程的类加载器
|
||||
private final List<File> jarFiles = new ArrayList<>(); // 存储已加载的JAR文件列表
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
* <p>
|
||||
* 在初始化时执行以下操作:
|
||||
* 1. 设置当前线程的类加载器
|
||||
* 2. 输出启动日志信息
|
||||
* 3. 从JVM启动参数中检索包含"external.jars.path.path"的参数
|
||||
* 4. 提取路径值并调用loadJar方法加载指定目录下的JAR文件
|
||||
* </p>
|
||||
*/
|
||||
public PlainTextClassLoader() {
|
||||
// 设置当前线程的类加载器
|
||||
Thread.currentThread().setContextClassLoader(classLoader);
|
||||
|
||||
// 打印启动信息
|
||||
System.out.println("启动自定义明文类加载器");
|
||||
|
||||
// 查找并加载外部JAR文件
|
||||
loadExternalJarsFromSystemProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从系统属性中查找并加载外部JAR文件
|
||||
*/
|
||||
private void loadExternalJarsFromSystemProperties() {
|
||||
List<String> inputArguments = ManagementFactory.getRuntimeMXBean().getInputArguments();
|
||||
|
||||
// 查找包含指定路径参数的启动参数
|
||||
inputArguments.stream()
|
||||
.filter(arg -> arg.contains(findPath))
|
||||
.map(this::extractPathFromArgument)
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(this::loadJar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从JVM参数中提取路径值
|
||||
*
|
||||
* @param argument JVM启动参数
|
||||
* @return 提取的路径值,如果提取失败则返回null
|
||||
*/
|
||||
private String extractPathFromArgument(String argument) {
|
||||
String prefix = "-D" + findPath + "=";
|
||||
if (argument.startsWith(prefix)) {
|
||||
String path = argument.replace(prefix, "");
|
||||
if (!path.isEmpty()) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理应用程序启动事件
|
||||
* <p>
|
||||
* 当Spring应用启动时会触发此方法。
|
||||
* 目前该方法为空实现,可以在此添加应用启动时需要执行的代码。
|
||||
* </p>
|
||||
*
|
||||
* @param event Spring应用启动事件对象
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(@NonNull ApplicationStartingEvent event) {
|
||||
// 应用程序启动事件的处理方法,目前为空
|
||||
}
|
||||
|
||||
/**
|
||||
* 将JAR文件添加到类加载器
|
||||
* <p>
|
||||
* 通过反射机制调用URLClassLoader的addURL方法,将指定的JAR文件URL添加到当前类加载器。
|
||||
* 添加成功后,JAR文件中的类可以被当前JVM加载和使用。
|
||||
* 同时将已加载的JAR文件记录到jarFiles列表中。
|
||||
* </p>
|
||||
*
|
||||
* @param jar 要添加到类加载器的JAR文件对象
|
||||
* @throws RuntimeException 如果添加过程中发生任何异常,将抛出RuntimeException
|
||||
*/
|
||||
@Override
|
||||
public void addJARFile(File jar) {
|
||||
if (jar == null) {
|
||||
throw new IllegalArgumentException("JAR文件不能为null");
|
||||
}
|
||||
|
||||
try {
|
||||
addUrlToClassLoader(jar);
|
||||
jarFiles.add(jar);
|
||||
System.out.println(jarFiles);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("添加JAR文件到类加载器失败: " + jar.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过反射将JAR文件URL添加到类加载器
|
||||
*
|
||||
* @param jar 要添加的JAR文件
|
||||
* @throws Exception 如果反射操作失败
|
||||
*/
|
||||
private void addUrlToClassLoader(File jar) throws Exception {
|
||||
Method addUrlMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
|
||||
if (!addUrlMethod.isAccessible()) {
|
||||
addUrlMethod.setAccessible(true);
|
||||
}
|
||||
URL jarUrl = jar.toURI().toURL();
|
||||
addUrlMethod.invoke(classLoader, jarUrl);
|
||||
}
|
||||
```
|
||||
|
||||
这是一个明文类加载器,实现了 `JarClassLoader` 接口和 Spring 的 `ApplicationListener<ApplicationStartingEvent>` 接口,用于在
|
||||
Spring Boot 应用启动时加载外部 JAR 文件:
|
||||
|
||||
主要特点:
|
||||
|
||||
- 在 Spring Boot 应用启动时自动执行
|
||||
- 通过 JVM 参数 `-Dexternal.jars.path=你的JAR文件目录路径` 指定外部 JAR 文件目录
|
||||
- 使用反射机制将 JAR 文件 URL 添加到当前线程的类加载器中
|
||||
|
||||
使用示例:
|
||||
|
||||
```bash
|
||||
java -Dexternal.jars.path=/path/to/jars -jar your-application.jar
|
||||
```
|
||||
|
||||
## 项目二:spring-boot-jar-slim-encrypt
|
||||
|
||||
这个工具用于压缩和加密 Spring Boot JAR 文件,主要包含以下两个核心类:
|
||||
|
||||
### 1. JarUtil 工具类
|
||||
|
||||
```java
|
||||
// 路径:spring-boot-jar-slim-encrypt/src/main/java/com/mangmang/JarUtil.java
|
||||
package com.sunri;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import io.xjar.XCryptos;
|
||||
import io.xjar.XEncryption;
|
||||
import org.apache.commons.compress.utils.IOUtils;
|
||||
import org.apache.commons.compress.utils.Sets;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarOutputStream;
|
||||
|
||||
public class JarUtil {
|
||||
/**
|
||||
* 表示UTF-8字符编码的常量。
|
||||
* 该变量用于在各种文件操作中强制使用UTF-8编码,
|
||||
* 确保在整个应用程序中一致地处理文本数据。
|
||||
*/
|
||||
private static final String UTF_8 = "UTF-8";
|
||||
/**
|
||||
* 常量BOOT_INF_LIB表示JAR文件中通常存储依赖库的默认目录路径。
|
||||
* 该路径主要用于在压缩或排除等操作中识别和处理库文件。
|
||||
*/
|
||||
private static final String BOOT_INF_LIB = "BOOT-INF/lib";
|
||||
/**
|
||||
* 用于标识JAR(Java归档)文件的文件扩展名。
|
||||
* 该常量表示JAR文件的标准扩展名,通常用于
|
||||
* 文件过滤、命名或在目录或归档中识别JAR文件的操作。
|
||||
*/
|
||||
private static final String JAR_EXTENSION = ".jar";
|
||||
/**
|
||||
* 定义在管理JAR过程中生成的需求文件的后缀,
|
||||
* 特别是在处理依赖项或排除项时使用。
|
||||
* 该字符串用作特定的文件名模式,用于保存与特定服务
|
||||
* 相关的排除依赖项或其他需求的列表。
|
||||
* 默认值为"-requirements.txt"。
|
||||
*/
|
||||
private static final String REQUIREMENTS_SUFFIX = "-requirements.txt";
|
||||
/**
|
||||
* 预定义的、不可修改的特定jar文件名集合,被视为
|
||||
* "安全"或"始终包含"的文件。这些jar文件通常在
|
||||
* 处理或压缩操作中免于排除过滤。
|
||||
* 该集合包含以下jar标识符:
|
||||
* - "spring"
|
||||
* - "logback-core"
|
||||
* - "tomcat"
|
||||
* 该变量用于根据jar文件名决定是否包含特定jar文件的操作中。
|
||||
* 它作为应用程序关键或必要jar的白名单。
|
||||
*/
|
||||
private static final Set<String> WHITE_LIST_JARS = Sets.newHashSet("spring", "logback-core", "tomcat");
|
||||
|
||||
/**
|
||||
* 通过排除和包含指定的条目来压缩给定的源JAR文件,并将结果写入目标JAR文件。
|
||||
* 它处理源JAR的条目,应用排除和包含规则,还可以将某些条目提取到指定的目录中。
|
||||
* 在此过程中创建一个临时文件,成功完成后将其重命名为目标JAR文件。
|
||||
*
|
||||
* @param serviceName 正在处理的服务名称,主要用于日志记录和创建其他相关文件。
|
||||
* @param sourceJar 要压缩的源JAR文件。
|
||||
* @param includes 指定应保留哪些条目的包含模式集合。可能会自动添加额外的默认包含项。
|
||||
* @param exclusions 指定应排除哪些条目的排除模式集合。
|
||||
* @param targetJar 将写入压缩JAR的文件。
|
||||
* @param libDir 某些被排除的条目可能被提取到的目录(如适用)。
|
||||
*/
|
||||
public static void compress(String serviceName, File sourceJar, Set<String> includes, Set<String> exclusions, File targetJar, String libDir) {
|
||||
includes.addAll(WHITE_LIST_JARS);
|
||||
File tempJar = new File(targetJar.getAbsolutePath() + ".tmp");
|
||||
Set<String> excludedJars = new HashSet<>();
|
||||
|
||||
if (processJarEntries(sourceJar, tempJar, includes, exclusions, libDir, excludedJars)) {
|
||||
finalizeCompression(serviceName, targetJar, tempJar, excludedJars, libDir);
|
||||
} else {
|
||||
boolean delete = tempJar.delete();
|
||||
System.out.println("删除临时文件:{" + delete + "}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理源JAR文件中的条目以生成临时JAR文件,
|
||||
* 同时根据包含和排除规则过滤条目。如果需要,
|
||||
* 还会将指定的JAR条目提取到库目录中。
|
||||
*
|
||||
* @param sourceJar 要处理的源JAR文件
|
||||
* @param tempJar
|
||||
```
|
||||
|
||||
这个工具类提供了两个主要功能:
|
||||
|
||||
#### JAR 包压缩功能
|
||||
|
||||
`compress` 方法实现了 JAR 瘦身功能:
|
||||
|
||||
- 根据包含列表和排除列表过滤 JAR 中的依赖
|
||||
- 将被排除的依赖提取到指定的库目录
|
||||
- 生成一个记录排除依赖的需求文件
|
||||
- 创建一个只包含必要依赖的精简 JAR 文件
|
||||
|
||||
#### JAR 包加密功能
|
||||
|
||||
`encrypt` 方法利用 XJar 库实现了 JAR 加密:
|
||||
|
||||
- 支持指定加密密码
|
||||
- 通过包含和排除模式选择性地加密 JAR 中的内容
|
||||
- 生成加密后的 XJar 文件
|
||||
|
||||
### 2. SpringBootJarSlimEncryptApplication 主应用
|
||||
|
||||
```java
|
||||
// 路径:spring-boot-jar-slim-encrypt/src/main/java/com/mangmang/SpringBootJarSlimEncryptApplication.java
|
||||
```
|
||||
|
||||
这是工具的主应用类,提供了完整的命令行接口来处理 JAR 文件的压缩和加密:
|
||||
|
||||
主要功能:
|
||||
|
||||
- 通过配置常量定义输入/输出目录、加密设置等
|
||||
- 支持从 XML 配置文件加载要包含和排除的依赖项
|
||||
- 批量处理多个 JAR 文件
|
||||
- 支持通过系统属性覆盖默认配置
|
||||
|
||||
主要配置参数:
|
||||
|
||||
- `xml.dir`: 依赖项 XML 文件目录(默认: `./config/xml/`)
|
||||
- `raw.dir`: 原始 JAR 文件目录(默认: `./config/rawJars/`)
|
||||
- `compress.dir`: 压缩后 JAR 文件目录(默认: `./config/compressJars/`)
|
||||
- `libs.dir`: 提取的库文件目录(默认: `./config/libs/`)
|
||||
- `xjar.dir`: 加密后的 XJar 文件目录(默认: `./config/xJars/`)
|
||||
- `compress.enable`: 是否启用压缩功能(默认: `true`)
|
||||
|
||||
## 使用步骤
|
||||
|
||||
### 步骤 1: 集成自定义类加载器
|
||||
|
||||
在你的 Spring Boot 项目中添加自定义类加载器依赖:
|
||||
|
||||
```xml
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mangmang</groupId>
|
||||
<artifactId>spring-boot-custom-classloader</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### 步骤 2: 构建 Spring Boot 应用
|
||||
|
||||
正常构建你的 Spring Boot 应用:
|
||||
|
||||
```bash
|
||||
mvn clean package
|
||||
```
|
||||
|
||||
### 步骤 3: 配置依赖排除和包含规则
|
||||
|
||||
创建两个 XML 文件以定义要排除和包含的依赖项:
|
||||
|
||||
**exclusions.xml**(要排除的依赖):
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
<!-- 其他要排除的依赖 -->
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
**includes.xml**(要保留的依赖):
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<artifactId>spring-boot-custom-classloader</artifactId>
|
||||
</dependency>
|
||||
<!-- 其他要保留的依赖 -->
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
### 步骤 4: 执行 JAR 瘦身和加密工具
|
||||
|
||||
将你的 Spring Boot JAR 文件放入 `./config/rawJars/` 目录,然后运行瘦身加密工具:
|
||||
|
||||
```bash
|
||||
java -jar spring-boot-jar-slim-encrypt.jar
|
||||
```
|
||||
|
||||
你可以通过系统属性覆盖默认配置:
|
||||
|
||||
```bash
|
||||
java -Dcompress.enable=true -Dlibs.dir=/custom/libs/path -jar spring-boot-jar-slim-encrypt.jar
|
||||
```
|
||||
|
||||
### 步骤 5: 部署和运行
|
||||
|
||||
部署加密后的 JAR 文件和提取的库文件:
|
||||
|
||||
```bash
|
||||
java -Dexternal.jars.path=/path/to/libs -jar your-application.xjar
|
||||
```
|
||||
|
||||
## 技术原理解析
|
||||
|
||||
### JAR 瘦身原理
|
||||
|
||||
1. 扫描 Spring Boot JAR 中的 `BOOT-INF/lib` 目录
|
||||
2. 根据配置的排除和包含规则过滤依赖
|
||||
3. 将被排除的依赖提取到外部目录
|
||||
4. 创建一个不包含被排除依赖的新 JAR 文件
|
||||
|
||||
### JAR 加密原理
|
||||
|
||||
1. 使用 XJar 库实现 JAR 文件内容的加密
|
||||
2. 只加密指定的文件模式(如 Java 类文件、配置文件等)
|
||||
3. 避免加密某些需要保持明文的资源
|
||||
|
||||
### 自定义类加载器原理
|
||||
|
||||
1. 在 Spring Boot 应用启动时初始化自定义类加载器
|
||||
2. 扫描指定目录下的 JAR 文件
|
||||
3. 使用反射机制将 JAR 文件 URL 添加到当前类加载器
|
||||
|
||||
## 方案优势
|
||||
|
||||
1. **减小 JAR 体积**:将大型依赖库外置,显著减小主 JAR 文件体积
|
||||
2. **提高安全性**:通过加密保护核心业务逻辑和敏感配置
|
||||
3. **灵活配置**:支持通过 XML 配置和系统属性灵活控制瘦身和加密过程
|
||||
4. **无缝集成**:与 Spring Boot 应用无缝集成,无需修改应用代码
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 确保加密密码安全保存,丢失密码将导致无法运行加密的 JAR
|
||||
2. 测试瘦身后的应用,确保所有需要的依赖都能正确加载
|
||||
3. 部署时必须将提取的依赖库和加密后的 JAR 一起部署
|
||||
4. 启动应用时必须指定外部库路径参数
|
||||
|
||||
## 结论
|
||||
|
||||
通过结合 JAR 瘦身、JAR 加密和自定义类加载器,我们成功构建了一套完整的 Spring Boot 应用优化和保护方案。这不仅有效减小了部署包的体积,还提高了应用的安全性,为企业级
|
||||
Spring Boot 应用的部署提供了一种实用的解决方案。
|
||||
|
||||
在实际应用中,可以根据具体需求调整配置参数,以达到最佳的平衡点。例如,可以根据应用规模和安全需求调整要排除的依赖和加密的文件模式。
|
||||
|
||||
这套工具实现了将原本臃肿的 Spring Boot 应用拆分为核心加密 JAR 和外部依赖库的方案,使得应用部署更加灵活,也为应用分发和更新提供了更多可能性。
|
||||
|
||||
------
|
||||
|
||||
*注:本方案适用于需要保护核心业务逻辑或减小部署包体积的 Spring Boot
|
||||
应用。对于简单应用或开源项目,可能不必使用这么复杂的方案。*
|
558
src/programming/java/工具箱/WSL2.md
Normal file
558
src/programming/java/工具箱/WSL2.md
Normal file
@ -0,0 +1,558 @@
|
||||
---
|
||||
icon: bi:arrows-expand
|
||||
date: 2025-05-08
|
||||
category:
|
||||
- win10
|
||||
tag:
|
||||
- wsl
|
||||
- http
|
||||
title: WSL2
|
||||
---
|
||||
|
||||
# WSL2完全配置指南:从安装到实用工具
|
||||
Windows Subsystem for Linux (WSL2) 为Windows用户提供了无需双系统或虚拟机就能运行Linux环境的能力。本文将全面介绍WSL2的安装、配置和优化过程,包括网络设置、常用工具安装和问题排查等内容。
|
||||
<!-- more -->
|
||||
## 安装WSL2
|
||||
|
||||
1. **启用WSL功能**: 打开控制面板,启用"Windows Subsystem for Linux"和"虚拟机平台"功能,然后重启电脑。
|
||||
|
||||
2. **检查WSL版本**:
|
||||
|
||||
```powershell
|
||||
wsl --status
|
||||
wsl --update
|
||||
```
|
||||
|
||||
3. **设置默认为WSL2**:
|
||||
|
||||
```powershell
|
||||
wsl --set-default-version 2
|
||||
```
|
||||
|
||||
4. **查看可用的Linux发行版**:
|
||||
|
||||
```powershell
|
||||
wsl --list --online
|
||||
```
|
||||
|
||||
5. **安装Linux发行版**:
|
||||
|
||||
```powershell
|
||||
# 安装默认版本(Ubuntu)
|
||||
wsl --install
|
||||
|
||||
# 或安装指定版本
|
||||
wsl --install -d Ubuntu-24.04
|
||||
```
|
||||
|
||||
6. **设置用户名和密码**,安装完成后系统会提示设置。
|
||||
|
||||
7. **更新系统**:
|
||||
|
||||
```bash
|
||||
sudo apt update && sudo apt upgrade
|
||||
```
|
||||
|
||||
8. **验证安装**:
|
||||
|
||||
```powershell
|
||||
wsl -l -v
|
||||
```
|
||||
|
||||
## 网络配置
|
||||
|
||||
### 配置DNS
|
||||
|
||||
WSL2使用的DNS服务器在`/etc/resolv.conf`文件中设置,为防止每次启动重置,需要进行以下配置:
|
||||
|
||||
1. 创建`/etc/wsl.conf`文件:
|
||||
|
||||
```bash
|
||||
[network]
|
||||
generateResolvConf = false
|
||||
```
|
||||
|
||||
2. 删除原链接文件:
|
||||
|
||||
```bash
|
||||
rm /etc/resolv.conf
|
||||
```
|
||||
|
||||
3. 创建新配置:
|
||||
|
||||
```bash
|
||||
vi /etc/resolv.conf
|
||||
# 添加内容
|
||||
nameserver 114.114.114.114
|
||||
```
|
||||
|
||||
4. 重启WSL:
|
||||
|
||||
```bash
|
||||
exit
|
||||
wsl --shutdown
|
||||
wsl
|
||||
```
|
||||
|
||||
5. 测试网络:
|
||||
|
||||
```bash
|
||||
ping www.baidu.com
|
||||
```
|
||||
|
||||
### 配置桥接网络
|
||||
|
||||
1. **开启Hyper-V**后执行以下命令:
|
||||
|
||||
```powershell
|
||||
Get-NetAdapter
|
||||
New-VMSwitch -SwitchName "VETH" -NetAdapterName "以太网" -AllowManagementOS $True
|
||||
```
|
||||
|
||||
2. 创建`.wslconfig`配置文件:
|
||||
|
||||
```powershell
|
||||
cd ~
|
||||
New-Item .wslconfig
|
||||
notepad .\.wslconfig
|
||||
```
|
||||
|
||||
3. 添加以下内容:
|
||||
|
||||
```
|
||||
[wsl2]
|
||||
networkingMode=bridged
|
||||
vmSwitch=VETH
|
||||
ipv6=true
|
||||
```
|
||||
|
||||
### 配置网络代理
|
||||
|
||||
1. 关闭自动更新DNS:
|
||||
|
||||
```bash
|
||||
#/etc/wsl.conf
|
||||
[network]
|
||||
generateResolvConf = false
|
||||
```
|
||||
|
||||
2. 添加以下脚本至`.bashrc`或`.zshrc`:
|
||||
|
||||
```bash
|
||||
vi ~/.bashrc
|
||||
# 添加代理配置
|
||||
export hostip=10.6.212.22 # 替换为你的代理IP
|
||||
export hostport=7890 # 替换为你的代理端口
|
||||
alias proxy='
|
||||
export HTTPS_PROXY="http://${hostip}:${hostport}";
|
||||
export HTTP_PROXY="http://${hostip}:${hostport}";
|
||||
export ALL_PROXY="http://${hostip}:${hostport}";
|
||||
echo -e "Acquire::http::Proxy \"http://${hostip}:${hostport}\";" | sudo tee -a /etc/apt/apt.conf.d/proxy.conf > /dev/null;
|
||||
echo -e "Acquire::https::Proxy \"http://${hostip}:${hostport}\";" | sudo tee -a /etc/apt/apt.conf.d/proxy.conf > /dev/null;
|
||||
'
|
||||
alias unproxy='
|
||||
unset HTTPS_PROXY;
|
||||
unset HTTP_PROXY;
|
||||
unset ALL_PROXY;
|
||||
sudo sed -i -e '/Acquire::http::Proxy/d' /etc/apt/apt.conf.d/proxy.conf;
|
||||
sudo sed -i -e '/Acquire::https::Proxy/d' /etc/apt/apt.conf.d/proxy.conf;
|
||||
'
|
||||
```
|
||||
|
||||
3. 执行命令启用/禁用代理:
|
||||
|
||||
```bash
|
||||
# 启用代理
|
||||
proxy
|
||||
|
||||
# 禁用代理
|
||||
unproxy
|
||||
```
|
||||
|
||||
4. 固定DNS配置:
|
||||
|
||||
```bash
|
||||
sudo rm /etc/resolv.conf
|
||||
sudo bash -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'
|
||||
sudo bash -c 'echo "[network]" > /etc/wsl.conf'
|
||||
sudo bash -c 'echo "generateResolvConf = false" >> /etc/wsl.conf'
|
||||
sudo chattr +i /etc/resolv.conf
|
||||
```
|
||||
|
||||
5. 测试代理:
|
||||
|
||||
```bash
|
||||
curl -vv google.com
|
||||
```
|
||||
|
||||
## 基础功能配置
|
||||
|
||||
### 开启SSH服务
|
||||
|
||||
1. 安装SSH服务:
|
||||
|
||||
```bash
|
||||
sudo apt update && sudo apt upgrade
|
||||
sudo apt-get install openssh-server
|
||||
```
|
||||
|
||||
2. 修改SSH配置:
|
||||
|
||||
```bash
|
||||
sudo vi /etc/ssh/sshd_config
|
||||
```
|
||||
|
||||
找到`PasswordAuthentication`行,确保设置为`yes`
|
||||
|
||||
3. 启动并设置开机自启:
|
||||
|
||||
```bash
|
||||
sudo systemctl status ssh
|
||||
sudo systemctl start ssh
|
||||
sudo systemctl enable ssh
|
||||
```
|
||||
|
||||
### 安装桌面环境
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install ubuntu-desktop
|
||||
# 安装远程桌面服务
|
||||
sudo apt-get install xrdp
|
||||
sudo systemctl start xrdp
|
||||
sudo systemctl enable xrdp
|
||||
```
|
||||
|
||||
### 映射Windows目录至WSL
|
||||
|
||||
```bash
|
||||
# 创建挂载点
|
||||
sudo mkdir /mnt/z
|
||||
# 挂载Windows目录
|
||||
sudo mount -t drvfs C:/User/xxx/Desktop/挂载文件 /mnt/z
|
||||
```
|
||||
|
||||
## 系统管理
|
||||
|
||||
### 查看端口
|
||||
|
||||
查询端口占用有两种常用方法:
|
||||
|
||||
1. 使用`netstat`:
|
||||
|
||||
```bash
|
||||
sudo apt-get install net-tools
|
||||
sudo netstat -tunlp | grep 端口号
|
||||
```
|
||||
|
||||
2. 使用`lsof`:
|
||||
|
||||
```bash
|
||||
sudo apt-get install lsof
|
||||
sudo lsof -i:端口号
|
||||
```
|
||||
|
||||
### 修改主机名
|
||||
|
||||
1. 使用`hostnamectl`命令:
|
||||
|
||||
```bash
|
||||
sudo hostnamectl set-hostname 新主机名
|
||||
```
|
||||
|
||||
2. 修改配置文件:
|
||||
|
||||
```bash
|
||||
sudo vi /etc/hostname
|
||||
sudo vi /etc/hosts
|
||||
```
|
||||
|
||||
在hosts文件中将`127.0.1.1`对应的旧主机名替换为新主机名
|
||||
|
||||
3. 重启系统(可选):
|
||||
|
||||
```bash
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
## 开发环境配置
|
||||
|
||||
### IDEA中文乱码修复
|
||||
|
||||
1. 安装语言包:
|
||||
|
||||
```bash
|
||||
sudo apt install language-pack-zh-hans
|
||||
```
|
||||
|
||||
2. 配置语言环境:
|
||||
|
||||
```bash
|
||||
sudo dpkg-reconfigure locales
|
||||
# 选择en_US.UTF-8和zh_CN.UTF-8,并将zh_CN.UTF-8设为默认
|
||||
```
|
||||
|
||||
3. 安装字体工具:
|
||||
|
||||
```bash
|
||||
sudo apt install fontconfig
|
||||
```
|
||||
|
||||
4. 配置Windows字体:
|
||||
|
||||
```bash
|
||||
sudo vi /etc/fonts/local.conf
|
||||
```
|
||||
|
||||
添加内容:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||
<fontconfig>
|
||||
<dir>/mnt/c/Windows/Fonts</dir>
|
||||
</fontconfig>
|
||||
```
|
||||
|
||||
5. 刷新字体缓存:
|
||||
|
||||
```bash
|
||||
fc-cache -f -v
|
||||
```
|
||||
|
||||
6. 重启WSL:
|
||||
|
||||
```bash
|
||||
wsl --shutdown
|
||||
```
|
||||
|
||||
### IDEA配置输入法
|
||||
|
||||
1. 安装fcitx输入法:
|
||||
|
||||
```bash
|
||||
sudo apt install fcitx dbus-x11 im-config fcitx-sunpinyin
|
||||
```
|
||||
|
||||
2. 编辑`/etc/locale.gen`:
|
||||
|
||||
```bash
|
||||
vi /etc/locale.gen
|
||||
# 取消注释行:zh_CN.UTF-8
|
||||
```
|
||||
|
||||
3. 配置环境变量:
|
||||
|
||||
```bash
|
||||
vi ~/.profile
|
||||
# 添加内容
|
||||
export GTK_IM_MODULE=fcitx
|
||||
export QT_IM_MODULE=fcitx
|
||||
export XMODIFIERS=@im=fcitx
|
||||
export DefaultIMModule=fcitx
|
||||
fcitx-autostart &>/dev/null
|
||||
```
|
||||
|
||||
4. 更新配置:
|
||||
|
||||
```bash
|
||||
source ~/.profile
|
||||
```
|
||||
|
||||
5. 配置快捷键:
|
||||
|
||||
```bash
|
||||
fcitx-config-gtk3
|
||||
```
|
||||
|
||||
6. IDEA支持:编辑`idea.sh`启动脚本,添加:
|
||||
|
||||
```properties
|
||||
export XMODIFIERS=@im=fcitx
|
||||
export QT_IM_MODULE=fcitx
|
||||
```
|
||||
|
||||
### 安装Docker
|
||||
|
||||
1. 更新系统包:
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
```
|
||||
|
||||
2. 安装依赖:
|
||||
|
||||
```bash
|
||||
sudo apt install ca-certificates curl gnupg lsb-release
|
||||
```
|
||||
|
||||
3. 添加Docker官方GPG密钥:
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
```
|
||||
|
||||
4. 添加Docker APT源:
|
||||
|
||||
```bash
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
```
|
||||
|
||||
5. 更新包列表:
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
```
|
||||
|
||||
6. 安装Docker引擎:
|
||||
|
||||
```bash
|
||||
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
```
|
||||
|
||||
7. 启动并验证:
|
||||
|
||||
```bash
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
sudo docker --version
|
||||
```
|
||||
|
||||
### 安装1Panel
|
||||
|
||||
一键安装:
|
||||
|
||||
```bash
|
||||
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh
|
||||
```
|
||||
|
||||
查看管理员密码:
|
||||
|
||||
```bash
|
||||
sudo 1pctl user-info
|
||||
```
|
||||
|
||||
### 安装SVN
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install subversion
|
||||
svn --version # 验证安装
|
||||
```
|
||||
|
||||
## 问题记录
|
||||
|
||||
### SSH连接异常
|
||||
|
||||
症状:SSH服务启动失败,出现以下错误:
|
||||
|
||||
```
|
||||
error: Bind to port 22 on 0.0.0.0 failed: Address already in use.
|
||||
fatal: Missing privilege separation directory: /run/sshd
|
||||
```
|
||||
|
||||
解决方法:
|
||||
|
||||
1. 检查端口占用:
|
||||
|
||||
```bash
|
||||
sudo lsof -i:22
|
||||
```
|
||||
|
||||
2. 终止占用进程:
|
||||
|
||||
```bash
|
||||
sudo kill <PID>
|
||||
```
|
||||
|
||||
3. 创建缺失目录:
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /run/sshd
|
||||
sudo chmod 0755 /run/sshd
|
||||
```
|
||||
|
||||
4. 重启SSH服务:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart ssh
|
||||
```
|
||||
|
||||
## 常用指令
|
||||
|
||||
```powershell
|
||||
# 列出可用的Linux发行版
|
||||
wsl --list --online
|
||||
|
||||
# 列出已安装的发行版
|
||||
wsl --list --verbose # 或 wsl -l -v
|
||||
|
||||
# 设置WSL版本
|
||||
wsl --set-version <发行版名称> <版本号>
|
||||
|
||||
# 设置默认WSL版本
|
||||
wsl --set-default-version <版本号>
|
||||
|
||||
# 设置默认Linux发行版
|
||||
wsl --set-default <发行版名称>
|
||||
|
||||
# 运行特定发行版
|
||||
wsl --distribution <发行版名称> --user <用户名>
|
||||
|
||||
# 更新WSL
|
||||
wsl --update
|
||||
|
||||
# 检查WSL状态
|
||||
wsl --status
|
||||
|
||||
# 检查WSL版本
|
||||
wsl --version
|
||||
|
||||
# 以特定用户身份运行
|
||||
wsl --user <用户名>
|
||||
|
||||
# 卸载Linux发行版
|
||||
wsl --unregister <发行版名称>
|
||||
|
||||
# 标识IP地址
|
||||
wsl hostname -I # 返回WSL2 IP地址
|
||||
ip route show | grep -i default | awk '{ print $3}' # 返回Windows主机IP
|
||||
|
||||
# 更改默认用户
|
||||
<发行版名称> config --default-user <用户名>
|
||||
```
|
||||
|
||||
## 实用软件安装
|
||||
|
||||
### 安装适用于 Linux 的 Google Chrome
|
||||
|
||||
```bash
|
||||
cd /tmp
|
||||
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
|
||||
sudo apt install --fix-missing ./google-chrome-stable_current_amd64.deb
|
||||
```
|
||||
|
||||
启动命令:`google-chrome`
|
||||
|
||||
### 安装 VLC
|
||||
|
||||
```bash
|
||||
sudo apt install vlc -y
|
||||
```
|
||||
|
||||
启动命令:`vlc`
|
||||
|
||||
### 安装 X11 应用
|
||||
|
||||
```bash
|
||||
sudo apt install x11-apps -y
|
||||
```
|
||||
|
||||
启动命令示例:`xcalc`、`xclock`、`xeyes`
|
||||
|
||||
------
|
||||
|
||||
通过本文的配置指南,你可以构建一个功能完善的WSL2环境,满足日常开发、学习和娱乐需求。WSL2的灵活性使得Windows用户无需切换操作系统就能享受Linux的强大功能,是开发人员的理想工具。
|
Binary file not shown.
After Width: | Height: | Size: 248 KiB |
Binary file not shown.
After Width: | Height: | Size: 225 KiB |
Binary file not shown.
After Width: | Height: | Size: 167 KiB |
190
src/programming/java/工具箱/gitee-ssh.md
Normal file
190
src/programming/java/工具箱/gitee-ssh.md
Normal file
@ -0,0 +1,190 @@
|
||||
---
|
||||
icon: bi:arrows-expand
|
||||
date: 2025-05-08
|
||||
category:
|
||||
- 实用工具
|
||||
tag:
|
||||
- gitee
|
||||
- 码云
|
||||
title: Gitee SSH
|
||||
---
|
||||
|
||||
在Gitee上设置SSH公钥:完整指南
|
||||
<!-- more -->
|
||||
|
||||
# 在Gitee上设置SSH公钥:完整指南
|
||||
|
||||
## 引言
|
||||
|
||||
在使用Git进行代码管理时,SSH协议为开发者提供了一种安全且便捷的仓库访问方式。相比HTTPS协议,SSH协议不需要每次操作都输入用户名和密码,大大提高了开发效率。对于经常使用Gitee平台的Java开发者来说,正确配置SSH公钥是日常工作流程中的重要一环。本文将详细介绍如何在Gitee平台上生成并设置SSH公钥,帮助您实现更高效的代码管理。
|
||||
|
||||
## SSH公钥的基本概念
|
||||
|
||||
在深入了解操作步骤前,我们先来理解一下SSH公钥认证的基本原理:
|
||||
|
||||
- SSH认证基于非对称加密,包含一对密钥:私钥(保存在本地)和公钥(上传至服务器)
|
||||
- 私钥必须安全保管,不可泄露;公钥则可以自由分享
|
||||
- 当您使用SSH协议访问仓库时,Gitee会验证您的身份,确认您是否拥有与已注册公钥匹配的私钥
|
||||
|
||||
## 详细操作步骤
|
||||
|
||||
### 1. 生成SSH密钥对
|
||||
|
||||
首先,我们需要生成SSH密钥对。对于Windows用户,建议使用**Windows PowerShell**或**Git Bash**执行以下命令(注意:Windows的命令提示符中没有`cat`和`ls`命令)。
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -C "Gitee SSH Key"
|
||||
```
|
||||
|
||||
参数说明:
|
||||
- `-t`:指定密钥类型,这里使用更安全的ed25519算法
|
||||
- `-C`:添加注释,便于识别密钥的用途
|
||||
|
||||
执行命令后,系统会提示您输入保存密钥的位置和密码短语。一般情况下,直接按三次回车键即可使用默认设置:
|
||||
|
||||
```bash
|
||||
Generating public/private ed25519 key pair.
|
||||
Enter file in which to save the key (/home/git/.ssh/id_ed25519):
|
||||
Enter passphrase (empty for no passphrase):
|
||||
Enter same passphrase again:
|
||||
Your identification has been saved in /home/git/.ssh/id_ed25519
|
||||
Your public key has been saved in /home/git/.ssh/id_ed25519.pub
|
||||
```
|
||||
|
||||
这样我们就成功生成了两个文件:
|
||||
- `id_ed25519`:私钥文件(保密,不要分享)
|
||||
- `id_ed25519.pub`:公钥文件(需要上传到Gitee)
|
||||
|
||||
### 2. 获取公钥内容
|
||||
|
||||
执行以下命令查看生成的SSH公钥内容:
|
||||
|
||||
```bash
|
||||
cat ~/.ssh/id_ed25519.pub
|
||||
```
|
||||
|
||||
命令会输出类似以下格式的公钥内容:
|
||||
|
||||
```
|
||||
ssh-ed25519 AAAA***5B Gitee SSH Key
|
||||
```
|
||||
|
||||
请完整复制这段输出的内容,包括开头的`ssh-ed25519`和末尾的注释`Gitee SSH Key`。
|
||||
|
||||
### 3. 将公钥添加到Gitee账户
|
||||
|
||||
获取到公钥内容后,我们需要将其添加到Gitee账户中:
|
||||
|
||||
1. 登录Gitee账户,点击右上角头像
|
||||
2. 选择「个人设置」->「安全设置」->「SSH 公钥」
|
||||
3. 点击「添加公钥」按钮
|
||||
4. 在表单中填入公钥标题(自定义,方便识别)和公钥内容
|
||||
5. 输入Gitee账户密码进行验证
|
||||
6. 点击「添加」按钮完成操作
|
||||
|
||||

|
||||
|
||||
### 4. 验证SSH连接
|
||||
|
||||
添加完成后,可以通过以下命令测试SSH连接是否配置成功:
|
||||
|
||||
```bash
|
||||
ssh -T git@gitee.com
|
||||
```
|
||||
|
||||
如果配置正确,您将看到以下输出,其中USERNAME是您的Gitee用户名:
|
||||
|
||||
```bash
|
||||
Hi USERNAME! You've successfully authenticated, but GITEE.COM does not provide shell access.
|
||||
```
|
||||
|
||||
看到这个提示就说明SSH公钥已经成功配置,您可以开始使用SSH协议来操作Gitee上的仓库了。
|
||||
|
||||
## SSH公钥的管理
|
||||
|
||||
在Gitee平台上,您可以方便地管理已添加的SSH公钥:
|
||||
|
||||
1. 浏览公钥列表:通过「个人设置」->「安全设置」->「SSH 公钥」页面查看所有已添加的SSH公钥
|
||||
2. 查看公钥详情:点击具体的公钥可以查看其详细信息
|
||||
3. 删除公钥:当某个SSH公钥不再需要时,可以直接删除它
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 账户SSH公钥vs仓库SSH公钥
|
||||
|
||||
在Gitee平台上,存在两种不同类型的SSH公钥,理解它们的区别对正确使用Git操作非常重要:
|
||||
|
||||
### 账户SSH公钥
|
||||
|
||||
- 与您的Gitee账户绑定
|
||||
- 当您的账户对仓库有推送/拉取权限时,可以使用这个公钥进行对应操作
|
||||
- 验证时会显示您的用户名:`Hi USERNAME! You've successfully authenticated...`
|
||||
- 适用于日常开发过程中的代码提交、拉取等操作
|
||||
|
||||
### 仓库SSH公钥(部署公钥)
|
||||
|
||||
- 仅针对特定仓库,与账户无关
|
||||
- 仅具有仓库的**拉取**权限,无法进行推送操作
|
||||
- 验证时显示为匿名用户:`Hi Anonymous! You've successfully authenticated...`
|
||||
- 主要用于部署环境(如生产服务器)拉取代码,避免在服务器上存储个人账户凭证
|
||||
|
||||
> 注意:如果您需要设置仓库的部署公钥,请参考Gitee帮助文档中的"添加部署公钥"章节。
|
||||
|
||||
## 实用技巧与常见问题
|
||||
|
||||
### 使用不同的SSH密钥访问不同的Git服务
|
||||
|
||||
如果您同时使用多个Git平台(如Gitee、GitHub、GitLab等),可以为每个平台生成不同的SSH密钥对,并在SSH配置文件中指定使用规则。
|
||||
|
||||
1. 为不同平台生成不同的密钥,例如:
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -C "Gitee" -f ~/.ssh/gitee_id_ed25519
|
||||
ssh-keygen -t ed25519 -C "GitHub" -f ~/.ssh/github_id_ed25519
|
||||
```
|
||||
|
||||
2. 创建或编辑`~/.ssh/config`文件:
|
||||
```
|
||||
# Gitee平台
|
||||
Host gitee.com
|
||||
HostName gitee.com
|
||||
PreferredAuthentications publickey
|
||||
IdentityFile ~/.ssh/gitee_id_ed25519
|
||||
|
||||
# GitHub平台
|
||||
Host github.com
|
||||
HostName github.com
|
||||
PreferredAuthentications publickey
|
||||
IdentityFile ~/.ssh/github_id_ed25519
|
||||
```
|
||||
|
||||
### SSH连接故障排查
|
||||
|
||||
如果在验证SSH连接时遇到问题,可以尝试以下步骤:
|
||||
|
||||
1. 使用`-v`参数获取详细信息:
|
||||
```bash
|
||||
ssh -vT git@gitee.com
|
||||
```
|
||||
|
||||
2. 检查SSH密钥权限(Unix/Linux/macOS系统):
|
||||
```bash
|
||||
chmod 700 ~/.ssh
|
||||
chmod 600 ~/.ssh/id_ed25519
|
||||
chmod 644 ~/.ssh/id_ed25519.pub
|
||||
```
|
||||
|
||||
3. 确认SSH代理正在运行:
|
||||
```bash
|
||||
eval $(ssh-agent -s)
|
||||
ssh-add ~/.ssh/id_ed25519
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
正确设置和使用SSH公钥对于Java开发者在Gitee平台上进行高效的代码管理至关重要。通过本文介绍的步骤,您可以轻松生成SSH密钥对、将公钥添加到Gitee账户,并开始使用SSH协议访问您的代码仓库。这不仅提高了安全性,还简化了您的日常工作流程,避免了重复输入用户名和密码的繁琐过程。
|
||||
|
||||
对于团队开发和持续集成/持续部署(CI/CD)环境,了解账户SSH公钥和仓库部署公钥的区别尤为重要,这有助于您根据不同场景选择最合适的认证方式,确保代码安全的同时提高开发和部署效率。
|
||||
|
||||
希望本指南能帮助您在Gitee平台上更加顺畅地使用Git进行项目管理和协作开发。如果在实际操作中遇到任何问题,欢迎参考Gitee的官方帮助文档获取更多支持。
|
Loading…
Reference in New Issue
Block a user