From cedb58feca4528498ebe3cd097bb8a8c6b9654cf Mon Sep 17 00:00:00 2001 From: TinyYu Date: Sun, 31 Jul 2022 22:53:44 +0800 Subject: [PATCH] =?UTF-8?q?zuul=E5=92=8Cgateway?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- note/springCloudNetflix-7-31.md | 55 +++++++++ pom.xml | 7 ++ spring-cloud-netflix-gateway/pom.xml | 29 +++++ .../java/cn/mobius/GateWayApplication.java | 13 +++ .../java/cn/mobius/config/FilterConfig.java | 29 +++++ .../cn/mobius/filter/RequestTimeFilter.java | 41 +++++++ .../cn/mobius/filter/TimeGlobleFilter.java | 65 +++++++++++ .../src/main/resources/application.yml | 25 ++++ .../target/classes/application.yml | 25 ++++ .../cn/mobius/GateWayApplication.class | Bin 0 -> 801 bytes spring-cloud-netflix-zuul/pom.xml | 34 ++++++ .../main/java/cn/mobius/ZuulApplication.java | 15 +++ .../cn/mobius/fallback/PayServerFallback.java | 100 ++++++++++++++++ .../cn/mobius/fliter/LoginCheckFilter.java | 108 ++++++++++++++++++ .../src/main/resources/application.yml | 39 +++++++ .../target/classes/application.yml | 39 +++++++ .../classes/cn/mobius/ZuulApplication.class | Bin 0 -> 850 bytes .../mobius/fallback/PayServerFallback$1.class | Bin 0 -> 2072 bytes .../mobius/fallback/PayServerFallback.class | Bin 0 -> 1161 bytes .../cn/mobius/fliter/LoginCheckFilter.class | Bin 0 -> 3379 bytes 20 files changed, 624 insertions(+) create mode 100644 note/springCloudNetflix-7-31.md create mode 100644 spring-cloud-netflix-gateway/pom.xml create mode 100644 spring-cloud-netflix-gateway/src/main/java/cn/mobius/GateWayApplication.java create mode 100644 spring-cloud-netflix-gateway/src/main/java/cn/mobius/config/FilterConfig.java create mode 100644 spring-cloud-netflix-gateway/src/main/java/cn/mobius/filter/RequestTimeFilter.java create mode 100644 spring-cloud-netflix-gateway/src/main/java/cn/mobius/filter/TimeGlobleFilter.java create mode 100644 spring-cloud-netflix-gateway/src/main/resources/application.yml create mode 100644 spring-cloud-netflix-gateway/target/classes/application.yml create mode 100644 spring-cloud-netflix-gateway/target/classes/cn/mobius/GateWayApplication.class create mode 100644 spring-cloud-netflix-zuul/pom.xml create mode 100644 spring-cloud-netflix-zuul/src/main/java/cn/mobius/ZuulApplication.java create mode 100644 spring-cloud-netflix-zuul/src/main/java/cn/mobius/fallback/PayServerFallback.java create mode 100644 spring-cloud-netflix-zuul/src/main/java/cn/mobius/fliter/LoginCheckFilter.java create mode 100644 spring-cloud-netflix-zuul/src/main/resources/application.yml create mode 100644 spring-cloud-netflix-zuul/target/classes/application.yml create mode 100644 spring-cloud-netflix-zuul/target/classes/cn/mobius/ZuulApplication.class create mode 100644 spring-cloud-netflix-zuul/target/classes/cn/mobius/fallback/PayServerFallback$1.class create mode 100644 spring-cloud-netflix-zuul/target/classes/cn/mobius/fallback/PayServerFallback.class create mode 100644 spring-cloud-netflix-zuul/target/classes/cn/mobius/fliter/LoginCheckFilter.class diff --git a/note/springCloudNetflix-7-31.md b/note/springCloudNetflix-7-31.md new file mode 100644 index 0000000..3d40e7c --- /dev/null +++ b/note/springCloudNetflix-7-31.md @@ -0,0 +1,55 @@ +[toc] + +# SpringCloudNetflix-day03 + +## 1.Zuul服务网关 + +- Zuul 是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet(filter)应用。Zuul 在云平台上提供动态路由(请求分发),监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门,也要注册入Eureka。zuul本身是一个独立的服务,默认集成了Ribbon,zuul通过Ribbon将客户端的请求分发到下游的微服务,所以zuul需要通过Eureka做服务发行,同时zuul也集成了Hystrix。 +- 建立独立的工程去搭建Zuul服务,同时需要把Zuul注册到EurekaServer,因为当请求过来时,zuul需要通过EurekaServer获取下游的微服务通信地址,使用Ribbon发起调用。 + +### 1.zuul工作原理 + +- zuul的底层是通过各种Filter来实现的,zuul中的filter按照执行顺序分为了“pre”前置(”custom”自定义一般是前置),“routing”路由,“post”后置,以及“error”异常Filter组成,当各种Filter出现了异常,请求会跳转到“error filter”,然后再经过“post filter” 最后返回结果 +- 正常流程: + - 请求到达首先会经过pre类型过滤器,而后到达routing类型,进行路由,请求就到达真正的服务提供者,执行请求,返回结果后,会到达post过滤器。而后返回响应。 +- 异常流程: + - 整个过程中,pre或者routing过滤器出现异常,都会直接进入error过滤器,再error处理完毕后,会将请求交给POST过滤器,最后返回给用户。 + - 如果是error过滤器自己出现异常,最终也会进入POST过滤器,而后返回。 + - 如果是POST过滤器出现异常,会跳转到error过滤器,但是与pre和routing不同的时,请求不会再到达POST过滤器了。 + +## 2.SpringCloudGateway服务网关 + +### 1.Zuul与Gateway + +- Zuul是Netflix的开源项目,Spring Cloud将其收纳成为自己的一个子组件。zuul用的是多线程阻塞模型,它本质上就是一个同步 Servlet,这样的模型比较简单,他都问题是多线程之间上下文切换是有开销的,线程越多开销就越大。线程池数量固定意味着能力接受的请求数固定,当后台请求变慢,面对大量的请求,线程池中的线程容易被耗尽,后续的请求会被拒绝。 +- 在Zuul 2.0中它采用了 Netty 实现异步非阻塞编程模型,异步非阻塞模式对线程的消耗比较少,对线程上线文切换的消耗也比较小,并且可以接受更多的请求。它的问题就是线程模型比较复杂。 +- Spring Cloud Gateway是Spring Cloud自己的产物,基于Spring 5 和Spring Boot 2.0 开发,Spring Cloud Gateway的出现是为了代替zuul,在Spring Cloud 高版本中没有对zuul 2.0进行集成,SpringCloud Gateway使用了高性能的Reactor模式通信框架Netty。 +- Spring Cloud Gateway 的目标,不仅提供统一的`路由`方式,并且基于 Filter 链的方式提供了`网关基本的功能` + +### 2.Spring Cloud Gataway的特点 + +- 基于 Spring 5,Project Reactor , Spring Boot 2.0 +- 默认集成 Hystrix 断路器 +- 默认集成 Spring Cloud DiscoveryClient +- Predicates 和 Filters 作用于特定路由,易于编写的 Predicates 和 Filters +- 支持动态路由、限流、路径重写 + +### 3.Spring Cloud Gataway的核心概念 + +- Filter(过滤器): + - pring Cloud `Gateway的Filter和Zuul的过滤器类似`,可以在请求发出前后进行一些业务上的处理 ,这里分为`两种类型的Filter,分别是Gateway Filter网关filter和Global Filter全局Filter +- Route(路由): + - 网关配置的基本组成模块,和Zuul的路由配置模块类似。一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。说白了就是把url请求路由到对应的资源(服务),或者说是一个请求过来Gateway应该怎么把这个请求转发给下游的微服务,转发给谁。 +- Predicate(断言): + - 这是一个 Java 8 的 Predicate,可以使用它来`匹配来自 HTTP 请求的任何内容`,例如 headers 或参数。断言的输入类型是一个 ServerWebExchange。简单理解就是处理HTTP请求的匹配规则,在什么样的请情况下才能命中资源继续访问。 + +### 4.Spring Cloud Gateway的工作方式 + +- 客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序通过特定于请求的过滤器链来运行请求。筛选器由虚线分隔的原因是,筛选器可以在发送代理请求之前和之后运行逻辑。所有“前置”过滤器逻辑均被执行。然后发出代理请求。发出代理请求后,将运行“后”过滤器逻辑。 + +### 5.Predicate断言工厂 + +- 其实断言工厂就是用来判断http请求的匹配方式。比如我们再上面案例中配置的:“`Path=/user/**`” ,就是使用的是 “`Path Route Predicate Factory`” 路径匹配工厂,意思是http请求的资源地址必须是 /user 才会被匹配到对应的路由,然后继续执行对应的服务获取资源。 + + + diff --git a/pom.xml b/pom.xml index 861af05..8d9f653 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,8 @@ spring-cloud-order-server spring-cloud-common spring-cloud-pay-server + spring-cloud-netflix-zuul + spring-cloud-netflix-gateway pom @@ -60,6 +62,11 @@ lombok 1.18.12 + + com.alibaba + fastjson + 1.2.76 + \ No newline at end of file diff --git a/spring-cloud-netflix-gateway/pom.xml b/spring-cloud-netflix-gateway/pom.xml new file mode 100644 index 0000000..15fce9d --- /dev/null +++ b/spring-cloud-netflix-gateway/pom.xml @@ -0,0 +1,29 @@ + + + + springcloud-parent + cn.mobius + 1.0-SNAPSHOT + + 4.0.0 + + spring-cloud-netflix-gateway + + + 8 + 8 + + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + org.springframework.cloud + spring-cloud-starter-gateway + + + \ No newline at end of file diff --git a/spring-cloud-netflix-gateway/src/main/java/cn/mobius/GateWayApplication.java b/spring-cloud-netflix-gateway/src/main/java/cn/mobius/GateWayApplication.java new file mode 100644 index 0000000..2c2f743 --- /dev/null +++ b/spring-cloud-netflix-gateway/src/main/java/cn/mobius/GateWayApplication.java @@ -0,0 +1,13 @@ +package cn.mobius; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +@SpringBootApplication +@EnableDiscoveryClient // 服务注册和发现 +public class GateWayApplication { + public static void main(String[] args) { + SpringApplication.run(GateWayApplication.class,args); + } +} diff --git a/spring-cloud-netflix-gateway/src/main/java/cn/mobius/config/FilterConfig.java b/spring-cloud-netflix-gateway/src/main/java/cn/mobius/config/FilterConfig.java new file mode 100644 index 0000000..5e787ed --- /dev/null +++ b/spring-cloud-netflix-gateway/src/main/java/cn/mobius/config/FilterConfig.java @@ -0,0 +1,29 @@ +package cn.mobius.config; + +import cn.mobius.filter.RequestTimeFilter; +import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 将自定义过滤器配置在对应的路由上 + */ +@Configuration +public class FilterConfig { + + //配置Filter作用于那个访问规则上 + @Bean + public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) { + + return builder.routes().route(r -> r.path("/services/user/**") + //去掉2个前缀 + .filters(f -> f.stripPrefix(2) + .filter(new RequestTimeFilter()) + .addResponseHeader("X-Response-test", "test")) + .uri("lb://service-user") + .order(0) + .id("test-RequestTimeFilter") + ).build(); + } +} diff --git a/spring-cloud-netflix-gateway/src/main/java/cn/mobius/filter/RequestTimeFilter.java b/spring-cloud-netflix-gateway/src/main/java/cn/mobius/filter/RequestTimeFilter.java new file mode 100644 index 0000000..7f9a022 --- /dev/null +++ b/spring-cloud-netflix-gateway/src/main/java/cn/mobius/filter/RequestTimeFilter.java @@ -0,0 +1,41 @@ +package cn.mobius.filter; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.cloud.gateway.filter.GatewayFilter; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.core.Ordered; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +/** + * 自定义gateway 过滤器 + */ +public class RequestTimeFilter implements GatewayFilter, Ordered { + + private static final Log log = LogFactory.getLog(GatewayFilter.class); + private static final String COUNT_Start_TIME = "countStartTime"; + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + //开始时间 + exchange.getAttributes().put(COUNT_Start_TIME, System.currentTimeMillis()); + //执行完成之后 + return chain.filter(exchange).then( + Mono.fromRunnable(() -> { + //开始时间 + Long startTime = exchange.getAttribute(COUNT_Start_TIME); + //结束时间 + Long endTime=(System.currentTimeMillis() - startTime); + if (startTime != null) { + log.info(exchange.getRequest().getURI().getRawPath() + ": " + endTime + "ms"); + } + }) + ); + } + + @Override + public int getOrder() { + return Ordered.LOWEST_PRECEDENCE; + } +} diff --git a/spring-cloud-netflix-gateway/src/main/java/cn/mobius/filter/TimeGlobleFilter.java b/spring-cloud-netflix-gateway/src/main/java/cn/mobius/filter/TimeGlobleFilter.java new file mode 100644 index 0000000..4693c30 --- /dev/null +++ b/spring-cloud-netflix-gateway/src/main/java/cn/mobius/filter/TimeGlobleFilter.java @@ -0,0 +1,65 @@ +package cn.mobius.filter; + +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cloud.gateway.filter.GatewayFilterChain; +import org.springframework.cloud.gateway.filter.GlobalFilter; +import org.springframework.core.Ordered; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.List; + +/** + * 自定义全局过滤器 + */ +@Component +@Slf4j +public class TimeGlobleFilter implements GlobalFilter, Ordered { + + @Override + public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { + + List token = exchange.getRequest().getHeaders().get("token"); + + log.info("检查 TOKEN = {}" ,token); + if(token == null || token.isEmpty()){ + //响应对象 + ServerHttpResponse response = exchange.getResponse(); + //构建错误结果 + HashMap data = new HashMap<>(); + data.put("code",401); + data.put("message","未登录"); + + DataBuffer buffer = null; + try { + byte[] bytes = JSON.toJSONString(data).getBytes("utf-8"); + buffer = response.bufferFactory().wrap(bytes); + + //设置完成相应,不会继续执行后面的filter + //response.setComplete(); + response.setStatusCode(HttpStatus.UNAUTHORIZED); + response.getHeaders().add("Content-Type","application/json;charset=UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + //把结果写给客户端 + return response.writeWith(Mono.just(buffer)); + } + + log.info("Token不为空 ,放行"); + return chain.filter(exchange); + } + + @Override + public int getOrder() { + return 0; + } +} \ No newline at end of file diff --git a/spring-cloud-netflix-gateway/src/main/resources/application.yml b/spring-cloud-netflix-gateway/src/main/resources/application.yml new file mode 100644 index 0000000..6364356 --- /dev/null +++ b/spring-cloud-netflix-gateway/src/main/resources/application.yml @@ -0,0 +1,25 @@ +eureka: + client: + serviceUrl: + defaultZone: http://localhost:1010/eureka/ + instance: + prefer-ip-address: true #使用ip注册到Eureka + instance-id: gateway-server:1060 #指定客户端实例的ID +spring: + application: + name: gateway-server + cloud: + gateway: + discovery: + locator: + enabled: false #开放服务名访问方式 + lower-case-service-id: true #服务名小写 + routes: + - id : application-user #指定服务名 + uri: lb://user-server #去注册中心找这个服务名 + predicates: #断言,匹配访问的路径 + - Path=/user/** #服务访问路径 + filters: + - StripPrefix=1 #请求转发的时候会去掉 /user访问路径 +server: + port: 1060 diff --git a/spring-cloud-netflix-gateway/target/classes/application.yml b/spring-cloud-netflix-gateway/target/classes/application.yml new file mode 100644 index 0000000..6364356 --- /dev/null +++ b/spring-cloud-netflix-gateway/target/classes/application.yml @@ -0,0 +1,25 @@ +eureka: + client: + serviceUrl: + defaultZone: http://localhost:1010/eureka/ + instance: + prefer-ip-address: true #使用ip注册到Eureka + instance-id: gateway-server:1060 #指定客户端实例的ID +spring: + application: + name: gateway-server + cloud: + gateway: + discovery: + locator: + enabled: false #开放服务名访问方式 + lower-case-service-id: true #服务名小写 + routes: + - id : application-user #指定服务名 + uri: lb://user-server #去注册中心找这个服务名 + predicates: #断言,匹配访问的路径 + - Path=/user/** #服务访问路径 + filters: + - StripPrefix=1 #请求转发的时候会去掉 /user访问路径 +server: + port: 1060 diff --git a/spring-cloud-netflix-gateway/target/classes/cn/mobius/GateWayApplication.class b/spring-cloud-netflix-gateway/target/classes/cn/mobius/GateWayApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..20cf912cf480f8b972bc05385ebda388a4440e2f GIT binary patch literal 801 zcmaJfgc5Ph2_bufXJ6j};-W#s?>&$i}?^i>4DRFvvs%FyU}`G=+EK= z;=m8!MF7#dd^y469GH(f)v8Ww1YC zXpihvF|4K9s8@BFDfdof1x5O)m7rZoXrX? zh1b?3#99h%7&Zs*(=%}{cp*&A$KGj^Crwx3a^l%o0yC_?RQ}XX-v}p4<&~qvcx-DY z)pH$`ZT;QyVd%oJ{kAq;YGVJ_sdlByU zu!9G*hxzJWXJ<-!hT%VFxKzEMm@e4WbO+gB;R;5DsH$Yi*7uhWXN^~%JRe;xC(N|a zg2Dk#u!k1?XW?mqg&FCL$m3)g+0O6_*yjfB(ivdj8ofa8G66BJH?baW5J@P0+>im? serxy@E64Ntm=I8YMAdVSE^cCt;_LKv7&$@Bt>)}wgKQ|fP4*7(3y=uaF#rGn literal 0 HcmV?d00001 diff --git a/spring-cloud-netflix-zuul/pom.xml b/spring-cloud-netflix-zuul/pom.xml new file mode 100644 index 0000000..52fde34 --- /dev/null +++ b/spring-cloud-netflix-zuul/pom.xml @@ -0,0 +1,34 @@ + + + + springcloud-parent + cn.mobius + 1.0-SNAPSHOT + + 4.0.0 + + spring-cloud-netflix-zuul + spring-cloud-netflix-zuul + + + 8 + 8 + + + + + org.springframework.cloud + spring-cloud-starter-netflix-zuul + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + \ No newline at end of file diff --git a/spring-cloud-netflix-zuul/src/main/java/cn/mobius/ZuulApplication.java b/spring-cloud-netflix-zuul/src/main/java/cn/mobius/ZuulApplication.java new file mode 100644 index 0000000..81a4a84 --- /dev/null +++ b/spring-cloud-netflix-zuul/src/main/java/cn/mobius/ZuulApplication.java @@ -0,0 +1,15 @@ +package cn.mobius; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; +import org.springframework.cloud.netflix.zuul.EnableZuulProxy; + +@SpringBootApplication +@EnableZuulProxy // 开启zuul +@EnableEurekaClient // zuul也是一个eureka客户端 +public class ZuulApplication { + public static void main(String[] args) { + SpringApplication.run(ZuulApplication.class,args); + } +} diff --git a/spring-cloud-netflix-zuul/src/main/java/cn/mobius/fallback/PayServerFallback.java b/spring-cloud-netflix-zuul/src/main/java/cn/mobius/fallback/PayServerFallback.java new file mode 100644 index 0000000..008b16d --- /dev/null +++ b/spring-cloud-netflix-zuul/src/main/java/cn/mobius/fallback/PayServerFallback.java @@ -0,0 +1,100 @@ +package cn.mobius.fallback; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.stereotype.Component; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +/** + * zuul熔断器配置 + */ +@Component // 需要交给spring管理 +public class PayServerFallback implements FallbackProvider { + + private final Logger logger = LoggerFactory.getLogger(FallbackProvider.class); + + /** + * 指定需要熔断处理的服务 + * @return + */ + @Override + public String getRoute() { + // 如果写"*"代表所有服务 + return "pay-server"; + } + + /** + * @param route 服务的路由 + * @param cause 异常 + * @return ClientHttpResponse 熔断后的返回值(托底数据) + */ + @Override + public ClientHttpResponse fallbackResponse(String route, Throwable cause) { + return new ClientHttpResponse() { + /** + * 请求状态 + * @return + * @throws IOException + */ + @Override + public HttpStatus getStatusCode() throws IOException { + return HttpStatus.OK; + } + + /** + * 请求状态的值 + * @return + * @throws IOException + */ + @Override + public int getRawStatusCode() throws IOException { + return 200; + } + + /** + * 请求状态的文本值 + * @return + * @throws IOException + */ + @Override + public String getStatusText() throws IOException { + return "OK"; + } + + @Override + public void close() { + + } + + /** + * 响应体 + * @return + * @throws IOException + */ + @Override + public InputStream getBody() throws IOException { + return new ByteArrayInputStream("抱歉服务不可用".getBytes(StandardCharsets.UTF_8)); + } + + /** + * 设置响应头 + * @return + */ + @Override + public HttpHeaders getHeaders() { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + return httpHeaders; + } + }; + } +} diff --git a/spring-cloud-netflix-zuul/src/main/java/cn/mobius/fliter/LoginCheckFilter.java b/spring-cloud-netflix-zuul/src/main/java/cn/mobius/fliter/LoginCheckFilter.java new file mode 100644 index 0000000..f7de772 --- /dev/null +++ b/spring-cloud-netflix-zuul/src/main/java/cn/mobius/fliter/LoginCheckFilter.java @@ -0,0 +1,108 @@ +package cn.mobius.fliter; + +import com.alibaba.fastjson.JSONArray; +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; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * 自定义过滤器 + */ +@Component // 需要交给spring管理 +public class LoginCheckFilter extends ZuulFilter { + + // 日志 + private static final Logger log = LoggerFactory.getLogger(LoginCheckFilter.class); + + // 执行顺序 + private static final int ORDER = 1; + + /** + * 指定过滤器类型 + * @return + */ + @Override + public String filterType() { + // 前置过滤器 + return FilterConstants.PRE_TYPE; + } + + /** + * 过滤器的执行顺序,越小越优先执行 + * @return + */ + @Override + public int filterOrder() { + return ORDER; + } + + /** + * 决定run方法是否要被执行 + * @return + */ + @Override + public boolean shouldFilter() { + // 获取request对象 + HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); + + // 获取请求地址uri + String requestURI = request.getRequestURI(); + + log.info("请求地址:" + requestURI); + // 判断是否是公共的接口 + if (requestURI.endsWith("/login") || requestURI.endsWith("/register") || requestURI.contains("/static/")) { + return false; // 不执行run方法 + } + + // 执行run方法,做登陆业务 + return true; + } + + /** + * 过滤器的核心业务方法 + * @return + * @throws ZuulException + */ + @Override + public Object run() throws ZuulException { + HttpServletRequest request = RequestContext.getCurrentContext().getRequest(); + HttpServletResponse response = RequestContext.getCurrentContext().getResponse(); + + // 获取token + String token = request.getHeader("token"); + + // 判断是否登录 + if (!StringUtils.hasLength(token)) { // 字符序列不为 null 值,并且字符序列的长度大于 0 + Map map = new HashMap<>(); + map.put("success",false); + map.put("message","未登录,请前往登录!"); + + // 编码 + response.setContentType("application/json;charset=utf-8"); + String s = JSONArray.toJSONString(map); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 返回没有权限状态 + + try { + response.getWriter().print(s); + } catch (IOException e) { + e.printStackTrace(); + } + + // 阻止filter继续往后执行 + RequestContext.getCurrentContext().setSendZuulResponse(false); + } + + return null; + } +} diff --git a/spring-cloud-netflix-zuul/src/main/resources/application.yml b/spring-cloud-netflix-zuul/src/main/resources/application.yml new file mode 100644 index 0000000..0f86163 --- /dev/null +++ b/spring-cloud-netflix-zuul/src/main/resources/application.yml @@ -0,0 +1,39 @@ +#注册到EurekaServer +eureka: + client: + serviceUrl: + defaultZone: http://localhost:1010/eureka/ + #使用ip地址进行注册 + instance: + prefer-ip-address: true + #要指定服务的实例ID + instance-id: zuul-server:1050 +server: + port: 1050 +spring: + application: + name: zuul-server #服务名 + +zuul: + prefix: "/servers" #统一访问前缀 + ignoredServices: "*" #禁用掉使用浏览器通过服务名的方式访问服务 + routes: + pay-server: "/pay/**" #指定pay-server这个服务使用 /pay路径来访问 - 别名 + order-server: "/order/**" #指定order-server这个服务使用 /order路径来访问 + user-server: "/user/**" #指定user-server这个服务使用/user路径来访问 + retryable: true #是否开启重试功能 + ribbon: + eager-load.enabled: true # 饥饿加载 +ribbon: + MaxAutoRetries: 1 #对当前服务的重试次数 + MaxAutoRetriesNextServer: 1 #切换相同Server的次数 + OkToRetryOnAllOperations: false # 对所有的操作请求都进行重试,如post就不能重试,如果没做幂等处理,重试多次post会造成数据的多次添加或修改 + ConnectTimeout: 3000 #请求连接的超时时间 + ReadTimeout: 5000 #请求处理的超时时间 +hystrix: + command: + default: + execution: + isolation: + thread: + timeoutInMilliseconds: 10000 #如果配置ribbon的重试,hystrix的超时时间要大于ribbon的超时时间 diff --git a/spring-cloud-netflix-zuul/target/classes/application.yml b/spring-cloud-netflix-zuul/target/classes/application.yml new file mode 100644 index 0000000..0f86163 --- /dev/null +++ b/spring-cloud-netflix-zuul/target/classes/application.yml @@ -0,0 +1,39 @@ +#注册到EurekaServer +eureka: + client: + serviceUrl: + defaultZone: http://localhost:1010/eureka/ + #使用ip地址进行注册 + instance: + prefer-ip-address: true + #要指定服务的实例ID + instance-id: zuul-server:1050 +server: + port: 1050 +spring: + application: + name: zuul-server #服务名 + +zuul: + prefix: "/servers" #统一访问前缀 + ignoredServices: "*" #禁用掉使用浏览器通过服务名的方式访问服务 + routes: + pay-server: "/pay/**" #指定pay-server这个服务使用 /pay路径来访问 - 别名 + order-server: "/order/**" #指定order-server这个服务使用 /order路径来访问 + user-server: "/user/**" #指定user-server这个服务使用/user路径来访问 + retryable: true #是否开启重试功能 + ribbon: + eager-load.enabled: true # 饥饿加载 +ribbon: + MaxAutoRetries: 1 #对当前服务的重试次数 + MaxAutoRetriesNextServer: 1 #切换相同Server的次数 + OkToRetryOnAllOperations: false # 对所有的操作请求都进行重试,如post就不能重试,如果没做幂等处理,重试多次post会造成数据的多次添加或修改 + ConnectTimeout: 3000 #请求连接的超时时间 + ReadTimeout: 5000 #请求处理的超时时间 +hystrix: + command: + default: + execution: + isolation: + thread: + timeoutInMilliseconds: 10000 #如果配置ribbon的重试,hystrix的超时时间要大于ribbon的超时时间 diff --git a/spring-cloud-netflix-zuul/target/classes/cn/mobius/ZuulApplication.class b/spring-cloud-netflix-zuul/target/classes/cn/mobius/ZuulApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..39a6ab1550336e26cffeb399f080d771afd26c5a GIT binary patch literal 850 zcma)4%We}f6g|$P6Nb>1v=mBth+Ucm-XMfDP^m;^H9$pBkYMGRI8(PXcI5Fu;ICML zSnvUS6ykassR5-DmVB@7`<`R}`u*c4fJe9=qJ^6QZiU#z?ErfWYfqI{?tr1$-ybuy zhGrreHe#jatExz(eJhfjJiXYYA|DH@yuEO?+=(g~_Tp6Y!X&CH`TMHM4`;JnrNSwr zBWhU)r5SemAL3K-QSe;ojE|gEI*aO&!e-QDYekr0^QCkrW^yd7D5R5?62pr8E-GhIqo*pX ztmLCQEbT#5pNe%zfMkN>KF!>!afJO1d@J(t?12?{?d~Tb5WMjidWiS z4a#UI=Z+5-e0nODMv&WwBRoKZKBYemFb|MqKo%#>NVf;yz`oYu4oM#duHp*G?s)=2 zvO%6Mu2Bd_%C3C IL3aoE1Am9+S^xk5 literal 0 HcmV?d00001 diff --git a/spring-cloud-netflix-zuul/target/classes/cn/mobius/fallback/PayServerFallback$1.class b/spring-cloud-netflix-zuul/target/classes/cn/mobius/fallback/PayServerFallback$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8ee0de2b7fff9e6a7e2a7662f30e5a98c9dbdfbd GIT binary patch literal 2072 zcma)6U2ofD6n>mEb>ew#(rz7$G4_$JNyFx~Y%tbRXhK7?rA=wlO49`8P4cesmfDf+ ztjis@Oq#gik{j;00KqD4otVTm;&-s}FA(RA-NwqAE|Ki_Bj-HldCrIb{_l@J0bIj+ z1VfloFpTL4KESmwuFLo^jE^F?fsYm3#EgOvW@UV$KoLfB_*CpZlQAzNEh8gg(5dNm z{HlaY`HG=!nPt6cYxh{aUS^dC+6rqGx%H4+S?^|sJZ5!6cjhD{6aBd)*Ch;O%qo{K zoYxJ$+}tX2tHjE6x*5rv6;@womM+fT<$xe1LCqNkw=#8R+nkR5g^N!S$LJDwYG!qX zS!|0t+#>Jeo7^cn%xT&#m5D?$Z(5t0-LQ0H^PVu=HmwI*&2bvqBE4K=0#gD%}D8I2~sy&s>vdi>KrFP^;m{v7}-d1p&MwA%0}(JSj51RI!Sp ziW1hS!~1FQ_!JemQ?x?)KCe(Ir+db$)OBt+TBf~-zFFmVgIa}BH@Yu4S2$=PqTUY; zBC$V&9lWm+ueX!$rc|@cZ81eNM|5^iy3{Tgdy4GLgM{&;+vs3y&bQSYRPRcSSvGfQ z0+>-{RyE_EX(&T$rR>HH38!5deq+ywX!*+F&X9z#7#iv#f;j6X&`CMkclq)Q6+$t89sb0PH9yk)qAySwz4TqY+g_=n8 zIr@wbgJMI9M#b>Z*IlM(6ekeCN!rcP8lY8~Og)1%xr@M4It4IB??LheCUJ`1W3Cn6 z!f85@eH%@}JG2i;hgW&J9`T?igfU5hy2Y6Q4(#?DHoWuEU zloD4Ja3I(L=dRn1V}iWT2Z$)&~+igi0La4+18< z=r`NCfaptv?u-oXKz@$!E+XAj)_ge8L#QN>^r$QmvM5>XC6qh6IF?WCKz)wmsSe~2 xf@JVD!q}ktf76C`D;V>j!-!C2Qv?~r`(zuyWh$B|f`+Sjn|2EQH$*G_{s#(Q{<#1E literal 0 HcmV?d00001 diff --git a/spring-cloud-netflix-zuul/target/classes/cn/mobius/fallback/PayServerFallback.class b/spring-cloud-netflix-zuul/target/classes/cn/mobius/fallback/PayServerFallback.class new file mode 100644 index 0000000000000000000000000000000000000000..a37e45417f7178980dff878811e4a1a0e3ca4052 GIT binary patch literal 1161 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 ZBPS`YH1M>8?jPV