当前位置: 首页 > 编程日记 > 正文

Spring Cloud入门教程 - Zuul实现API网关和请求过滤

简介

Zuul是Spring Cloud提供的api网关和过滤组件,它提供如下功能:

  • 认证
  • 过滤
  • 压力测试
  • Canary测试
  • 动态路由
  • 服务迁移
  • 负载均衡
  • 安全
  • 静态请求处理
  • 动态流量管理

在本教程中,我们将用zuul,把web端的请求/product转发到对应的产品服务上,并且定义一个pre过滤器来验证是否经过了zuul的转发。

基础环境

  • JDK 1.8
  • Maven 3.3.9
  • IntelliJ 2018.1
  • Git

项目源码

Gitee码云

创建Zuul服务

在IntelliJ中创建一个maven项目:

  • cn.zxuqian
  • apiGateway

然后在pom.xml中添加如下代码:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.zxuqian</groupId><artifactId>apiGateway</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.1.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.cloud</groupId><!-- name has changed, before: spring-cloud-starter-zuul --><artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency><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-config</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Finchley.M9</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><properties><java.version>1.8</java.version></properties><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/libs-milestone</url><snapshots><enabled>false</enabled></snapshots></repository></repositories></project>

需要注意的是,Spring官网的教程给的zuul的artifactId为spring-cloud-starter-zuul,这个是旧版zuul的名字,在我们的Finchley.M9版本中已经更名为spring-cloud-starter-netflix-zuul

添加src/main/resources/bootstrap.yml文件,指定spring.application.name

spring:application:name: zuul-server

创建cn.zxuqian.Application类:

package cn.zxuqian;import cn.zxuqian.filters.PreFilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}@Beanpublic PreFilter preFilter() {return new PreFilter();}
}

这里使用了@EnableZuulProxy来指定使用zuul的反向代理,把我们的请求转发到对应的服务器上。然后启用了eureka的服务发现。Zuul默认也会使用Ribbon做负载均衡,所以可以通过eureka发现已注册的服务。PreFilter是一个预过滤器,用来在request请求被处理之前进行一些操作,它的代码如下:

package cn.zxuqian.filters;import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import javax.servlet.http.HttpServletRequest;public class PreFilter extends ZuulFilter {private static Logger log = LoggerFactory.getLogger(PreFilter.class);@Overridepublic String filterType() {return "pre";}@Overridepublic int filterOrder() {return 1;}@Overridepublic boolean shouldFilter() {return true;}@Overridepublic Object run() throws ZuulException {RequestContext ctx = RequestContext.getCurrentContext();HttpServletRequest request = ctx.getRequest();log.info(String.format("%s 方式请求 %s", request.getMethod(), request.getRequestURL().toString()));return null;}
}

filterType - Zuul内置的filter类型有四种,pre, routeposterror,分别代表请求处理前,处理时,处理后和出错后。
filterOrder - 指定了该过滤器执行的顺序。
shouldFilter - 是否开启此过滤器。
run - 过滤器的业务逻辑。这里只是简单的log了一下reqeust的请求方式和请求的路径。

接下来,在我们的配置中心的git仓库中创建zuul-server.yml文件,并添加如下配置:

