sentinel 熔断降级
sentinel 熔斷降級
????????????
官網:https://sentinelguard.io/zh-cn/docs/circuit-breaking.html
?????????????
???????????????????
???????????????????????????????????
熔斷降級
???????????
熔斷降級:服務由于響應慢、異常等原因觸發熔斷策略后,快速失敗,避免線程堆積造成服務雪崩(熔斷降級通常在調用端配置)
?????????????????
???????????
熔斷策略
# 慢調用比例:SLOW_REQUEST_RATIO,以慢調用比例作為閾值 慢調用:如果一個請求的響應時間需要大于設置的慢調用響應時間(RT),該請求統計為慢調用; 熔斷觸發:單位統計時長(statIntervalMs)內請求數目大于設置的最小請求數目,并且慢調用的比例大于閾值,在熔斷時長內自動觸發熔斷(調用方法時,拋出DegradeException) 熔斷恢復:在熔斷時長后,熔斷器進入探測恢復狀態(half-open狀態),如果接下來的請求響應時間 < 設置的慢調用響應時間,則結束熔斷如果接下來的請求響應時間 > 設置的慢調用響應時間,則繼續在熔斷時長內保持熔斷# 異常比例 :ERROR_RATIO,以請求異常比例作為閥值,閾值范圍是[0.0, 1.0] 異常請求:請求調用拋出異常,則該請求統計為異常請求 熔斷觸發:單位統計時長(statIntervalMs)內請求數目 > 設置的最小請求數目,并且異常的比例 > 閾值,在熔斷時長內自動被熔斷 熔斷恢復:在熔斷時長后,熔斷器進入探測恢復狀態(HALF-OPEN 狀態),如果接下來的一個請求執行成功,則結束熔斷;如果請求執行失敗,則繼續在熔斷時長內保持熔斷# 異常數:ERROR_COUNT,以異常請求數作為閥值 異常請求:請求調用拋出異常,則該請求統計為異常請求 熔斷觸發:單位統計時長(statIntervalMs)內請求數目 > 設置的最小請求數目,并且異常請求 > 設置的異常請求數閥值,在熔斷時長內自動被熔斷 熔斷恢復:在熔斷時長后,熔斷器進入探測恢復狀態(HALF-OPEN 狀態),如果接下來的一個請求執行成功,則結束熔斷;如果請求執行失敗,則繼續在熔斷時長內保持熔斷????????????
DegradeRule:熔斷降級規則
public class DegradeRule extends AbstractRule {private int grade = 0; //熔斷策略,支持慢調用比例(默認)、異常比例、異常數策略private double count; //限流閥值private int timeWindow; //熔斷時間窗口,單位為秒private int minRequestAmount = 5; //最小請求數private double slowRatioThreshold = 1.0D; //慢調用比例閾值private int statIntervalMs = 1000; //統計時間窗口,默認1spublic DegradeRule() {}????????????
AbstractRule
public abstract class AbstractRule implements Rule {private String resource; //限流資源private String limitApp; //調用來源、default、otherpublic AbstractRule() {}????????????
??????????????????
???????????????????????????????????
實現原理
??????
DegradeSlot
@SpiOrder(-1000) public class DegradeSlot extends AbstractLinkedProcessorSlot<DefaultNode> {public DegradeSlot() {}public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count, boolean prioritized, Object... args) throws Throwable {this.performChecking(context, resourceWrapper); //檢查熔斷規則,如果觸發熔斷,直接拋出DegradeException異常this.fireEntry(context, resourceWrapper, node, count, prioritized, args);//追星后續限流操作}void performChecking(Context context, ResourceWrapper r) throws BlockException {List<CircuitBreaker> circuitBreakers = DegradeRuleManager.getCircuitBreakers(r.getName()); //獲取資源相關的斷路器if (circuitBreakers != null && !circuitBreakers.isEmpty()) {Iterator var4 = circuitBreakers.iterator();CircuitBreaker cb;do {if (!var4.hasNext()) {return;}cb = (CircuitBreaker)var4.next();} while(cb.tryPass(context)); //熔斷窗口到期,檢查單詞請求是否可以通過throw new DegradeException(cb.getRule().getLimitApp(), cb.getRule());//熔斷檢查未通過,拋出DegradeException異常}}public void exit(Context context, ResourceWrapper r, int count, Object... args) {Entry curEntry = context.getCurEntry();if (curEntry.getBlockError() != null) {this.fireExit(context, r, count, args);} else {List<CircuitBreaker> circuitBreakers = DegradeRuleManager.getCircuitBreakers(r.getName());if (circuitBreakers != null && !circuitBreakers.isEmpty()) {if (curEntry.getBlockError() == null) {Iterator var7 = circuitBreakers.iterator();while(var7.hasNext()) {CircuitBreaker circuitBreaker = (CircuitBreaker)var7.next();circuitBreaker.onRequestComplete(context);}}this.fireExit(context, r, count, args);} else {this.fireExit(context, r, count, args);}}} }????????????????
CircuitBreaker
public interface CircuitBreaker {DegradeRule getRule();boolean tryPass(Context var1);CircuitBreaker.State currentState();void onRequestComplete(Context var1);public static enum State {OPEN,HALF_OPEN,CLOSED;private State() {}} }??????????
AbstractCircuitBreaker
public abstract class AbstractCircuitBreaker implements CircuitBreaker {protected final DegradeRule rule;protected final int recoveryTimeoutMs;private final EventObserverRegistry observerRegistry;protected final AtomicReference<State> currentState;protected volatile long nextRetryTimestamp;public AbstractCircuitBreaker(DegradeRule rule) {this(rule, EventObserverRegistry.getInstance());}AbstractCircuitBreaker(DegradeRule rule, EventObserverRegistry observerRegistry) {this.currentState = new AtomicReference(State.CLOSED);AssertUtil.notNull(observerRegistry, "observerRegistry cannot be null");if (!DegradeRuleManager.isValidRule(rule)) {throw new IllegalArgumentException("Invalid DegradeRule: " + rule);} else {this.observerRegistry = observerRegistry;this.rule = rule;this.recoveryTimeoutMs = rule.getTimeWindow() * 1000;}}public DegradeRule getRule() {return this.rule;}public State currentState() {return (State)this.currentState.get();}public boolean tryPass(Context context) { //熔斷檢查if (this.currentState.get() == State.CLOSED) { //斷路器為closed,返回truereturn true;} else if (this.currentState.get() != State.OPEN) { //斷路器狀態不為open,返回falsereturn false;} else {return this.retryTimeoutArrived() && this.fromOpenToHalfOpen(context);} //判斷是否是請求重試時間,如果不是,直接返回false//如果是,斷路器狀態設置為HalfOpen,異步執行單次請求,//如果單次請求不通過,斷路器狀態切換為open,//如果單次請求通過,返回true,可執行后續限流操作}abstract void resetStat();protected boolean retryTimeoutArrived() {return TimeUtil.currentTimeMillis() >= this.nextRetryTimestamp;} //判斷是否為請求重試時間protected void updateNextRetryTimestamp() {this.nextRetryTimestamp = TimeUtil.currentTimeMillis() + (long)this.recoveryTimeoutMs;} //下次重試時間:當前時間 + recoveryTimeoutMs(即rule.getTimeWindow() * 1000)protected boolean fromCloseToOpen(double snapshotValue) {State prev = State.CLOSED;if (this.currentState.compareAndSet(prev, State.OPEN)) {this.updateNextRetryTimestamp();this.notifyObservers(prev, State.OPEN, snapshotValue);return true;} else {return false;}}protected boolean fromOpenToHalfOpen(Context context) {if (this.currentState.compareAndSet(State.OPEN, State.HALF_OPEN)) {//使用cas將斷路器狀態設置為HALF_OPENthis.notifyObservers(State.OPEN, State.HALF_OPEN, (Double)null);Entry entry = context.getCurEntry();entry.whenTerminate(new BiConsumer<Context, Entry>() {public void accept(Context context, Entry entry) {if (entry.getBlockError() != null) {//請求出現異常,狀態設置為openAbstractCircuitBreaker.this.currentState.compareAndSet(State.HALF_OPEN, State.OPEN);AbstractCircuitBreaker.this.notifyObservers(State.HALF_OPEN, State.OPEN, 1.0D);}}});return true; //如果沒有異常,返回true} else {return false;}}private void notifyObservers(State prevState, State newState, Double snapshotValue) {Iterator var4 = this.observerRegistry.getStateChangeObservers().iterator();while(var4.hasNext()) {CircuitBreakerStateChangeObserver observer = (CircuitBreakerStateChangeObserver)var4.next();observer.onStateChange(prevState, newState, this.rule, snapshotValue);}}protected boolean fromHalfOpenToOpen(double snapshotValue) {if (this.currentState.compareAndSet(State.HALF_OPEN, State.OPEN)) {this.updateNextRetryTimestamp();this.notifyObservers(State.HALF_OPEN, State.OPEN, snapshotValue);return true;} else {return false;}}protected boolean fromHalfOpenToClose() {if (this.currentState.compareAndSet(State.HALF_OPEN, State.CLOSED)) {this.resetStat();this.notifyObservers(State.HALF_OPEN, State.CLOSED, (Double)null);return true;} else {return false;}}protected void transformToOpen(double triggerValue) {State cs = (State)this.currentState.get();switch(cs) {case CLOSED:this.fromCloseToOpen(triggerValue);break;case HALF_OPEN:this.fromHalfOpenToOpen(triggerValue);}} }?????????????
????????????????????
???????????????????????????????????
使用示例
????
**********
服務端
??????
???????????????????????
???????
application.yml
spring:application:name: nacos-providercloud:nacos:discovery:server-addr: localhost:8848dubbo:#registry:# address: spring-cloud://localhost:8848protocol:name: dubboport: -1???????
HelloService
public interface HelloService {String hello(); }???????
HelloServiceImpl
@DubboService public class HelloServiceImpl implements HelloService {@Overridepublic String hello() {throw new RpcException("出錯了");} }??????????
DemoApplication
@EnableDubbo //開啟dubbo @SpringBootApplication public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}}???????????
**********
消費端
???
???????????????????????
?????????????
application.yml
spring:application:name: nacos-providercloud:nacos:discovery:server-addr: localhost:8848dubbo:#registry:# address: spring-cloud://localhost:8848protocol:name: dubboport: -1????????
CustomDegradeRule
public class CustomDegradeRule implements InitFunc {@Overridepublic void init() throws Exception {DegradeRule degradeRule = new DegradeRule("com.example.demo.service.HelloService:hello()");degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT).setCount(1).setMinRequestAmount(5).setTimeWindow(10);DegradeRuleManager.loadRules(Collections.singletonList(degradeRule));} }???????????
HelloService
public interface HelloService {String hello(); }?????????
HelloController
@RestController public class HelloController {@DubboReference//@DubboReference(mock = "true")private HelloService helloService;@RequestMapping("/hello")public String hello(){System.out.println(helloService.hello());return "success";} }?????????????
DemoApplication
@EnableDubbo @SpringBootApplication public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}}?????????
META-INF/services/com.alibaba.csp.sentinel.init.InitFunc
com.example.demo.config.CustomDegradeRule??????????????
**********
jmeter 測試
??
線程組、http請求
?????????????????
?????????????????
?????????
查看結果樹
?????????????????
2022-04-06 17:08:19.155 WARN 4870 --- [client.listener] a.c.d.m.r.DubboServiceMetadataRepository : Current application will subscribe all services(size:2) in registry, a lot of memory and CPU cycles may be used, thus it's strongly recommend you using the externalized property 'dubbo.cloud.subscribed-services' to specify the services 2022-04-06 17:08:21.411 INFO 4870 --- [erverWorker-4-1] o.a.d.r.t.netty4.NettyServerHandler : [DUBBO] The connection of /192.168.5.9:54897 -> /192.168.5.9:20881 is established., dubbo version: 2.7.8, current host: 192.168.5.9 2022-04-06 17:08:23.509 INFO 4870 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2022-04-06 17:08:23.509 INFO 4870 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2022-04-06 17:08:23.523 INFO 4870 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 13 ms 2022-04-06 17:08:23.550 ERROR 4870 --- [nio-8081-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.dubbo.rpc.RpcException: 出錯了] with root causeorg.apache.dubbo.rpc.RpcException: 出錯了at com.example.demo.service.impl.HelloServiceImpl.hello(HelloServiceImpl.java:12) ~[na:na]at org.apache.dubbo.common.bytecode.Wrapper3.invokeMethod(Wrapper3.java) ~[na:na]at org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:47) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:84) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:56) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:52) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboProviderFilter.invoke(SentinelDubboProviderFilter.java:80) ~[sentinel-apache-dubbo-adapter-1.8.0.jar:na]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:89) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:46) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:77) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:129) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:152) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:41) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:145) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:100) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:175) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57) ~[dubbo-2.7.8.jar:2.7.8]at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_211]at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_211]at java.lang.Thread.run(Thread.java:748) [na:1.8.0_211]2022-04-06 17:08:23.591 ERROR 4870 --- [nio-8081-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.dubbo.rpc.RpcException: 出錯了] with root causeorg.apache.dubbo.rpc.RpcException: 出錯了at com.example.demo.service.impl.HelloServiceImpl.hello(HelloServiceImpl.java:12) ~[na:na]at org.apache.dubbo.common.bytecode.Wrapper3.invokeMethod(Wrapper3.java) ~[na:na]at org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:47) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:84) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:56) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:52) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboProviderFilter.invoke(SentinelDubboProviderFilter.java:80) ~[sentinel-apache-dubbo-adapter-1.8.0.jar:na]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:89) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:46) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:77) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:129) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:152) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:41) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:145) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:100) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:175) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57) ~[dubbo-2.7.8.jar:2.7.8]at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_211]at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_211]at java.lang.Thread.run(Thread.java:748) [na:1.8.0_211]2022-04-06 17:08:23.602 ERROR 4870 --- [nio-8081-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.dubbo.rpc.RpcException: 出錯了] with root causeorg.apache.dubbo.rpc.RpcException: 出錯了at com.example.demo.service.impl.HelloServiceImpl.hello(HelloServiceImpl.java:12) ~[na:na]at org.apache.dubbo.common.bytecode.Wrapper3.invokeMethod(Wrapper3.java) ~[na:na]at org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:47) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:84) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:56) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:52) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboProviderFilter.invoke(SentinelDubboProviderFilter.java:80) ~[sentinel-apache-dubbo-adapter-1.8.0.jar:na]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:89) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:46) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:77) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:129) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:152) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:41) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:145) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:100) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:175) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57) ~[dubbo-2.7.8.jar:2.7.8]at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_211]at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_211]at java.lang.Thread.run(Thread.java:748) [na:1.8.0_211]2022-04-06 17:08:23.610 ERROR 4870 --- [nio-8081-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.dubbo.rpc.RpcException: 出錯了] with root causeorg.apache.dubbo.rpc.RpcException: 出錯了at com.example.demo.service.impl.HelloServiceImpl.hello(HelloServiceImpl.java:12) ~[na:na]at org.apache.dubbo.common.bytecode.Wrapper3.invokeMethod(Wrapper3.java) ~[na:na]at org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:47) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:84) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:56) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:52) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboProviderFilter.invoke(SentinelDubboProviderFilter.java:80) ~[sentinel-apache-dubbo-adapter-1.8.0.jar:na]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:89) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:46) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:77) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:129) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:152) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:41) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:145) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:100) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:175) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57) ~[dubbo-2.7.8.jar:2.7.8]at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_211]at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_211]at java.lang.Thread.run(Thread.java:748) [na:1.8.0_211]2022-04-06 17:08:23.618 ERROR 4870 --- [nio-8081-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.apache.dubbo.rpc.RpcException: 出錯了] with root causeorg.apache.dubbo.rpc.RpcException: 出錯了at com.example.demo.service.impl.HelloServiceImpl.hello(HelloServiceImpl.java:12) ~[na:na]at org.apache.dubbo.common.bytecode.Wrapper3.invokeMethod(Wrapper3.java) ~[na:na]at org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:47) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:84) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:56) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:52) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboProviderFilter.invoke(SentinelDubboProviderFilter.java:80) ~[sentinel-apache-dubbo-adapter-1.8.0.jar:na]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:89) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:46) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:77) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:129) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:152) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:41) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:83) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:145) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:100) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:175) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51) ~[dubbo-2.7.8.jar:2.7.8]at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57) ~[dubbo-2.7.8.jar:2.7.8]at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_211]at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_211]at java.lang.Thread.run(Thread.java:748) [na:1.8.0_211]2022-04-06 17:08:23.640 ERROR 4870 --- [nio-8081-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: SentinelBlockException: DegradeException] with root causejava.lang.RuntimeException: SentinelBlockException: DegradeExceptionat com.alibaba.csp.sentinel.slots.block.BlockException.block(BlockException:0) ~[sentinel-core-1.8.0.jar:1.8.0]2022-04-06 17:08:23.644 ERROR 4870 --- [nio-8081-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: SentinelBlockException: DegradeException] with root causejava.lang.RuntimeException: SentinelBlockException: DegradeExceptionat com.alibaba.csp.sentinel.slots.block.BlockException.block(BlockException:0) ~[sentinel-core-1.8.0.jar:1.8.0]2022-04-06 17:08:23.649 ERROR 4870 --- [nio-8081-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: SentinelBlockException: DegradeException] with root causejava.lang.RuntimeException: SentinelBlockException: DegradeExceptionat com.alibaba.csp.sentinel.slots.block.BlockException.block(BlockException:0) ~[sentinel-core-1.8.0.jar:1.8.0]2022-04-06 17:08:23.653 ERROR 4870 --- [nio-8081-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: SentinelBlockException: DegradeException] with root causejava.lang.RuntimeException: SentinelBlockException: DegradeExceptionat com.alibaba.csp.sentinel.slots.block.BlockException.block(BlockException:0) ~[sentinel-core-1.8.0.jar:1.8.0]2022-04-06 17:08:23.658 ERROR 4870 --- [io-8081-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: SentinelBlockException: DegradeException] with root causejava.lang.RuntimeException: SentinelBlockException: DegradeExceptionat com.alibaba.csp.sentinel.slots.block.BlockException.block(BlockException:0) ~[sentinel-core-1.8.0.jar:1.8.0]說明:前5次輸出RpcException,后5次由于觸發熔斷降級,拋出DegradeException
???????????
**********
dubbo mock降級
?????????
HelloServiceMock
public class HelloServiceMock implements HelloService {@Overridepublic String hello() {return "調用出錯,本地降級";} }??????????
HelloController
@RestController public class HelloController {//@DubboReference@DubboReference(mock = "true")private HelloService helloService;@RequestMapping("/hello")public String hello(){System.out.println(helloService.hello());return "success";} }?????????????
查看結果樹
?????????????????
????????????????? ?
# 消費端控制臺輸出 2022-04-06 17:04:08.691 INFO 4800 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 3.907 seconds (JVM running for 4.626) 2022-04-06 17:04:09.611 WARN 4800 --- [client.listener] a.c.d.m.r.DubboServiceMetadataRepository : Current application will subscribe all services(size:2) in registry, a lot of memory and CPU cycles may be used, thus it's strongly recommend you using the externalized property 'dubbo.cloud.subscribed-services' to specify the services 2022-04-06 17:04:11.063 INFO 4800 --- [erverWorker-4-1] o.a.d.r.t.netty4.NettyServerHandler : [DUBBO] The connection of /192.168.5.9:54787 -> /192.168.5.9:20881 is established., dubbo version: 2.7.8, current host: 192.168.5.9 2022-04-06 17:04:11.654 INFO 4800 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2022-04-06 17:04:11.654 INFO 4800 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2022-04-06 17:04:11.668 INFO 4800 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 14 ms 調用出錯,本地降級 調用出錯,本地降級 調用出錯,本地降級 調用出錯,本地降級 調用出錯,本地降級 2022-04-06 17:04:11.777 ERROR 4800 --- [nio-8081-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: SentinelBlockException: DegradeException] with root causejava.lang.RuntimeException: SentinelBlockException: DegradeExceptionat com.alibaba.csp.sentinel.slots.block.BlockException.block(BlockException:0) ~[sentinel-core-1.8.0.jar:1.8.0]2022-04-06 17:04:11.795 ERROR 4800 --- [nio-8081-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: SentinelBlockException: DegradeException] with root causejava.lang.RuntimeException: SentinelBlockException: DegradeExceptionat com.alibaba.csp.sentinel.slots.block.BlockException.block(BlockException:0) ~[sentinel-core-1.8.0.jar:1.8.0]2022-04-06 17:04:11.800 ERROR 4800 --- [nio-8081-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: SentinelBlockException: DegradeException] with root causejava.lang.RuntimeException: SentinelBlockException: DegradeExceptionat com.alibaba.csp.sentinel.slots.block.BlockException.block(BlockException:0) ~[sentinel-core-1.8.0.jar:1.8.0]2022-04-06 17:04:11.805 ERROR 4800 --- [nio-8081-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: SentinelBlockException: DegradeException] with root causejava.lang.RuntimeException: SentinelBlockException: DegradeExceptionat com.alibaba.csp.sentinel.slots.block.BlockException.block(BlockException:0) ~[sentinel-core-1.8.0.jar:1.8.0]2022-04-06 17:04:11.809 ERROR 4800 --- [nio-8081-exec-9] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: SentinelBlockException: DegradeException] with root causejava.lang.RuntimeException: SentinelBlockException: DegradeExceptionat com.alibaba.csp.sentinel.slots.block.BlockException.block(BlockException:0) ~[sentinel-core-1.8.0.jar:1.8.0]說明:前5次請求服務端拋出RpcExeption,消費端使用mock降級;后5次由于消費端觸發sentinel熔斷,直接拋出DegradeException
??????????
??????????????????
總結
以上是生活随笔為你收集整理的sentinel 熔断降级的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: unity3d的Animation 动画
- 下一篇: 小米9预约如此火爆,雷军的供货能跟上吗?