微服务网关
一. Zuul网关1. 创建工程 并导入依赖2. application.yml 配置文件3. 启动类添加注解4. 依次启动服务5. 进入浏览器访问测试二. ZuulFilter 过滤器1. ZuulFilter简介2. 在filters包下创建PowerFilter类3. 再次访问网址三. 计数器限流1. 在application.yml 配置文件添加!2. 再去连续快速的访问网址3.再 controller 包下创建 ErrorController 错误信息控制器4. 再去连续快速的访问网址四. 令牌桶限流1. 在 filters 包下创建 LimitFilter 类2. 在 application.yml 中注释掉计数器限流配置3. 去浏览器连续快速访问一. Zuul网关
1. 创建工程 并导入依赖
添加依赖
<!-- zuul网关 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId><version>2.1.0.RELEASE</version></dependency><!-- 计数器 --><dependency><groupId>com.marcosbarbero.cloud</groupId><artifactId>spring-cloud-zuul-ratelimit</artifactId><version>1.3.4.RELEASE</version></dependency>
2. application.yml 配置文件
server:port: 7003spring:application:name: zuul-servereureka: # 注册中心client:service-url:defaultZone: http://localhost:7001/eureka/ #,http://localhost:7002/eureka/ #添加到的eureka注册中心的地址instance:prefer-ip-address: true #在eureka地址页面中显示微服务的ip地址和端口instance-id: ${spring.cloud.client.ip-address}:${server.port} #设置发送心跳时间间隔lease-renewal-interval-in-seconds: 5 #设置没有发送心跳 微服务在eureka中保存的最大时间lease-expiration-duration-in-seconds: 10# zuul 网关zuul:routes:user-server: # 这里是路由id,随意写path: /** # 这里是映射路径 user 是api/user/get 此处写api/** 实际的就为api/api/user/getserviceId: user-server #配置转发的微服务名称order-server:path: /**serviceId: order-server
3. 启动类添加注解
4. 依次启动服务
5. 进入浏览器访问测试
链接:http://localhost:7003/userserver/findUserOrder?uid=2
展示此数据就说明成功了
二. ZuulFilter 过滤器
1. ZuulFilter简介
以通过配置 urlPatterns 来拦截对应的请求。而 Zuul 中的过滤器总共有 4 种类型,且每种类型都有对应的使用场景。
PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfifilx Ribbon请求微服务。POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP
Header、收集统计信息和指标、将响应从微服务发送给客户端等。ERROR:在其他阶段发生错误时执行该过滤器。
2. 在filters包下创建PowerFilter类
package com.ddz.filters;import flix.zuul.ZuulFilter;import flix.zuul.context.RequestContext;import flix.zuul.exception.ZuulException;import org.flix.zuul.filters.support.FilterConstants;import org.ponent;import javax.servlet.http.HttpServletRequest;@Componentpublic class PowerFilter extends ZuulFilter {/* 过滤器类型,可选值有 pre、route、post、error */@Overridepublic String filterType() {return FilterConstants.PRE_TYPE;}/* 过滤器的执行顺序,数值越小,优先级越高 */@Overridepublic int filterOrder() {return 0;}/* 是否执行该过滤器,true 为执行,false 为不执行,这个也可以利用配置中心来实现,达到动态的开启和关闭过滤器 */@Overridepublic boolean shouldFilter() {return true;}/* 业务逻辑,本次是判断请求的url是否带有token,没有则通过设置 ctx.setSendZuulResponse(false),告诉 Zuul 不需要将当前请求转发到后端的服务了,通过setResponseBody 返回数据给客户端 */@Overridepublic Object run() throws ZuulException {RequestContext context = RequestContext.getCurrentContext(); //获取上下文HttpServletRequest request = context.getRequest();String token = request.getParameter("token"); //获取tokenif (token == null || "".equals(token)) {context.setSendZuulResponse(false); // 过滤该请求context.setResponseStatusCode(401); // 返回错误码context.setResponseBody("{'msg':'401 account without'}"); // 返回错误信息return "access";}return "next";}}
3. 再次访问网址
链接:http://localhost:7003/userserver/findUserOrder?uid=2
不带token访问
带token 访问
三. 计数器限流
1. 在application.yml 配置文件添加!
zuul:ratelimit:enabled: true #开启限流policies: # 多个微服务user-server: # 上面写的路由idlimit: 3 #60s 内请求超过 3 次,服务端就抛出异常,60s 后可以恢复正常请求quota: 30 #单位时间内允许访问的总时间(单位时间窗口期内,所有的请求的总时间不能超过这个时间限制)refresh-interval: 10 #单位时间设置type: origin #针对 IP 进行限流,不影响其他 IP
2. 再去连续快速的访问网址
链接:http://localhost:7003/userserver/findUserOrder?uid=2&token=1
以上错误信息,返回给前端易读性差下面对错误信息优化
3.再 controller 包下创建 ErrorController 错误信息控制器
package com.ddz.controller;import org.springframework.boot.web.servlet.error.ErrorController;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;import java.util.Map;@RestControllerpublic class ErrorHander implements ErrorController {@Overridepublic String getErrorPath() {return "error";}/* 自定义的异常信息方法 */@RequestMapping(value = "error")public Map<String, Object> error() {Map<String, Object> dto = new HashMap<>();dto.put("msg", "计数器访问限流"); //提示信息dto.put("code", 401); // 错误码return dto;}}
4. 再去连续快速的访问网址
链接:http://localhost:7003/userserver/findUserOrder?uid=2&token=1
四. 令牌桶限流
1. 在 filters 包下创建 LimitFilter 类
package com.ddz.filters;import mon.util.concurrent.RateLimiter;import flix.zuul.ZuulFilter;import flix.zuul.context.RequestContext;import flix.zuul.exception.ZuulException;import org.flix.zuul.filters.support.FilterConstants;import org.ponent;import javax.servlet.http.HttpServletRequest;@Componentpublic class LimitFilter extends ZuulFilter {// 定义一个令牌桶,每秒产生2个令牌,即每秒最多处理2个请求private static final RateLimiter RATE_LIMITER = RateLimiter.create(2);/* 过滤器类型,可选值有 pre、route、post、error */@Overridepublic String filterType() {return FilterConstants.PRE_TYPE;}/* 过滤器的执行顺序,数值越小,优先级越高 */@Overridepublic int filterOrder() {return -5;}/* 是否执行该过滤器,true 为执行,false 为不执行,这个也可以利用配置中心来实现,达到动态的开启和关闭过滤器 */@Overridepublic boolean shouldFilter() {RequestContext context = RequestContext.getCurrentContext();//HttpServletRequest request = context.getRequest();// tryAcquire() 只要能够马上获致到1个令牌,则返回true,不阻塞// tryAcquire(5, 3, TimeUnit.SECONDS) 在3秒钟内可以获取到5个令牌,则返回true,不阻塞// acquire(5) 获取到5个令牌,否则一直等待,会阻塞,返回值为阻塞的时长// acquire() 获取到1个令牌,否则一直等待,会阻塞,返回值为阻塞的时长if (!RATE_LIMITER.tryAcquire()) {context.getResponse().setContentType("application/json; charset=utf-8");context.setSendZuulResponse(false); // false指当前请被过滤调context.setResponseStatusCode(401); // 错误码context.setResponseBody("{code:401,msg:'你限流了'}"); // 错误信息return false;}return true;}/* 业务逻辑 */@Overridepublic Object run() throws ZuulException {return null;}}
2. 在 application.yml 中注释掉计数器限流配置
3. 去浏览器连续快速访问
链接:http://localhost:7003/userserver/findUserOrder?uid=2&token=1