基於Alibaba Nacos和Sentinel,實現灰度路由和流量防禦一體化的解決方案,發佈在最新的 Nepxion Discovery 5.4.0 版,具體參考:git
源碼主頁,請訪問 源碼主頁
指南主頁,請訪問 指南主頁
文檔主頁,請訪問 文檔主頁github
Nepxion Discovery框架在實現灰度發佈和路由功能前提下,結合Nacos和Sentinel,對流量再實施一層防禦措施,更能達到企業級的流量安全控制的目的。它的功能包括:spring
[Nacos] 阿里巴巴中間件部門開發的新一代集服務註冊發現中心和配置中心爲一體的中間件。它是構建以「服務」爲中心的現代應用架構 (例如微服務範式、雲原生範式) 的服務基礎設施,支持幾乎全部主流類型的「服務」的發現、配置和管理,更敏捷和容易地構建、交付和管理微服務平臺數組
[Sentinel] 阿里巴巴中間件部門開發的新一代以流量爲切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性的分佈式系統的流量防衛兵。它承接了阿里巴巴近10年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量能夠承受的範圍)、消息削峯填谷、集羣流量控制、實時熔斷下游不可用應用等安全
服務端在Discovery框架原有依賴的基礎上,再引入以下依賴架構
<dependency> <groupId>com.nepxion</groupId> <artifactId>discovery-plugin-strategy-starter-service-sentinel</artifactId> <version>${discovery.version}</version> </dependency> <dependency> <groupId>com.nepxion</groupId> <artifactId>discovery-plugin-strategy-sentinel-starter-nacos</artifactId> <!-- <artifactId>discovery-plugin-strategy-sentinel-starter-apollo</artifactId> --> <version>${discovery.version}</version> </dependency>
參照下面代碼,爲接口方法增長@SentinelResource註解,value爲sentinel-resource,blockHandler和fallback是防禦其做用後須要執行的方法app
@RestController @ConditionalOnProperty(name = DiscoveryConstant.SPRING_APPLICATION_NAME, havingValue = "discovery-guide-service-b") public class BFeignImpl extends AbstractFeignImpl implements BFeign { private static final Logger LOG = LoggerFactory.getLogger(BFeignImpl.class); @Override @SentinelResource(value = "sentinel-resource", blockHandler = "handleBlock", fallback = "handleFallback") public String invoke(@PathVariable(value = "value") String value) { value = doInvoke(value); LOG.info("調用路徑:{}", value); return value; } public String handleBlock(String value, BlockException e) { return value + "-> B server sentinel block, cause=" + e.getClass().getName() + ", rule=" + e.getRule() + ", limitApp=" + e.getRuleLimitApp(); } public String handleFallback(String value) { return value + "-> B server sentinel fallback"; } }
Sentinel在配置中心訂閱的Key格式,以下:負載均衡
1\. Nacos的Key格式:Group爲元數據中配置的[組名],Data Id爲[服務名]-[規則類型] 2\. Apollo的Key格式:[組名]-[服務名]-[規則類型]
Sentinel規則的用法,請參照Sentinel官方文檔框架
增長服務discovery-guide-service-b的規則,Group爲discovery-guide-group,Data Id爲discovery-guide-service-b-sentinel-flow,規則內容以下:分佈式
[ { "resource": "sentinel-resource", "limitApp": "default", "grade": 1, "count": 1, "strategy": 0, "refResource": null, "controlBehavior": 0, "warmUpPeriodSec": 10, "maxQueueingTimeMs": 500, "clusterMode": false, "clusterConfig": null } ]
如圖所示
增長服務discovery-guide-service-b的規則,Group爲discovery-guide-group,Data Id爲discovery-guide-service-b-sentinel-degrade,規則內容以下:
[ { "resource": "sentinel-resource", "limitApp": "default", "count": 2, "timeWindow": 10, "grade": 0, "passCount": 0 } ]
如圖所示
增長服務discovery-guide-service-b的規則,Group爲discovery-guide-group,Data Id爲discovery-guide-service-b-sentinel-authority,規則內容以下:
[ { "resource": "sentinel-resource", "limitApp": "discovery-guide-service-a", "strategy": 0 } ]
如圖所示
增長服務discovery-guide-service-b的規則,Group爲discovery-guide-group,Data Id爲discovery-guide-service-b-sentinel-system,規則內容以下:
[ { "resource": null, "limitApp": null, "highestSystemLoad": -1.0, "highestCpuUsage": -1.0, "qps": 200.0, "avgRt": -1, "maxThread": -1 } ]
如圖所示
增長服務discovery-guide-service-b的規則,Group爲discovery-guide-group,Data Id爲discovery-guide-service-b-sentinel-param-flow,規則內容以下:
[ { "resource": "sentinel-resource", "limitApp": "default", "grade": 1, "paramIdx": 0, "count": 1, "controlBehavior": 0, "maxQueueingTimeMs": 0, "burstCount": 0, "durationInSec": 1, "paramFlowItemList": [], "clusterMode": false } ]
如圖所示
該方式對於上面5種規則都有效,這裏以受權規則展開闡述
受權規則中,limitApp,若是有多個,能夠經過「,」分隔。"strategy": 0 表示白名單,"strategy": 1 表示黑名單
修改配置項Sentinel Request Origin Key爲服務名的Header名稱,修改受權規則中limitApp爲對應的服務名,可實現基於服務名的防禦機制
配置項,該配置項默認爲n-d-service-id,能夠不配置
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-id
增長服務discovery-guide-service-b的規則,Group爲discovery-guide-group,Data Id爲discovery-guide-service-b-sentinel-authority,規則內容以下,表示全部discovery-guide-service-a服務容許訪問discovery-guide-service-b服務
[ { "resource": "sentinel-resource", "limitApp": "discovery-guide-service-a", "strategy": 0 } ]
修改配置項Sentinel Request Origin Key爲灰度組的Header名稱,修改受權規則中limitApp爲對應的組名,可實現基於組名的防禦機制
配置項
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-group
增長服務discovery-guide-service-b的規則,Group爲discovery-guide-group,Data Id爲discovery-guide-service-b-sentinel-authority,規則內容以下,表示隸屬my-group組的全部服務都容許訪問服務discovery-guide-service-b
[ { "resource": "sentinel-resource", "limitApp": "my-group", "strategy": 0 } ]
修改配置項Sentinel Request Origin Key爲灰度版本的Header名稱,修改受權規則中limitApp爲對應的版本,可實現基於版本的防禦機制
配置項
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-version
增長服務discovery-guide-service-b的規則,Group爲discovery-guide-group,Data Id爲discovery-guide-service-b-sentinel-authority,規則內容以下,表示版本爲1.0的全部服務都容許訪問服務discovery-guide-service-b
[ { "resource": "sentinel-resource", "limitApp": "1.0", "strategy": 0 } ]
修改配置項Sentinel Request Origin Key爲灰度區域的Header名稱,修改受權規則中limitApp爲對應的區域,可實現基於區域的防禦機制
配置項
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-region
增長服務discovery-guide-service-b的規則,Group爲discovery-guide-group,Data Id爲discovery-guide-service-b-sentinel-authority,規則內容以下,表示區域爲dev的全部服務都容許訪問服務discovery-guide-service-b
[ { "resource": "sentinel-resource", "limitApp": "dev", "strategy": 0 } ]
修改配置項Sentinel Request Origin Key爲灰度區域的Header名稱,修改受權規則中limitApp爲對應的區域值,可實現基於機器地址和端口的防禦機制
配置項
spring.application.strategy.service.sentinel.request.origin.key=n-d-service-address
增長服務discovery-guide-service-b的規則,Group爲discovery-guide-group,Data Id爲discovery-guide-service-b-sentinel-authority,規則內容以下,表示地址和端口爲192.168.0.88:8081和192.168.0.88:8082的服務都容許訪問服務discovery-guide-service-b
[ { "resource": "sentinel-resource", "limitApp": "192.168.0.88:8081,192.168.0.88:8082", "strategy": 0 } ]
經過適配類實現自定義業務參數的組合式防禦機制
// 版本號+用戶名,實現組合式熔斷 public class MyServiceSentinelRequestOriginAdapter extends DefaultServiceSentinelRequestOriginAdapter { @Override public String parseOrigin(HttpServletRequest request) { String version = request.getHeader(DiscoveryConstant.N_D_SERVICE_VERSION); String user = request.getHeader("user"); return version + "&" + user; } }
在配置類裏@Bean方式進行適配類建立
@Bean public ServiceSentinelRequestOriginAdapter ServiceSentinelRequestOriginAdapter() { return new MyServiceSentinelRequestOriginAdapter(); }
增長服務discovery-guide-service-b的規則,Group爲discovery-guide-group,Data Id爲discovery-guide-service-b-sentinel-authority,規則內容以下,表示版本爲1.0且傳入的Http Header的user=zhangsan,同時知足這兩個條件下的全部服務都容許訪問服務discovery-guide-service-b
[ { "resource": "sentinel-resource", "limitApp": "1.0&zhangsan", "strategy": 0 } ]
運行效果
如圖所示
如圖所示
如圖所示
分爲基於單個服務實例和基於服務名對應的多個服務實例的Sentinel規則推送
直接訪問該服務實例的Swagger主頁便可
如圖所示
須要開啓discovery-console服務,並訪問其Swagger主頁便可
如圖所示
做者介紹:任浩軍, 10 多年開源經歷,Github ID:@HaojunRen,Nepxion 開源社區創始人,Nacos Group Member,Spring Cloud Alibaba & Nacos & Sentinel Committer ,曾就任於平安銀行平臺架構部,負責銀行 PaaS 系統基礎服務框架研發。
王偉華, 10 餘年 Java 開發,Github ID:@vipweihua,對微服務架構研究多年,當前更多關注於微服務中的網關、限流熔斷、灰度路由等,現就任於平安銀行平臺架構部,從事銀行 PaaS 系統基礎服務框架研發。
阿里雲雙11領億元補貼,拼手氣抽iPhone 11 Pro、衛衣等好禮,點此參與:http://t.cn/Ai1hLLJT
本文做者:任浩軍
本文爲雲棲社區原創內容,未經容許不得轉載。