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. dropwizard metrics - 基本使用介绍

    之前在healthcheck中介绍了怎样通过metrics lib往系统中增加一些简单的健康侦測.如今讲讲dropwizard metrics更重要的部分.记录系统的度量信息. dropwizard提 ...

  2. 消息队列之 RabbitMQ

    https://www.jianshu.com/p/79ca08116d57 关于消息队列,从前年开始断断续续看了些资料,想写很久了,但一直没腾出空,近来分别碰到几个朋友聊这块的技术选型,是时候把这块 ...

  3. 支持Android 的几款开源3D引擎调研

    最近由于工作需要,对支持Android的一些开源3D引擎做了调研,结果如下: 1.Ogre 十分强大的一款3D引擎,号称工业级标准的开源项目,不仅可以用于游戏,还可以用于其他和3D相关的软件.大多数该 ...

  4. Linux服务器svn与项目同步

    命令:svn checkout svn://192.168.67.131/trunk/w1

  5. springmvc+jquery实现省市区地址下拉框联动

    参考资料:http://www.cnblogs.com/whgw/archive/2012/05/11/2496667.html 1.jsp页面实现 <%@ page language=&quo ...

  6. mysql数据库中查看当前使用的数据库是哪个数据库?

    环境描述: mysql版本:5.5.57-log 操作系统版本:Red Hat Enterprise Linux Server release 6.6 (Santiago) 需求说明: 查看当前使用的 ...

  7. docker machine介绍和使用

    https://www.cnblogs.com/sparkdev/p/7044950.html https://www.jianshu.com/p/cc3bb8797d3b

  8. 使用npm国内镜像

    嫌npm指令速度慢的童鞋可以把npm的源转换成国内的即可提高响应速度: 镜像使用方法(三种办法任意一种都能解决问题,建议使用第1或者第3种,将配置写死,下次用的时候配置还在):1.通过config命令 ...

  9. Linux+Redis实战教程_day02_2、redis简述及安装与启动

    2. redis简述及安装 关系型数据库(SQL): Mysql,oracle 特点:数据和数据之间,表和字段之间,表和表之间是存在关系的 例如:部门表 001部门,   员工表 001 用户表,用户 ...

  10. Hbase 管理页面

    进入Hbase首页可以查看各种信息: http://192.168.23.128:16010/master-status