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
    
  • 相关阅读:
    中国历史朝代公元对照简表
    [Solved] DashBoard – Excel Service: The data sources may be unreachable, may not be responding, or may have denied you access.
    Delete/Remove Project from TFS 2010
    Sharepoint site showing system account instead of my username on the top right corner.
    你的成功在于你每天养成的习惯
    Internet Information Services is running in 32bit emulation mode. Correct the issue listed above and rerun setup.
    Prepare to back up and restore a farm (Office SharePoint Server 2007)
    Word中字号与磅值的对应关系
    How to: Change the Frequency for Refreshing the Data Warehouse for Team System
    UI Automation in WPF/Silverlight
  • 原文地址:https://www.cnblogs.com/nwu-edu/p/9628747.html
Copyright © 2011-2022 走看看