前言
在之前的博客中有讲过微服务,微服务就是将一个大的应用拆分成多个可以独立运行的小的服务,而SpringCloud就是一个微服务的生态。
当有了多个微服务以后微服务所产生的问题也随之而来:
- 不同的微服务所部署的服务器可能不同,这就导致客户端在进行请求的时候需要记住所有微服务的地址,而且如果微服务的地址发生了变更,客户端需要同步变更才行
- 在某些场景下可能存在跨域问题
- 如果系统需要进行身份认证的话,每个微服务都需要独立认证
鉴于以上存在的这些问题,服务网关的概念随之产生
服务网关
微服务网关介于客户端与服务器之间的中间层,它是一个服务器,是系统对外的唯一入口。所有的外部请求都会先经过微服务网关。客户端只需要与网关交互,只知道一个网关地址即可。服务网关将所有微服务整合起来,可以进行一些统一操作,如授权认证、负载均衡、路由转发等
路由转发
服务网关是微服务系统对外的统一入口,客户端在请求微服务时,只需要访问网关即可,网关通过服务的注册与发现组件(Eureka、Nacos)获取到所有微服务的信息(ip,端口)然后根据规则将请求转发至对应微服务
Zuul
Zuul网关是是Netflflix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用从而实现路由转发、负载均衡等功能
路由转发的简单使用
1、Zuul是一个独的微服务,所以需要先在项目中新建一个SpringBoot模块
2、引入相关依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
3、在启动类上增加启用Zuul的注解@EnableZuulProxy
4、修改配置文件
zuul:
routes:
product-server:
path: /product-service/**
url: http://127.0.0.1:8829
以上配置表示的是如果进来的请求中包含product-service
则将该请求转发至http://127.0.0.1:8829
,即最终的请求路径为http://127.0.0.1:8829/product-service/**
面向服务的路由配置
使用上述方法就完成了一个微服务的路由转发配置,如果有多个微服务需要进行多个配置
此时会产生一个问题:如果有很多个微服务,每个都这样配置会很麻烦,而且如果服务的地址发生了变更,配置也需要改变,这里就可以使用前面提到过的配合服务的注册与发现组件实现面向服务的路由配置
1、在Zuul所有微服务中引入服务注册与发现组件,这里以Eurekc为例(引入过程请查看SpirngCloud系列Eureka相关内容)
2、修改配置文件
zuul:
routes:
product-service:
path: /product-service/**
serviceId: service-product
以上配置表示的是如果进来的请求中包含product-service
则从Eureka中获取服务id为service-product
的服务,并将请求转发至该服务
过滤器
过滤器 (filter) 是zuul的核心组件,zuul大部分功能都是通过过滤器来实现的。 zuul中定义了4种标准过滤器类型,这些过滤器类型对应于请求的典型生命周期。
- PRE:这种过滤器在请求被路由之前调用。可利用这种过滤器实现身份验证、在 集群中选择请求的微服务、记录调试信息等。
- ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服 务的请求,并使用 Apache HttpClient或Netfilx Ribbon请求微服务
- POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准 的 HTTPHeader、收集统计信息和指标、将响应从微服务发送给客户端等。
- ERROR:在其他阶段发生错误时执行该过滤器。
自定义过滤器实现
1、自定义过滤器类,实现ZuulFilter类并重写其方法
@Component
public class CustomerZuulFilter extends ZuulFilter {
@Override
public String filterType() {
return FilterConstants.ROUTE_TYPE;
}
@Override
public int filterOrder() {
return FilterConstants.PRE_DECORATION_FILTER_ORDER;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
// 自定义逻辑
RequestContext currentContext = RequestContext.getCurrentContext();
HttpServletRequest request = currentContext.getRequest();
String remoteAddr = request.getServerName();
return null;
}
}
因Component注解将过滤器注入容器中,当请求进入zuul网关时,就会根据过滤器时机策略执行对应的过滤器了。
👍 欢迎前往博客主页查看更多内容
👍 如果觉得不错,期待您的点赞、收藏、评论、关注
👍 如有错误欢迎指正!