50、开发环境搭建与原生编译Java微服务指南

开发环境搭建与原生编译Java微服务指南

1. Windows环境安装与配置

1.1 安装Docker Desktop for Windows

要在Windows上安装和配置Docker Desktop,请按以下步骤操作:
1. 从 https://hub.docker.com/editions/community/docker-ce-desktop-windows/ 下载并安装Docker Desktop for Windows。
2. 安装过程中若提示启用WSL 2,请选择“是”。
3. 安装完成后,从开始菜单启动Docker Desktop。
4. 从Docker菜单中选择“设置”,在设置窗口中选择“常规”选项卡:
- 确保选中“使用基于WSL 2的引擎”复选框。
- 为避免每次重启PC后手动启动Docker Desktop,建议同时选中“登录时启动Docker Desktop”复选框。
5. 点击“应用并重启”按钮完成配置。

1.2 安装Visual Studio Code及其Remote WSL扩展

为简化在Linux服务器中编辑源代码的操作,建议使用Visual Studio Code及其WSL 2扩展(Remote WSL)。具体安装和配置步骤如下:
1. 从 https://code.visualstudio.com 下载并安装Visual Studio Code。安装时,在“选择其他任务”提示中,选择“添加到PATH”选项,以便能在Linux服务器中使用 code 命令打开文件夹。
2. 安装完成后,从开始菜单启动Visual Studio Code。
3. 使用链接 https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl 安装Remote WSL扩展。

1.3 在WSL 2的Linux服务器中安装工具

从开始菜单启动Windows Terminal,并按照“安装Windows Terminal”部分的说明在Linux服务器中打开终端。Ubuntu中已预装 git curl 工具,其余工具将使用 apt install sdk install curl install 组合的方式进行安装。

1.3.1 使用apt install安装工具

使用以下命令安装 jq zip unzip siege

sudo apt update
sudo apt install -y jq
sudo apt install -y zip
sudo apt install -y unzip
sudo apt install -y siege

安装Helm,运行以下命令:

curl -s https://baltocdn.com/helm/signing.asc | \
  gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null 
sudo apt-get install apt-transport-https --yes 
echo "deb [arch=$(dpkg --print-architecture) \
  signed-by=/usr/share/keyrings/helm.gpg] \
  https://baltocdn.com/helm/stable/debian/ all main" | \
  sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt install -y helm
1.3.2 使用SDKman安装Java和Spring Boot CLI

