zuul 自定义路由规则
1,zuul的maven配置
<!--spring cloud 相关包-->
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.SR2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<!-- zuul依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
2,静态路径配置
比如现在我有两个服务,一个服务叫gate 即zuul 网关,一个服务叫service-a ,是网关后面的一个服务,这里面service-a即是:
application.yml
spring:
application:
name:service-a
路由配置1:
zuul: routes: service-a: /node/**
这个意思是,gate 收到一个浏览器的请求,比如:http://localhost:8080/node/student/getStudents,那么就会转发给service-a,注意service-a提供的接口不能带node了,应该是:
@RestController @RequestMapping("stduent") public class TestController { @RequestMapping("getStudents") public Object getStudents() { return null; } }
3,动态配置路由规则
有时候,我们会经常添加一些新的路由规则,每次静态添加不仅多而且麻烦,还会重新启动网关,这时就需要动态配置路由规则了,可以使用代码实现。
在zuul中,默认使用的路径类是:SimpleRouteLocator.java
在它的bean配置类:ZuulServerAutoConfiguration.java中是这样配置的
@Bean @ConditionalOnMissingBean(SimpleRouteLocator.class) public SimpleRouteLocator simpleRouteLocator() { return new SimpleRouteLocator(this.server.getServlet().getServletPrefix(), this.zuulProperties); }
它表示当没有此类型SimpleRouteLocator.class的实现时,使用这个bean,所以我们要实现自己的路由配置,只需要重新实现相关的方法即可。
首先实现一个路由规则加载类
import java.util.LinkedHashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator; import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; /** * * @ClassName: LogServerRouterFilter * @Description: 日志请求相关路由分发到指定的服务器 * @author: wgs * @date: 2018年12月18日 下午3:06:00 */ public class LogServerRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator { @Autowired private ServerConfigService serverConfigService; public LogServerRouteLocator(String servletPath, ZuulProperties properties) { super(servletPath, properties); } @Override public void refresh() { doRefresh(); } //覆盖这个方法,从重实现它 @Override protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() { //重新定义一个路由映射map LinkedHashMap<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap<>();
//把父类中的映射继承下来,它主要是从配置文件中取的映射。 routesMap.putAll(super.locateRoutes());
//这里的路由信息来自于配置文件 for (Map.Entry<String, String> entry : serverConfigService.getGmNodes().entrySet()) { String serverId = entry.getKey(); String serviceId = entry.getValue().toLowerCase(); String path = "/node/**"; ZuulRoute zuulRoute = new ZuulRoute(); //服务提供者的id,即spring.application.name zuulRoute.setServiceId(serviceId); //这个id是匹配的前半部分,比如匹配模式是/node/** 那么这个id就是/node zuulRoute.setId("/node"); //匹配的路径 zuulRoute.setPath(path);
//这里注意一下,这个key就是要匹配的path,可以查看父类的实现,它就是使用path做为key的。 routesMap.put(path, zuulRoute); }return routesMap; } }
上面 ZuulRoute的创建路由规则和静态配置是等价的。
然配置Bean
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class BeanConfig { @Autowired ZuulProperties zuulProperties; @Autowired ServerProperties server; @Bean public LogServerRouteLocator getRouteLocator() { return new LogServerRouteLocator(this.server.getServlet().getServletPrefix(), this.zuulProperties); } }
欢迎添加学习交流QQ群:66728073,197321069,398808948