微服务架构整理-(十二SpringCloud实战之Zuul网关)

Posted 浦江之猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务架构整理-(十二SpringCloud实战之Zuul网关)相关的知识,希望对你有一定的参考价值。

SpringCloud实战之Zuul网关

Zuul概念

Zuul是Netflix旗下的又一重要成员,是一个基于 JVM 路由和服务端的网关和负载均衡器,是一个提供路由、监控、弹性、安全等方面的服务框架。其核心是过滤器,通过这些过滤器我们可以扩展出很多功能,例如:

  • 动态路由
    动态地将客户端的请求路由到后端不同的服务,做一些逻辑处理,比如聚合多个服务的数据返回。
  • 请求监控
    可以对整个系统的请求进行监控,记录详细的请求响应日志,可以实时统计出当前系统的访问量以及监控状态。
  • 认证鉴权
    对每一个访问的请求做认证,拒绝非法请求,保护好后端的服务,所有的请求通过Zuul进行认证鉴权,无需在每个微服务中进行。
  • 压力测试
    有些系统上线前,需要进行压力测试来验证系统的稳定性和可靠性,以便系统能更好的应对可种促销活动,尤其是现在的双11,双12等活动。当并发量达到一定量级时,这些请求能否有效的转发到对应的服务上,都可以在事先通过Zuu进行压力测试。
  • 灰度发布
    灰度发布可以保证系统的平稳过度,在初始灰度的时候就可以发现、调整问题,以降低新特性对整个系统的影响度。

Zuul构建网关

Zuul的网关功能非常强大,这里通过一个简单的例子,通过zuul网关路由到之前的微服务中。

创建Spring Boot 工程

springboot版本:2.2.6.RELEASE 。工程名:zuul。启动类为:ZuulApplication

添加依赖

需要添加2个依赖,分别为eureka,zuul.

<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>

添加注解

启动类上添加@EnableZuulProxy注解

@SpringBootApplication
//开启
@EnableZuulProxy
public class ZuulApplication 

	public static void main(String[] args) 
		SpringApplication.run(ZuulApplication.class, args);
	

添加配置文件

需要在配置文件中添加基础配置,eureka,路由规则等。

基础配置

配置端口号与服务名

server:
  port: 9008 #端口
spring:
  favicon:
    enabled: false
  application:
    name: service-zuul #服务名称

注册Eureka

由于serice-zuul也是一个微服务因此也需要注册到Eureka中

#配置eureka server
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      #注册到两个eureka上
      defaultZone: http://localhost:9005/eureka/,http://localhost:9006/eureka/

添加路由规则

#配置路由规则
zuul:
  routes:
    api-monkey:
      path: /api-monkey/**
      serviceId: service-openfeign

以上配置,路由规则就是匹配所有符合/api-monkey/**的请求,只要路径中带有/api-monkey/都将被转发到service-openfeign服务上,至于service-openfeign服务的地址到底是什么则由eureka-server注册中心去分析,我们只需要写上服务名即可。

以当前搭建的项目为例,请求 http://localhost:9008/api-monkey/buy/1 接口则相当于请求 http://localhost:9007/buy/1 (service-openfeign服务的地址为 http://localhost:9007/buy/1), 路由规则中配置的api-monkey是路由的名字,可以任意定义,但是一组path和serviceId映射关系的路由名要相同。返回结果为:


    "id": 1,
    "name": "apple1",
    "price": 8000.00

说明API网关服务已经构建成功。

Zuul请求过滤

Zuul 就像一个安检站 ,所有请求都会经过这个安检站,安检站中需要对所有的请求按照一定的规则进行过滤。例如:请求验证,当验证通过了才可以进行转发。这里模拟一个带token的过滤,如果请求中没有token,则返回无效请求,反之进行跳转

定义过虑逻辑


@Component
//必须要继承ZuulFilter
public class OAuth2Filter extends ZuulFilter 

    @Override
    public Object run() throws ZuulException 
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String token = request.getParameter("token");
        if (token == null) 
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            ctx.addZuulResponseHeader("content-type", "text/html;charset=utf-8");
            ctx.setResponseBody("无效请求");
        
        return null;
    

    @Override
    public boolean shouldFilter() 
        return true;
    

    @Override
    public int filterOrder() 
        return 0;
    

    @Override
    public String filterType() 
        return "pre";
    


  • filterType方法的返回值为过滤器的类型,过滤器的类型决定了过滤器在哪个生命周期执行,pre 表示在路由之前执行过滤器,其他值还有 post 、error 、route和static,当然也可以自定义。
  • filterOrder方法表示过滤器的执行顺序,当过滤器很多时, 需要通过此方法的返回值来指定过滤器的执行顺序 。
  • shouldFilter方法用来判断过滤器是否执行,true表示执行,false 表示不执行。
  • run方法表示过滤的具体逻辑, 如果请求地址中携带了token参数的话,则认为是合法请求,否则为非法请求,如果是非法请求的话,首先设置ctx.setSendZuulResponse(false)表示不对该请求进行路由,然后设置响应码和响应值。这里只是个模拟,所以run方法的返回值目前暂时没有任何意义。

请求结果

  • http://localhost:9008/api-monkey/buy/1?token=123

    "id": 1,
    "name": "apple1",
    "price": 8000.00

  • http://localhost:9008/api-monkey/buy/1
    无效请求

Zuul路由规则

在上面的例子中,路由规则配的是:

#配置路由规则
zuul:
  routes:
    api-monkey:
      path: /api-monkey/**
      serviceId: service-openfeign

当访问地址符合/api-monkey/**规则的时候,会被自动定位到service-openfeign服务上。如果路由规则什么都不写,则zuul默认会路由到注册中心中的所有服务。格式为:域名/服务名/api地址
例如,本服务系统中可以向外提供服务的有service-openfeignservice-product,则对应的请求分别为:

  • http://localhost:9008/service-openfeign/buy/1?token=111
  • http://localhost:9008/service-product/product/1?token=111
    当然,也可以在配置文件中添加相应的路由规则
  • 忽略某个服务
zuul:
  ignored-services: service-product
  • 忽略某带某个关键字的api
zuul:
  ignored-patterns: /**/hello/**
  • 配置前缀
zuul:
  prefix:/v1

此时访问路径就变成:http://localhost:9008/v1/api-monkey/buy/1?token=123

  • 路由规则通配符
通配符含义举例备注
匹配任意单个字符/api-monkey/?可以匹配: /api-monkey/1
*匹配单路径任意数量字符/api-monkey/*可以匹配:/api-monkey/1,/api-monkey/22,/api-monkey/333 不可以匹配:/api-monkey/1/2/3
**匹配多路径任意单个字符/api-monkey/**可以匹配: /api-monkey/1,/api-monkey/1/22

总结

关于Zuul的基本知识点就介绍完了。最后,希望本文能帮助大家,祝大家在IT之路上少走弯路,一路绿灯不堵车,测试一性通过,bug秒解!
源码下载

以上是关于微服务架构整理-(十二SpringCloud实战之Zuul网关)的主要内容,如果未能解决你的问题,请参考以下文章

微服务架构整理-(十二SpringCloud实战之Zuul网关)

微服务架构整理-(七SpringCloud实战之RestTemplate)

微服务架构整理-(七SpringCloud实战之RestTemplate)

微服务架构整理-(八SpringCloud实战之Hystrix [1])

微服务架构整理-(八SpringCloud实战之Hystrix [1])

微服务架构整理-(十一SpringCloud实战之OpenFeign)