最近在重构公司的一个老项目,决定采用Spring Cloud Gateway+Nacos这套技术栈来实现微服务架构。经过两周的实践踩坑,终于把整套环境跑通了。这里把我的搭建过程详细记录下来,希望能帮到有同样需求的开发者。
这套架构最大的优势在于:
刚开始搭建时,我直接用了最新版本的Spring Boot和Spring Cloud,结果各种兼容性问题接踵而来。经过多次尝试,最终确定了这套稳定版本组合:
特别注意:Spring Cloud Alibaba的版本号比较特殊,2022.0.0.0-RC2是专门适配Spring Cloud 2022.x的版本,如果用错会导致各种奇怪的错误。
Nacos的安装比较简单,这里分享几个实用技巧:
properties复制# 单机模式启动
spring.datasource.platform=mysql
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8
db.user=root
db.password=yourpassword
bash复制# Linux/Mac
sh startup.sh -m standalone
# Windows
startup.cmd -m standalone
生产环境一定要配置MySQL持久化,否则重启后所有配置都会丢失。我吃过这个亏,线上配置全没了...
父pom的dependencyManagement一定要写对,否则子模块会各种报错:
xml复制<dependencyManagement>
<dependencies>
<!-- 必须用pom类型 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2022.0.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Alibaba的版本号要特别注意 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2022.0.0.0-RC2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
bootstrap.yml的配置有几个容易踩坑的点:
yaml复制spring:
application:
name: nacos-provider # 服务名要全小写
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: public # 生产环境建议按环境划分
ephemeral: false # 非临时实例,下线时会等待一段时间
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yaml # 必须和实际文件后缀一致
refresh-enabled: true # 开启配置刷新
接口实现时记得暴露健康检查端点:
java复制@GetMapping("/provider/hello/{name}")
public String hello(@PathVariable String name) {
// 获取当前服务端口,用于验证负载均衡
String port = System.getProperty("server.port");
return String.format("Hello %s! From provider (port: %s)", name, port);
}
Feign客户端的正确打开方式:
java复制@FeignClient(name = "nacos-provider",
configuration = FeignConfig.class, // 自定义配置
fallback = ProviderFallback.class) // 降级类
public interface ProviderFeignClient {
@GetMapping("/provider/hello/{name}")
String hello(@PathVariable("name") String name);
}
// 降级实现
@Component
public class ProviderFallback implements ProviderFeignClient {
@Override
public String hello(String name) {
return "fallback: " + name;
}
}
Feign配置类示例:
java复制@Configuration
public class FeignConfig {
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL; // 生产环境建议用BASIC
}
@Bean
public Retryer retryer() {
return new Retryer.Default(100, 1000, 3);
}
}
网关的配置有几个关键点需要注意:
yaml复制spring:
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true # 服务名大小写敏感
routes:
- id: provider-route
uri: lb://nacos-provider # lb表示负载均衡
predicates:
- Path=/api/provider/**
filters:
- StripPrefix=1 # 去掉第一个路径段
- AddRequestHeader=X-Request-Foo, Bar # 添加请求头
- CircuitBreaker=myCircuitBreaker # 熔断配置
生产环境必须部署集群,我的推荐配置:
启动命令示例:
bash复制# 集群模式启动,指定peer节点
sh startup.sh -p 8848 -m cluster -n 3
java复制@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("async_route", r -> r.path("/async/**")
.filters(f -> f.stripPrefix(1))
.uri("lb://async-service"))
.build();
}
java复制@Bean
public List<ViewResolver> viewResolvers() {
List<ViewResolver> list = new ArrayList<>();
list.add(new DefaultErrorViewResolver());
return list;
}
properties复制server.http2.enabled=true
yaml复制spring:
profiles:
active: @profileActive@ # Maven过滤
cloud:
nacos:
config:
namespace: ${spring.profiles.active}
yaml复制# 在Nacos中创建shared-config.yaml
spring:
redis:
host: redis-host
port: 6379
java复制@Bean
public NacosConfigProperties nacosConfigProperties() {
NacosConfigProperties properties = new NacosConfigProperties();
properties.setEncryptEnabled(true);
return properties;
}
自定义健康检查指标:
java复制@Component
public class CustomHealthIndicator implements HealthIndicator {
@Override
public Health health() {
// 检查数据库、缓存等
return Health.up().withDetail("db", "ok").build();
}
}
推荐使用ELK栈:
集成Prometheus+Grafana:
xml复制<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
application.yml配置:
yaml复制management:
endpoints:
web:
exposure:
include: health,info,prometheus
metrics:
tags:
application: ${spring.application.name}
这套架构经过我们生产环境验证,可以支撑日均百万级的请求量。关键在于合理配置和持续优化,特别是网关层和Nacos集群的调优。实际使用中还需要根据业务特点进行调整,比如添加鉴权、限流等安全措施。