问:什么是网关服务?
答:给外部提供单一的访问接口,并作过滤和拦截处理的服务。java
问:微服务架构中网关服务有什么做用?
答:咱们微服务架构中项目众多,若是直接抛给外部,将会很容易引发调用错误而且大大增长了维护成本,因此咱们须要提供单一访问接口,外部请求所有经过统一端口网关,而后在分发到不一样的服务器。若是熟悉nginx 的同窗想必就知道,其实就是nginx 反向代理的功能。linux
问:那为何不使用nginx,而是使用zuul
答: nginx 确实能够实现网关的功能,可是咱们一样的要维护nginx.conf 文件,若是项目够多,是很容易出问题的,使用zuul 的话,能够和eureka 自然的融合,使得管理维护起来更加方便。nginx
下面咱们就来看下怎么实现zuul 吧。git
咱们建立一个zuul 的模块,pom.xml 文件中引入zuul 和erueka程序员
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
在启动类中咱们加入@EnableZuulProxy 注解
将springBootApplication 注解换成@SpringCloudApplication 注解。
EnableZuulProxy 注解表示启动zuul 网关服务。
SpringCloudApplication 注解,咱们来看下源码github
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public @interface SpringCloudApplication { }
能够看到包含的注解主要是SpringBootApplication、EnableDiscoveryClient、EnableCircuitBreaker 而这三个注解,咱们前面都接触过的,SpringBootApplication就是Springboot项目启动的专用注解,EnableDiscoveryClient注解是将服务注册到服务中心,并发现服务的。EnableCircuitBreaker 是实现熔断处理的注解,因此说SpringCloudApplication 注解是对三个的一层封装,因此咱们之后构建微服务的时候,使用SpringCloudApplication 注解会更方便。spring
接下来咱们在配置问价中增长以下配置segmentfault
server.port=9007 spring.application.name=zuul eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/ zuul.routes.test-a.path=/a/** zuul.routes.test-a.service-id=ribbon-consumer
server.port和spring.application.name 用来指定项目启动的端口和项目在注册中心的名称,eureka.client.serviceUrl.defaultZone用来指定注册中心的地址。
zuul.routes.*.path 和zuul.routes.*.service-id 用来指定咱们的目的项目。
好比我这里配置的ribbon-consumer 项目,将localhost:9007/a/** 转发到ribbon-consumer 对应的接口上。
# 测试
好了,咱们如今就把网关配置好了。咱们如今启动一下项目,启动以下几个项目进行测试吧就。
其中EurekaServer是注册中心,ribbon-consumer 是服务消费者,ribbon-consumer 是服提供者,zuul 是网关。咱们启动好这几个项目后,咱们输入一下地址:安全
http://localhost:9007/a/index
能够看到其实访问的是服务器
http://localhost:9003/index
上面的能够看到,咱们主要的配置就是在配置文件中配置好目标地址的路径。可是这样的话,和nginx 有什么区别呢,若是项目足够多配置起来仍是会出错的,因此前面说zuul 和eureka 能够无缝链接,因此,这里zuul 作了一个默认映射,为全部注册到注册中心的服务提供了一个惟一对应的默认映射。怎么说呢,咱们看一下服务中心的控制台。
zuul 将eureka 中服务名做为映射前缀,好比
http://localhost:9007/ribbon-consumer/index
能够看到,达到了同样的效果,ribbon-consumer 就是服务名。
前面咱们讲了zuul 网关能够转发请求,可是它还有一个强大的功能,那就是请求过滤,咱们知道具体项目中咱们的接口会作安全限制,因此在具体的项目中会写过滤器和拦截器。在微服务项目中,咱们既然提供了统一的网关服务,因此咱们能够将安全校验和具体业务剥离出来,将安全校验放在zuul 网关中来统一处理,这样减小了冗余代码,也方便维护。
那么怎在zuul 中实现请求过滤呢?
继承ZuulFilter 类。
咱们建立一个AccessFilter你类来继承ZuulFilter 。代码以下:
@Slf4j public class AccessFilter extends ZuulFilter { @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException { RequestContext ctx=RequestContext.getCurrentContext(); HttpServletRequest request=ctx.getRequest(); String token=request.getParameter("token"); if(token == null || !token.equals("123456")){ log.info("token is error!"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(500); return "error"; } log.info("token is ok"); return null; } }
直接将书上的解释拿出来了。主要的方法是run方法,获取请求中的request 和参数,对参数进行校验从而过滤。
这里我就是对token 进行简单的校验,也就是说只有检验经过了才能访问目标接口。
昨晚上面这些还不够,还差一步,在项目zuul 服务启动的时候,须要将 AccessFilter bean 注册服务中。因此咱们在启动类中注入
@Bean public AccessFilter accessFilter(){ return new AccessFilter(); }
好了,咱们来启动一下项目看看。
能够看到就能够起到拦截的做用。
到此为止,zuul 网关服务搭建好了,并运行一个很是简单的例子。
代码上传到github:
https://github.com/QuellanAn/SpringCloud
后续加油♡
欢迎你们关注我的公众号 "程序员爱酸奶"
分享各类学习资料,包含java,linux,大数据等。资料包含视频文档以及源码,同时分享本人及投递的优质技术博文。
若是你们喜欢记得关注和分享哟❤