springcloud-feign&gateway&config&bus
阿新 • • 發佈:2020-12-05
一 feign
集成了ribbon負載均衡功能,集成了hystrix熔斷器功能。支援請求壓縮1 使用feign替代resttemplate傳送rest請求
1)在consumer中匯入依賴openfeign 2)建立feign客戶端,面向介面程式設計,@feignclient註解,屬性賦值服務名;方法上寫方法請求對映。feign通過動態代理生成實現類 3) 控制層,注入Feign客戶端介面,面向介面程式設計呼叫方法實現遠端呼叫服務提供者的對應方法 4)啟動類使用 `@EnableFeignClients`註解開啟feign 接收路徑攜帶引數變數不能省略賦值,@PathVariable路徑變數、@RequestParam請求引數 int login(@RequestParam("s") String s); //這裡是引數變數用@RequestParam("s")註解,路徑變數則用@PathVariable("s") //可以傳遞普通引數,不能傳遞Java物件,Java物件只能轉換為json字串格式2負載均衡
# 修改服務地址輪詢策略,預設是輪詢,配置之後變隨機 # MaxAutoRetriesNextServer: 0 # 最大重試下一個服務次數(叢集的情況才會用到,一起來規律是1=2,2 2=2,4 3=4,4 4=4,6 5=6,6) user-provider: ribbon: #輪詢 NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule ConnectTimeout: 10000 # 連線超時時間,比如修改服務提供者的ip讓你連不上那你消費者肯定連線超時報錯 ReadTimeout:2000 # 資料讀取超時時間,這個是連上服務提供者,然後伺服器提供者程式執行超過2秒報錯 MaxAutoRetries: 1 # 最大重試次數(第一個服務),比如連上了,但讀取超時再重去嘗試讀取1次,控制器被訪問↓ MaxAutoRetriesNextServer: 0 # 最大重試下一個服務次數(叢集的情況才會用到,一起來規律在上↑) OkToRetryOnAllOperations: false # 無論是請求超時或者socket read timeout等情況都進行重試
3熔斷器
也就是發生故障不走動態代理生成的實現類,走自定義的介面實現類來降級 1)配置檔案開啟feign熔斷器支援feign: hystrix: enabled:2)熔斷降級類 實現介面:自定義方法體。注意實現類需加上@component註解,才能把物件交給spring容器。 也可以採用內部類方式 3)在介面@feignclient註解內給屬性fallback賦值來指定降級類true # 開啟Feign的熔斷功能
4feign壓縮yml配置
對請求和響應進行GZIP壓縮,以減少通訊過程中的效能損耗。 通過配置開啟請求與響應的壓縮功能compression:feign: compression: request: enabled: true # 開啟請求壓縮 response: enabled: true # 開啟響應壓縮也可對請求資料型別,及觸發壓縮上下限進行設定
5feign日誌級別配置類
普通日誌等級配置# com.ywj 包下的日誌級別都為Debug
logging:
level:
com.ywj: debug
feign日誌等級配置。除了使用配置類,也可以在啟動類內通過@bean注入給spring容器管理。
@Configuration//配置類註解! public class FeignConfig { /** * 日誌級別 * @return */ @Bean public Logger.Level feignLoggerLevel(){ return Logger.Level.FULL; } }
二 spring cloud gateway閘道器
核心:過濾,路由 同樣作為一個微服務,需註冊到eureka;工程pom檔案匯入閘道器依賴及eureka客戶端依賴;啟動類新增開啟發現客戶端註解;配置檔案,埠,應用名,eureka地址1路由配置
靜態路由--動態路由 區域性過濾器--全域性過濾器spring: cloud: gateway: routes: # id唯一標識,可自定義 - id: gate-service-route #路由服務地址 #靜態路由策略 # uri: http://localhost:18081 #動態,lb協議表示從Eureka註冊中心獲取服務請求地址,應該用服務名叢集訪問,會使用負載均衡訪問對應服務,負載均衡LoaderBalance uri: lb://user-provider #路由攔截地址配置(斷言) predicates: - Path=/** #注意首字母P要是大寫的,2個* # 配置區域性過濾器 filters: # 請求地址新增路徑字首過濾器 #- PrefixPath=/user # 去除路徑字首過濾器 - StripPrefix=1 - My # 配置全域性預設過濾器 default-filters: # 往響應過濾器中加入資訊 - AddResponseHeader=X-Response-Default-MyName,ywj注意:斷言,過濾器等關鍵字key首字母大寫。- Path=/** #注意首字母P要是大寫的,2個*
2自定義過濾器
1)全域性過濾器
package com.zl.filter; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @Component//這個不能少,建立物件才能呼叫下面的非靜態方法↓ public class LoginGlobalFilter implements GlobalFilter, Ordered { /** * 過濾攔截 * @param exchange * @param chain * @return */ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { //獲取請求引數 //千萬不要點錯用這個方法String token = request.getQueryParams().get("token").get(0);//NullPointerException,否則出現空指標異常 String token = exchange.getRequest().getQueryParams().getFirst("token"); System.out.println("通過全域性過濾器"); //如果token為空,則表示沒有登入 if(StringUtils.isEmpty(token)){ //沒登入,狀態設定413 exchange.getResponse().setStatusCode(HttpStatus.PAYLOAD_TOO_LARGE); //結束請求 return exchange.getResponse().setComplete(); } //放行 return chain.filter(exchange); } /** * 定義過濾器執行順序 * 返回值越小,越靠前執行,可以理解為預設從小到大執行 * @return */ @Override public int getOrder() { return 0; } }
2)區域性過濾器
自定義區域性攔截器,要注意自定義類的字首用在配置檔案,字尾必須是指定工廠字尾package com.zl.filter; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.util.MultiValueMap; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @Component public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.Config> { public MyGatewayFilterFactory() { super(MyGatewayFilterFactory.Config.class); } @Override public GatewayFilter apply(Config config) { return new GatewayFilter() { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println("通過區域性過濾器"); MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams(); String token = queryParams.getFirst("token"); ServerHttpResponse response = exchange.getResponse(); if (token == null) { return response.setComplete(); } return chain.filter(exchange); } }; } public static class Config { } }