SpringCloud系列八:Zuul 路由访问(Zuul 的基本使用、Zuul 路由功能、zuul 过滤访问、Zuul 服务降级)

1、概念:Zuul 路由访问

2、具体内容

在现在为止所有的微服务都是通过 Eureka 找到的,但是在很多的开发之中为了规范微服务的使用,提供有一个路由的处理控制组件:Zuul,也就是说 Zuul 就作为中间的一个代理层出现。

2.1、Zuul 的基本使用

本次使用 Zuul 将访问无安全认证的微服务信息,例如:公司信息就属于无安全认证的微服务;

1、 为了突出 zuul 的功能,建立一个新的主机映射:

127.0.0.1 gateway-9501.com

以后所有的微服务的访问不再直接进行处理了,而是通过 Zuul 进行跳转后获得

2、 建立一个新的模块:microcloud-zuul-gateway-9501;

3、 【microcloud-zuul-gateway-9501】修改 pom.xml 文件,追加 zuul 相关依赖包:

· 注意:Zuul 服务最终还是会注册到 Eureka 之中,那么千万要将其配置好;

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

4、 【microcloud-zuul-gateway-9501】修改 application.yml 配置文件:

server:
  port: 9501

eureka:
  client: # 客户端进行Eureka注册的配置
    service-url:
      defaultZone: http://edmin:[email protected]:7001/eureka,http://edmin:[email protected]:7002/eureka,http://edmin:[email protected]:7003/eureka
  instance:
    lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒)
    lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒)
    instance-id: gateway-9501.com  # 在信息列表时显示主机名称
    prefer-ip-address: true     # 访问的路径变为IP地址

info:
  app.name: study-microcloud
  company.name: www.study.cn
  build.artifactId: $project.artifactId$
  build.version: $project.verson$

spring:
  application:
    name: microcloud-zuul-gateway

5、 【microcloud-zuul-gateway-9501】创建程序启动的主类:

package cn.study.microcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy
public class Zuul_9501_StartSpringCloudApplication {
    public static void main(String[] args) {
        SpringApplication.run(Zuul_9501_StartSpringCloudApplication.class, args);
    }
}

可以看到【microcloud-zuul-gateway-9501】已经注册到eureka中了

6、 访问公司微服务信息:

· 原始访问路径:http://company-8101.com:8101/company/get/hello;

· Zuul 代理访问:http://gateway-9501.com:9501/microcloud-provider-company/company/get/hello;

现在使用 Zuul 代理的只有 company,因为 dept 上有安全认证不能访问。

2.2、Zuul 路由功能

整体的 Zuul 运行之后你会发现,zuul 所实现就是一个代理功能,那么现在就会出现一个问题,例如:以之前访问的路径为例:

http://gateway-9501.com:9501/microcloud-provider-company/company/get/hello

此时必须要知道应用程序的名称,但是如果不知道这个名称肯定无法访问,可是如果让用户知道这个名称,那么使用 zuul 就 没有任何的实际意义,直接调用即可。而 zuul 的主要功能是代理,那么代理的功能就是不让用户看见真实的操作,所以在实际的使用之中就需要为 zuul 设置一些路由规则。

1、 【microcloud-zuul-gateway-9501】为指定的应用设置路径,修改 application.yml 配置文件:

