SpringBoot学习8.7-zuul服务网关

概要

zuul:springcloud中支持api网关开发的组件。主要功能是路由转发和过滤器。

开发要点:

  • 依赖netflix-zuul
  • zuul微服务请求url匹配配置
  • @EnableZuulProxy启动zuul
  • 过滤器开发

1.maven依赖

主要依赖netflix-zuul。zuu也需要注册到eureka服务端中。

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.0.0.RELEASE</version>
	<relativePath /> <!-- lookup parent from repository -->
</parent>
 
......
 
<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	<java.version>1.8</java.version>
	<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
</properties>
 
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
	<!-- zuul网关 -->
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
	</dependency>
</dependency>
 
<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-dependencies</artifactId>
			<version>${spring-cloud.version}</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

2.spring配置

注意配置中的微服务请求url匹配配置

server:
  port: 80 # 服务器端口
spring:
  application:
    name: app-zuul # 微服务名称
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:7001/eureka/ # 治理客户端服务域  
#zuul网关
zuul:
  routes:
    serviceproduct: # 产品微服务
      path: /product/** # 指定请求匹配url
      serviceId: service-product # 指定请求转发的微服务id
    serviceuser: # 用户微服务
      path: /user/**
      serviceId: service-user   
#zuul网关超时设置     
ribbon:
  ConnectTimeout: 1000
  ReadTimeout: 2000

3.注解@EnableZuulProxy启动zuul代理

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

4.zuul过滤器的开发

自定义过滤器需要实现ZuulFilter接口,且可以有多个实现类,按照设定顺序进行过滤。

过滤器需要实现以下四个方法(方法说明参考代码注释):

  • shouldFilter()
  • run()
  • filterType()
  • filterOrder()

首先开发第一个过滤器:

import javax.servlet.http.HttpServletRequest;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
/** zuul过滤器pre01 */
@Component
public class ZuulFilterPre01 extends ZuulFilter {
	// 是否应该执行该过滤器,如果是false,则不执行该filter
	@Override
	public boolean shouldFilter() {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		String id = request.getParameter("id");
		// 如果id是空,则不开启过滤,直接放行
		return !StringUtils.isEmpty(id);
	}
	// 执行业务操作,可执行sql,nosql等业务
	@Override
	public Object run() throws ZuulException {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		String id = request.getParameter("id");
		// 如果id=1,则继续执行下一个filter或转发请求
		if ("1".equals(id)) {
			// 会进行路由,继续执行下一个filter或转发请求
			ctx.setSendZuulResponse(true);
			ctx.setResponseStatusCode(200);
			// 可以把一些值放到ctx中,便于后面的filter获取使用
			ctx.set("isOK", true);
		} else {
			// 不需要进行路由,不会转发请求
			ctx.setSendZuulResponse(false);
			ctx.setResponseStatusCode(401);
			ctx.set("isOK", false);
			// 返回错误内容给客户端
			ctx.setResponseBody((ctx.getResponseBody() == null ? "" : ctx.getResponseBody())
					+ "{\"error\":\"id mast be 1\"}");
		}
		return null;
	}
	// 过滤器类型
	// 顺序: pre ->routing -> post ,以上3个顺序出现异常时都可以触发error类型的filter
	@Override
	public String filterType() {
		return FilterConstants.PRE_TYPE;
	}
	// 同filterType类型中,order值越大,优先级越低
	@Override
	public int filterOrder() {
		return 0;
	}
}

开发第二个过滤器:

/** zuul过滤器pre02 */
@Component
public class ZuulFilterPre02 extends ZuulFilter {
	// 是否应该执行该过滤器,如果是false,则不执行该filter
	@Override
	public boolean shouldFilter() {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		String name = request.getParameter("name");
		// 如果name是空,则不开启过滤,直接放行
		return !StringUtils.isEmpty(name);
	}
	// 执行业务操作,可执行sql,nosql等业务
	@Override
	public Object run() throws ZuulException {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		String name = request.getParameter("name");
		// 如果name=zhangsan,则继续执行下一个filter或转发请求
		if ("zhangsan".equals(name)) {
			// 会进行路由,继续执行下一个filter或转发请求
			ctx.setSendZuulResponse(true);
			ctx.setResponseStatusCode(200);
			// 可以把一些值放到ctx中,便于后面的filter获取使用
			ctx.set("isOK", true);
		} else {
			// 不需要进行路由,不会转发请求
			ctx.setSendZuulResponse(false);
			ctx.setResponseStatusCode(401);
			ctx.set("isOK", false);
			// 返回错误内容给客户端
			ctx.setResponseBody((ctx.getResponseBody() == null ? "" : ctx.getResponseBody())
					+ "{\"error\":\"name mast be zhangsan\"}");
		}
		return null;
	}
	// 过滤器类型
	// 顺序: pre ->routing -> post ,以上3个顺序出现异常时都可以触发error类型的filter
	@Override
	public String filterType() {
		return FilterConstants.PRE_TYPE;
	}
	// 同filterType类型中,order值越大,优先级越低
	@Override
	public int filterOrder() {
		return 1;
	}
}

5.测试

启动zuul工程,注册到eureka中。

启动service-product微服务工程(文章SpringBoot学习8.5-feign负载均衡调用微服务中的代码)。

访问http://localhost/product/productRestController/product/5?id=2&name=lisi

可见,两个过滤器都未转发请求。

访问http://localhost/product/productRestController/product/5?id=1&name=lisi

访问http://localhost/product/productRestController/product/5?id=1&name=zhangsan

可见:两个过滤器都给予放行,从微服务获取了数据。

 

github:https://github.com/zhangyangfei/spring-cloud-learn.git 中的cloud-parent工程。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值