<!-- nacos設定--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>2.2.6.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.2.6.RELEASE</version> </dependency> <!-- sentinel設定--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2.2.6.RELEASE</version> </dependency> <!-- sentinel 規則基於nacos儲存--> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> <version>1.8.3</version> </dependency>
server:
servlet:
context-path: /sentinel-nacos-demo
spring:
application:
name: sentinel-nacos-demo
profiles:
active: local
cloud:
nacos:
config:
server-addr: xxx.xxx.xx.x:8848
#server-addr: xxx.xxx.xx.x:8848
group: ${spring.application.name}
file-extension: yaml
# 設定中心使用單獨namespace
namespace: "study"
discovery:
server-addr: xxx.xxx.xx.x:8848
namespace: "study"
group: "sentinel-nocas-demo"
sentinel:
transport:
dashboard: xxx.xxx.xx.x:8842 #啟動本專案後需要請求一次才能向sentinel控制檯註冊
port: 8719 #當一個伺服器部署多個應用時要設定不同port,單個應用可忽略
client-ip: 10.32.4.230 #指定本機ip地址,避免多個虛擬地址,導致資料獲取失敗
datasource:
## 設定流程控制
## rule-type 設定表示該資料來源中的規則屬於哪種型別的規則(flow流控,degrade熔斷降級,authority授權,system系統保護, param-flow熱點引數限流, gw-flow, gw-api-group)
flow:
nacos:
server-addr: xxx.xxx.xx.x:8848
namespace: "study"
data-id: ${spring.application.name}-sentinel-flow-rules
group-id: sentinel-group
data-type: json
rule-type: flow
## 設定降級規則
degrade:
nacos:
server-addr: xxx.xxx.xx.x:8848
namespace: "study"
dataId: ${spring.application.name}-sentinel-degrade-rules
groupId: sentinel-group
data-type: json
rule-type: degrade
system:
nacos:
server-addr: xxx.xxx.xx.x:8848
namespace: "study"
dataId: ${spring.application.name}-sentinel-system-rules
groupId: sentinel-group
data-type: json
rule-type: system
[ { "resource": "/sentinel/rule/flow", "limitApp": "default", "grade": 1, "count": 1, "strategy": 0, "controlBehavior": 0, "clusterMode": false } ]
[ { "resource": "/sentinel/rule/degrade", "count": 1, "grade": 0, "timeWindow": 10, "minRequestAmount": 1, "statIntervalMs": 1000, "slowRatioThreshold": 0.1 } ]
[ { "avgRt":1, "highestCpuUsage":-1, "highestSystemLoad":-1, "maxThread":-1, "qps":1000 } ]
@Component public static class MyBlockExceptionHandler implements BlockExceptionHandler { @Override public void handle(HttpServletRequest httpServletRequest, HttpServletResponse response, BlockException e) throws Exception { //Sentinel規則的詳細資訊 BaseResponse r = BaseResponse.error("sentinel-控制攔截"); if (e instanceof FlowException) { r = BaseResponse.error("介面限流了",e.toString()); } else if (e instanceof DegradeException) { r = BaseResponse.error( "服務降級了",e.toString()); } else if (e instanceof ParamFlowException) { r = BaseResponse.error("熱點引數限流了",e.toString()); } else if (e instanceof SystemBlockException) { r = BaseResponse.error( "觸發系統保護規則了",e.toString()); } else if (e instanceof AuthorityException) { r = BaseResponse.error( "授權規則不通過",e.toString()); } //返回json資料 response.setStatus(500); response.setCharacterEncoding("utf-8"); response.setContentType(MediaType.APPLICATION_JSON_VALUE); new ObjectMapper().writeValue(response.getWriter(), r); } }
sentinel: transport: dashboard: xxx.168.16.13:8842 #啟動本專案後需要請求一次才能向sentinel控制檯註冊 port: 8719 #當一個伺服器部署多個應用時要設定不同port,單個應用可忽略 client-ip: xx.xx.4.230 #指定本機ip地址,避免多個虛擬地址,導致資料獲取失敗
ProcessorSlot
作為 SPI 介面進行擴,使得 Slot Chain 具備了擴充套件的能力。開發人員可以自行加入自定義的 slot 並編排 slot 間的執行順序,從而可以給 Sentinel 新增自定義的功能。1.定義實現類載入順序 @Spi(isSingleton = false, order = Constants.ORDER_NODE_SELECTOR_SLOT) 2.定義NodeSelectorSlot實現類繼承自抽象類 public class NodeSelectorSlot extends AbstractLinkedProcessorSlot<Object> 3.定義抽象類實現介面 public abstract class AbstractLinkedProcessorSlot<T> implements ProcessorSlot<T> 4.定義鏈路頂層介面 public interface ProcessorSlot<T>
ProcessorSlot
介面,是不能加入到責任鏈路中的。參考原始碼:public class DefaultSlotChainBuilder implements SlotChainBuilder { @Override public ProcessorSlotChain build() { ProcessorSlotChain chain = new DefaultProcessorSlotChain(); List<ProcessorSlot> sortedSlotList = SpiLoader.of(ProcessorSlot.class).loadInstanceListSorted(); for (ProcessorSlot slot : sortedSlotList) { if (!(slot instanceof AbstractLinkedProcessorSlot)) { RecordLog.warn("The ProcessorSlot(" + slot.getClass().getCanonicalName() + ") is not an instance of AbstractLinkedProcessorSlot, can't be added into ProcessorSlotChain"); continue; } chain.addLast((AbstractLinkedProcessorSlot<?>) slot); } return chain; } }
public abstract class ProcessorSlotChain extends AbstractLinkedProcessorSlot<Object> { /** * Add a processor to the head of this slot chain. * * @param protocolProcessor processor to be added. */ public abstract void addFirst(AbstractLinkedProcessorSlot<?> protocolProcessor); /** * Add a processor to the tail of this slot chain. * * @param protocolProcessor processor to be added. */ public abstract void addLast(AbstractLinkedProcessorSlot<?> protocolProcessor); }
/** * 編寫一個自定義限流鏈路 * * @author wangling * @date 2022/07/05 */ @Spi(order = -3000) public class TestMySlot extends AbstractLinkedProcessorSlot<DefaultNode> { @Override public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode obj, int count, boolean prioritized, Object... args) throws Throwable { try { fireEntry(context, resourceWrapper, obj, count, prioritized, args); throw new BusinessException("TestMySlot-測試"); } catch (Exception e) { throw e; } catch (Throwable e) { RecordLog.warn("Unexpected entry exception", e); } } @Override public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) { try { fireExit(context, resourceWrapper, count, args); } catch (Throwable e) { RecordLog.warn("Unexpected entry exit exception", e); } } }
微信讚賞
支付寶讚賞