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:studyjava@eureka-7001.com:7001/eureka,http://edmin:studyjava@eureka-7002.com:7002/eureka,http://edmin:studyjava@eureka-7003.com: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:hello@gateway-9501.com: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:studyjava@gateway-9501.com: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:studyjava@gateway-9501.com:9501/study-proxy/dept-proxy/dept/get/1

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

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

  1. SpringCloud系列八:自定义Ribbon配置

    1. 回顾 上文使用Ribbon实现了客户端侧的负载均衡.但是很多场景下,我们可能需要自定义Ribbon的配置,比如修改Ribbon的负载均衡规则. Spring Cloud允许使用Java代码或属性 ...

  2. springcloud系列八 整合Hystrix

    feign本身是支持Hystrix的,所以不需要引入其他依赖: 我们可以看看feign这个项目的依赖,就是引入这个依赖的pom.xml 要想看这个很简单,点击那个依赖进去就可以了 点进去就可以看到 & ...

  3. SpringCloud系列——Zuul 动态路由

    前言 Zuul 是在Spring Cloud Netflix平台上提供动态路由,监控,弹性,安全等边缘服务的框架,是Netflix基于jvm的路由器和服务器端负载均衡器,相当于是设备和 Netflix ...

  4. SpringCloud系列之API网关(Gateway)服务Zuul

    1.什么是API网关 API网关是所有请求的入口,承载了所有的流量,API Gateway是一个门户一样,也可以说是进入系统的唯一节点.这跟面向对象设计模式中的Facet模式很像.API Gatewa ...

  5. spring cloud Zuul + 路由熔断【服务降级】 --- 心得

    1.前言 刚入门 时,使用 ribbon + hystrix + restTemplate  ,实现了简单的 接口访问 + 客户端负载均衡 + 服务熔断保护 : 然后学习了 feign ,整合了  r ...

  6. SpringCloud系列——SSO 单点登录

    前言 作为分布式项目,单点登录是必不可少的,文本基于之前的的博客(猛戳:SpringCloud系列——Zuul 动态路由,SpringBoot系列——Redis)记录Zuul配合Redis实现一个简单 ...

  7. 《springCloud系列》——Eureka 进行服务治理

    整理一下: @EnableEurekaServer 注册中心 @EnableDiscoveryClient 提供服务 @EnableFeignClients 消费者(Feign特有的,而且他自带断路器 ...

  8. SpringCloud系列:前言

    准备写springcloud系列了,先吐槽下自己,之前准备把学到的东西写下来,都因为工作或自己太懒(主要还是懒),写了个开篇就GG了,这次springcloud一定会坚持写完.加油! 这里先说下我搭建 ...

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

    springCloud系列教程包含如下内容: springCloud系列教程01:Eureka 注册中心集群搭建 springCloud系列教程02:ConfigServer 配置中心server搭建 ...

随机推荐

  1. Buaa菜鸡从今天好好学打码,好好学数学,好好学英语,好好打篮球,好好锻炼,好好吃饭,好好... 好好找女朋友!

    新链接: https://iamparasite.github.io/

  2. BUAA-OO第二单元小结

    一.设计策略 三次作业中,由于前两次作业都只有一部电梯,因此我的线程只有两个,一个等待队列输入进程,以及一个电梯运行进程.等待队列输入进程实现十分简单,只需要根据输入把request添加到等待队列即可 ...

  3. robotframework之用cmd去执行用例

    1.电脑cmd进入 2.在cmd中输入相应的执行命令即可以正常执行 3.执行完成,会显示当前用例执行情况,以及output/log/report的默认保存路径 接下来详细说一下执行不同用例的具体指令, ...

  4. C#利用首尾時間計算中間時間差

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. 初始化HTML样式(转载)

    方式一 ;; } body { background:#fff; color:#555; font-size:14px; font-family: Verdana, Arial, Helvetica, ...

  6. python 集成cython && push 测试pip 仓库

    昨天创建了一个简单的python 集成cython 的项目 master 但是有几个问题 目前的构建时基于make 同时需要本地执行,为了方便基于pip 的安装,做了如下调整 项目准备 项目使用ven ...

  7. 使用kingshard遇到的坑

    禁止用mysqldump 连接kingshard, 会导致表锁死 读取NULL值变为文本 通过kingshard连接 select出来的null值变为文本"NULL" kingsh ...

  8. apache做反向代理

    实验目的 通过apache实现反向代理的功能,类似nginx反向代理和haproxy反向代理 环境准备 逻辑架构如下 前端是apche服务器,监听80端口,后端有两台web服务器,分别是node1和n ...

  9. 注解@Resource和@Autowired区别对比

    @Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Sprin ...

  10. spring事务详解(二)简单样例

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...