1. Zuul 路由网关介绍
其实我们可以吧zuul看成,是公司的前台,我在在做使用zureka做完分布式操作之后呢,我们会发现这些端口我们都可以直接连接,那么既然能直接连接肯定不行,所以我们需要统一管理这些端口,用一个端口去调用这些端口,而Zuul就是解决这个问题的.
具体功能:
- 外部访问统一入口
- 过滤功能
也即以后的访问微服务都是通过Zuul跳转后获得
所以我们也需要把zuul注册Eureka
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zl5ykcm9-1570769868038)(8D8C02577D8145C5AD0DCE9889147BFC)]
2.统一管理功能
2.1 依赖配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
2.2 application.yml配置
server:
port: 9000
#注册到eureka上的服务名
spring:
application:
name: ms-zuul
eureka:
client:
#表示是否从注册中心抓取服务
fetch-registry: true
# 是否将我这个服务注册到注册中心
register-with-eureka: false
# 表示注册中心的地址(自己的eureka)
service-url:
defaultZone: http://localhost:7961/eureka/
2.3 启动类配置
加上 @EnableZuulProxy 这个注解
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {
public static void main( String[] args ) {
SpringApplication.run(ZuulApplication.class, args);
}
}
接下来我们就可以直接通过zuul的端口去调用euerka注册的类了
具体流程↓
http://localhost:9000/shop-provider/ticket/23
记得端口后面跟注册的服务名,接着注册的网名
从上面的结果我们可看出zuul基本配置成功,但是同时会有一个问题,就是服务名暴露出来了,所以下面我们来看看统一网关设置
3 网关过滤
3.1 application.yml配置
server:
port: 9000
#注册到eureka上的服务名
spring:
application:
name: ms-zuul
eureka:
client:
#表示是否从注册中心抓取服务
fetch-registry: true
# 是否将我这个服务注册到注册中心
register-with-eureka: false
# 表示注册中心的地址
service-url:
defaultZone: http://localhost:7961/eureka/
#过滤部分↓
zuul:
routes:
shop-provider: #这个名字可以随便命名,通常定义为每个微服务中的spring.application.name的值
serviceId: shop-provider #该值必须为spring.application.name的值
path: /tk/** #可以通过该路径访问服务
shop-consumer:
serviceId: shop-consumer
path: /us/**
prefix: /v1 #前缀
ignored-services: "*" #通过该服务名访问不了
3.2 实现方法
写一个类 继承 ZuulFilter 实现具体过滤方法
注意: 我这里给了一个判断值需要在headers 中给定这个token 不然一样还是会被拒绝
@Component
public class ZuulFilterImpl extends ZuulFilter {
/**
* pre 在达到具体的服务之前
* post 在达到具体的服务之后
* error 抛出异常
* route 具体服务在执行的过程中
*/
@Override
public String filterType() {
return "pre";
}
/**
* 执行顺序 越小越前
*
* @return
*/
@Override
public int filterOrder() {
return 0;
}
/**
* 是否开启过滤
*
* @return
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 过滤具体内容
*
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
// token
//获取RequestContext对象,目的是只能通过该对象来获取 request、response对象
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
HttpServletResponse response = context.getResponse();
String token = request.getHeader("token");
if(token == null || "".equals(token.trim())) {
// 如果判断满足就false, 目的是用我们自己定义的响应格式
context.setSendZuulResponse(false);
// 返回的数据 可以是json数据 用来回复
context.setResponseBody("一个不合法的请求.");
// 返回状态码 例如 404 500 等等
context.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
//修改编码方式 (可有可无 如果有乱码建议可以来一个,但是不一定有用 ( =A =~ ) )
response.setCharacterEncoding("gbk");
}
return null;
}
}