Spring Cloud Zuul路由网关服务过滤实现代码
作者:彭超 发布时间:2021-08-26 10:56:07
Zuul 简介
Zuul 的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如 /api/admin 转发到到 Admin 服务,/api/member 转发到到 Member 服务。Zuul 默认和 Ribbon 结合实现了负载均衡的功能。
引入依赖
在 pom.xml 中主要添加 spring-cloud-starter-netflix-eureka-server 和 spring-cloud-starter-netflix-zuul 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
相关配置
在 application.yml 中主要添加 Zuul 路由配置
zuul:
routes:
api-a:
path: /api/ribbon/**
serviceId: hello-spring-cloud-web-admin-ribbon
api-b:
path: /api/feign/**
serviceId: hello-spring-cloud-web-admin-feign
路由说明:
以 /api/ribbon 开头的请求都转发给 spring-cloud-web-admin-ribbon 服务
以 /api/feign 开头的请求都转发给 spring-cloud-web-admin-feign 服务
在 Application 入口类中添加 @EnableZuulProxy 注解开启 zuul 功能
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
配置网关路由失败时的回调
创建 WebAdminFeignFallbackProvider 回调类
/**
* 路由 hello-spring-cloud-web-admin-feign 失败时的回调
*/
@Component
public class WebAdminFeignFallbackProvider implements FallbackProvider {
@Override
public String getRoute() {
// ServiceId,如果需要所有调用都支持回退,则 return "*" 或 return null
return "hello-spring-cloud-web-admin-feign";
}
/**
* 如果请求服务失败,则返回指定的信息给调用者
* @param route
* @param cause
* @return
*/
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
return new ClientHttpResponse() {
/**
* 网关向 api 服务请求失败了,但是消费者客户端向网关发起的请求是成功的,
* 不应该把 api 的 404,500 等问题抛给客户端
* 网关和 api 服务集群对于客户端来说是黑盒
* @return
* @throws IOException
*/
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return HttpStatus.OK.value();
}
@Override
public String getStatusText() throws IOException {
return HttpStatus.OK.getReasonPhrase();
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> map = new HashMap<>();
map.put("status", 200);
map.put("message", "无法连接");
return new ByteArrayInputStream(objectMapper.writeValueAsString(map).getBytes("UTF-8"));
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
// 和 getBody 中的内容编码一致
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return headers;
}
};
}
}
测试路由访问
依次运行 EurekaApplication > ServiceAdminApplication > WebAdminRibbonApplication > WebAdminFeignApplication > ZuulApplication 各服务
访问:http://localhost:8769/api/ribbon/hi?message=zuul
浏览器显示
port : 8763,message : zuul
访问:http://localhost:8769/api/feign/hi?message=zuul
浏览器显示
port : 8763,message : zuul
至此说明 Zuul 的路由功能配置成功。
使用 Zuul 的服务过滤功能
Zuul 不仅仅只是路由,还有很多强大的功能。比如用在安全验证方面。
创建服务过滤器
/**
* Zuul 的服务过滤演示
*/
@Component
public class LoginFilter extends ZuulFilter {
private static final Logger logger = LoggerFactory.getLogger(LoginFilter.class);
/**
* 配置过滤类型,有四种不同生命周期的过滤器类型
* 1. pre:路由之前
* 2. routing:路由之时
* 3. post:路由之后
* 4. error:发送错误调用
* @return
*/
@Override
public String filterType() {
return "pre";
}
/**
* 配置过滤的顺序
* @return
*/
@Override
public int filterOrder() {
return 0;
}
/**
* 配置是否需要过滤:true/需要,false/不需要
* @return
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 过滤器的具体业务代码
* @return
* @throws ZuulException
*/
@Override
public Object run() throws ZuulException {
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
String token = request.getParameter("token");
if (token == null) {
logger.warn("Token is empty");
context.setSendZuulResponse(false);
context.setResponseStatusCode(401);
try {
context.getResponse().getWriter().write("Token is empty");
} catch (IOException e) {
}
} else {
logger.info("OK");
}
return null;
}
}
测试过滤器
访问:http://localhost:8769/api/feign/hi?message=zuul
网页显示
Token is empty
访问:http://localhost:8769/api/feign/hi?message=zuul&token=1
网页显示
port : 8763,message : zuul
来源:https://antoniopeng.com/2019/11/16/springcloud/SpringCloudZuul%E8%B7%AF%E7%94%B1%E7%BD%91%E5%85%B3%E5%8F%8A%E6%9C%8D%E5%8A%A1%E8%BF%87%E6%BB%A4/
猜你喜欢
- 最近在做上传文件的服务,简单看了网上的教程。结合实践共享出代码。由于网上的大多数没有服务端的代码,这可不行呀,没服务端怎么调试呢。Ok,先上
- 随着互联网的蓬勃发展,越来越多的互联网企业面临着用户量膨胀而带来的并发安全问题。本文着重介绍了在java并发中常见的几种锁机制。1.偏向锁偏
- 需求基于MTK8163 8.1平台定制导航栏部分,在左边增加音量减,右边增加音量加思路需求开始做之前,一定要研读SystemUI Navig
- java 中HttpClient传输xml字符串实例详解介绍:我现在有一个对象page,需要将page对象转换为xml格式并以binary方
- 本文基于jdk1.8进行分析。ReentrantLock是一个可重入锁,在ConcurrentHashMap中使用了ReentrantLoc
- Android超清晰6.0权限申请AndPermission的具体实现代码,供大家参考,具体内容如下前言这是我经常使用的框架,原因:1.思路
- 本文实例讲述了c#用for语句输出一个三角形的方法。分享给大家供大家参考。具体分析如下:这是一道面试题,要求是这样的:只使用一个for循环输
- java多态性多态分两种:(1) 编译时多态(设计时多态):方法重载。(2) 运行时多态:J
- 前言:文件的上传和下载在日常开发中很是常见,那么这一功能是如何实现的呢,下面我给大家介绍一下实现条件:1、需要一个form标签,method
- 一、Spring Bean 集合注入在【Spring学习笔记(三)】已经讲了怎么注入基本数据类型和引用数据类型,接下来介绍如何注入比较特殊的
- 需求在配置类中,从application.properties中读取一个复杂list。如List<Person>或者初始化一个m
- 1、CountDownLatch:一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。2、ThreadPoolE
- 接收从控制台输入的数据可以使用Scanner类实现,Scanner类在一个名为util的包中需要在程序中导入这个包, 即在程序中添加impo
- 如果有哪一个做程序员的小伙伴说自己没有遇到中文乱码问题,我是不愿意相信的。今天在做微信订阅号的智能回复时,又一时迷乱的跳进了中文乱码这个火坑
- private void button1_Click(object sender, EventArgs e) &nbs
- NumberFormat.getInstance()方法返回NumberFormat的一个实例(实际上是NumberFormat具体的一个子
- 开发过程中有这样一个场景,2个 bean 初始化逻辑中有依赖关系,需要控制二者的初始化顺序。实现方式可以有多种,本文结合目前对 Spring
- 1、认识 Spring CacheSpring Cache是Spring提供的一整套缓存解决方案。它本身并不提供缓存实现,而是提供统一的接口
- 你以前听到的谈论关于Java8的所有都是围绕lambda表达式. 但它仅仅是Java8的一部分. Java 8 有许多新特性—一些强大的新类
- ApplicationContext简述ApplicationContext代表IOC容器,在SpringIOC容器中读取Bean配置创建B