ダボのサービス低下ダボのサービス低下

 

ターン:

サービス低下ダボを設定するには、管理コンソールで1

数字の意味を設定すると、以下のとおりです。消費者は、リモート呼び出しを開始しない、com.zhang.HelloService法、ダイレクトリターンヌルを呼び出します。

実際の操作は次のとおりです。/dubbo/com.zhang.HelloService/configuratorsのオーバーライドノードZKを追加しました。

オーバーライド:?//0.0.0.0/com.zhang.HelloServiceカテゴリ=コンフィギュレータ&ダイナミック=偽&グループ= A&モック=力:リターン+ヌル

 

(ダボ所与の文書の抜粋):2は、サービス低下コードによって実行することができます

サービス劣化関数は、一時的に非クリティカルサービスエラーをブロックし、ダウングレード後に返品ポリシーを定義することができます。
レジストリへの動的な構成をカバーするルールを書きます:

RegistryFactory registryFactory =  
    ExtensionLoader.getExtensionLoader(RegistryFactory。クラス).getAdaptiveExtension(); 
レジストリのレジストリ= registryFactory.getRegistry(URL.valueOf( "飼育係://10.20.153.10:2181" ));  registry.register(URL.valueOf( "?オーバーライド://0.0.0.0/com.foo.BarServiceカテゴリ=コンフィギュレータ&ダイナミック=偽&アプリケーション= consumer_app&モック=力:リターン+ヌル"));

モック=力:リターン+ NULLは
、直接メソッドを呼び出して、消費者を表すリモート呼び出しを開始するのではなく、サービスのためのヌル値を戻します。呼び出し側のサービスに重要な影響を保護するために使用することはできません。
モック=失敗:リターン+ nullは
、消費者が失敗した後のサービスの、このメソッドの呼び出し、その後、null値を返し、例外をスローしません表します。とき不安定、発信者のサービスへの影響を容認することは重要ではありません。

ダボサービス低下の真の意味:プロバイダ上で動作しませんが、あなたは何をサービスアクションを呼び出すか、消費者に語りました。

 

3.ここモックサービスを呼び出す方法を消費者、消費者側静的構成モックを分析します

ユーザは:でモックの構成属性<ダボ参照>。カスタムモックを設定し、まだ彼らは知って取得する方法。=モックするには:例えば、「力のリターン+ヌル」を、我々は最初のダボデフォルトMockInvokerを分析します。

MockClusterInvokerロジック:

