API网关是微服务架构中的很重要的一个部分,内部有多个不同的服务提供给外部来使用,API网关可以对外做统一的入口,也可以在网关上做协议转换,权限控制和请求统计和限流等其他的工作

spring-cloud封装了Netflix提供的开源的API网关实现zuul,我们可以很方便地启动一个zuul网关的实例,并支持向eureka进行注册,并对在eureka上已经注册的服务进行代理

使用IDEA的spring initializer来创建一个zuul项目

填写相关的group类型等信息,选择使用gradle来进行构建

选择zuul和eureka client

选择项目位置和gradle安装的位置:

在启动类上添加 @EnableZuulProxy 注解,这个注解是@EnableZuulServer的加强版,不仅标识了这是一个zuul Server 而且启用了eureka注册中心和负载均衡ribbon

启动类的代码:

package com.jiaoyiping.springcloud.zuul;

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

zuul最本质的功能是做反向代理,路由转发和对请求的拦截和处理,路由转发的配置在配置文件中,zuul可以做一下几种形式的转发:

将请求重定向到一个外部的URL上,

如果我们要配置,符合/baidu前缀的请求都重定向到baidu.com去,可以做如下的配置:

zuul:
routes:
baidu:
path: /baidu/**
url: http://www.baidu.com

将请求转发到内部提供的请求路径上去,使用forforward:

比如,如果我们的网关自己提供了一个以/session开头的服务,我们想让对网关的请求中以/session开头的请求都让网关自己提供的这个服务来处理,则可以进行如下的配置

zuul:
routes:
session:
path: /session/**
url: forward:/session

对已经注册到eureka中的服务进行代理和请求转发,此时只需要提供eureka中服务的serviceid即可

 zuul:
routes:
provider:
path: /provider/**
serviceId: PROVIDER
#(去请求目标服务的时候)是否丢掉前缀,根据需求来配置
stripPrefix: true

完整的配置如下:

spring:
application:
name: zuul
cloud:
inetutils:
preferred-networks: 192.168.1.
server:
port: 8084
tomcat:
uri-encoding: UTF-8
servlet:
context-path: /
logging:
config: classpath:logback.xml
zuul:
routes:
baidu:
path: /baidu/**
url: http://www.baidu.com
provider:
path: /provider/**
serviceId: PROVIDER
#(去请求目标服务的时候)是否丢掉前缀,根据需求来配置
stripPrefix: true
session:
path: /session/**
url: forward:/session
eureka:
instance:
hostname: 192.168.1.5
prefer-ip-address: true
instance-id: 192.168.1.5:${server.port}
client:
healthcheck:
enabled: true
registerWithEureka: true
fetchRegistry: true
service-url:
defaultZone: http://127.0.0.1:8081/eureka/
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 25000 ribbon:
MaxAutoRetries: 2
MaxAutoRetriesNextServer: 3
restclient:
enabled: true

zuul中的Filter的配置,zuul中提供了三种类型的Filter,preFilter,routeFilter和postFilter,分别对应请求中的不同的阶段,针对同一个请求,有一个RequestContext对象,在三个阶段的Filter中进行共享

假设我们要开发一个统计请求时间的功能,需要在preFilter里边记录开始时间,并将整个开始时间放在RequestContext中,在postFilter里边拿到开始时间,用当前的时间减去开始时间,就是请求执行的时间

定义一个preFilter:

package com.jiaoyiping.springcloud.zuul.filter;

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 org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; /**
* Created with Intellij IDEA
*
* @author: jiaoyiping
* Mail: jiaoyiping@gmail.com
* Date: 2018/04/05
* Time: 16:24
* To change this template use File | Settings | Editor | File and Code Templates
*/ public class TimeCostPreFilter extends ZuulFilter {
public static final String START_TIME_KEY = "start_time";
private Logger logger = LoggerFactory.getLogger(TimeCostPreFilter.class); @Override
public String filterType() {
return FilterConstants.PRE_TYPE;
} @Override
public int filterOrder() {
return 0;
} /**
* 判断是否要拦截的逻辑
*
* @return
*/
@Override
public boolean shouldFilter() {
return true;
} @Override
public Object run() throws ZuulException {
long startTime = System.currentTimeMillis();
RequestContext.getCurrentContext().set(START_TIME_KEY, startTime);
return null;
}
}

定义以postFilter:

package com.jiaoyiping.springcloud.zuul.filter;

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 org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; /**
* Created with Intellij IDEA
*
* @author: jiaoyiping
* Mail: jiaoyiping@gmail.com
* Date: 2018/04/05
* Time: 16:37
* To change this template use File | Settings | Editor | File and Code Templates
*/ public class TimeCostPostFilter extends ZuulFilter {
private static final String START_TIME_KE = "start_time";
private Logger logger = LoggerFactory.getLogger(TimeCostPostFilter.class); @Override
public String filterType() {
return FilterConstants.POST_TYPE;
} @Override
public int filterOrder() {
return 0;
} @Override
public boolean shouldFilter() {
return true;
} @Override
public Object run() throws ZuulException {
long startTime = (long) RequestContext.getCurrentContext().get(START_TIME_KE);
logger.info("请求完成,耗时{}秒", (System.currentTimeMillis() - startTime) / 1000);
return null;
}
}

在一个配置类中将这两个Filter注入:

package com.jiaoyiping.springcloud.zuul.config;