zuul:
  routes:
    microcloud-provider-company: /company-proxy/** 

那么此时就可以通过“/company-proxy”来访问“microcloud-provider-company”名称。

http://gateway-9501.com:9501/company-proxy/company/get/hello

但是现在还会存在有一个实际的问题,虽然现在开启了路由访问支持,但是依然支持通过应用名称进行访问:

http://gateway-9501.com:9501/microcloud-provider-company/company/get/hello

2、 【microcloud-zuul-gateway-9501】修改 application.yml 配置文件忽略掉应用名称访问:

· 忽略掉“microcloud-provider-company”应用名称;

zuul:
  ignored-services:
    microcloud-provider-company
  routes:
    microcloud-provider-company: /company-proxy/** 

这个时候就可以进行代理的安全使用,但是如果你一个系统之中存在有几百个微服务,如果按照如上的方式进行配置就会非 常的麻烦,所以最简单的做法是可以采用一个通配符“*”的模式来完成:

zuul:
  ignored-services:
    "*"
  routes:
    microcloud-provider-company: /company-proxy/**

现在表示所有的 Eureka 中的服务名称的信息访问都要忽略掉,所有的访问都需要配置一个映射路径的模式来完成。

3、 【microcloud-zuul-gateway-9501】除了以上的模式进行服务定义之外,在 zuul 之中也可以采用如下的方式进行处理:

zuul:
   ignored-services:
    "*"
  routes:
   mycompany.path: /company-proxy/**
   mycompany.serviceId: microcloud-provider-company

其中在代码里面出现的“mycompany”是一个逻辑名称,该名称的主要作用是将 path 与 serviceId 绑定在一起。

4、 【microcloud-zuul-gateway-9501】如果说现在不想通过 Eureka 进行访问,则也可以直接连接到 company 微服务的地址

zuul:
   ignored-services:
    "*"
   routes:
    company.path: /company-proxy/**
    company.url: http://company-8101.com:8101/company

此时的地址上由于已经存在有了“company”前缀,所以访问地址为:

http://gateway-9501.com:9501/company-proxy/get/hello

但是从实际的开发来讲不建议采用此类模式处理,因为所有的服务如果直接绑定了指定的服务提供者的地址,那么将不方便 进行负载均衡的配置处理,而且没有 Eureka 所有微服务的管理也非常不方便。

5、 【microcloud-zuul-gateway-9501】设置公共前缀:

zuul:
  prefix: /study-proxy
  ignored-services:
    "*"
  routes:
    microcloud-provider-company: /company-proxy/**

一旦存在有前缀定义之后所有微服务的访问上就必须追加有前缀名称:

http://gateway-9501.com:9501/study-proxy/company-proxy/company/get/hello

以上的地址:

· “/study-proxy”:整个 zuul 的前缀;

· “/company-proxy”:是在 zuul 中定义的映射路径;

· “/company/get/hello”:是微服务提供者提供的操作路径。

2.3、zuul 过滤访问

对于 zuul 的功能本质上就属于一个代理操作,但是在实际的使用之中,所有的微服务一定都要有自己的认证信息,那么在这 样的状态下,如果你当前所代理的微服务具有认证信息,那么就必须在其访问前追加认证的头部操作,这样的功能就需要通过 zuul的过滤操作完成。

1、 【microcloud-zuul-gateway-9501】修改 application.yml 配置,这个配置之中追加 dept 微服务的代理;

zuul:
  prefix: /study-proxy
  ignored-services:
    "*"
  routes:
    microcloud-provider-company: /company-proxy/**
    microcloud-provider-dept: /dept-proxy/** 

此时的访问路径:http://studyjava:[email protected]:9501/study-proxy/dept-proxy/dept/get/1;现在的密码只是设置给了 zuul,而 zuul 并不能够将认证的信息传递到部门微服务之中。

2、 【microcloud-zuul-gateway-9501】追加过滤处理操作:

package cn.study.microcloud.filter;

import java.nio.charset.Charset;
import java.util.Base64;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

public class AuthorizedRequestFilter extends ZuulFilter {    // 进行授权访问处理

    @Override
    public Object run() {    // 表示具体的过滤执行操作
        RequestContext currentContext = RequestContext.getCurrentContext() ; // 获取当前请求的上下文
        String auth = "studyjava:hello"; // 认证的原始信息
        byte[] encodedAuth = Base64.getEncoder()
                .encode(auth.getBytes(Charset.forName("US-ASCII"))); // 进行一个加密的处理
        // 在进行授权的头信息内容配置的时候加密的信息一定要与“Basic”之间有一个空格
        String authHeader = "Basic " + new String(encodedAuth);
        currentContext.addZuulRequestHeader("Authorization", authHeader);
        return null;
    }

    @Override
    public boolean shouldFilter() {    // 该Filter是否要执行
        return true ;
    }

    @Override
    public int filterOrder() {
        return 0;    // 设置优先级,数字越大优先级越低
    }

    @Override
    public String filterType() {
        // 在进行Zuul过滤的时候可以设置其过滤执行的位置,那么此时有如下几种类型:
        // 1、pre:在请求发出之前执行过滤,如果要进行访问,肯定在请求前设置头信息
        // 2、route:在进行路由请求的时候被调用;
        // 3、post:在路由之后发送请求信息的时候被调用;
        // 4、error:出现错误之后进行调用
        return "pre";
    }

}

3、 【microcloud-zuul-gateway-9501】建立一个配置程序类作为认证请求的配置 Bean。

package cn.study.microcloud.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import cn.study.microcloud.filter.AuthorizedRequestFilter;

@Configuration
public class ZuulConfig {
    @Bean
    public AuthorizedRequestFilter getAuthorizedRequestFilter() {
        return new AuthorizedRequestFilter() ;
    }
}

那么这个时候就意味着你现在的程序可以直接利用 zuul 的代理访问所有加密的微服务。

4、 【microcloud-zuul-gateway-9501】考虑到 zuul 也需要进行安全访问,所以应该修改项目中的 pom.xml 配置文件,追加 Spring 安全访 问配置处理操作:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>  

5、 【microcloud-zuul-gateway-9501】修改 application.yml 配置文件,最佳有用户信息配置:

security:
  basic:
    enabled: true
  user:
    name: zdmin
    password: studyjava

那么此时现在表示 zuul 的代理上有了认证信息,则访问的地址上必须加上 zuul 的认证操作:

http://zdmin:[email protected]:9501/study-proxy/dept-proxy/dept/get/1

6、 【microcloud-service】现在所有的服务要通过 zuul 的代理来进行操作对于代理的配置如果要通过 feign 进行访问,那么在编写 feign 的时候就必须设置代理的服务名称;

package cn.study.service;

import java.util.List;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import cn.study.commons.config.FeignClientConfig;
import cn.study.service.fallback.IDeptClientServiceFallbackFactory;
import cn.study.vo.Dept;
@FeignClient(value = "MICROCLOUD-ZUUL-GATEWAY", configuration = FeignClientConfig.class, fallbackFactory = IDeptClientServiceFallbackFactory.class)
public interface IDeptClientService {
    @RequestMapping(method = RequestMethod.GET, value = "/study-proxy/dept-proxy/dept/get/{id}")
    public Dept get(@PathVariable("id") long id);
    @RequestMapping(method = RequestMethod.GET, value = "/study-proxy/dept-proxy/dept/list")
    public List<Dept> list();
    @RequestMapping(method = RequestMethod.POST, value = "/study-proxy/dept-proxy/dept/add")
    public boolean add(Dept dept);
}

7、 【microcloud-service】修改服务的配置类,测试访问的应该是 zuul 的地址:

package cn.study.commons.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import feign.Logger;
import feign.auth.BasicAuthRequestInterceptor;
@Configuration
public class FeignClientConfig {
    @Bean
    public Logger.Level getFeignLoggerLevel() {
        return feign.Logger.Level.FULL ;
    }
    @Bean
    public BasicAuthRequestInterceptor getBasicAuthRequestInterceptor() {
        return new BasicAuthRequestInterceptor("zdmin", "studyjava");
    }
}

8、 【microcloud-zuul-gateway-9501】默认情况下只要配置了过滤器,就可以进行一个正常的启动,如果现在有些过滤器突然不想让它 用了,则也可以通过修改 application.yml 配置文件让其禁用:

zuul:
  AuthorizedRequestFilter:
    pre:
      disable: true

此时表示“AuthorizedRequestFilter”过滤器将被禁止使用。如果以后有多个过滤服务出现的话,可以通过配置文件实现过滤 的启用与禁用控制。

2.4、Zuul 服务降级

Zuul 是一个代理服务,那么如果被代理的服务突然断掉了,那么这个时候 zuul 上面一定会显示出错误信息。例如:现在停止 掉“dept-8001:8001”端口上的微服务。

如果现在程序无法使用,则 zuul 的代理执行时就会出现有 timeout 的信息。但是千万要记住,由于现在的客户端已经提供有了 feign 中的服务降级的配置支持,所以客户端没有任何的问题,问题只出现在代理端。但是对于一个完善的 zuul 的代理应该更好的 实现服务降级的处理操作,所以如果有需要也可以在 zuul 中进行服务降级配置。

1、 【microcloud-zuul-gateway-9501】建立一个 Fallback 的回退处理类。

package cn.study.microcloud.fallback;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
@Component
public class DeptProviderFallback implements ZuulFallbackProvider {

    @Override
    public String getRoute() {
        return "microcloud-provider-dept";    // 设置好处理的失败路由
    }

    @Override
    public ClientHttpResponse fallbackResponse() {
        return new ClientHttpResponse() {

            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream(
                        "{\"deptno\":777777,\"dname\":\"【ERROR】Zuul-Fallback\",\"loc\":\"Gateway客户端提供\"}"
                                .getBytes());    // 当出现服务调用错误之后返回的数据内容
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders headers = new HttpHeaders() ;
                headers.set("Content-Type", "text/html; charset=UTF-8");
                return headers;
            }

            @Override
            public HttpStatus getStatusCode() throws IOException {
                return HttpStatus.BAD_REQUEST;
            }

            @Override
            public int getRawStatusCode() throws IOException {
                return HttpStatus.BAD_REQUEST.value();
            }

            @Override
            public String getStatusText() throws IOException {
                return HttpStatus.BAD_REQUEST.getReasonPhrase();
            }
            @Override
            public void close() {

            }};
    }

}

2、 【microcloud-zuul-gateway-9501】直接访问地址:

http://zdmin:[email protected]:9501/study-proxy/dept-proxy/dept/get/1

由于此时你返回的都是错误的代码,则客户端接收到此代码之后会认为服务器端已经死掉了。

原文地址:https://www.cnblogs.com/leeSmall/p/8850215.html

时间: 2024-10-14 04:09:04

SpringCloud系列八:Zuul 路由访问(Zuul 的基本使用、Zuul 路由功能、zuul 过滤访问、Zuul 服务降级)的相关文章

SpringCloud系列研究---服务网关zuul

一.zuul简介 服务网关是微服务架构中的入口,微服务平台通过服务网关统一向外部暴露API供客户端调用,网关除了具备服务路由.均衡负载功能之外,它还具备了权限控制等功能.在Spring Cloud中的Zuul就担任了这样的一个角色,为微服务架构提供了保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,使得服务集群主体能够具备更高的可复用性和可测试性. 二.环境介绍 同上一篇介绍ribbo中的环境一样,首先我们在A服务器上启动Eureka服务,然后在B.C两台服务器上分别启动ms

springCloud系列教程01:Eureka 注册中心集群搭建

springCloud系列教程包含如下内容: springCloud系列教程02:ConfigServer 配置中心server搭建 springCloud系列教程03:ConfigClient 配置中心client搭建 springCloud系列教程04:配置信息动态刷新 /bus/refresh springCloud系列教程05:@FeignClient微服务间接口调用及权限验证 springCloud系列教程06:zuul统一网关配置及权限验证 springCloud系列教程07:综合演

SQL Server 2008空间数据应用系列八:基于Bing Maps(Silverlight)的空间数据存储

原文:SQL Server 2008空间数据应用系列八:基于Bing Maps(Silverlight)的空间数据存储 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2008 R2调测. 2.具备 Transact-SQL 编程经验和使用 SQL Server Management Studio 的经验. 3.具有使用 Microsoft Visual Studio 进行 Microsoft .NET Framework开发的经验. 4.具有

S5PV210开发系列八_Yaffs的移植

S5PV210开发系列八 Yaffs的移植 象棋小子    1048272975 Nand作为市面上最基本的非易失性闪存技术之中的一个,应用在各种固态大容量存储解决方式中.因为Nand flash自身的特点,Nand存储器往往须要一款专用的Nand文件系统进行管理.开源的Yaffs文件系统因为其优异的性能,在Nand flash中受到广泛的应用,笔者此处就Yaffs的移植作一个简单的介绍. 1. Yaffs概述 Yaffs是由Aleph One公司所发展出来的Nand flash文件系统,专门为

Cocos2d-x 系列八之Box2d入门

既然已有了cocos2d-x,为什么还要Box2d呢,是因为cocos2d-x作为一个图像引擎,只是用于显示图像,图像之间可以任意的重合,如果想要做到类物理学的碰撞等运动效果,就需要用到Box2d这个物理引擎用来模仿物理世界中的物体: 本讲主要简单讲述如何创建动态物体,静态物体,漂浮物体,以及它们与图像的绑定: 下面直接通过一个例子来看三种物体的创建方法: 首先需要说明的一点是:在Box2d中,使用的单位是米,而不是像素,所以,在进行位置转换的时候,需要按比例缩放,Box2d中,比较理想的距离大

Cocos2d-x 系列八之绘图API

本节来看一下在cocos2d-x中,常用的一些绘图api: 先来看一个工具类,以便于快速指定游戏窗口的一些位置,如左上,右上等:VisibleRect.h #ifndef __VISIBLERECT_H__ #define __VISIBLERECT_H__ #include "cocos2d.h" class VisibleRect { public: static cocos2d::Rect getVisibleRect(); static cocos2d::Vec2 left()

struts2官方 中文教程 系列八:异常处理

在本教程中,我们将探讨如何启用Struts 2框架处理web应用程序生成的任何未捕获的异常.Struts 2提供了健壮的异常处理,包括能够自动记录任何未捕获的异常,并将用户重定向到错误web页面. 贴个本帖的地址,以免被爬:struts2官方 中文教程 系列八:异常处理  即 http://www.cnblogs.com/linghaoxinpian/p/6915066.html 下载本章节代码 全局异常处理(Global Exception Handling) 使用Struts 2框架,您可以

ARP欺骗(原始套接字系列八)

ARP欺骗的原理可简单的解释如下:假设有三台主机A,B,C位于同一个交换式局域网中,监听者处于主机A,而主机B,C正在通信.现在A希望能嗅探到B->C的数据,于是A就可以伪装成C对B做ARP欺骗--向B发送伪造的ARP应答包,应答包中IP地址为C的IP地址而MAC地址为A的MAC地址. 这个应答包会刷新B的ARP缓存,让B认为A就是C,说详细点,就是让B认为C的IP地址映射到的MAC地址为主机A的MAC地址.这样,B想要发送给C的数据实际上却发送给了A,就达到了嗅探的目的.我们在嗅探到数据后,还

C语言快速入门系列(八)

C语言快速入门系列(八) C语言位运算与文件 本章引言: 在不知不觉中我们的C快速入门系列已经慢慢地接近尾声了,而在这一节中,我们会对 C语言中的位运算和文件进行解析,相信这两章对于一些人来说是陌生的,因为很多 老师都会跳过这两个大知识点,其实这两个也是灰常重要的!比如一个问题,叫你算 变量a乘以2,怎么写效率高?直接a *2,很多人都这样写,但是如果你会位运算的话,你会a<<1; 位运算的效率可是比a*2高的哦!另一个问题,不用变量左中间值,直接交换两个变量的值? 你怎么做?也是用到位运算!