除了Zuul还可以使用SpringCloud的Gateway组件,这是新出的路由组件。
https://spring.io/projects/spring-cloud-gateway
https://cloud.spring.io/spring-cloud-gateway/reference/html/
新建一个Maven工程,命名为micro-service-new-gateway。
同样新建主类ApplicationMain,并加入依赖。
这里不使用zuul,而换作spring-cloud-starter-gateway依赖,其他依赖和Zuul工程的依赖一样。
在ApplicationMain类中加入一个Bean。
package com.lpplpp.gateway.app; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.context.annotation.Bean; @SpringBootApplication public class ApplicationMain { public static void main(String[] args) { SpringApplication.run(ApplicationMain.class, args); System.out.println("new gateway microservice is running"); } @Bean public RouteLocator myRoutes(RouteLocatorBuilder builder) { return builder.routes().build(); } }
现在有了一个路由RouteLocator,可以加入路由规则。
package com.lpplpp.gateway.app; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.context.annotation.Bean; @SpringBootApplication public class ApplicationMain { public static void main(String[] args) { SpringApplication.run(ApplicationMain.class, args); System.out.println("new gateway microservice is running"); } @Bean public RouteLocator myRoutes(RouteLocatorBuilder builder) { return builder.routes() .route(p -> p .path("/product/1") .uri("http://127.0.0.1:8080/product/1")) .build(); } }
配置application.yml设置端口为8686,微服务名称为micro-service-new-gateway。
启动这个微服务,发现出问题了。
报错信息:“No qualifying bean of type 'org.springframework.core.convert.ConversionService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Qualifier(value=webFluxConversionService)}”
这是因为SpringCloud Gateway不再采用Tomcat作为容器,而内置了Netty容器。解决方式是在pom.xml去除spring-boot-starter-web的依赖。
这时再重新启动,访问浏览器地址http://localhost:8686/product/1
结果:
{"id":1,"name":"mobile"}
在ApplicationMain中已经把uri和path实现了,也可以用配置的方式在application.yml中实现。有了配置,当然就不需要@Bean注入RouteLocator。
访问http://localhost:8686/product/1
结果:
{"id":1,"name":"mobile"}
再加入一个配置,让网关处理订单的请求。
访问http://localhost:8686/order/1
结果:
{"id":1,"name":"mobile order","product":{"id":1,"name":"mobile"}}
SpringCloud Gateway实现的路由支持非阻塞,限流,长连接等,这是比Zuul更好的特性。