コードをコピー
// MockClusterInvoker
 パブリック結果を呼び出し(呼び出しの呼び出し)がスローRpcException {  結果結果= NULLを// 获取<ダボ:参照>モック属性的文字列値=。directory.getUrl()getMethodParameter(invocation.getMethodName()、Constants.MOCK_KEY、Boolean.FALSE.toString())(トリム)。IF(value.length()== 0 || value.equalsIgnoreCase( "偽" )){ // モック= ""或者モック= "false"の結果は= この.invoker.invoke(呼び出し)。} そうであれば(value.startsWith( "力" )){ // 强制使用モック、如モック= "力:リターン+ NULL" であれば(logger.isWarnEnabled()){logger.info( "力モック:" + invocation.getMethodName()+ "力模擬有効、URL:" + directory.getUrl())。}結果= doMockInvoke(呼び出し、NULL ); } { // モック= "失敗:リターン+ヌル"或= "MyMock"モック試し{結果= この.invoker.invoke(呼び出し)。} キャッチ(RpcException電子){ 場合(e.isBiz()){ スローE。} { 場合(logger.isWarnEnabled()){logger.info( "フェイルモック:" + invocation.getMethodName()+ "フェイル模擬有効にし、URL:" + directory.getUrl()、E)。} // 出现超时异常結果=doMockInvoke(呼び出し、E)。}}} 戻り値の結果; } プライベート結果doMockInvoke(呼び出しの呼び出し、RpcException電子){結果結果= NULL ; 実行者<T> minvoker。リスト<インボーカ<T >> mockInvokers = selectMockInvoker(呼び出し)。IF(mockInvokers == NULL || mockInvokers.size()== 0 ){ // 如果没有配置自定义モック、则使用默认MockInvoker minvoker =(インボーカ<T>)新しいMockInvoker(directory.getUrl())。} {minvoker = mockInvokers.get(0 )。} 試みる{ // 调用結果= minvoker.invoke(呼び出し)。} キャッチ(RpcException ME){ もし(me.isBiz()){結果= 新しいRpcResult(me.getCause())。} { スロー新しいRpcException(me.getCodeを()、getMockExceptionMessage(E、私)、me.getCause()); }} キャッチ(私をスロー可能オブジェクト){ スロー新しいRpcException(、私をgetMockExceptionMessage(e)を、me.getCause()); } 戻り値の結果; }
コードをコピー

デフォルトのMockInvoker:

コードをコピー
// MockInvoker
public Result invoke(Invocation invocation) throws RpcException {
    //获取url中的sayHello.mock参数值 String mock = getUrl().getParameter(invocation.getMethodName() + "." + Constants.MOCK_KEY); if (invocation instanceof RpcInvocation) { ((RpcInvocation) invocation).setInvoker(this); } if (StringUtils.isBlank(mock)){ //获取mock属性值 mock = getUrl().getParameter(Constants.MOCK_KEY); } if (StringUtils.isBlank(mock)){ throw new RpcException(new IllegalAccessException("mock can not be null. url :" + url)); } //假定mock="force:return+null",处理后mock="return+null" mock = normallizeMock(URL.decode(mock)); if (Constants.RETURN_PREFIX.trim().equalsIgnoreCase(mock.trim())){ RpcResult result = new RpcResult(); result.setValue(null); return result; } else if (mock.startsWith(Constants.RETURN_PREFIX)) { //构造返回值 mock = mock.substring(Constants.RETURN_PREFIX.length()).trim(); mock = mock.replace('`', '"'); try { Type[] returnTypes = RpcUtils.getReturnTypes(invocation); Object value = parseMockValue(mock, returnTypes); return new RpcResult(value); } catch (Exception ew) { throw new RpcException("mock return invoke error. method:" + invocation.getMethodName() + ", mock:" + mock + ", url: "+ url , ew); } } else if (mock.startsWith(Constants.THROW_PREFIX)) { mock = mock.substring(Constants.THROW_PREFIX.length()).trim(); mock = mock.replace('`', '"'); if (StringUtils.isBlank(mock)){ throw new RpcException(" mocked exception for Service degradation. "); } else { //用户自定义类 Throwable t = getThrowable(mock); throw new RpcException(RpcException.BIZ_EXCEPTION, t); } } else { //impl mock try { Invoker<T> invoker = getInvoker(mock); return invoker.invoke(invocation); } catch (Throwable t) { throw new RpcException("Failed to create mock implemention class " + mock , t); } } } //mock=fail:throw //mock=fail:return //mock=xx.Service private String normallizeMock(String mock) { if (mock == null || mock.trim().length() ==0){ return mock; } else if (ConfigUtils.isDefault(mock) || "fail".equalsIgnoreCase(mock.trim()) || "force".equalsIgnoreCase(mock.trim())){ mock = url.getServiceInterface()+"Mock"; } if (mock.startsWith(Constants.FAIL_PREFIX)) { mock = mock.substring(Constants.FAIL_PREFIX.length()).trim(); } else if (mock.startsWith(Constants.FORCE_PREFIX)) { mock = mock.substring(Constants.FORCE_PREFIX.length()).trim(); } return mock; }
コードをコピー

 

标签: dubbo

1. 在 dubbo 管理控制台配置服务降级

上图的配置含义是:consumer 调用 com.zhang.HelloService 的方法时,直接返回 null,不发起远程调用。

实际操作是:在 zk 的 /dubbo/com.zhang.HelloService/configurators 节点中添加了 override。

override://0.0.0.0/com.zhang.HelloService?category=configurators&dynamic=false&group=a&mock=force:return+null

 

2. 也可以通过代码,进行服务降级:(dubbo文档中给出了代码片段)

可以通过服务降级功能,临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。
向注册中心写入动态配置覆盖规则:

RegistryFactory registryFactory = 
    ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=consumer_app&mock=force:return+null"));

mock=force:return+null
表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。
mock=fail:return+null
表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。

dubbo 服务降级的真实含义:并不是对 provider 进行操作,而是告诉 consumer,调用服务时要做哪些动作。

 

3. 现在分析consumer端静态配置mock, consumer中如何调用mock服务

用户可以在<dubbo:reference>中配置mock属性。如何配置自定义的mock,还没有搞懂。以mock="force:return+null"为例,我们先分析dubbo默认的MockInvoker。

MockClusterInvoker逻辑:

コードをコピー
// MockClusterInvoker
public Result invoke(Invocation invocation) throws RpcException {
    Result result = null; // 获取<dubbo:reference>的mock属性。 String value = directory.getUrl().getMethodParameter(invocation.getMethodName(), Constants.MOCK_KEY, Boolean.FALSE.toString()).trim(); if (value.length() == 0 || value.equalsIgnoreCase("false")){ //mock="" 或者 mock="false" result = this.invoker.invoke(invocation); } else if (value.startsWith("force")) { //强制使用mock,如mock="force:return+null" if (logger.isWarnEnabled()) { logger.info("force-mock: " + invocation.getMethodName() + " force-mock enabled , url : " + directory.getUrl()); } result = doMockInvoke(invocation, null); } else { //mock="fail:return+null" 或 mock="MyMock" try { result = this.invoker.invoke(invocation); }catch (RpcException e) { if (e.isBiz()) { throw e; } else { if (logger.isWarnEnabled()) { logger.info("fail-mock: " + invocation.getMethodName() + " fail-mock enabled , url : " + directory.getUrl(), e); } //出现超时异常 result = doMockInvoke(invocation, e); } } } return result; } private Result doMockInvoke(Invocation invocation, RpcException e) { Result result = null; Invoker<T> minvoker; List<Invoker<T>> mockInvokers = selectMockInvoker(invocation); if (mockInvokers == null || mockInvokers.size() == 0){ //如果没有配置自定义Mock,则使用默认MockInvoker minvoker = (Invoker<T>) new MockInvoker(directory.getUrl()); } else { minvoker = mockInvokers.get(0); } try { //调用 result = minvoker.invoke(invocation); } catch (RpcException me) { if (me.isBiz()) { result = new RpcResult(me.getCause()); } else { throw new RpcException(me.getCode(), getMockExceptionMessage(e, me), me.getCause()); } } catch (Throwable me) { throw new RpcException(getMockExceptionMessage(e, me), me.getCause()); } return result; }
コードをコピー

默认的MockInvoker:

コードをコピー
// MockInvoker
public Result invoke(Invocation invocation) throws RpcException {
    //获取url中的sayHello.mock参数值 String mock = getUrl().getParameter(invocation.getMethodName() + "." + Constants.MOCK_KEY); if (invocation instanceof RpcInvocation) { ((RpcInvocation) invocation).setInvoker(this); } if (StringUtils.isBlank(mock)){ //获取mock属性值 mock = getUrl().getParameter(Constants.MOCK_KEY); } if (StringUtils.isBlank(mock)){ throw new RpcException(new IllegalAccessException("mock can not be null. url :" + url)); } //假定mock="force:return+null",处理后mock="return+null" mock = normallizeMock(URL.decode(mock)); if (Constants.RETURN_PREFIX.trim().equalsIgnoreCase(mock.trim())){ RpcResult result = new RpcResult(); result.setValue(null); return result; } else if (mock.startsWith(Constants.RETURN_PREFIX)) { //构造返回值 mock = mock.substring(Constants.RETURN_PREFIX.length()).trim(); mock = mock.replace('`', '"'); try { Type[] returnTypes = RpcUtils.getReturnTypes(invocation); Object value = parseMockValue(mock, returnTypes); return new RpcResult(value); } catch (Exception ew) { throw new RpcException("mock return invoke error. method:" + invocation.getMethodName() + ", mock:" + mock + ", url: "+ url , ew); } } else if (mock.startsWith(Constants.THROW_PREFIX)) { mock = mock.substring(Constants.THROW_PREFIX.length()).trim(); mock = mock.replace('`', '"'); if (StringUtils.isBlank(mock)){ throw new RpcException(" mocked exception for Service degradation. "); } else { //用户自定义类 Throwable t = getThrowable(mock); throw new RpcException(RpcException.BIZ_EXCEPTION, t); } } else { //impl mock try { Invoker<T> invoker = getInvoker(mock); return invoker.invoke(invocation); } catch (Throwable t) { throw new RpcException("Failed to create mock implemention class " + mock , t); } } } //mock=fail:throw //mock=fail:return //mock=xx.Service private String normallizeMock(String mock) { if (mock == null || mock.trim().length() ==0){ return mock; } else if (ConfigUtils.isDefault(mock) || "fail".equalsIgnoreCase(mock.trim()) || "force".equalsIgnoreCase(mock.trim())){モック= url.getServiceInterface()+ "モック" } であれば(mock.startsWith(Constants.FAIL_PREFIX)){モック= mock.substring(Constants.FAIL_PREFIX.length()))(トリム。} そうであれば(mock.startsWith(Constants.FORCE_PREFIX)){モック= mock.substring(Constants.FORCE_PREFIX.length())(トリム)。} 戻り模擬。}
コードをコピー

 

おすすめ

転載: www.cnblogs.com/libin6505/p/11270147.html