从零搭建一个微服务Demo:手把手教你用SpringBoot整合SpringCloud Netflix五大件
从零搭建一个微服务Demo:手把手教你用SpringBoot整合SpringCloud Netflix五大件
微服务架构已经成为现代企业级应用开发的主流选择。对于Java开发者而言,SpringBoot和SpringCloud的组合提供了快速构建分布式系统的完美解决方案。本文将带领你从零开始,通过实际编码演示如何将一个简单的SpringBoot应用逐步扩展为完整的微服务系统,集成Eureka服务注册中心、Ribbon客户端负载均衡、Hystrix熔断器、Zuul API网关和Config配置中心这五大核心组件。
1. 环境准备与基础项目搭建
在开始之前,确保你的开发环境满足以下要求:
- JDK 1.8或更高版本
- IntelliJ IDEA(推荐)或其他Java IDE
- Maven 3.5+
- Git客户端
首先创建一个基础的SpringBoot项目作为我们的起点:
mvn archetype:generate -DgroupId=com.example -DartifactId=microservice-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
然后修改pom.xml文件,添加SpringBoot和SpringCloud的依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
提示:SpringCloud版本需要与SpringBoot版本匹配,这里我们使用2021.0.3(代号"2021.0.x")与SpringBoot 2.7.x配合使用。
2. 集成Eureka服务注册与发现
服务注册与发现是微服务架构的基础功能。我们将首先搭建一个Eureka Server,然后改造我们的基础应用成为Eureka Client。
2.1 创建Eureka Server
新建一个模块作为Eureka服务注册中心:
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
配置application.yml:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
2.2 将应用注册为Eureka Client
修改基础应用的pom.xml添加Eureka Client依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
在启动类上添加@EnableEurekaClient注解:
@SpringBootApplication
@EnableEurekaClient
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
配置application.yml:
spring:
application:
name: demo-service
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
启动Eureka Server和Demo应用后,访问http://localhost:8761,你应该能看到DEMO-SERVICE已经注册到Eureka。
3. 实现服务间调用与负载均衡
在微服务架构中,服务间的通信是核心功能。我们将使用Ribbon和Feign两种方式实现服务调用。
3.1 使用Ribbon实现客户端负载均衡
首先创建第二个服务provider-service,同样注册到Eureka。然后在demo-service中添加Ribbon支持:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
创建一个RestTemplate bean并添加@LoadBalanced注解:
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
现在可以通过服务名调用provider-service:
@RestController
public class DemoController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/call-provider")
public String callProvider() {
return restTemplate.getForObject(
"http://provider-service/api/resource",
String.class
);
}
}
3.2 使用Feign简化服务调用
Feign提供了更声明式的服务调用方式。首先添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
在启动类上添加@EnableFeignClients注解:
@EnableFeignClients
@SpringBootApplication
public class DemoApplication {
// ...
}
创建Feign客户端接口:
@FeignClient("provider-service")
public interface ProviderClient {
@GetMapping("/api/resource")
String getResource();
}
然后在Controller中注入使用:
@Autowired
private ProviderClient providerClient;
@GetMapping("/feign-call")
public String feignCall() {
return providerClient.getResource();
}
4. 集成Hystrix实现熔断与降级
在分布式系统中,服务故障是不可避免的。Hystrix提供了熔断、降级和隔离机制来增强系统的弹性。
4.1 基本熔断配置
添加Hystrix依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
在启动类上添加@EnableCircuitBreaker注解:
@EnableCircuitBreaker
@SpringBootApplication
public class DemoApplication {
// ...
}
为Feign客户端启用Hystrix支持(在application.yml中):
feign:
hystrix:
enabled: true
4.2 实现降级逻辑
为Feign客户端指定fallback类:
@FeignClient(name = "provider-service", fallback = ProviderClientFallback.class)
public interface ProviderClient {
// ...
}
@Component
public class ProviderClientFallback implements ProviderClient {
@Override
public String getResource() {
return "Fallback response";
}
}
或者使用方法级的熔断:
@HystrixCommand(fallbackMethod = "fallbackMethod")
@GetMapping("/hystrix-example")
public String hystrixExample() {
// 可能失败的操作
}
public String fallbackMethod() {
return "Fallback response";
}
4.3 Hystrix仪表盘监控
添加Hystrix仪表盘依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
在启动类上添加@EnableHystrixDashboard注解:
@EnableHystrixDashboard
@SpringBootApplication
public class DemoApplication {
// ...
}
访问http://localhost:8080/hystrix,输入监控流地址http://localhost:8080/actuator/hystrix.stream即可查看熔断器状态。
5. 使用Zuul构建API网关
API网关是微服务架构中的重要组件,负责路由、过滤和聚合等跨领域功能。
5.1 创建Zuul网关服务
新建一个模块作为网关服务,添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
在启动类上添加@EnableZuulProxy注解:
@EnableZuulProxy
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
基本配置application.yml:
zuul:
routes:
demo-service:
path: /demo/**
serviceId: demo-service
provider-service:
path: /provider/**
serviceId: provider-service
5.2 实现自定义过滤器
Zuul的强大之处在于可以自定义各种过滤器:
@Component
public class AuthFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String token = request.getHeader("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
ctx.setResponseBody("Unauthorized");
}
return null;
}
}
5.3 网关的负载均衡与熔断
Zuul默认集成了Ribbon和Hystrix,可以通过以下配置调整:
ribbon:
ConnectTimeout: 1000
ReadTimeout: 3000
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
6. 集中化配置管理
随着服务数量增加,分散的配置管理变得困难。Spring Cloud Config提供了集中化的配置管理解决方案。
6.1 搭建Config Server
新建一个模块作为配置中心,添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
在启动类上添加@EnableConfigServer注解:
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
配置application.yml指定Git仓库:
server:
port: 8888
spring:
cloud:
config:
server:
git:
uri: https://github.com/your-repo/config-repo
search-paths: '{application}'
6.2 客户端配置
在demo-service中添加Config Client依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
创建bootstrap.yml(优先级高于application.yml):
spring:
application:
name: demo-service
cloud:
config:
uri: http://localhost:8888
fail-fast: true
6.3 配置刷新
要实现配置的动态刷新,首先在需要刷新的bean上添加@RefreshScope:
@RefreshScope
@RestController
public class DemoController {
@Value("${custom.property}")
private String customProperty;
// ...
}
然后添加Actuator依赖并暴露refresh端点:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置application.yml:
management:
endpoints:
web:
exposure:
include: refresh,health,info
现在,修改Git仓库中的配置后,向客户端服务的/actuator/refresh端点发送POST请求即可刷新配置。
7. 系统整合与测试
现在我们已经完成了所有核心组件的集成,让我们来验证整个系统是否正常工作。
7.1 启动顺序建议
- 配置中心(Config Server)
- 服务注册中心(Eureka Server)
- 配置客户端服务(如provider-service)
- API网关(Zuul)
- 其他微服务
7.2 验证服务注册与发现
访问Eureka控制台http://localhost:8761,确认所有服务都已注册:
| 服务名称 | 状态 | 实例数 |
|---|---|---|
| CONFIG-SERVER | UP | 1 |
| GATEWAY | UP | 1 |
| DEMO-SERVICE | UP | 1 |
| PROVIDER-SERVICE | UP | 1 |
7.3 测试API网关路由
通过网关访问各个服务:
- http://localhost:8080/demo/hello → 路由到demo-service
- http://localhost:8080/provider/api/resource → 路由到provider-service
7.4 验证熔断机制
故意停止provider-service,然后访问demo-service的接口,应该能看到降级响应。
7.5 配置中心测试
修改Git仓库中的配置,通过POST请求刷新客户端配置,验证配置是否生效。
8. 生产环境注意事项
在实际生产环境中部署微服务系统时,还需要考虑以下方面:
- Eureka高可用:部署多个Eureka节点并相互注册
- Zuul性能优化:调整线程池、超时设置和缓存
- 配置安全:加密敏感配置信息
- 服务监控:集成Spring Boot Admin和Prometheus
- 日志收集:使用ELK或类似方案集中管理日志
- 容器化部署:考虑使用Docker和Kubernetes
// 示例:Eureka Server高可用配置
eureka:
client:
serviceUrl:
defaultZone: http://peer1:8761/eureka/,http://peer2:8761/eureka/
注意:生产环境中应该为每个组件配置适当的资源限制和健康检查,并建立完善的监控告警系统。
更多推荐
所有评论(0)