zoukankan      html  css  js  c++  java
  • Spring cloud学习--Zuul01

    Zuul解决的问题

    • 作为系统的统一入口,屏蔽了系统内部各个微服务的细节
    • 可以与微服务治理框架结合,实现自动化的服务实例维护以及负载均衡的路由转发
    • 实现接口权限校验与微服务业务逻辑的解耦

    搭建Zuul服务

    zuul maven依赖

    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-zuul</artifactId>
            </dependency>
    

    spring-cloud-starter-zuul包含zuul-core、spring-cloud-starter-hystrix、spring-cloud-starter-ribbon、spring-cloud-starter-actrator

    主类上开启API网关服务功能

    //@SpringCloudApplication = @SpringBootApplication + @EnableDiscoveryClient + @EnableCircuitBreaker
    @EnableZuulProxy
    @SpringCloudApplication
    public class ApiGatewayApplication
    {
    	public static void main(String[] args) {
    		SpringApplication.run(ApiGatewayApplication.class, args);
    	}
    }
    

    配置application.properties

    spring.application.name=api-gateway
    server.port=5555
    

    实现简单的传统路由转发功能

    只需要加入

    #实现传统的路由转发功能
    zuul.routes.api-a-url.path=/api-a-url/**
    zuul.routes.api-a-url.url=http://localhost:8080/
    

    所有符合/api-a-url/**规则的访问都将被路由转发到http://localhost:8080/地址上,也就是说当我们访问http://localhost:5555/api-a-url/hello的时候,
    API网关服务会将该请求路由到http://localhost:8080/hello提供的微服务上

    面向服务的路由

    • 加入Eureka依赖
    <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
    
    • 配置路由
    spring.application.name=api-gateway
    server.port=5555
    
    #实现传统的路由转发功能
    #zuul.routes.api-a-url.path=/api-a-url/**
    #zuul.routes.api-a-url.url=http://localhost:8080/
    
    zuul.routes.api-a.path=/api-a/**
    zuul.routes.api-a.serviceId=eureka-client
    
    zuul.routes.api-b.path=/api-b/**
    zuul.routes.api-b.serviceId=feign-consumer
    
    #eureka.instance.hostname=localhost
    #注册服务的注册中心地址
    eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
    

    注意与传统路由的区别,一个是面向url的,一个是面向服务的

    请求过滤

    请求过滤解决的问题

    • 将鉴权校验的非业务部分剥离出来,形成独立的业务服务
    • 微服务中不需要调用此业务服务进行鉴权校验

    简单的示例

    • 创建过滤器
    public class AccessFilter extends ZuulFilter
    {
        private static Logger log = LoggerFactory.getLogger(AccessFilter.class);
        //filterType:过滤器的类型,他决定过滤器会在请求的哪个生命周期中执行,pre代表会在请求被路由之前执行
        @Override
        public String filterType()
        {
            return "pre";
        }
        
        //filterOrder过滤器执行顺序
        @Override
        public int filterOrder()
        {
            return 0;
        }
        //shouldFilter执行生效的条件
        @Override
        public boolean shouldFilter()
        {
            return true;
        }
        //过滤器的具体逻辑
        @Override
        public Object run()
        {
            RequestContext ctx = RequestContext.getCurrentContext();
            HttpServletRequest request = ctx.getRequest();
    
            log.info("send {} request to {}", request.getMethod(), request.getRequestURL().toString());
    
            Object accessToken = request.getParameter("accessToken");
            if(null == accessToken)
            {
                log.warn("access token is empty.");
                ctx.setSendZuulResponse(false);
                ctx.setResponseStatusCode(401);
                return null;
            }
            log.info("access token ok.");
            return  null;
        }
    }
    
    • 在主类中创建具体的bean,实例化过滤器
    @EnableZuulProxy
    @SpringCloudApplication
    public class ApiGatewayApplication
    {
    	@Bean
    	public AccessFilter accessFilter()
    	{
    		return  new AccessFilter();
    	}
    
    	public static void main(String[] args) {
    		SpringApplication.run(ApiGatewayApplication.class, args);
    	}
    }
    

    访问http://localhost:5555/api-a/hello?accessToken=token返回hello world,访问http://localhost:5555/api-a/hello返回401错误

    注意细节

    • 简化path与serviceId组合
      zuul.rotes.=.
      eg:zuul.routes.feign-consumer=/feign-consumer/**
    • zuul默认为每一个服务实例使用其服务名自动创建映射关系进行路由
      例如不配置路由的情况下,访问http://localhost:5555/eureka-client/hello?accessToken=token,可以返回hello world
    • 使用zuul.ignored-services=/user-service/**,可以跳过该服务,不创建改服务的路由
      例如:zuul.ignored-services=*,对所有服务不自动创建路由

    自定义路由映射规则

    eg: 想要将名称userService-v1的服务映射为/v1/userService/的路由
    在主类中加入自定义规则

    @Bean
    	public PatternServiceRouteMapper serviceRouteMapper()
    	{
    		return new PatternServiceRouteMapper(
    				"(?<name>^.+)-(?<version>v.+$)",
    				"${version}/${name}"
    		);
    	}
    

    当匹配表达式的时候,使用此映射规则;不匹配时,采用默认的映射规则

    路径匹配

    Ant风格

    ?:匹配任意单个字符
    *:匹配任意数量的字符
    **:匹配任意数量的字符,支持多级目录

    匹配的顺序

    路由的规则是通过LinkedHashMap保存的,是有序依次加入的,所以是按照配置的先后顺序匹配的。但是properties文件是无序的,如果要想按照先后顺序匹配,可以使用YAML配置文件

    忽略表达式

    使用zuul.ignored-patterns可以忽略掉API网关对路由的限制,eg:

    zuul.ignored-patterns=/**/hello/**
    

    表示任何访问//hello/的路由都不会得到映射,得不到返回内容

    路由前缀

    zuul.prefix=/api
    

    Cookie与头信息

    在请求路由时,zuul会默认过滤掉HTTP请求头信息中的一些敏感信息,防止他们被传递到下游的外部服务器。默认的敏感头信息通过zuul.sensitiveHeaders参数定义,
    包括Cookie、Set-Cookie、Authorization三个属性

    • 全局为空覆盖默认值,不推荐
    zuul.sensitiveHeaders=
    
    • 指定路由参数配置,推荐
    #方法1:对指定路由开启自定义敏感头
    zuul.routes.<router>.customSensitiveHeaders=true
    #方法2:将指定路由的敏感头设置为空
    zuul.routes.<router>.sensitiveHeaders=
    

    重定向的问题

    从访问的路由可以看出,访问成功后,http的url仍然是路由跳转前的web应用实例地址,而不是路由的地址,此问题导致spring security和shiro在登陆完成后,请求头信息中的状态码为302,请求响应头信息中的Location指向了具体的服务实例地址,而请求中的host信息缺指向了路由前的host。故网管进行路由转发前的Host信息没有设置正确。
    解决方法:

    zuul.addHostHeader=true
    

    此解决方案适版本而定

    Hystrix和Ribbon支持

    Zuul天生拥有线程隔离和断路器的自我保护功能,以及对服务调用的客户端负载均衡功能。但是使用path与url的映射的路由转发不会采用HystrixCommand来包装,不具备线程隔离和断路器的保护功能,也不具备负载均衡的能力

    参数配置

    • API网关路由转发请求的HystrixCommand执行超时时间的设置,单位为毫秒
    hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
    
    • 设置路由请求转发,创建请求连接的超时时间
    ribbon.ConnectTimeout=2000
    

    当此超时时间小于上面的超时时间时,会自动进行重试路由请求
    当大于时,不会断路重连

    • 建立连接后的转发请求时间
    ribbon.ReadTimeout=3000
    

    短路重连规则同上

    • 关闭重试机制
    #全局关闭
    zuul.retryable=false
    #指定路由关闭
    zuul.routes.<route>.retryable=false
    
  • 相关阅读:
    8.7题解
    2019.9.16 csp-s模拟测试44 反思总结
    洛谷P3168 [CQOI2015]任务查询系统
    洛谷P2468 [SDOI2010]粟粟的书架
    2019.8.14 NOIP模拟测试21 反思总结
    2019.8.13 NOIP模拟测试19 反思总结
    2019.8.12 NOIP模拟测试18 反思总结
    大约是个告别【草率极了】
    2019.8.10 NOIP模拟测试16 反思总结【基本更新完毕忽视咕咕咕】
    2019.8.9 NOIP模拟测试15 反思总结
  • 原文地址:https://www.cnblogs.com/nwu-edu/p/9628747.html
Copyright © 2011-2022 走看看