一、zuul作用
1.微服务网关
2.全局拦截
3.局域网透过
4.限流
二、微服务网关
1.新建zull项目
![](https://img.haomeiwen.com/i12544606/bd08211214091397.png)
2.添加yml配置
server:
port: 80
spring:
application:
name: demo-zuul
eureka:
client:
enabled: true #该客户端是否可用
service-url:
defaultZone: http://localhost:8761/eureka #注册中心地址
register-with-eureka: true #注册该服务,默认为true
fetch-registry: true #获取服务列表,默认为true
3.开启网关功能(启动类添加@EnableZuulProxy注解),配置动态路由规则
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.filters.discovery.PatternServiceRouteMapper;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@EnableZuulProxy//开启网关功能
public class DemoZuulApplication {
public static void main(String[] args) {
SpringApplication.run(DemoZuulApplication.class, args);
}
//配置动态路由规则
@Bean
public PatternServiceRouteMapper getPatternServiceRouteMapper() {
return new PatternServiceRouteMapper("(?<name>^.+)", "${name}");
}
}
4.启动项目
通过网关地址+微服务名可以访问到在注册中心注册了的微服务。
![](https://img.haomeiwen.com/i12544606/299434a1115469ea.png)
例如现在有一个demo-zuul网关,两个demo-member服务。
通过访问网关的地址(http://localhost)来访问demo-member服务的接口。
访问地址为:http://localhost/demo-member/user/loadBalance
这里会先通过url中的/demo-member 路由到demo-member服务中,再到demo-member服务里面去找/user/loadBalance接口。
![](https://img.haomeiwen.com/i12544606/b894b30b74a796da.png)
![](https://img.haomeiwen.com/i12544606/6c489cb9a57468c9.png)
这边我启动了两个demo-member服务,顺便测试了下使用zuul来访问微服务的负载均衡能力。
三、全局拦截
1.添加一个验证token有效性的拦截器
![](https://img.haomeiwen.com/i12544606/29ecb9a79053374a.png)
package com.thy.filter;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
@Component
public class TokenFilter extends ZuulFilter {
/**
* 是否拦截
*/
@Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
// RequestContext ctx = RequestContext.getCurrentContext();
// ctx.getBoolean("isOk");
HttpServletRequest request = ctx.getRequest();
String requestURI = request.getRequestURI();
//排除拦截的url
if (requestURI.equals("/demo-member/user/loadBalance")) {
return false;
}
return true;
}
/**
* 拦截下来干嘛
*/
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String token = request.getParameter("token");
// ctx.set("isOk",true); // 可以在上下文里面设置一个key,在下一次拦截时,就可以获取到
if (null == token) {
ctx.setResponseBody("token is null");
ctx.setResponseStatusCode(400);
ctx.setSendZuulResponse(false);
return null;
}
if (!"123456".equals(token)) {
ctx.setResponseBody("token is error");
ctx.setResponseStatusCode(400);
ctx.setSendZuulResponse(false);
return null;
}
ctx.setSendZuulResponse(true);
return null;
}
/**
* 拦截类型 pre route前拦截 route route时拦截 post 两者之间 error 发现错误拦截
*/
@Override
public String filterType() {
// TODO Auto-generated method stub
return "pre";
}
/**
* 拦截的次序 越小,越先执行
*/
@Override
public int filterOrder() {
// TODO Auto-generated method stub
return 0;
}
}
四、局域网透过
![](https://img.haomeiwen.com/i12544606/fddc6c629c18f2a9.png)
Nginx也可以做
五、跨域请求
1.介绍
![](https://img.haomeiwen.com/i12544606/2b47f6082a566ae9.png)
html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Page Title</title>
<script src="jquery.js"></script>
</head>
<body>
<h1>跨域请求测试</h1>
</body>
<script>
$.get("http://localhost/demo-member/user/loadBalance?token=123456",function(res){
alert(res.data);
})
</script>
</html>
会有跨域访问的问题
![](https://img.haomeiwen.com/i12544606/aadce0474cf8e0d6.png)
2.跨域问题解决方案
(1).Jsonp(都可以)
(2).CorsMapping(web-mvc)
(3).CorsFilter(zuul)
(4).Spring安全(Spring安全框架)
zuul配置CorsFilter解决跨域请求问题
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class ZuulFilterConfig {
// 在zuul里面解决跨域请求,有2 种方法,第一种就是注入一个CorsFilter ,2:spring 自带的安全框架
@Bean
public CorsFilter getCorsFilter() {
CorsConfiguration config = new CorsConfiguration();
//允许所有域名
config.addAllowedOrigin("*");
//允许所有请求头
config.addAllowedHeader("*");
//允许所有方法
config.addAllowedMethod("*");
//允许cookie
config.setAllowCredentials(true);
//预检请求的缓存时间,在此时间内,相同的跨域请求不在验证
config.setMaxAge(7200*100l);
UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", config);
return new CorsFilter(urlBasedCorsConfigurationSource );
}
}
六、限流
1.介绍
DDOS:(没法避免,只能通过限流来解决)
分布式拒绝服务(DDoS:Distributed Denial of Service)攻击指借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目标发动DDoS攻击,从而成倍地提高拒绝服务攻击的威力。
限流:
一个客户端,1 min访问我100(恶意的)
拦截用户的请求,看这个ip,1 min访问了我100次就拦截
2.导入依赖
<dependency>
<groupId>com.marcosbarbero.cloud</groupId>
<artifactId>spring-cloud-zuul-ratelimit</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
3.添加配置
zuul:
ratelimit:
enabled: true #开启限流
#repository: REDIS #选择存储的位置,默认在内存里面的HashMap存储
behind-proxy: true #代理之后
default-policy-list: #可选 - 针对所有的路由配置的策略,除非特别配置了policies
- limit: 10 #可选 - 每个刷新时间窗口对应的请求数量限制
quota: 1000 #可选- 每个刷新时间窗口对应的请求时间限制(秒)
refresh-interval: 60 # 刷新时间窗口的时间,默认值 (秒)
type: #可选 限流方式
- user
- origin
- url
4.结果
因为配置中limit配置的是10,refresh-interval是60,所以在60s内第11次访问接口时会抛出以下异常。
![](https://img.haomeiwen.com/i12544606/877eb8d7b746a10f.png)
网友评论