import com.jiaoyiping.springcloud.zuul.filter.PDSFilter;
import com.jiaoyiping.springcloud.zuul.filter.TimeCostPostFilter;
import com.jiaoyiping.springcloud.zuul.filter.TimeCostPreFilter;
import com.netflix.zuul.ZuulFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /**
* Created with Intellij IDEA
*
* @author: jiaoyiping
* Mail: jiaoyiping@gmail.com
* Date: 2018/04/05
* Time: 17:32
* To change this template use File | Settings | Editor | File and Code Templates
*/
@Configuration
public class FilterConfig { @Bean
public ZuulFilter timeCostPreFilter() {
return new TimeCostPreFilter();
} @Bean
public ZuulFilter timeCostPostFilter() {
return new TimeCostPostFilter();
} @Bean
public ZuulFilter pdsFilter() {
return new PDSFilter();
}
}

启动项目,可以发现,zuul网关已经注册到了eureka上:

请求provide对应的地址,发现,zuul可以成功地调用eureka上对应的服务,并将结果正确返回:

基于spring-cloud的微服务(4)API网关zuul的更多相关文章

  1. 干货|基于 Spring Cloud 的微服务落地

    转自 微服务架构模式的核心在于如何识别服务的边界,设计出合理的微服务.但如果要将微服务架构运用到生产项目上,并且能够发挥该架构模式的重要作用,则需要微服务框架的支持. 在Java生态圈,目前使用较多的 ...

  2. 基于Spring Cloud的微服务落地

    微服务架构模式的核心在于如何识别服务的边界,设计出合理的微服务.但如果要将微服务架构运用到生产项目上,并且能够发挥该架构模式的重要作用,则需要微服务框架的支持. 在Java生态圈,目前使用较多的微服务 ...

  3. 基于Spring Cloud的微服务入门教程

    (本教程的原地址发布在本人的简书上:http://www.jianshu.com/p/947d57d042e7,若各位看官有什么问题或不同看法请在这里或简书留言,谢谢!) 本人也是前段时间才开始接触S ...

  4. 基于 Spring Cloud 的微服务架构实践指南(下)

    show me the code and talk to me,做的出来更要说的明白 本文源码,请点击learnSpringCloud 我是布尔bl,你的支持是我分享的动力! 一.引入 上回 基于 S ...

  5. 基于 Spring Cloud 的微服务架构实践指南(上)

    show me the code and talk to me,做的出来更要说的明白 GitHub 项目learnSpringCloud同步收录 我是布尔bl,你的支持是我分享的动力! 一. 引入 上 ...

  6. Spring Cloud第十四篇 | Api网关Zuul

    ​ 本文是Spring Cloud专栏的第十四篇文章,了解前十三篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring C ...

  7. 画了一张基于Spring Cloud的微服务系统架构图

  8. 基于Spring Boot和Spring Cloud实现微服务架构学习

    转载自:http://blog.csdn.net/enweitech/article/details/52582918 看了几周Spring相关框架的书籍和官方demo,是时候开始总结下这中间的学习感 ...

  9. 基于Spring Boot和Spring Cloud实现微服务架构学习--转

    原文地址:http://blog.csdn.net/enweitech/article/details/52582918 看了几周spring相关框架的书籍和官方demo,是时候开始总结下这中间的学习 ...

随机推荐

  1. SQL2000系统表、存储过程、函数的功能介绍及应用

    转自:http://blog.csdn.net/zlp321002/article/details/480925 ----系统表------------------------------------ ...

  2. XML 中可嵌入 cmd命令脚本

    原文要参照代码 1. XML解析 Task逻辑块可相互组合,形成复杂的树状结构,其结构用XML表示,即写成XML文件的形式. 样例如下: <!-- 顺序执行块 --> <seq> ...

  3. thinkphp 3.2 多表查询 group

    分析一 $res = M('member') ->table('__MEMBER__ as a') ->join('__ORDER__ as b') ->field('a.id,b. ...

  4. ML基础 : 训练集,验证集,测试集关系及划分 Relation and Devision among training set, validation set and testing set

    首先三个概念存在于 有监督学习的范畴 Training set: A set of examples used for learning, which is to fit the parameters ...

  5. 关系型数据库 和 非关系型数据对比 以及 MySQL与Oracle对比

    一.关系型数据库 关系型数据库,是指采用了关系模型来组织数据的数据库.    关系模型1970年提出的,关系模型的概念得到了充分的发展并逐渐成为主流数据库结构的主流模型.    简单来说,关系模型指的 ...

  6. What's new in JDK 8

    (1)http://docs.oracle.com/javase/8/docs/technotes/guides/language/enhancements.html#javase8 (2)https ...

  7. Servlet3简介

    servlet基础知识:http://blog.csdn.net/chjttony/article/details/6086292 ServletContext相关知识:http://blog.csd ...

  8. Cannot call sendError() after the response has been committed - baiyangliu

    当response提交后,不能调用sendError(),什么意思? 出现这个错误,一定是多次response导致的.可以这么理解,承载客户端和服务器进行Http交互的Socket连接已经关闭了,而你 ...

  9. phpcms v9 get的强大之处(列表页调用点击数)

    {pc:get sql="select * from v9_art as g left join v9_art_data as p on p.id=g.id and g.catid=12 o ...

  10. centos6.8 安装Python2.7后, yum出现“No module named yum”错误

    出现yum错误:No module named yum 解决方法,查看 /usr/bin下python有哪几个版本 ll /usr/bin 我这里是:2.6  和  2.7 (刚安装的) 由于yum命 ...