server:port: 8083
zuul:routes:products:path: /product/**serviceId: product-service

这里配置了zuul的端口为8083,然后映射所有/product/的请求到我们的product-service服务上。如果不配置serviceId,那么products这个Key就会默认作为ServiceId,而我们的例子中,ServiceId包括了-,所以在下边显示指定了ServiceId。配置完成后提交到git。

更新productService

productService的uri做了一点改动,使其更符合rest风格:

@RequestMapping("/list")
public String productList() {log.info("Access to /products endpoint");return "外套,夹克,毛衣,T恤";
}

这里@RequestMapping匹配的路径改为了/list,之前是/products

更新web客户端

在我们的web客户端的ProductService中添加一个新的方法:

public String productListZuul() {return this.restTemplate.getForObject("http://zuul-server/product/list", String.class);
}

这次我们直接请求zuul-server服务,然后由它把我们的请求反射代理到product-service服务。最后在ProductController中添加一个请求处理方法:

@RequestMapping("/product/list")
public String productListZuul() {return productService.productListZuul();
}

用来处理/product/list请求,然后调用ProductService类中的方法。

测试

使用mvn spring-boot:run启动configServerregistry, zuulServer, productServiceweb这几个工程,然后启动第二个productService,使用SERVER_PORT=8082 spring-boot:run
访问几次http://localhost:8080/product/list,然后除了会在浏览器看到返回的结果,我们还会在zuulServer的命令行窗口中看到如下字样:

GET 方式请求 http://xuqians-imac:8083/product/list

然后在两个productService的命令行窗口中,我们还会看到随机出现的

Access to /products endpoint

说明zuulServer也会自动进行负载均衡。

欢迎访问我的博客张旭乾的博客

大家有什么想法欢迎来讨论。

转载于:https://blog.51cto.com/13727459/2113223

相关文章:

​谷歌大神 Jeff Dean 领衔,万字展望5大 AI 趋势

‍‍作者 | 学术头条来源 | 学术头条对于关心人工智能技术进展的读者来说&#xff0c;每年年底来自整个谷歌 research 团队撰写的年终总结&#xff0c;可谓是必读读物。今天&#xff0c;由谷歌大神 Jeff Dean 领衔&#xff0c;这份总结虽迟但到。出于知识传播目的&#xff0c;“…

php的webservice的wsdl的XML无法显示

php的webservice的因为wsdl有中文所以xml无法显示 可以用Nopepad 转码即可 以UTF-8无BOM编码

Journey源码分析三:模板编译

2019独角兽企业重金招聘Python工程师标准>>> 在Journey源码分析二&#xff1a;整体启动流程中提到了模板编译&#xff0c;这里详细说下启动流程 看下templates.Generate()源码: func Generate() error {compiledTemplates.Lock()defer compiledTemplates.Unlock()//…

linux中安装程序

实验&#xff1a;为 Linux 主机安装应用程序 环境&#xff1a;vmware workstation 14 . redhad-server-6.4需求&#xff1a;1.使用 RPM 包的方式安装 Mozilla Firefox 浏览器2.使用源代码包编译的方式安装 Apache3.使用 RPM 包的方式安装Webmin管理软件&#xff0c;并使用 rpm查…

php 的webservice类库NuSoap介绍

NuSOAP 是 PHP 环境下的 WEB 服务编程工具&#xff0c;用于创建或调用 WEB 服务。它是一个开源软件&#xff0c;当前版本是 0.9.5 &#xff0c;支持 SOAP1.1 、 WSDL1.1 &#xff0c;可以与其他支持 SOAP1.1 和 WSDL1.1 的系统互操作。 NuSOAP 完全由PHP语言编写&#xff0c;由…

我用 YOLOv5 做情感识别!

作者 | 陈信达来源 | DatawhaleAI技术已经应用到了我们生活中的方方面面&#xff0c;而目标检测是其中应用最广泛的算法之一&#xff0c;疫情测温仪器、巡检机器人、甚至何同学的airdesk中都有目标检测算法的影子。下图就是airdesk&#xff0c;何同学通过目标检测算法定位手机位…

Odoo 学习 【二】Environment 概览

Environment 参考链接: http://odoo-new-api-guide-line.readthedocs.io/en/latest/environment.html#environment 在新的API中&#xff0c;引入了环境的概念&#xff0c;它的主要目标是提供对游标、用户、模型、上下文、记录集、和缓存的封装。 有了这些&#xff0c;你没有必要…

php使用NuSoap产生webservice结合WSDL让asp.net调用

<?php require_once("nusoap-0.9.5/lib/nusoap.php"); //定义服务程序 function Add($a,$b){return $a$b;}//初始化服务对象 , 这个对象是类 soap_server 的一个实例 $soap new soap_server; //调用服务对象的 register 方法注册需要被客户端访问…

分享 10 个超实用的 Python 编程技巧

作者 | 欣一来源 | Python爱好者集中营今天小编来给大家分享几个Python的编程技巧&#xff0c;帮助你迅速完成地从小白到Python大神的蜕变。字典翻转首先我们来看字典的翻转&#xff0c;假设我们有下面类似的一个字典对象与数据car_dict { "brand":"Tesla"…

百度编辑器(1.4.3—net版)上传图片路径及其他配置

1&#xff1a;文件配置图&#xff1a; 2&#xff1a;文件夹配置图&#xff1a; 3&#xff1a;多余的功能删除&#xff08;懒人不想使用百度编辑器官网的自定义&#xff0c;而选择全部功能的直接下载&#xff0c;对于没用的功能可以注释掉&#xff0c;以后有需要就可以再拿出来用…

windows下配置redis集群,启动节点报错:createing server TCP listening socket *:7000:listen:Unknown error...

windows下配置redis集群&#xff0c;启动节点报错&#xff1a;createing server TCP listening socket *:7000:listen:Unknown error 学习了&#xff1a;https://blog.csdn.net/u014652744/article/details/71774171 竟然真的是需要bind 127.0.0.1 不同的机器为啥就不一样呢&am…

apache日志分析简介

对apache的日志分析做下简单的介绍,主要参考apache官网的Log Files,手册参照 http://httpd.apache.org/docs/2.2/logs.html一.日志分析 如果apache的安装时采用默认的配置,那么在/logs目录下就会生成两个文件,分别是access_log和error_log1.access_log access_log为访问日志,记…

Kotlin语法(基础)

一、基础语法&#xff1a; 1. 定义包名&#xff1a; 包名应该在源文件的最开头&#xff0c;包名不必和文件夹路径一致&#xff1a;源文件可以放在任意位置。 package my.demo 2. 定义函数&#xff1a; fun sum(a: Int , b: Int) : Int{return a b } 表达式函数体自动推断型的返…

未来十年,人机交互将是重要的发展

编译 | 禾木木出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;机器人市场包括广泛且不断扩大的产品范围。经过多年的合作&#xff0c;可以预测机器人技术和机器人行业的未来发展。根据需求&#xff0c;专业服务应用将占据主要市场份额。客户行为的变化已成为行业发展…

20170507Linux七周二次课 io监控free ps 网络状态 抓包

七周二次课&#xff08;5月7日&#xff09;10.6 监控io性能10.7 free命令10.8 ps命令10.9 查看网络状态10.10 linux下抓包扩展tcp三次握手四次挥手 http://www.doc88.com/p-9913773324388.htmltshark几个用法&#xff1a;http://www.aminglinux.com/bbs/thread-995-1-1.html监控…

navicat for mysql导出表结构

show create table cm_events;

《新程序员003》正式上市!华为、阿里等 30+ 公司的云原生及数字化实战经验...

作者 | 唐小引出品 | 《新程序员》编辑部《新程序员 003&#xff1a;云原生和全面数字化实践》图书今日正式上市&#xff0c;纸书和电子书同步上架 CSDN 商城、New 程序员小程序、京东、当当等平台。这是由 50 余位技术专家共同创作&#xff0c;写给所有关注云原生和数字化的开…

sed及awk显示指定行内容

文件内容为[roottest1 test]# cat file.test 1 2 3 4 5 6 7 8 9 101. 显示第二行内容(指定行)1&#xff09;sed[roottest1 test]# sed -n 2p file.test 22&#xff09;awk[roottest1 test]# awk NR2 {print $0} file.test 2 [roottest1 test]# awk {if(NR2)print $0} file.t…

win10 spark+scala+eclipse+sbt 安装配置

转载请务必注明原创地址为&#xff1a;http://dongkelun.com/2018/03/... 1、首先安装配置jdk1.8以上,建议全部的安装路径不要有空格 2、安装spark 2.1 下载 下载地址&#xff1a;http://spark.apache.org/downloads.html&#xff0c;我下载的是 spark-2.2.1-bin-hadoop2.7.tgz…

jquery的live方法

live(type, [data], fn)手册API的介绍 jQuery 给所有匹配的元素附加一个事件处理函数&#xff0c;即使这个元素是以后再添加进来的也有效。 如下用 live给classclickme的元素绑定一个click事件&#xff1a; $(.clickme).live(click, function() { alert("Live handler ca…

碱基序列的儿子最长上涨

Font Size:Aa Aa AaDescription 给出一个由n个数组成的序列x[1..n]&#xff0c;找出它的最长单调上升子序列的长度。即找出最大的长度m和a1, a2……,am&#xff0c;使得 a1 < a2 < … … < am 且 x[a1] < x[a2] < … … < x[am]。Input 先输入一个整数t&…

用 Python 写 3D 游戏,太赞了

作者 | 可可卷CSDN博客 | 可可卷vizard介绍Vizard是一款虚拟现实开发平台软件&#xff0c;从开发至今已走过十个年头。它基于C/C&#xff0c;运用新近OpenGL拓展模块开发出的高性能图形引擎。当运用Python语言执行开发时&#xff0c;Vizard同时自动将编写的程式转换为字节码抽象…

人人都能学会的python编程教程3:字符串和编码

字符串 在python3中已经全面支持中文。 由于Python源代码也是一个文本文件&#xff0c;所以&#xff0c;当你的源代码中包含中文的时候&#xff0c;在保存源代码时&#xff0c;就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时&#xff0c;为了让它按UTF-8编码读取&…

基本MVC原理

参考《Pro PHP》 简单实现了一个mvc框架。 地址http://code.google.com/p/smallframework/自动加载的问题<?php function __autoload($class) { if(file_exists($class.".php")) { require_once($class.".php"); } } class autoload{ public static fu…

31个好用的 Python 字符串方法,建议收藏!

作者 | 小F来源 | 法纳斯特字符串是Python中基本的数据类型&#xff0c;几乎在每个Python程序中都会使用到它。今天&#xff0c;就带大家学习一下31个最重要的内置字符串方法。希望大家能从中找到对自己有帮助的技巧。▍1、Slicingslicing切片&#xff0c;按照一定条件从列表或…

《深入理解计算机系统》读书随笔-位操作

最近开始读《深入理解计算机系统》这本书。对于书中提到的从程序员的角度解读计算机系统这一说法非常感兴趣&#xff0c;所以决定好好读一读。从开始接触计算机编程就是站在一个高级语言的层次&#xff0c;虽然对编译原理&#xff0c;操作系统&#xff0c;汇编语言和计算机组成…

专访小邪:从十年技术之路看阿里技术体系的变革

2019独角兽企业重金招聘Python工程师标准>>> 摘要&#xff1a; 从2008年到2018年&#xff0c;从阿里巴巴中间件团队到飞天八部——小邪与阿里的十年。 编者按&#xff1a;从2008年到2018年&#xff0c;从阿里巴巴中间件团队到飞天八部——小邪与阿里的十年。 2008年…

PHP SPL笔记

PHP SPL笔记作者&#xff1a; 阮一峰日期&#xff1a; 2008年7月 8日这几天&#xff0c;我在学习PHP语言中的SPL。这个东西应该属于PHP中的高级内容&#xff0c;看上去很复杂&#xff0c;但是非常有用&#xff0c;所以我做了长篇笔记。不然记不住&#xff0c;以后要用的时候&am…

算力超越 iPhone,芯片堪比Mac,网友:“买来能干啥?”

整理 | 郑丽媛出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;自去年“元宇宙”概念突然爆火&#xff0c;作为其“入门钥匙”的 AR/VR 设备也顺势成为了话题焦点&#xff0c;尤其在多家外媒爆料苹果也在为此发力、甚至从 Meta 挖人以争取在 2022 年正式推出时&…

ios开发日记- 5 屏幕截图

-(void)fullScreenshots{UIWindow *screenWindow [[UIApplication sharedApplication] keyWindow]; UIGraphicsBeginImageContext(screenWindow.frame.size);//全屏截图&#xff0c;包括window [screenWindow.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage …