在前面SpringCloud之Hystrix、SpringCloud之Feign基本都SpringCloud后端服务之间的交互有了一定的理解后,考虑到了另一个问题。
每台服务器的ip和端口都不一致,前端怎么去请求嘞?
于是了解到了SpringCloud的五大组件之一的Zuul
目录
一、Zuul简介
zuul 是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用。
Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门。
二、Zuul网关的作用
网关有以下几个作用:
- 统一入口:未全部为服务提供一个唯一的入口,网关起到外部和内部隔离的作用,保障了后台服务的安全性。
- 鉴权校验:识别每个请求的权限,拒绝不符合要求的请求。
- 动态路由:动态的将请求路由到不同的后端集群中。
- 减少客户端与服务端的耦合:服务可以独立发展,通过网关层来做映射。
三、使用Zuul
3.1 引入依赖
注意:高版本的cloud版本不支持zuul了,所以需要对SpringCloud和Spring boot版本进行降级
我这里将Spring boot降级为2.0.6.RELEASE,Spring Cloud降级为Finchley.SR2
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--引入Zuul -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
3.2 启动类
在启动类添加注解@EnableZuulProxy
@SpringBootApplication
@EnableZuulProxy
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
3.3 路由映射
将外部请求转发到具体的微服务实例上
3.3.1 配置文件
在zuul.routes下管理服务的请求
zuul:
routes:
good-service :
service-id : goods-customer
path : /goods-service/**
good-serive : 自定义命名,标识被管理的服务名
service-id : 服务在注册中心注册的名称
path:zuul管理下对应服务的路径,zuul可以通过这个路径请求到对应的服务
3.3.2 cannot deserialize from Object value
测试时出,zuul请求到对应的服务,返回时将对象的json字符串进行反序列化报错了。
解决方法:给对应的bean添加无参构造函数
3.3.3 测试
在zuul服务器请求goods服务消费者的findAll接口
http://localhost:7001/goods-service/goods/findAll
请求成功
3.4 请求过滤
通过设置身份验证,过滤非法请求;
3.4.1 创建拦截类
通过继承ZuulFilter创建拦截类
public class TestFilter extends ZuulFilter {
//四种类型:pre,routing,error,post
//pre:主要用在路由映射的阶段是寻找路由映射表的
//routing:具体的路由转发过滤器是在routing路由器,具体的请求转发的时候会调用
//error:一旦前面的过滤器出错了,会调用error过滤器。
//post:当routing,error运行完后才会调用该过滤器,是在最后阶段的
@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 context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
String token = request.getParameter("token");
if (token == null) {
context.setSendZuulResponse(false);
context.setResponseStatusCode(401);
context.setResponseBody("unAuthrized");
}
return null;
}
}
3.4.2 管理拦截类
在启动类中将拦截类放入容器中管理
@SpringBootApplication
@EnableZuulProxy
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public TestFilter tokenFilter() {
return new TestFilter();
}
}