javascript
Springboot 集成Springcloud gateway的入门
最近做項目使用到了springcloude gateway作為網關,因此在此記錄下springcloud gateway的入門操作,后續再將源碼解讀寫出來,先立個flag。
回歸正題,Springcloud gateway是spring 最新推出的網關中間件,用于代替 Netflix Zuul,因為 Netflix Zuul是基于mvc實現的,并發性能較低,springcloud gateway底層是通過基于netty的webflux實現的,并發性能比較好,因為比較適合高并發的網關。
一、依賴配置(pom文件配置)
配置property和dependencyManagement(用于聲明版本,給pom的子類直接引用)
<properties><!-- <spring-cloud.version>Greenwich.SR2</spring-cloud.version>--><spring-cloud.version>Hoxton.SR1</spring-cloud.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>0.9.0.RELEASE</version><type>pom</type><scope>import</scope></dependency><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>添加依賴
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId><exclusions><exclusion><groupId>com.google.guava</groupId><artifactId>guava</artifactId></exclusion></exclusions></dependency>二、yml文件以及property文件的配置
1、bootstrap.yml文件(啟動優先級最高)的配置
spring:application:#聲明服務名稱name: test-gateway-servicecloud:gateway:discovery:locator:#這里配置聲明是否使用springcloud gateway的服務注冊,false 代表不使用enabled: falsedefault-filters:#聲明默認的filter為Hystrix- name: Hystrixargs:name : default#聲明默認的回調接口fallbackUri: 'forward:/defaultFallback'#這里配置路由規則,可以通過配置文件配置,也可以通過寫代碼配置,#這里只展示通過配置文件配置的方式,往后展示通過代碼配置的方式routes:- id: test1-inside-router#這里指定命中path中的路徑的請求會跳轉到test1-service的微服務中uri: lb://test1-servicepredicates:- Path=/justTest/**filters:- StripPrefix=1- id: test2-inside-router- #這里指定命中path中的路徑的請求會跳轉到test2-service的微服務中uri: lb://test2-servicepredicates:- Path=/test/shop/**filters:#這里單獨聲明hystrix熔斷服務配置 hystrix:command:default:execution:isolation:strategy: SEMAPHOREthread:timeoutInMilliseconds: 4000至此,springboot集成springcloud gateway即完成
對于路由規則的配置,除了可以通過yml或者property文件配置之外,還可以通過代碼的形式,代碼的形式樣例代碼如下:
@Configuration @Log4j2 public class FilterConfigration {@Beanpublic RouteLocator testOutSideRoute(RouteLocatorBuilder builder) {return builder.routes().route(r ->r.path("/justTest/**").filters(f -> f.filters(new CommonAuthFilter())).uri("lb://test1-service")).build();}@Beanpublic RouteLocator shopOutSideRoute(RouteLocatorBuilder builder) {return builder.routes().route(r ->r.path("test/shop/**").filters(f -> f.filters(new CommonAuthFilter())).uri("lb://test2-service")).build();} }至此,網關已經可以跑起來,并路由到相應的接口,但是,網關的作用并不是僅限于此,還可以做鑒權、給修改、增加請求的參數等等(暫時先不說限流、熔斷的功能,后續會詳聊),如果想攔截請求,并做相應的修改或者做日志記錄等,springcloud gateway給我們開了口子,可以通過定義全局的filter或者自定義的filter來實現。
這里僅僅展示做簡單的認證并記錄請求的全局filter。
import com.alibaba.fastjson.JSON; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; 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.data.redis.core.RedisTemplate; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono;import java.util.HashMap; import java.util.List; import java.util.Map;@Component @Log4j2 public class AuthAndLogFilter implements GlobalFilter, Ordered {@Autowiredprivate RedisTemplate redisTemplate;@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest serverHttpRequest = exchange.getRequest();ServerHttpResponse serverHttpResponse = exchange.getResponse();log.info("==========網關收到請求:{}==========", serverHttpRequest.getPath());StringBuilder logBuilder = new StringBuilder();List<String> tokenList = serverHttpRequest.getHeaders().get("token");Map<String, Object> mapResult = new HashMap<>();String requestUrl = exchange.getRequest().getPath().toString();if (requestUrl.startsWith("/test/a/b/")) {log.info("白名單路徑,無需校驗token");} else {if (!CollectionUtils.isEmpty(tokenList)) {String token = tokenList.get(0);log.info("上送的token為:{}" , token);if (!redisTemplate.hasKey(token)) {log.info("登錄超時,需要重新登錄");mapResult.put("code", 500);mapResult.put("message", "登錄超時,請重新登錄");DataBuffer bodyDataBuffer = serverHttpResponse.bufferFactory().wrap(JSON.toJSONString(mapResult).getBytes());serverHttpResponse.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");return serverHttpResponse.writeWith(Mono.just(bodyDataBuffer));}} else {log.info("沒有上送token");mapResult.put("code", 500);mapResult.put("message", "登錄超時,請重新登錄");DataBuffer bodyDataBuffer = serverHttpResponse.bufferFactory().wrap(JSON.toJSONString(mapResult).getBytes());serverHttpResponse.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");return serverHttpResponse.writeWith(Mono.just(bodyDataBuffer));}}return chain.filter(exchange);}@Overridepublic int getOrder() {/*** Get the order value of this object.* Higher values are interpreted as lower priority. As a consequence,* the object with the lowest value has the highest priority (somewhat* analogous to Servlet {@code load-on-startup} values).* Same order values will result in arbitrary sort positions for the* affected objects.* 這個值越大,優先級越低,也就是加載的順序越往后*/return -20;} }到這里,gateway網關可以跑起來了,但是如果放到生產環境還元不行,主要是有兩個地方需要改進:
1)、路由規則都是寫死的,萬一又接口改動或者新增或者刪除,則需要停服,重新發布才能生效。
2)、這里沒有使用服務發現中間件,不適合微服務環境
針對問題1,可以使用基于分布式配置平臺,將路由規則配置到分布式配置中間件,要改路由規則,只需要修改分布式配置文件即可,無需重啟服務,或者通過開發api接口,實現代碼層級自動化動態修改路由規則。
針對問題2,可以使用springcloud gateway + nacos的組合來實現服務發現和分布式配置。
以上兩點,下一篇文章再做詳細在展開。
總結
以上是生活随笔為你收集整理的Springboot 集成Springcloud gateway的入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Linux中远程通过ip和端口号以及密
- 下一篇: Spring Cloud Gateway