SpringCloud(5)路由网关Spring Cloud Zuul
一个简单的微服务系统如下图:

1.为什么需要Zuul
Zuul很容易实现 负载均衡、智能路由 和 熔断器,可以做身份认证和权限认证,可以实现监控,在高流量状态下,对服务进行降级。
2.路由网关
继续前面文章的搭建,新建一个Spring Boot工程模块。取名为service-zuul.
1.导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>service-zuul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>service-zuul</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.注解 @EnableZuulProxy 开启路由网关
@EnableZuulProxy //开启路由网关
@EnableEurekaClient
@SpringBootApplication
public class ServiceZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceZuulApplication.class, args);
}
}
3.配置 application.yml
server:
port: 8769
spring:
application:
name: service-zuul
client:
service-url:
defaultZone: http://localhost:8761/eureka/
zuul:
routes:
api-a:
path: /api-a/**
serviceId: service-feign
api-b:
path: /api-b/**
serviceId: service-ribbon
首先指定服务注册中心的地址为 http://localhost:8761/eureka/,服务的端口为8769,服务名为 service-zuul,以 /api-a/ 开头的请求都转发给 service-feign 服务,以 /api-b/ 开头的请求都转发给 service-ribbon 服务。
依次运行eureka-server、service-hi、service-ribbon、service-feign、service-zuul工程,其中service-hi以8762端口和8763端口启动两个实例。
打开浏览器访问 http://localhost:8769/api-a/hi?name=mark 两次,浏览器显示.
hi mark,i am from port:8763
hi mark,i am from port:8762
这说明zuul起到了路由的作用。如果某服务存在多个实例,Zuul会结合 Ribbon 做负载均衡,将请求均分的部分路由到不同的服务实例。
3.配置过滤器
Zuul不仅只是路由,并且还能过滤,做一些安全验证。继续改造工程,增加一个Filter Bean.
@Component
public class MyFilter extends ZuulFilter {
Logger log = LoggerFactory.getLogger(getClass());
/**
* 过滤器的类型
* pre:路由之前
* routing:路由之时
* post: 路由之后
* error:发送错误调用
*/
@Override
public String filterType() {
return "pre";
}
/**
* 过滤的顺序
*/
@Override
public int filterOrder() {
return 0;
}
/**
* 写逻辑判断,是否要过滤
* true:永远过滤
*/
@Override
public boolean shouldFilter() {
return true;
}
/**
* 过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问
*/
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
Object accessToken = request.getParameter("token");
if (accessToken == null) {
log.warn("token is empty");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
try {
ctx.getResponse().getWriter().write("token is empty");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
log.info("ok");
return null;
}
}
访问http://localhost:8769/api-b/hi?name=mark
token is empty
访问http://localhost:8769/api-b/hi?name=mark&token=123 两次
hi mark,i am from port:8763
hi mark,i am from port:8762
4.配置API前戳版本号
在上面 Zuul 工程 application.yml 的基础上增加一条配置 zuul.prefix: /v1,然后重启 Zuul 工程,访问 http://localhost:8769/v1/api-b/hi?name=mark&token=123 即可。
5.配置熔断器
在 Zuul 实现熔断功能很简单,类似实现过滤器的步骤,只需要实现 ZuulFallbackProvider 接口即可。完整代码.
@Component
public class MyFallbackProvider implements ZuulFallbackProvider {
/**
* 指定熔断器用于哪些服务
*/
@Override
public String getRoute() {
return "service-feign";
}
/**
* 熔断时的逻执行代码
* @return
*/
@Override
public ClientHttpResponse fallbackResponse() {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return 200;
}
@Override
public String getStatusText() throws IOException {
return "OK";
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream("oooops!error,I'm the fallback.".getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
return httpHeaders;
}
};
}
}
重新启动 service-zuul 工程,并关闭 service-hi 的所有实例,在浏览器上访问 http://localhost:8769/v1/api-a/hi?name=mark&token=123 显示:
oooops!error,I'm the fallback.
如果需要所有的路由服务都加熔断功能,只需要在 getRoute 方法上返回 “*” 的匹配符即可.
@Override
public String getRoute() {
return "*";
}
6.Zuul的常见使用方式
Zuul 采用的是异步阻塞模型,性能比 Nginx 差,由于 Zuul 和其他 Netflix 组件相互配合、无缝集成,Zuul 很容易就能实现负载均衡、智能路由和熔断器等功能。在大多数情况下,Zuul 都是以集群的形式存在。
一种常见的使用方式是对不同的渠道使用不同的Zuul来进行路由,例如移动端共用一个 Zuul 网关实例,Web端用另一个 Zuul 网关实例,其他的客户端用另一个Zuul实例进行路由。
另外一种就是常见的集群是通过 Nginx 和 Zuul 相互结合来做负载均衡。
参考方志朋《深入理解Spring Cloud与微服务构建》
SpringCloud(5)路由网关Spring Cloud Zuul的更多相关文章
- 路由网关--spring cloud zuul
路由网关--spring boot Zuul 1.为什么需要Zuul? Zuul Ribbon 以及 Eureka 相结合,可以实现智能路由和负载均衡的功能, Zuul 能够将请求流量按某种策略分发到 ...
- spring boot 2.0.3+spring cloud (Finchley)5、路由网关Spring Cloud Zuul
Zuul作为微服务系统的网关组件,用于构建边界服务,致力于动态路由.过滤.监控.弹性伸缩和安全. 为什么需要Zuul Zuul.Ribbon以及Eureka结合可以实现智能路由和负载均衡的功能:网关将 ...
- Spring Cloud 微服务二:API网关spring cloud zuul
前言:本章将继续上一章Spring Cloud微服务,本章主要内容是API 网关,相关代码将延续上一章,如需了解请参考:Spring Cloud 微服务一:Consul注册中心 Spring clou ...
- 服务网关Spring Cloud Zuul
Spring Cloud Zuul 开发环境 idea 2019.1.2 jdk1.8.0_201 Spring Boot 2.1.9.RELEASE Spring Cloud Greenwich S ...
- Spring Cloud Zuul 网关使用与 OAuth2.0 认证授权服务
API 网关的出现的原因是微服务架构的出现,不同的微服务一般会有不同的服务地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题: 客户端会 ...
- Spring Cloud 微服务三: API网关Spring cloud gateway
前言:前面介绍了一款API网关组件zuul,不过发现spring cloud自己开发了一个新网关gateway,貌似要取代zuul,spring官网上也已经没有zuul的组件了(虽然在仓库中可以更新到 ...
- spring cloud: zuul: 微网关-简单使用与路由配置
spring cloud: zuul: 微网关-简单使用与路由配置 首先引入依赖 <dependency> <groupId>org.springframework.cloud ...
- Spring Cloud Zuul API服务网关之请求路由
目录 一.Zuul 介绍 二.构建Spring Cloud Zuul网关 构建网关 请求路由 请求过滤 三.路由详解 一.Zuul 介绍 通过前几篇文章的介绍,我们了解了Spring Cloud ...
- Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式。
时间过的很快,写springcloud(十):服务网关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更高级的使用方式. 上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制 ...
随机推荐
- C# 实现对PPT插入、编辑、删除表格
现代学习和办公当中,经常会接触到对表格的运用,像各种单据.报表.账户等等.在PPT演示文稿中同样不可避免的应用到各种数据表格.对于在PPT中插入表格,我发现了一个新方法,不过我用到了一款免费的.NET ...
- .babelrc配置(webpack)
babel是一种js语法编译器,在前端开发过程中,由于浏览器的版本和兼容性问题,很多js的新方法和特性的使用都受到了限制.使用babel可以将代码中js代码编译成兼容绝大多数主流浏览器的代码. bab ...
- Django的urls.py加载静态资源图片,TypeError: view must be a callable or a list/tuple in the case of include().
Django的urls.py加载静态资源图片,TypeError: view must be a callable or a list/tuple in the case of include(). ...
- LEDAPS1.3.0版本移植到windows平台----HuSr大气校正模块
这个是2012年左右放在百度空间的,谁知百度空间关闭...转移到博客园. 最近项目用到3.1.2版本的LEDAPS,新版本的使用情况会在后续文章中慢慢丰富. HuSr是将LEDAPS项目中的TM/ET ...
- jsp用el表达式获取后台传来的值,或者获取session中的值
<script type="text/javascript"> var usernameC = ${sessionScope.SESSION_USER_PROFILE. ...
- 微信小程序下拉刷新和上拉加载的实现
一: 下拉刷新 下拉刷新两个步骤就能实现. 1.在要实现下拉刷新的页面的json配置文件里面加上 "enablePullDownRefresh": true, //开启下拉刷新 & ...
- Spark之Pipeline处理模式
一.简介 Pipeline管道计算模式:只是一种计算思想,在数据处理的整个流程中,就想水从管道流过一下,是顺序执行的. 二.特点 1.数据一直在管道中,只有在对RDD进行持久化[cache,persi ...
- Angualr学习笔记
0.安装即环境初始化 下载node至windows,点击安装,所有环境变量直接OK: linux下载tar后,解压,在/etc/profile的path路径下增加node执行路径: export PA ...
- c/c++ 多线程 绕过mutex的保护
多线程 绕过mutex的保护 mutex,能够解决线程安全的问题,但它不是万能的.下面的例子虽然使用了mutex,但是恶意注入了一个外部函数,导致把被mutex保护的双向链表,让一个外部的指针指向了, ...
- sqlserver数据库导出表结构和表数据生成创建表和insert语句
问题描述: 有时候我们只需要导出一张表和表数据到另外一个数据库,如果是备份整个库的话,就会很麻烦那样,没法满足需求. 解决方法: 以sqlserver2014为例:把MGActivity数据库的bat ...