微服务架构下,每个服务都有自己的API文档,开发人员需要记住每个服务的文档地址,这无疑增加了调试的复杂度。Spring Cloud Gateway作为微服务架构中的API网关,天然具备服务发现和路由转发能力。而Knife4j 4.3作为Swagger的增强版,提供了强大的文档聚合功能。两者的结合,可以让我们在网关层面统一管理和调试所有微服务的API文档。
我在实际项目中遇到过这样的场景:一个电商系统有商品服务、订单服务、用户服务等十几个微服务,每个服务都有自己的Swagger文档。开发人员调试时需要频繁切换不同服务的文档地址,非常不便。后来我们引入了Knife4j的网关聚合功能,问题迎刃而解。
首先需要在各个微服务中引入Knife4j的依赖。对于基于Spring Boot 3的项目,需要使用特定的starter:
xml复制<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.3.0</version>
</dependency>
这里有个坑需要注意:Knife4j 4.3不再依赖Springfox,而是基于SpringDoc实现。如果你的项目之前使用的是Springfox,需要特别注意API注解的变化。
在每个微服务的application.yml中,需要配置基本的Swagger信息:
yaml复制springdoc:
swagger-ui:
path: /swagger-ui.html
api-docs:
path: /v3/api-docs
group-configs:
- group: 'default'
paths-to-match: '/**'
packages-to-scan: com.youlai.system.controller
我建议将packages-to-scan配置为你的Controller包路径,这样可以避免扫描不必要的类,提高启动速度。
在网关服务中,需要添加Knife4j的网关聚合starter:
xml复制<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-gateway-spring-boot-starter</artifactId>
<version>4.3.0</version>
</dependency>
然后在application.yml中配置服务发现和聚合策略:
yaml复制spring:
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
knife4j:
gateway:
enabled: true
strategy: discover
discover:
version: openapi3
enabled: true
这里有个经验分享:lower-case-service-id设置为true可以避免因为服务名大小写不一致导致的问题。我们在测试环境就遇到过因为服务名大小写不一致导致文档无法聚合的情况。
虽然Knife4j支持自动发现服务,但我还是建议显式配置路由规则:
yaml复制routes:
- id: system-service
uri: lb://youlai-system
predicates:
- Path=/youlai-system/**
filters:
- StripPrefix=1
显式配置路由有两个好处:一是可以更精确地控制访问路径,二是在服务启动时就能发现配置问题,而不是等到访问文档时才报错。
在微服务架构中,API安全至关重要。Knife4j很好地支持了OAuth2认证。首先需要在Swagger配置类中添加安全方案:
java复制@Bean
public OpenAPI apiInfo() {
return new OpenAPI()
.components(new Components()
.addSecuritySchemes(HttpHeaders.AUTHORIZATION,
new SecurityScheme()
.type(SecurityScheme.Type.OAUTH2)
.name(HttpHeaders.AUTHORIZATION)
.flows(new OAuthFlows()
.password(new OAuthFlow()
.tokenUrl(tokenUrl)
.refreshUrl(tokenUrl)
)
)
.in(SecurityScheme.In.HEADER)
.scheme("Bearer")
)
)
.addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION));
}
配置完成后,在Knife4j的UI界面中点击"Authorize"按钮,输入客户端凭证:
认证成功后,Knife4j会自动将获取到的access_token添加到后续所有API请求的Header中。这里有个实用技巧:如果你的认证服务返回的是包装过的响应体,需要确保access_token在原始格式中可以直接获取,否则Knife4j无法自动解析。
如果发现某些服务的文档没有聚合到网关,可以按照以下步骤排查:
认证失败通常有以下几种原因:
在开发环境中可能会遇到跨域问题,可以通过以下配置解决:
yaml复制spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowed-origins: "*"
allowed-methods: "*"
allowed-headers: "*"
但在生产环境中,建议配置具体的允许来源,而不是使用通配符。
随着微服务数量的增加,文档聚合可能会影响网关性能。以下是一些优化建议:
我在一个包含30+微服务的项目中,通过合理的缓存配置和分组策略,将文档聚合的响应时间从最初的5秒降低到了1秒以内。
除了基本的API文档外,Knife4j还支持添加丰富的文档信息:
java复制@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("系统API文档")
.version("1.0")
.description("这是一个电商系统API文档")
.termsOfService("http://example.com/terms")
.license(new License().name("Apache 2.0"))
);
}
默认情况下,接口是按字母顺序排列的。如果需要自定义排序,可以配置:
yaml复制springdoc:
swagger-ui:
tags-sorter: alpha
operations-sorter: alpha
在实际项目中,我们通常会有多个环境。可以通过Profile来区分不同环境的配置:
yaml复制spring:
profiles: dev
knife4j:
gateway:
enabled: true
---
spring:
profiles: prod
knife4j:
gateway:
enabled: false
这样在生产环境就可以关闭文档聚合功能,提高安全性。
Knife4j可以与Spring Boot Admin一起使用,提供更全面的微服务监控体验。只需要确保两者的路径不冲突即可。
如果你的系统使用了Prometheus监控,可以通过Knife4j查看各个服务的监控端点文档,方便调试。
Knife4j的请求记录功能可以与日志系统结合,实现API调用的全链路追踪。这对于排查复杂的分布式系统问题非常有帮助。