Spring Cloud 微服务架构的部署流程
环境准备
在开始部署 Spring Cloud 微服务架构之前,我们需要确保开发环境和部署环境的基础软件已经安装并配置好。以下是一些必备的软件和工具:
JDK(Java Development Kit)
Spring Cloud 基于 Java 开发,所以需要安装 JDK。推荐使用 JDK 8 及以上版本。例如,在 Linux 系统上安装 OpenJDK 11,可以通过以下命令:
sudo apt update
sudo apt install openjdk-11-jdk
安装完成后,通过 java -version
命令验证安装:
java -version
openjdk version "11.0.11" 2021-04-20
OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.20.04)
OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.20.04, mixed mode, sharing)
Maven
Maven 是 Java 项目的构建工具,用于管理项目依赖和构建过程。在 Linux 上安装 Maven,可以使用以下命令:
sudo apt install maven
验证 Maven 安装,使用 mvn -v
命令:
mvn -v
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /usr/share/maven
Java version: 11.0.11, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "5.4.0-91-generic", arch: "amd64", family: "unix"
Git
Git 用于版本控制,方便我们管理微服务项目的代码。在 Linux 上安装 Git:
sudo apt install git
验证安装:
git --version
git version 2.25.1
容器化工具(可选但推荐)
如果打算使用容器化技术(如 Docker)来部署微服务,需要安装 Docker。在 Ubuntu 上安装 Docker:
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
验证 Docker 安装:
sudo docker run hello-world
创建 Spring Cloud 微服务项目
我们以一个简单的用户服务为例,展示如何创建 Spring Cloud 微服务项目。
创建 Maven 项目
使用 Maven 命令创建一个基础的 Spring Boot 项目:
mvn archetype:generate -DgroupId=com.example -DartifactId=user-service -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
进入项目目录:
cd user-service
将项目转换为 Spring Boot 项目,修改 pom.xml
文件,添加 Spring Boot 相关依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
编写服务代码
在 src/main/java/com/example/userservice
目录下创建 UserController.java
文件:
package com.example.userservice;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@GetMapping("/users")
public String getUsers() {
return "Hello, this is a list of users.";
}
}
在 src/main/java/com/example/userservice
目录下创建 UserServiceApplication.java
作为 Spring Boot 应用的启动类:
package com.example.userservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
测试服务
在项目根目录下,使用 Maven 命令启动服务:
mvn spring-boot:run
打开浏览器,访问 http://localhost:8080/users
,应该能看到返回的 “Hello, this is a list of users.” 信息。
服务注册与发现
Spring Cloud 常用的服务注册与发现组件是 Eureka 和 Consul。这里以 Eureka 为例进行介绍。
创建 Eureka Server
创建一个新的 Maven 项目作为 Eureka Server:
mvn archetype:generate -DgroupId=com.example -DartifactId=eureka-server -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
进入项目目录:
cd eureka-server
修改 pom.xml
文件,添加 Eureka Server 依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
在 src/main/java/com/example/eurekaserver
目录下创建 EurekaServerApplication.java
作为启动类,并添加 @EnableEurekaServer
注解:
package com.example.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
在 src/main/resources
目录下创建 application.properties
文件,配置 Eureka Server:
server.port=8761
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
启动 Eureka Server:
mvn spring-boot:run
打开浏览器,访问 http://localhost:8761
,可以看到 Eureka Server 的管理界面。
注册用户服务到 Eureka Server
修改用户服务的 pom.xml
文件,添加 Eureka Client 依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
在用户服务的 application.properties
文件中添加 Eureka Server 相关配置:
server.port=8081
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
eureka.instance.prefer-ip-address=true
在用户服务的启动类 UserServiceApplication.java
中添加 @EnableEurekaClient
注解:
package com.example.userservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
重新启动用户服务,然后在 Eureka Server 的管理界面中可以看到用户服务已经注册成功。
配置中心
Spring Cloud Config 是常用的配置中心组件,它可以集中管理微服务的配置文件。
创建 Config Server
创建一个新的 Maven 项目作为 Config Server:
mvn archetype:generate -DgroupId=com.example -DartifactId=config-server -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
进入项目目录:
cd config-server
修改 pom.xml
文件,添加 Spring Cloud Config Server 依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.3</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
在 src/main/java/com/example/configserver
目录下创建 ConfigServerApplication.java
作为启动类,并添加 @EnableConfigServer
注解:
package com.example.configserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
在 src/main/resources
目录下创建 application.properties
文件,配置 Config Server:
server.port=8888
spring.cloud.config.server.git.uri=https://github.com/yourusername/config-repo
spring.cloud.config.server.git.search-paths=config-repo
spring.cloud.config.server.git.username=yourusername
spring.cloud.config.server.git.password=yourpassword
这里假设配置文件存储在 GitHub 的 config-repo
仓库中。启动 Config Server:
mvn spring-boot:run
使用 Config Server 配置用户服务
修改用户服务的 bootstrap.properties
文件(如果没有则创建),配置 Config Server:
spring.application.name=user-service
spring.cloud.config.uri=http://localhost:8888
spring.cloud.config.fail-fast=true
在 config-repo
仓库中创建 user-service.properties
文件,用于存储用户服务的配置:
server.port=8082
重新启动用户服务,此时用户服务会从 Config Server 获取配置,端口将变为 8082。
负载均衡与服务调用
Spring Cloud Ribbon 是客户端负载均衡器,Feign 是声明式的 Web 服务客户端,它们可以结合使用来实现微服务之间的负载均衡调用。
使用 Ribbon 进行负载均衡
假设我们有两个实例的用户服务,分别运行在 8081 和 8082 端口。在调用方服务(如一个订单服务)中,添加 Ribbon 依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
在配置文件中配置负载均衡策略,例如在 application.properties
文件中:
user-service.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
这里使用随机负载均衡策略。在调用用户服务的代码中,通过 Ribbon 进行负载均衡调用:
package com.example.orderservice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/orders")
public String getOrders() {
String response = restTemplate.getForObject("http://user-service/users", String.class);
return "Orders related to: " + response;
}
}
在启动类中配置 RestTemplate
并添加 @LoadBalanced
注解:
package com.example.orderservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class OrderServiceApplication {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
使用 Feign 简化服务调用
Feign 基于 Ribbon 实现,并且提供了更简洁的声明式调用方式。在订单服务中添加 Feign 依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在启动类中添加 @EnableFeignClients
注解:
package com.example.orderservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
创建一个 Feign 客户端接口:
package com.example.orderservice;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "user-service")
public interface UserFeignClient {
@GetMapping("/users")
String getUsers();
}
修改 OrderController
使用 Feign 客户端:
package com.example.orderservice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OrderController {
@Autowired
private UserFeignClient userFeignClient;
@GetMapping("/orders")
public String getOrders() {
String response = userFeignClient.getUsers();
return "Orders related to: " + response;
}
}
微服务的容器化部署
使用 Docker 可以将微服务及其依赖打包成容器,方便在不同环境中部署。
创建 Docker 镜像
以用户服务为例,在项目根目录下创建 Dockerfile
:
FROM openjdk:11-jre-slim
COPY target/user-service-1.0-SNAPSHOT.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
构建 Docker 镜像:
sudo docker build -t user-service:1.0.0.
其中 -t
选项指定镜像的标签,user-service:1.0.0
表示镜像名称为 user-service
,版本为 1.0.0
。最后的 .
表示 Dockerfile 所在的当前目录。
运行 Docker 容器
运行用户服务的 Docker 容器:
sudo docker run -d -p 8081:8081 user-service:1.0.0
这里 -d
选项表示在后台运行容器,-p 8081:8081
表示将容器内部的 8081 端口映射到宿主机的 8081 端口。
使用 Docker Compose 进行多容器部署
如果有多个微服务,如 Eureka Server、Config Server 和用户服务,可以使用 Docker Compose 进行统一管理。在项目根目录下创建 docker-compose.yml
文件:
version: '3'
services:
eureka-server:
image: eureka-server:1.0.0
ports:
- 8761:8761
config-server:
image: config-server:1.0.0
ports:
- 8888:8888
user-service:
image: user-service:1.0.0
ports:
- 8081:8081
构建并启动所有容器:
sudo docker-compose up -d
这样就可以一次性启动所有相关的微服务容器。
部署到 Kubernetes 集群
Kubernetes 是一个强大的容器编排平台,可以更好地管理微服务的部署、扩展和维护。
创建 Kubernetes 集群
可以使用 Minikube 在本地创建一个单节点的 Kubernetes 集群,也可以使用云提供商(如 Google Kubernetes Engine、Amazon EKS 等)创建生产级别的集群。以 Minikube 为例,安装 Minikube:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
启动 Minikube:
minikube start
创建 Kubernetes 部署和服务
以用户服务为例,创建 user-service-deployment.yml
文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
spec:
replicas: 2
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
spec:
containers:
- name: user-service
image: user-service:1.0.0
ports:
- containerPort: 8081
创建 user-service-service.yml
文件:
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
- protocol: TCP
port: 8081
targetPort: 8081
type: ClusterIP
使用以下命令在 Kubernetes 集群中创建部署和服务:
kubectl apply -f user-service-deployment.yml
kubectl apply -f user-service-service.yml
监控与日志管理
在微服务架构中,监控和日志管理非常重要,可以帮助我们及时发现和解决问题。
使用 Spring Boot Actuator 进行监控
在每个微服务的 pom.xml
文件中添加 Spring Boot Actuator 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在 application.properties
文件中配置 Actuator 暴露的端点:
management.endpoints.web.exposure.include=*
启动微服务后,可以通过 http://localhost:8081/actuator
访问监控端点,查看各种运行时信息,如健康检查、指标等。
日志管理
Spring Boot 内置了日志框架,可以在 application.properties
文件中配置日志级别和输出格式:
logging.level.com.example.userservice=debug
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
对于生产环境,可以将日志输出到文件,并使用集中式日志管理工具(如 ELK Stack,即 Elasticsearch、Logstash 和 Kibana 的组合)进行统一管理和分析。例如,通过 Logstash 收集微服务的日志,发送到 Elasticsearch 存储,然后在 Kibana 中进行可视化展示和查询。
通过以上详细的步骤,我们完成了 Spring Cloud 微服务架构从环境准备、项目创建、服务注册与发现、配置中心使用、负载均衡与服务调用、容器化部署、Kubernetes 部署以及监控与日志管理的全流程部署。每个环节都紧密相连,共同构成了一个完整且健壮的微服务架构体系,为企业级应用的开发和部署提供了可靠的支持。