使用SDKman( https://sdkman.io )安装Java和Spring Boot CLI,按以下步骤操作:
1. 安装SDKman:

curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
  1. 验证SDKman是否正确安装:
sdk version

预期输出类似: SDKMAN5.9.2+613
3. 安装Java:

sdk install java 17.0.6-tem
  1. 安装Spring Boot CLI:
sdk install springboot 3.0.4
1.3.3 使用curl和install安装其余工具

安装 kubectl minikube istioctl ,运行以下命令:

# 安装kubectl
curl -LO "https://dl.k8s.io/release/v1.26.1/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
rm kubectl

# 安装minikube
curl -LO https://storage.googleapis.com/minikube/releases/v1.29.0/minikube-linux-amd64
sudo install -o root -g root -m 0755 minikube-linux-amd64 /usr/local/bin/minikube
rm minikube-linux-amd64

# 安装istioctl
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.17.0 TARGET_ARCH=x86_64 sh -
sudo install -o root -g root -m 0755 istio-1.17.0/bin/istioctl /usr/local/bin/istioctl
rm -r istio-1.17.0

1.4 验证工具安装

运行以下命令验证工具安装情况,打印各工具的版本信息:

git version && \
docker version -f json | jq -r .Client.Version && \
java -version 2>&1 | grep "openjdk version" && \
curl --version | grep "curl" | sed 's/(.*//' && \
jq --version && \
spring --version && \
siege --version 2>&1 | grep SIEGE && \
helm version --short && \
kubectl version --client -o json | \
  jq -r .clientVersion.gitVersion && \
minikube version | grep "minikube" && \
istioctl version --remote=false

1.5 访问源代码

源代码可在GitHub仓库 https://github.com/PacktPublishing/Microservices-with-Spring-Boot-and-Spring-Cloud-Third-Edition 找到。为能在WSL 2的Linux服务器中运行相关命令,需将源代码下载到一个文件夹,并设置环境变量 $BOOK_HOME 指向该文件夹,示例命令如下:

export BOOK_HOME=~/Microservices-with-Spring-Boot-and-Spring-Cloud-Third-Edition
git clone https://github.com/PacktPublishing/Microservices-with-Spring-Boot-and-Spring-Cloud-Third-Edition.git $BOOK_HOME

验证从Visual Studio Code访问下载到WSL 2的Linux服务器中的源代码,运行以下命令:

cd $BOOK_HOME
code .

1.6 代码结构

每个章节包含多个Java项目,每个微服务和Spring Cloud服务对应一个项目,还有一些供其他项目使用的库项目。以某一章节为例,其项目结构如下:

├── api
├── microservices
│   ├── product-composite-service
│   ├── product-service
│   ├── recommendation-service
│   └── review-service
├── spring-cloud
│   ├── authorization-server
│   ├── config-server
│   ├── eureka-server
│   └── gateway
└── util

所有项目使用Gradle构建,文件结构遵循Gradle标准约定:

├── build.gradle
├── settings.gradle
└── src
    ├── main
    │   ├── java
    │   └── resources
    └── test
        ├── java
        └── resources

2. 原生编译Java微服务

2.1 何时进行Java源代码的原生编译

Java以其“一次构建,随处运行”的特性提供了出色的跨平台支持。传统上,Java源代码编译为字节码,运行时Java VM通过即时编译(JIT)将字节码转换为目标平台的可执行代码,这会导致Java程序启动较慢。在微服务时代,对微服务的快速升级、弹性伸缩以及零成本运行的需求增加,快速启动变得至关重要。同时,容器技术的使用使得应用自身的跨平台支持重要性降低,Docker可用于构建支持多平台的镜像。因此,将Java源代码在构建时编译为目标平台的二进制格式(AOT编译)成为满足快速启动需求的有效方式。

2.2 介绍GraalVM项目

Oracle多年来致力于高性能Java VM及相关工具的开发,形成了GraalVM项目( https://www.graalvm.org )。GraalVM的VM是多语言的,支持多种编程语言。其Native Image编译器可将Java字节码编译为特定操作系统和硬件平台的二进制可执行文件(Native Image),该文件可在无Java VM的环境下运行,包含应用类和依赖类,以及处理垃圾回收、线程调度等的Substrate VM。

构建Native Image时,Native Image编译器基于封闭世界假设进行静态代码分析,即运行时可调用的所有字节码在构建时必须可达,因此运行时无法动态加载或创建构建时不可用的类。为克服这些限制,GraalVM提供了配置选项,可提供可达性元数据来描述反射和代理类的使用。GraalVM Native Image编译器可通过CLI命令(Native Image)或作为Maven、Gradle构建的一部分启动,本文使用Gradle插件。

2.3 介绍Spring的AOT引擎

Spring团队也在支持Spring应用的原生编译方面做了很多工作。Spring Framework 6和Spring Boot 3正式支持构建Native Image,其核心是Spring的AOT引擎。该引擎在构建时分析Spring Boot应用,生成GraalVM Native Image编译器所需的初始化源代码和可达性元数据,替代基于反射的初始化,减少了运行时对动态特性的依赖。

创建Spring Boot应用的Native Image的过程如下:

graph LR
    A[应用源代码] --> B[Java编译器编译为字节码]
    B --> C[Spring的AOT引擎分析代码,生成AOT源代码和可达性元数据]
    C --> D[Java编译器将AOT生成的代码编译为字节码]
    B & D & C --> E[GraalVM的Native Image编译器创建Native Image]

构建Native Image有两种方式:
- 为当前操作系统创建Native Image :使用Gradle的 nativeImage 任务,借助已安装的GraalVM Native Image编译器为当前操作系统和硬件架构创建可执行文件。前提是在构建文件中声明了GraalVM的Gradle插件。
- 将Native Image创建为Docker镜像 :暂未详细介绍此方式的具体步骤。

3. 处理原生编译问题

3.1 原生编译的限制

GraalVM Native Image编译器在进行原生编译时存在一些限制。比如在使用反射和动态代理方面,由于其基于封闭世界假设进行静态代码分析,要求运行时可调用的所有字节码在构建时必须可达,所以在运行时不能动态加载或创建在AOT编译时不可用的类。这就导致如果代码中大量使用反射来在运行时动态创建对象或调用方法,以及使用动态代理来实现一些功能增强,可能会在原生编译时出现问题。

3.2 解决方法

为了克服这些限制,GraalVM项目提供了配置选项,允许我们为原生编译器提供可达性元数据。通过这些配置,我们可以描述反射和代理类在运行时的使用情况。具体来说,可以参考 https://www.graalvm.org/22.3/reference-manual/Native Image/metadata/ 来了解如何创建所需的可达性元数据。在实际操作中,我们可以根据代码中反射和动态代理的使用情况,手动编写配置文件来告知编译器哪些类和方法是需要在运行时动态访问的。

4. 测试和编译Native Images

4.1 编译Native Image的准备

在编译Native Image之前,需要确保已经正确安装了GraalVM及其相关工具,并且在项目的构建文件(如 build.gradle )中声明了GraalVM的Gradle插件。同时,要根据前面提到的方法处理好原生编译的限制问题,准备好可达性元数据。

4.2 编译Native Image的步骤

4.2.1 为当前操作系统创建Native Image

如果要为当前操作系统创建Native Image,可以使用Gradle的 nativeImage 任务。在项目根目录下,执行以下命令:

./gradlew nativeImage

这个命令会调用已安装的GraalVM Native Image编译器,为当前操作系统和硬件架构创建可执行文件。

4.2.2 将Native Image创建为Docker镜像

将Native Image创建为Docker镜像,一般需要编写Dockerfile。以下是一个简单的示例:

# 基础镜像
FROM graalvm/graalvm-ce:latest

# 设置工作目录
WORKDIR /app

# 复制项目文件
COPY . .

# 编译Native Image
RUN ./gradlew nativeImage

# 暴露端口
EXPOSE 8080

# 启动命令
CMD ["./build/native-image/application"]

在项目根目录下,执行以下命令来构建Docker镜像:

docker build -t my-native-image .

然后可以使用以下命令运行Docker容器:

docker run -p 8080:8080 my-native-image

4.3 测试Native Image

在编译完成后,需要对Native Image进行测试,确保其功能正常。可以使用单元测试框架(如JUnit)对代码进行单元测试,也可以使用集成测试框架(如Spring Boot Test)进行集成测试。以下是一个简单的JUnit单元测试示例:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class MyServiceTest {

    @Test
    public void testMyService() {
        MyService service = new MyService();
        int result = service.add(2, 3);
        assertEquals(5, result);
    }
}

5. 使用Docker Compose进行测试

5.1 编写Docker Compose文件

Docker Compose可以帮助我们管理多个容器的运行。以下是一个简单的Docker Compose文件示例:

version: '3'
services:
  my-service:
    image: my-native-image
    ports:
      - "8080:8080"
  database:
    image: postgres:latest
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydb
    ports:
      - "5432:5432"

这个文件定义了两个服务: my-service database my-service 使用我们之前构建的 my-native-image 镜像, database 使用PostgreSQL数据库镜像。

5.2 启动和停止容器

在项目根目录下,执行以下命令启动容器:

docker-compose up -d

-d 参数表示在后台运行容器。要停止容器,可以执行以下命令:

docker-compose down

5.3 测试服务

启动容器后,可以使用 curl 等工具测试服务是否正常工作。例如:

curl http://localhost:8080/api/resource

6. 使用Kubernetes进行测试

6.1 部署到Kubernetes

要将Native Image部署到Kubernetes集群,需要编写Deployment和Service的YAML文件。以下是一个简单的Deployment示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-service-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-service
  template:
    metadata:
      labels:
        app: my-service
    spec:
      containers:
      - name: my-service
        image: my-native-image
        ports:
        - containerPort: 8080

这个Deployment定义了3个副本的 my-service 容器。

以下是一个简单的Service示例:

apiVersion: v1
kind: Service
metadata:
  name: my-service-service
spec:
  selector:
    app: my-service
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: LoadBalancer

这个Service将 my-service 暴露为LoadBalancer类型的服务。

使用以下命令将Deployment和Service部署到Kubernetes集群:

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

6.2 测试服务

部署完成后,可以使用以下命令获取Service的外部IP地址:

kubectl get services

然后使用浏览器或 curl 工具访问该IP地址,测试服务是否正常工作。

7. 总结

通过以上步骤,我们学习了如何在Windows环境下安装和配置开发所需的工具,包括Docker Desktop、Visual Studio Code及其扩展,以及在WSL 2的Linux服务器中安装各种工具。同时,我们了解了何时需要对Java源代码进行原生编译,以及GraalVM项目和Spring的AOT引擎的相关知识。我们还学习了如何处理原生编译中的问题,以及如何测试和编译Native Image,包括使用Docker Compose和Kubernetes进行测试。原生编译可以显著提高Java微服务的启动速度和降低内存消耗,是一种值得探索的技术。但目前该技术还处于早期阶段,在实际应用中可能会遇到一些问题,需要我们不断去解决和优化。

【SCI一区论文复】基于SLSPC系列的高阶PT-WPT无线电能传输系统研究(Matlab代码实现)内容概要:本文围绕“基于SLSPC系列的高阶PT-WPT无线电能传输系统研究”展开,重点复现SCI一区论文中的核心技术,通过Matlab代码实现高阶无线电能传输系统的建模仿真。研究聚焦SLSPC拓扑结构在恒压-恒流(CV/CC)输出特性方面的优势,深入分析系统的传输效率、耦合特性、频率分裂现象及参数敏感性,并探讨其在高功率、长距离无线充电场景中的应用潜力。文中详细给出了系统数学建模、参数设计、仿真验证等关键步骤,旨在帮助读者掌握先进无线电能传输技术的核心原理实现方法。; 适合人群:具备一定电力电子、自动控制理论基础,熟悉Matlab/Simulink仿真工具,从事无线电能传输、新能源充电技术等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①深入理解SLSPC型无线电能传输系统的恒压恒流输出机理;②掌握高阶WPT系统的建模、仿真性能分析方法;③复现SCI一区论文成果,为后续科研创新提供技术基础和代码参考;④应用于无线充电、电动汽车、植入式医疗设备等领域的系统设计优化。; 阅读建议:建议读者结合Matlab代码逐段分析系统模型构建过程,重点关注谐振参数设计、传输特性仿真及效率优化策略,同时可拓展研究不同耦合条件下的系统行为,以深化对高阶WPT系统动态特性的理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值