2.11、 Feign應用
- 是對下面代碼的優化
springCloud-系統學習3- 建立微服務工程2 - 自動根據參數拼接http請求位址
2.11.1、 操作
效果
2.12、Feign負載均衡及熔斷
- Feign內建了ribbon配置項和Hystrix熔斷的Fallback配置項,可以使用Feign來配置他。
- 為了友善測試,我們将一切的ribbon配置項和Hystrix項全部注釋掉
springCloud-系統學習3- 建立微服務工程2 springCloud-系統學習3- 建立微服務工程2 springCloud-系統學習3- 建立微服務工程2 springCloud-系統學習3- 建立微服務工程2
2.12.1 Feign 負載均衡
2.12.2 Feign 服務熔斷
關閉user-service看效果
2.12.3、 請求壓縮
feign:
hystrix:
enabled: true # 開啟Feign的熔斷功能
compression:
request:
enabled: true # 開啟請求壓縮
mime-types: text/html,application/xml,application/json # 設定壓縮的資料類型
min-request-size: 2048 # 設定觸發壓縮的大小下限
response:
enabled: true # 開啟響應壓縮
2.12.4、 日志級别
01、Feign 的Level級别
- NONE:不記錄任何日志資訊,這是預設值。
- BASIC:僅記錄請求的方法,URL以及響應狀态碼和執行時間
- HEADERS:在BASIC的基礎上,額外記錄了請求和響應的頭資訊
- FULL:記錄所有請求和響應的明細,包括頭資訊、請求體、中繼資料。
02、測試結果
2.13、 Spring Cloud Gateway
- 基于Filter鍊提供網關基本功能:安全、監控、埋點、限流等。
- 為微服務架構提供簡單、有效且統一的API路由管理方式。
- 是替代Netflix Zuul的一套解決方案。
- 元件的核心是一系列的過濾器
- 通過這些過濾器可以将用戶端發送的請求轉發(路由)到對應的微服務。
-
是加在整個微服務最前沿的防火牆和代理器,隐藏微服務結點IP端口資訊,從
而加強安全保護。
- 本身也是一個微服務,需要注冊到Eureka服務注冊中心。
- 核心功能
- 過濾
- 路由
2.13.1、 架構
- 不管是來自于用戶端(PC或移動端)的請求,還是服務内部調用。一切對服務的請求都可經過網關,然後再由網關來實作鑒權、動态路由等等操作。
- Gateway就是我們服務的統一入口。
2.13.2、 概念
01、路由(route)
- 由一個ID、一個目的URL、一組斷言工廠、一組Filter組成。
- 如果路由斷言為真,說明請求URL和配置路由比對。
02、斷言(Predicate)
- Spring Cloud Gateway中的斷言函數輸入類型是Spring 5.0架構中的ServerWebExchange。
-
Spring Cloud Gateway的斷言函數允許開發者去定義比對來自于Http Request中的任何
資訊比如請求頭和參數。
03、過濾器(Filter)
- 一個标準的Spring WebFilter。
- Spring Cloud Gateway中的Filter分為兩種類型
- Gateway Filter
- Global Filter。
- 過濾器Filter将會對請求和響應進行修改處理。
2.14、搭建網關服務,實作以下功能
- 搭建gateway-demo
- 将包含有/user的請求路由到user-service服務中
2.14.1、操作
2.14.2、結果
2.14.3、問題
- 我們現在可以直接通過網關通路user-service服務,那麼consumer-demo已經沒用了,那還需要consumer-demo嗎?
- 個人了解consumer-demo已經沒有用了。
2.15、面向服務的路由
- 在剛才的路由規則中,把路徑對應的服務位址寫死了!如果同一服務有多個執行個體的話,這樣做顯然不合理。
- 應該根據服務的名稱,去Eureka注冊中心查找服務對應的所有執行個體清單,然後進行動态路由!
2.15.1、操作
- lb 之後編寫的服務名必須要在eureka中注冊才能使用
- 動态路由:lb user-service(服務名)
- gateway将使用 LoadBalancerClient把user-service通過eureka解析為實際的主機和端口,并進行ribbon負載均衡。
2.15.2、結果
- 啟動 user-service9091
- 啟動 user-service9092
- 啟動 gateway-demo
- 啟動 eureka-server
2.16、路由字首處理
- 可以對請求到網關服務的位址添加或去除字首
2.16.1、添加字首
- 對請求位址添加字首路徑之後再作為代理的服務位址
- http://127.0.0.1:10010/8 --> http://user-service/user/8
- 字首路徑/user
2.16.2、去除字首
- 将請求位址中路徑去除一些字首路徑之後再作為代理的服務位址
- http://127.0.0.1:10010/api/user/8 --> http://user-service/user/8
- 去除字首路徑/api
- 通過StripPrefix=n 來指定了路由要去掉的n個字首,案例
- StripPrefix=1
- http://localhost:10010/api/user/8 --》http://user-servic/user/8
- StripPrefix=2
- http://localhost:10010/api/user/8 --》http://user-servic/8
- StripPrefix=1
2.17、Gateway的過濾器
- 命名規則
- XXXXGatewayFilterFactory
2.17.1、Gateway常見自帶過濾器
- AddRequestHeader
- 對比對上的請求加上Header
- AddRequestParameters
- 對比對上的請求路由添加參數
- AddResponseHeader
- 對從網關傳回的響應添加Header
- StripPrefix
- 對比對上的請求路徑去除字首
2.17.2、過濾器類型
- 局部過濾器
- 通過 spring.cloud.gateway.routes.filters 配置在具體路由下
- 隻作用在目前路由上;
- 自帶的過濾器都可以配置或者自定義按照自帶過濾器的方式。
- 如果配置spring.cloud.gateway.default-filters上會對所有路由生效
- 算是全局的過濾器;
- 如果配置spring.cloud.gateway.default-filters上會對所有路由生效
- 實作上都要實作GatewayFilterFactory接口。
- 全局過濾器
- 不需要在配置檔案中配置
- 作用在所有的路由上
- 實作 GlobalFilter 接口即可。
2.17.3、執行生命周期
- Gateway的Filter的生命周期也類似Spring MVC的攔截器
- 有兩個:“pre"和"post”,分别會在請求被執行前和被執行後調用
- “pre"和"post”,可以通過過濾器的GatewayFilterChain執行filter方法前後來實作。
2.17.4、常見使用場景
- 請求鑒權:
- GatewayFilterChain 執行filter方法前,如果發現沒有通路權限,直接就傳回空。
- 異常處理:
- GatewayFilterChain執行filter方法後,記錄異常并傳回。
- 服務調用時長統計
- GatewayFilterChain執行filter方法前後根據時間統計。
2.17.5、配置全局預設過濾器
2.17.6、自定義局部過濾器
結果
package fei.zhou.gatewaydemo.filter;
import java.util.Arrays;
import java.util.List;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
@Component
public class MyParam11GatewayFilterFactory extends AbstractGatewayFilterFactory<MyParam11GatewayFilterFactory.Config> {
static final String PARAM_NAME = "param";
public MyParam11GatewayFilterFactory() {
super(Config.class);
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(PARAM_NAME);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
// http://localhost:10010/user/8?name=userId config.param ==> name
// 擷取請求參數中param對應的參數名 的參數值
ServerHttpRequest request = exchange.getRequest();
if (request.getQueryParams().containsKey(config.param)) {
request.getQueryParams().get(config.param).forEach(
value -> System.out.println("------------局部過濾器-------參數名字:" + config.param + "--參數值:" + value));
}
return chain.filter(exchange);
};
}
public static class Config {
// 對應在配置過濾器的時候指定的參數名
private String param;
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
}
}
2.17.7、 自定義全局過濾器
- 定義一個全局過濾器檢查請求中是否攜帶有token參數
- 是:通過
- 否:不通過,告訴用戶端401提示
package fei.zhou.gatewaydemo.filter;
import org.apache.commons.lang.StringUtils;
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.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class MyGlobal11Filter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("--------------全局過濾器MyGlobal11Filter------------------");
String token = exchange.getRequest().getQueryParams().getFirst("token");
if (StringUtils.isBlank(token)) {
// 設定響應狀态碼為未授權
// UNAUTHORIZED(401, "Unauthorized"),
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
// 值越小越先執行
return 1;
}
}
2.17.8、Gateway 負載均衡和熔斷
- Gateway中預設內建了Ribbon負載均衡和Hystrix熔斷機制。
- 所有的逾時政策都是走的預設值,比如熔斷逾時時間隻有1S,很容易就觸發了。是以建議手動進行配置:
hystrix:
command:
default:
execution:
isolation:
thread:
# 服務提供者的逾時時間,2秒,如果請求服務提供者超過2秒,就服務降級和線程隔離
timeoutInMilliseconds: 6000
ribbon:
ConnectTimeout: 1000 # 連接配接逾時時長
ReadTimeout: 2000 # 資料通信逾時時長
MaxAutoRetries: 0 # 目前伺服器的重試次數
MaxAutoRetriesNextServer: 0 # 重試多少次服務
OkToRetryOnAllOperations: false # 是否對所有的請求方式都重試
2.17.9、Gateway 跨域配置
- 一般網關都是所有微服務的統一入口,必然在被調用的時候會出現跨域問題。
- 可以在網關伺服器中通過配置解決,允許哪些服務是可以跨域請求的。
01、跨域概念
- 在js請求通路中,如果通路的位址與目前伺服器的域名、ip或者端口号不一緻則稱為跨域請求。
- http://localhost:8080中的js —通路—> http://localhost:9091的資料,因為端口不同,是跨域請求。
- 若不解決則不能擷取到對應位址的傳回結果。
02、解決跨域的配置
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
#allowedOrigins: * # 這種寫法或者下面的都可以,*表示全部
allowedOrigins:
- "http://docs.spring.io"
allowedMethods:
- GET
- 可以允許來自 http://docs.spring.io 的get請求方式擷取服務資料。
- allowedOrigins
- 指定允許通路的伺服器位址,如http://docs.spring.io。
- ‘[/**]’
- 表示對所有通路到網關伺服器的請求位址
2.17.10、 Gateway的高可用
- 啟動多個Gateway服務,自動注冊到Eureka,形成叢集。
- 服務内部通路
- 通路Gateway,自動負載均衡,沒問題。
- 外部通路(PC端、移動端…)
- 它們無法通過Eureka進行負載均衡,那麼該怎麼辦?,Gateway怎麼高可用?
- 可以使用Nginx來對Gateway進行代理
- 它們無法通過Eureka進行負載均衡,那麼該怎麼辦?,Gateway怎麼高可用?
- 服務内部通路
2.17.11、Gateway與Feign的差別
- Gateway
- 作為整個應用的流量入口,接收所有的請求,如PC、移動端等,并且将不同的請求轉發至不同的處理微服務子產品,其作用可視為nginx;
- 大部分情況下用作權限鑒定、服務端流量控制
- Feign
- 将目前微服務的部分服務接口暴露出來
- 主要用于各個微服務之間的服務調用
2.18、 Spring Cloud Config分布式配置中心
2.18.1、 分布式配置中心
- 支援配置檔案放在配置服務本地
- 也支援放在遠端Git倉庫(GitHub、碼雲)
- 項目從配置中心拉取配置
2.18.2、 架構
2.18.3、 搭建配置中心微服務
01、建立碼雲的遠端公開git倉庫:spring_cloud_config
02、将user-Service的配置檔案放到git倉庫中,命名為userService-dev.yml
- 配置檔案的2種命名方式
- {application}-{profile}.yml
- {application}-{profile}.properties
- 配置檔案說明
- application:為應用名稱
- profile:用于區分開發環境,測試環境、生産環境等
- 案例userService-dev.yml
- 微服務user-Service開發環境下使用的配置檔案
03、搭建配置中心微服務
結果
2.18.4、 擷取配置中心配置
- 改造使用者微服務user-service,配置檔案資訊不再由微服務項目提供,而是從配置中心擷取
01、 user-service 操作
- japplication.yml 備份為 application.yml.back
- 删除application.yml檔案
- 新增bootstrap.yml檔案
spring:
cloud:
config:
# 要與倉庫中的配置檔案的application保持一緻
name: userService
# 要與倉庫中的配置檔案的profile保持一緻
profile: dev
# git倉庫中的配置檔案所屬的分支
label: master
discovery:
# 使用配置中心
enabled: true
# 配置中心服務名
service-id: config-server
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
結果
2.19、 Spring Cloud Bus
- Spring Cloud Bus是用輕量的消息代理将分布式的節點連接配接起來,可以用于廣播配置檔案的更改或者服務的監控管理。
- 也就是消息總線可以為微服務做監控,也可以實作應用程式之間互相通信。
- Spring Cloud Bus可選的消息代理有RabbitMQ和Kafka。
2.19.1、 原先的配置中心修改了配置,不能及時同步到各個微服務
01、git 添加屬性
02、user-service 設定列印屬性
03、重新開機user-service 後,請求資料有傳回
04、修改git屬性,不重新開機user-service
2.19.2、 git倉庫的配置檔案更新,在不重新開機系統的情況下實作及時同步到各個微服務
01、 架構
02、 config-server配置操作
03、 user-service配置操作
04、更新配置
05、釋出MQ通知
http://127.0.0.1:12000/actuator/bus-refresh
映射的配置
# 暴露觸發消息總線的位址
include: bus-refresh
06、檢視結果(有實時更新)
代碼位址
https://gitee.com/DanShenGuiZu/spring_cloud_config.git