前言
在微服务架构下,服务是分散的,怎么把所有服务接口整合到一起是我们需要关注的。
下面举例用zuul作为分布式系统的网关,同时使用swagger生成文档,想把整个系统的文档整合在同一个页面上来说明。
项目结构
eureka-server:eureka服务注册中心,端口8761,
eureka-server2:eureka服务注册中心,端口8762,
eureka-server3:eureka服务注册中心,端口8763,
zuul-swagger2:zuul网关,端口8090,
management-device:外接设备系统,端口8083,
management-equip:设备管理系统,端口8082,
Zuul整合Swagger2
eureka注册中心的搭建这里不再讲述,直接来看zuul-swagger2项目里怎么集成swagger
pom.xml文件中引入依赖:
org.springframework.boot spring-boot-starter-parent 2.0.2.RELEASE org.springframework.cloud spring-cloud-dependencies Finchley.RELEASE pom import 2.9.0 org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-netflix-zuul io.springfox springfox-swagger2 ${swagger2.version} io.springfox springfox-swagger-ui ${swagger2.version}
在配置文件application.yml中添加配置(这里只做了eureka注册,没有做路由映射):
#端口 server: port: 8090 #应用名称 spring: application: name: zuul-swagger2 #服务注册 eureka: instance: hostname: zuul-swagger2 client: serviceUrl: defaultZone: http://skyworth:skyworth1@eureka-server:8761/eureka/,http://skyworth:skyworth2@eureka-server2:8762/eureka/,http://skyworth:skyworth3@eureka-server3:8763/eureka/ # 路由配置方式一 #zuul: # routes: #所有请求management-equip的请求,都会被拦截,并且转发到equip上 # management-equip: /equip/** # 路由配置方式二 #zuul: # routes: # # 其中equip是路由名称,可以随便定义,但是path和service-id需要一一对应 # equip: # path: /equip/** # # management-equip为注册到Eureka上的服务名 # service-id: management-equip
Swagger2配置类:
这里比较重要的是2个配置类。第一个:SwaggerConfig.class是swagger的配置类,DocumentationConfig,用于整合配置接口文档
SwaggerConfig.class
@Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket buildDocket() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(buildApiInf()) // .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage(""))// 需要生成文档的包的位置 .paths(PathSelectors.any()) .build(); } private ApiInfo buildApiInf() { return new ApiInfoBuilder() .title("海外智能云平台系统接口详情") .description("Zuul+Swagger2构建RESTful APIs") .termsOfServiceUrl("http://www.skyworth.com") .contact(new Contact("skyworth", "http://www.skyworth.com", "")) .version("1.0") .build(); } }
DocumentationConfig.class(注意红色部分,通过遍历eureka路由方式自动添加所有微服务 API 文档,SwaggerResourcesProvider 是资源提供者,我们重写他,把各个微服务的API文档资源路径返回,注释部分为手动添加的方式)
@Component @Primary public class DocumentationConfig implements SwaggerResourcesProvider { private final RouteLocator routeLocator; public DocumentationConfig(RouteLocator routeLocator) { this.routeLocator = routeLocator; } @Override public Listget() { List resources = new ArrayList<>(); List routes = routeLocator.getRoutes(); routes.forEach(route -> { resources.add(swaggerResource(route.getId(), route.getFullPath().replace("**", "v2/api-docs"), "1.0")); }); return resources; } // @Override // public List get() { // List resources = new ArrayList<>(); // resources.add(swaggerResource("外接设备系统", "/management-device/v2/api-docs", "1.0")); // resources.add(swaggerResource("设备管理系统", "/management-equip/v2/api-docs", "1.0")); // return resources; // } private SwaggerResource swaggerResource(String name, String location, String version) { SwaggerResource swaggerResource = new SwaggerResource(); swaggerResource.setName(name); swaggerResource.setLocation(location); swaggerResource.setSwaggerVersion(version); return swaggerResource; } }
最后是启动类Application
@SpringBootApplication @EnableZuulProxy public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
运行相关服务和zuul-swagger网关,输入:http://localhost:8090/swagger-ui.html
另外谈谈遇到的一个坑,之前没有加eureka.instance.prefer-ip-address=true,导致zuul一直访问不到其他服务(可能是eureka.instance.prefer-ip-address = true
就可以将IP注册到Eureka Server上,而如果不配置就是机器的主机名,而主机名没有做ip映射导致访问不大,具体原因需要探究)。
#服务注册 eureka: instance: hostname: device prefer-ip-address: true