SOFARPC源码解析-服务调用

简介摘要
SOFARPC服务调用创建服务引用配置ConsumerConfig,自定义设置接口名称、调用协议、直连调用地址以及连接超时时间等基础配置;通过服务消费者启动类ConsumerBootstrap引用服务,客户端集群Cluster调用消费端调用器ConsumerInvoker实现Client发送数据给Server调用过程。
SOFARPC以基于Netty实现的网络通信框架SOFABolt用作远程通信框架,使用者不用关心如何实现私有协议的细节,直接使用内置RPC通信协议,启动客户端与服务端同时注册用户请求处理器即可完成远程调用:
1.调用方式
SOFARPC服务调用提供同步Sync、异步Future、回调Callback以及单向Oneway四种调用类型:

SOFARPC源码解析-服务调用_第1张图片
服务调用基础通信模型.png

(1)Sync同步调用
同步调用方式,客户端发起调用后等待服务端返回结果再进行后续的操作,是SOFARPC的默认调用方式,无需进行任何设置即可。当前线程发起调用后阻塞请求线程,需要在指定的超时时间内等到响应结果才能完成本次调用。如果超时时间内没有得到响应结果,那么抛出超时异常。Sync同步调用模式最常用,注意要根据对端的处理能力合理设置超时时间。
(2)Future异步调用
客户端发起调用后不会等待服务端的结果,继续执行后面的业务逻辑。服务端返回响应结果被SOFARPC缓存,当客户端需要响应结果的时候需要主动获取结果,调用过程不会阻塞线程,获取结果的过程阻塞线程,目前支持bolt协议:

ConsumerConfig consumer = new ConsumerConfig()
            .setInterfaceId(HelloService.class.getName())
            .setInvokeType(RpcConstants.INVOKER_TYPE_FUTURE);

使用Future异步调用SOFABoot配置服务引用需要设置sofa:global-attrs元素的type属性声明调用方式为future:


    
        
    


    
        
    

如上设置为异步调用的方式。客户端获取响应结果有两种方式:
(1)通过 SofaResponseFuture直接获取结果。第一个参数是获取结果的超时时间,第二个参数表示是否清除线程上下文中的结果。

String result = (String)SofaResponseFuture.getResponse(0,true);

(2)获取原生Futrue,该种方式获取JDK原生的Future,参数表示是否清除线程上下文中的结果。因为响应结果放在JDK原生的Future,需要通过JDK Future的get()方法获取响应结果。

Future future = SofaResponseFuture.getFuture(true);

当前线程发起调用得到RpcResponseFuture对象,当前线程可以继续执行下一次调用。在任意时刻使用RpcResponseFuture对象的get()方法来获取结果,如果响应已经回来此时就马上得到结果;如果响应没有回来则阻塞住当前线程直到响应回来或者超时时间到。
(3)Callback回调调用
客户端提前设置回调实现类,在发起调用后不会等待结果,是真正的异步调用,永远不会阻塞线程,结果处理是在异步线程里执行。SOFA-RPC在获取到服务端的接口后会自动执行该回调实现,目前支持 bolt 协议。客户端回调类需要实现com.alipay.sofa.rpc.core.invoke.SofaResponseCallback接口:

SofaResponseCallback sofaResponseCallbackImpl = new SofaResponseCallbackImpl();

ConsumerConfig consumer = new ConsumerConfig()
            .setInterfaceId(HelloService.class.getName())
            .setInvokeType(RpcConstants.INVOKER_TYPE_CALLBACK)
            .setOnReturn(sofaResponseCallbackImpl)

如上设置是服务级别的设置,也可以进行调用级别的设置:

RpcInvokeContext.getContext().setResponseCallback(sofaResponseCallbackImpl);

使用Callback回调调用SOFABoot配置服务引用需要设置sofa:global-attrs元素的type属性声明调用方式为callback,通过callback-ref属性声明回调的实现类,使用该服务引用发起调用时结果返回时由SOFARPC自动执行该回调类:



    
        
    



    
        
    

当前线程发起调用则本次调用马上结束执行下一次调用。发起调用时需要注册回调,该回调需要分配异步线程池以待响应回来后在回调的异步线程池来执行回调逻辑。
(4)Oneway单向调用
客户端发送请求后不会等待服务端返回的结果,并且会忽略服务端的处理结果,目前支持bolt协议:

ConsumerConfig consumer = new ConsumerConfig()
            .setInterfaceId(HelloService.class.getName())
            .setInvokeType(RpcConstants.INVOKER_TYPE_ONEWAY);

使用Oneway单向调用SOFABoot配置服务引用需要设置sofa:global-attrs元素的type属性声明调用方式为oneway:



    
        
    


    
        
    

当前线程发起调用后,不关心调用结果不做超时控制,只要请求已经发出就完成本次调用。单向调用不关心响应结果,请求线程不会被阻塞,使用Oneway调用需要注意控制调用节奏防止压垮接收方。注意Oneway调用不保证成功,而且发起方无法知道调用结果。因此通常用于可以重试,或者定时通知类的场景,调用过程是有可能因为网络问题、机器故障等原因导致请求失败,业务场景需要能接受这样的异常场景才能够使用。
2.直连调用
SOFARPC支持指定地址进行调用的场景,设置直连地址即可:

ConsumerConfig consumer = new ConsumerConfig()        
            .setInterfaceId(HelloService.class.getName())        
            .setRegistry(registryConfig)        
            .setDirectUrl("bolt://127.0.0.1:12201");

3.泛化调用
SOFARPC泛化调用方式能够在客户端不需要依赖服务端的接口情况下发起调用,目前支持bolt协议。由于不知道服务端的接口,因此需要通过字符串的方式将服务端的接口,调用的方法,参数及结果类进行描述:

ConsumerConfig consumerConfig = new ConsumerConfig()
           .setInterfaceId("com.alipay.sofa.rpc.quickstart.HelloService")
           .setGeneric(true);
GenericService testService = consumerConfig.refer();

String result = (String) testService.$invoke("sayHello", new String[] { "java.lang.String" },new Object[] { "1111" });

如上通过setGeneric设置该服务为泛化服务,设置服务方的接口名。以GenericService作为泛化服务,通过GenericService能够发起泛化调用。发起调用时需要传入方法名、方法类型、方法参数。如果参数或者返回结果在客户端也需要泛化表示则通过GenericObject来实现获取序列化结果等:

GenericObject param = new GenericObject("com.alipay.sofa.rpc.invoke.generic.TestObj");
              
genericObject.putField("str", "xxxx");
genericObject.putField("num", 222);

GenericObject result = (GenericObject) testService.$genericInvoke("echoObj",
                    new String[] { "com.alipay.sofa.rpc.invoke.generic.TestObj" },
                    new Object[] { param });

String str = result.getField("str");
String num = result.getField("num");

(1)接口描述:所有泛化调用都需要在服务引用的时候声明interface为com.alipay.sofa.rpc.api.GenericService,这是SOFARPC提供的类。真正的服务接口通过sofa:global-attrs元素的generic-interface属性声明完成接口的描述。


   
      
   

(2)参数描述:由于客户端没有调用服务的参数类,因此通过GenericObject进行描述,GenericObject持有Map类型的变量,能够通过GenericObject提供的对该变量的操作方法将参数类的属性放到Map以此来描述参数类。

GenericObject genericObject = new GenericObject("com.alipay.sofa.rpc.samples.generic.SampleGenericParamModel");
genericObject.putField("name", "Bible");

(3)发起泛化调用:接口描述通过XML配置声明泛化引用的bean,通过该泛化引用能够发起服务调用,发起泛化调用的第一个参数就是方法名,第二个参数就是参数类的全类名,第三个参数就是描述参数类的 GenericObject。

(GenericObject) sampleGenericServiceReference.$genericInvoke("sayGeneric",
            new String[] { "com.alipay.sofa.rpc.samples.generic.SampleGenericParamModel" },
            new Object[] { genericObject });

(4)获取泛化结果:发起泛化调用如果客户端同样没有泛化结果的类,那么同样以GenericObject对调用结果进行描述,通过GenericObject的getField方法能够获取结果类的属性值,通过GenericObject的getType方法能够获取结果类的全类名。

GenericObject result = (GenericObject) sampleGenericServiceReference.$genericInvoke("sayGeneric",
            new String[] { "com.alipay.sofa.rpc.samples.generic.SampleGenericParamModel" },
            new Object[] { genericObject });

System.out.println(result.getType());
System.out.println(result.getField("name"));
System.out.println(result.getField("value"));

(5)泛化调用示例:SOFARPC泛化调用完整的泛化调用方式:

/**
* Java Bean
*/
public class People {
    private String name;
    private int    age;
    
    // getters and setters
}


/**
 * 服务方提供的接口
 */
interface SampleService {
   String hello(String arg);
   People hello(People people);
   String[] hello(String[] args);
}

/**
 * 客户端
 */
public class ConsumerClass {
   GenericService genericService;

   public void do() {
      // 1. $invoke仅支持方法参数类型在当前应用的 ClassLoader 中存在的情况
      genericService.$invoke("hello", new String[]{ String.class.getName() }, "I'm an arg");
      
      // 2. $genericInvoke支持方法参数类型在当前应用的 ClassLoader 中不存在的情况。
      // 2.1 构造参数
      GenericObject genericObject = new GenericObject("com.alipay.sofa.rpc.test.generic.bean.People"); // 构造函数中指定全路径类名
      genericObject.putField("name", "Lilei"); // 调用putField,指定field值
      genericObject.putField("age", 15);
      
      // 2.2 进行调用,不指定返回类型,返回结果类型为GenericObject
      Object obj = genericService.$genericInvoke("hello", new String[]{"com.alipay.sofa.rpc.test.generic.bean.People"}, new Object[] { genericObject });
      Assert.assertTrue(obj.getClass == GenericObject.class);
      
      // 2.3 进行调用,指定返回类型
      People people = genericService.$genericInvoke("hello", new String[]{"com.alipay.sofa.rpc.test.generic.bean.People"}, new Object[] { genericObject }, People.class);
      
      // 2.4 进行调用,参数类型是数组类型
      String[] result = (String[]) proxy.$genericInvoke("hello", new String[]{new String[0].getClass().getName()}, new Object[]{ new String[]{"args"} });
   }
}

源码解析
1.调用方式
参考sofa-rpc-boot-projects范例模块(com.alipay.sofa.rpc.samples.invoke):




    




    




    

package com.alipay.sofa.rpc.samples.invoke;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;

@ImportResource({ "classpath:invoke-server-example.xml" })
@SpringBootApplication
public class InvokeServerApplication {

    public static void main(String[] args) {

        SpringApplication springApplication = new SpringApplication(InvokeServerApplication.class);
        ApplicationContext applicationContext = springApplication.run(args);
    }
}
package com.alipay.sofa.rpc.samples.invoke;

import com.alipay.sofa.rpc.api.future.SofaResponseFuture;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;

@ImportResource({ "classpath:invoke-client-example.xml" })
@SpringBootApplication
public class InvokeClientApplication {

    public static void main(String[] args) {

        //change port to run in local machine
        System.setProperty("server.port", "8081");

        SpringApplication springApplication = new SpringApplication(InvokeClientApplication.class);
        ApplicationContext applicationContext = springApplication.run(args);

        HelloSyncService helloSyncServiceReference = (HelloSyncService) applicationContext
            .getBean("helloSyncServiceReference");
        HelloFutureService helloFutureServiceReference = (HelloFutureService) applicationContext
            .getBean("helloFutureServiceReference");
        HelloCallbackService helloCallbackServiceReference = (HelloCallbackService) applicationContext
            .getBean("helloCallbackServiceReference");

        String result = helloSyncServiceReference.saySync("sync");
        System.out.println(result);

        helloFutureServiceReference.sayFuture("future");
        try {
            System.out.println(SofaResponseFuture.getResponse(1000, true));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        helloCallbackServiceReference.sayCallback("callback");

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

运行调用方式服务端范例类InvokeServerApplication查看调用方式服务端输出日志:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.2.RELEASE)

Sofa-Middleware-Log SLF4J : Actual logging.path is [ ./logs ]
2018-06-03 18:41:23.848  INFO 12840 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual logging.path is [ ./logs ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.infra Logback ]
2018-06-03 18:41:23.938  INFO 12840 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.infra Logback ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.healthcheck Logback ]
2018-06-03 18:41:24.496  INFO 12840 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.healthcheck Logback ]
2018-06-03 18:41:24.619  INFO 12840 --- [           main] c.a.s.r.s.i.InvokeServerApplication      : Starting InvokeServerApplication on Program with PID 12840 (D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-samples\target\classes started by Administrator in D:\Program\Github\sofa-rpc-boot-projects)
2018-06-03 18:41:24.621  INFO 12840 --- [           main] c.a.s.r.s.i.InvokeServerApplication      : No active profile set, falling back to default profiles: default
2018-06-03 18:41:24.929  INFO 12840 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@59309333: startup date [Sun Jun 03 18:41:24 CST 2018]; root of context hierarchy
2018-06-03 18:41:28.758  INFO 12840 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from class path resource [invoke-client-example.xml]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc.boot Logback ]
2018-06-03 18:41:29.561  INFO 12840 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc.boot Logback ]
2018-06-03 18:41:29.889  INFO 12840 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from class path resource [invoke-server-example.xml]
2018-06-03 18:41:31.866  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'com.alipay.sofa.runtime.spring.configuration.SofaRuntimeAutoConfiguration' of type [class com.alipay.sofa.runtime.spring.configuration.SofaRuntimeAutoConfiguration$$EnhancerBySpringCGLIB$$80ecb4c1] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:31.893  WARN 12840 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloFutureServiceReference': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'sofaRuntimeContext': Requested bean is currently in creation: Is there an unresolvable circular reference?
2018-06-03 18:41:31.896  WARN 12840 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloCallbackServiceReference': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'sofaRuntimeContext': Requested bean is currently in creation: Is there an unresolvable circular reference?
2018-06-03 18:41:32.147  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'bindingConverterFactory' of type [class com.alipay.sofa.runtime.service.impl.BindingConverterFactoryImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:32.151  WARN 12840 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloFutureServiceReference': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'sofaRuntimeContext': Requested bean is currently in creation: Is there an unresolvable circular reference?
2018-06-03 18:41:32.154  WARN 12840 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloCallbackServiceReference': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'sofaRuntimeContext': Requested bean is currently in creation: Is there an unresolvable circular reference?
2018-06-03 18:41:32.277  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'bindingAdapterFactory' of type [class com.alipay.sofa.runtime.service.impl.BindingAdapterFactoryImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:32.279  WARN 12840 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloFutureServiceReference': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'sofaRuntimeContext': Requested bean is currently in creation: Is there an unresolvable circular reference?
2018-06-03 18:41:32.281  WARN 12840 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloCallbackServiceReference': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'sofaRuntimeContext': Requested bean is currently in creation: Is there an unresolvable circular reference?
2018-06-03 18:41:32.283  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sofaRuntimeProperties' of type [class com.alipay.sofa.runtime.spring.config.SofaRuntimeProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:32.291  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sofaRuntimeContext' of type [class com.alipay.sofa.runtime.spi.component.SofaRuntimeContext] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.runtime Logback ]
2018-06-03 18:41:32.415  INFO 12840 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.runtime Logback ]
2018-06-03 18:41:32.454  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'com.alipay.sofa.rpc.boot.SofaBootRpcAutoConfiguration' of type [class com.alipay.sofa.rpc.boot.SofaBootRpcAutoConfiguration$$EnhancerBySpringCGLIB$$b54b6dd6] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:32.632  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'consumerConfigHelper' of type [class com.alipay.sofa.rpc.boot.runtime.adapter.helper.ConsumerConfigHelper] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:32.699  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'callbackImpl' of type [class com.alipay.sofa.rpc.samples.invoke.CallbackImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:32.703  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sofaBootRpcProperties' of type [class com.alipay.sofa.rpc.boot.config.SofaBootRpcProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:32.705  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'zookeeperConfigurator' of type [class com.alipay.sofa.rpc.boot.config.ZookeeperConfigurator] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:32.707  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'localFileConfigurator' of type [class com.alipay.sofa.rpc.boot.config.LocalFileConfigurator] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:32.708  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'registryConfigContainer' of type [class com.alipay.sofa.rpc.boot.container.RegistryConfigContainer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Logback ]
2018-06-03 18:41:32.998  INFO 12840 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Logback ]
./logs\tracelog\static-info.log -> ./logs\tracelog\static-info.log.2018-06-02
./logs\tracelog\tracer-self.log -> ./logs\tracelog\tracer-self.log.2018-06-02
2018-06-03 18:41:33.392  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'consumerConfigContainer' of type [class com.alipay.sofa.rpc.boot.container.ConsumerConfigContainer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:33.930  INFO 12840 --- [           main] o.a.c.f.imps.CuratorFrameworkImpl        : Starting
2018-06-03 18:41:33.966  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:zookeeper.version=3.4.6-1569965, built on 02/20/2014 09:09 GMT
2018-06-03 18:41:33.966  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:host.name=Program
2018-06-03 18:41:33.966  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.version=1.8.0_141
2018-06-03 18:41:33.966  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.vendor=Oracle Corporation
2018-06-03 18:41:33.966  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.home=C:\Program Files\Java\jdk1.8.0_141\jre
2018-06-03 18:41:33.967  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.class.path=C:\Program Files\Java\jdk1.8.0_141\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\rt.jar;D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-samples\target\classes;D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-starter\target\classes;C:\Users\Administrator\.m2\repository\com\alipay\sofa\sofa-rpc-all\5.4.0\sofa-rpc-all-5.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\bolt\1.4.1\bolt-1.4.1.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\1.7.21\slf4j-api-1.7.21.jar;C:\Users\Administrator\.m2\repository\io\netty\netty-all\4.1.25.Final\netty-all-4.1.25.Final.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\hessian\3.3.0\hessian-3.3.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\tracer-core\2.1.1\tracer-core-2.1.1.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-api\0.22.0\opentracing-api-0.22.0.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-noop\0.22.0\opentracing-noop-0.22.0.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-mock\0.22.0\opentracing-mock-0.22.0.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-util\0.22.0\opentracing-util-0.22.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\lookout\lookout-api\1.4.0\lookout-api-1.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\runtime-sofa-boot-starter\2.4.0\runtime-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-client\2.9.1\curator-client-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-framework\2.9.1\curator-framework-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-recipes\2.9.1\curator-recipes-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-jaxrs\3.0.12.Final\resteasy-jaxrs-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\spec\javax\annotation\jboss-annotations-api_1.1_spec\1.0.1.Final\jboss-annotations-api_1.1_spec-1.0.1.Final.jar;C:\Users\Administrator\.m2\repository\javax\activation\activation\1.1.1\activation-1.1.1.jar;C:\Users\Administrator\.m2\repository\org\apache\httpcomponents\httpclient\4.3.6\httpclient-4.3.6.jar;C:\Users\Administrator\.m2\repository\org\apache\httpcomponents\httpcore\4.3.3\httpcore-4.3.3.jar;C:\Users\Administrator\.m2\repository\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;C:\Users\Administrator\.m2\repository\commons-codec\commons-codec\1.6\commons-codec-1.6.jar;C:\Users\Administrator\.m2\repository\commons-io\commons-io\2.1\commons-io-2.1.jar;C:\Users\Administrator\.m2\repository\net\jcip\jcip-annotations\1.0\jcip-annotations-1.0.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-client\3.0.12.Final\resteasy-client-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-jackson-provider\3.0.12.Final\resteasy-jackson-provider-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-core-asl\1.9.12\jackson-core-asl-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-mapper-asl\1.9.12\jackson-mapper-asl-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-jaxrs\1.9.12\jackson-jaxrs-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-xc\1.9.12\jackson-xc-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-netty4\3.0.12.Final\resteasy-netty4-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-validator-provider-11\3.0.12.Final\resteasy-validator-provider-11-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\hibernate\hibernate-validator\5.0.1.Final\hibernate-validator-5.0.1.Final.jar;C:\Users\Administrator\.m2\repository\javax\validation\validation-api\1.1.0.Final\validation-api-1.1.0.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\logging\jboss-logging\3.1.1.GA\jboss-logging-3.1.1.GA.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\classmate\0.8.0\classmate-0.8.0.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\jaxrs-api\3.0.12.Final\jaxrs-api-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-multipart-provider\3.0.12.Final\resteasy-multipart-provider-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-jaxb-provider\3.0.12.Final\resteasy-jaxb-provider-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\com\sun\xml\bind\jaxb-impl\2.2.7\jaxb-impl-2.2.7.jar;C:\Users\Administrator\.m2\repository\com\sun\xml\bind\jaxb-core\2.2.7\jaxb-core-2.2.7.jar;C:\Users\Administrator\.m2\repository\javax\xml\bind\jaxb-api\2.2.7\jaxb-api-2.2.7.jar;C:\Users\Administrator\.m2\repository\com\sun\istack\istack-commons-runtime\2.16\istack-commons-runtime-2.16.jar;C:\Users\Administrator\.m2\repository\com\sun\xml\fastinfoset\FastInfoset\1.2.12\FastInfoset-1.2.12.jar;C:\Users\Administrator\.m2\repository\javax\xml\bind\jsr173_api\1.0\jsr173_api-1.0.jar;C:\Users\Administrator\.m2\repository\javax\mail\mail\1.5.0-b01\mail-1.5.0-b01.jar;C:\Users\Administrator\.m2\repository\org\apache\james\apache-mime4j\0.6\apache-mime4j-0.6.jar;C:\Users\Administrator\.m2\repository\javax\el\javax.el-api\2.2.5\javax.el-api-2.2.5.jar;C:\Users\Administrator\.m2\repository\org\glassfish\web\javax.el\2.2.6\javax.el-2.2.6.jar;C:\Users\Administrator\.m2\repository\com\alibaba\dubbo\2.4.10\dubbo-2.4.10.jar;C:\Users\Administrator\.m2\repository\org\jboss\netty\netty\3.2.5.Final\netty-3.2.5.Final.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\4.3.4.RELEASE\spring-beans-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\4.3.4.RELEASE\spring-core-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\1.4.2.RELEASE\spring-boot-autoconfigure-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\test-sofa-boot-starter\2.4.0\test-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\healthcheck-sofa-boot-starter\2.4.0\healthcheck-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\infra-sofa-boot-starter\2.4.0\infra-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\4.3.4.RELEASE\spring-context-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\4.3.4.RELEASE\spring-aop-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\4.3.4.RELEASE\spring-expression-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot\1.4.2.RELEASE\spring-boot-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-actuator\1.4.2.RELEASE\spring-boot-starter-actuator-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter\1.4.2.RELEASE\spring-boot-starter-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-logging\1.4.2.RELEASE\spring-boot-starter-logging-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-classic\1.1.7\logback-classic-1.1.7.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-core\1.1.7\logback-core-1.1.7.jar;C:\Users\Administrator\.m2\repository\org\slf4j\jcl-over-slf4j\1.7.21\jcl-over-slf4j-1.7.21.jar;C:\Users\Administrator\.m2\repository\org\slf4j\jul-to-slf4j\1.7.21\jul-to-slf4j-1.7.21.jar;C:\Users\Administrator\.m2\repository\org\slf4j\log4j-over-slf4j\1.7.21\log4j-over-slf4j-1.7.21.jar;C:\Users\Administrator\.m2\repository\org\yaml\snakeyaml\1.17\snakeyaml-1.17.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-actuator\1.4.2.RELEASE\spring-boot-actuator-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-web\1.4.2.RELEASE\spring-boot-starter-web-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\1.4.2.RELEASE\spring-boot-starter-tomcat-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\8.5.6\tomcat-embed-core-8.5.6.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\8.5.6\tomcat-embed-el-8.5.6.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\8.5.6\tomcat-embed-websocket-8.5.6.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.8.4\jackson-databind-2.8.4.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.8.0\jackson-annotations-2.8.0.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.8.4\jackson-core-2.8.4.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-web\4.3.4.RELEASE\spring-web-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-webmvc\4.3.4.RELEASE\spring-webmvc-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\com\alibaba\fastjson\1.2.47\fastjson-1.2.47.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\common\sofa-common-tools\1.0.12\sofa-common-tools-1.0.12.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-test\2.9.1\curator-test-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\apache\zookeeper\zookeeper\3.4.6\zookeeper-3.4.6.jar;C:\Users\Administrator\.m2\repository\log4j\log4j\1.2.16\log4j-1.2.16.jar;C:\Users\Administrator\.m2\repository\jline\jline\0.9.94\jline-0.9.94.jar;C:\Users\Administrator\.m2\repository\io\netty\netty\3.7.0.Final\netty-3.7.0.Final.jar;C:\Users\Administrator\.m2\repository\org\javassist\javassist\3.18.1-GA\javassist-3.18.1-GA.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-math\2.2\commons-math-2.2.jar;C:\Users\Administrator\.m2\repository\com\google\guava\guava\16.0.1\guava-16.0.1.jar;C:\Users\Administrator\.m2\repository\com\101tec\zkclient\0.10\zkclient-0.10.jar;D:\Program\JetBrains\IntelliJ\lib\idea_rt.jar
2018-06-03 18:41:33.969  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.library.path=C:\Program Files\Java\jdk1.8.0_141\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Java\jdk1.8.0_141\bin;C:\Program Files\Java\jdk1.8.0_141\jre\bin;C:\Program Files\Maven\bin;C:\Program Files (x86)\Git\cmd;C:\Program Files\MySQL\MySQL Utilities 1.6\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;;C:\Program Files\Mercurial;.
2018-06-03 18:41:33.969  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.io.tmpdir=C:\Users\ADMINI~1\AppData\Local\Temp\
2018-06-03 18:41:33.970  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.compiler=
2018-06-03 18:41:33.970  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:os.name=Windows 10
2018-06-03 18:41:33.970  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:os.arch=amd64
2018-06-03 18:41:33.970  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:os.version=10.0
2018-06-03 18:41:33.970  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:user.name=Administrator
2018-06-03 18:41:33.970  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:user.home=C:\Users\Administrator
2018-06-03 18:41:33.970  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:user.dir=D:\Program\Github\sofa-rpc-boot-projects
2018-06-03 18:41:33.972  INFO 12840 --- [           main] org.apache.zookeeper.ZooKeeper           : Initiating client connection, connectString=127.0.0.1:2181 sessionTimeout=60000 watcher=org.apache.curator.ConnectionState@71a3a190
2018-06-03 18:41:34.129  INFO 12840 --- [127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn          : Opening socket connection to server 127.0.0.1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
2018-06-03 18:41:34.133  INFO 12840 --- [127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn          : Socket connection established to 127.0.0.1/127.0.0.1:2181, initiating session
2018-06-03 18:41:36.034  INFO 12840 --- [127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn          : Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x10001e7028f0002, negotiated timeout = 40000
2018-06-03 18:41:36.047  INFO 12840 --- [ain-EventThread] o.a.c.f.state.ConnectionStateManager     : State change: CONNECTED
2018-06-03 18:41:36.610  WARN 12840 --- [           main] org.apache.curator.utils.ZKPaths         : The version of ZooKeeper being used doesn't support Container nodes. CreateMode.PERSISTENT will be used instead.
2018-06-03 18:41:37.759  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'helloCallbackServiceReference' of type [class com.alipay.sofa.runtime.spring.factory.ReferenceFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:37.929  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'helloFutureServiceReference' of type [class com.alipay.sofa.runtime.spring.factory.ReferenceFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:38.098  INFO 12840 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'helloSyncServiceReference' of type [class com.alipay.sofa.runtime.spring.factory.ReferenceFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:41:39.747  INFO 12840 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2018-06-03 18:41:39.794  INFO 12840 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2018-06-03 18:41:39.796  INFO 12840 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.6
2018-06-03 18:41:41.360  INFO 12840 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-06-03 18:41:41.361  INFO 12840 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 16433 ms
2018-06-03 18:41:41.896  INFO 12840 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2018-06-03 18:41:41.906  INFO 12840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'metricsFilter' to: [/*]
2018-06-03 18:41:41.907  INFO 12840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-06-03 18:41:41.907  INFO 12840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-06-03 18:41:41.908  INFO 12840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-06-03 18:41:41.908  INFO 12840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2018-06-03 18:41:41.908  INFO 12840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'webRequestLoggingFilter' to: [/*]
2018-06-03 18:41:41.908  INFO 12840 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'applicationContextIdFilter' to: [/*]
2018-06-03 18:41:46.482  INFO 12840 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@59309333: startup date [Sun Jun 03 18:41:24 CST 2018]; root of context hierarchy
2018-06-03 18:41:48.970  INFO 12840 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-06-03 18:41:48.972  INFO 12840 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-06-03 18:41:49.032  INFO 12840 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-03 18:41:49.032  INFO 12840 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-03 18:41:49.628  INFO 12840 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-03 18:41:52.669  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/autoconfig || /autoconfig.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:41:52.671  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/heapdump || /heapdump.json],methods=[GET],produces=[application/octet-stream]}" onto public void org.springframework.boot.actuate.endpoint.mvc.HeapdumpMvcEndpoint.invoke(boolean,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.io.IOException,javax.servlet.ServletException
2018-06-03 18:41:52.674  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/trace || /trace.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:41:52.676  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/health/readiness || /health/readiness.json],produces=[application/json]}" onto public java.lang.Object com.alipay.sofa.healthcheck.service.SofaBootReadinessCheckMvcEndpoint.invoke(java.security.Principal)
2018-06-03 18:41:52.681  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/info || /info.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:41:52.683  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/configprops || /configprops.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:41:52.686  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/mappings || /mappings.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:41:52.688  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/sofaboot/versions || /sofaboot/versions.json],produces=[application/json]}" onto public java.lang.Object com.alipay.sofa.infra.endpoint.SofaBootVersionEndpointMvcAdapter.invoke()
2018-06-03 18:41:52.691  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/metrics/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint.value(java.lang.String)
2018-06-03 18:41:52.692  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/metrics || /metrics.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:41:52.693  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/logfile || /logfile.json],methods=[GET || HEAD]}" onto public void org.springframework.boot.actuate.endpoint.mvc.LogFileMvcEndpoint.invoke(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException
2018-06-03 18:41:52.694  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/health || /health.json],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(java.security.Principal)
2018-06-03 18:41:52.698  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/dump || /dump.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:41:52.704  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
2018-06-03 18:41:52.705  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env || /env.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:41:52.707  INFO 12840 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/beans || /beans.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:41:54.276  INFO 12840 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-06-03 18:41:54.362  INFO 12840 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-06-03 18:41:56.646  INFO 12840 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-06-03 18:42:02.021  INFO 12840 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2018-06-03 18:42:02.035  INFO 12840 --- [           main] c.a.s.r.s.i.InvokeServerApplication      : Started InvokeServerApplication in 40.355 seconds (JVM running for 51.286)
./logs\tracelog\rpc-server-digest.log -> ./logs\tracelog\rpc-server-digest.log.2018-06-02

运行调用方式客户端范例类InvokeClientApplication查看调用方式客户端输出日志:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.2.RELEASE)

Sofa-Middleware-Log SLF4J : Actual logging.path is [ ./logs ]
2018-06-03 18:43:17.320  INFO 8380 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual logging.path is [ ./logs ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.infra Logback ]
2018-06-03 18:43:17.345  INFO 8380 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.infra Logback ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.healthcheck Logback ]
2018-06-03 18:43:17.883  INFO 8380 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.healthcheck Logback ]
2018-06-03 18:43:17.936  INFO 8380 --- [           main] c.a.s.r.s.i.InvokeClientApplication      : Starting InvokeClientApplication on Program with PID 8380 (D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-samples\target\classes started by Administrator in D:\Program\Github\sofa-rpc-boot-projects)
2018-06-03 18:43:17.937  INFO 8380 --- [           main] c.a.s.r.s.i.InvokeClientApplication      : No active profile set, falling back to default profiles: default
2018-06-03 18:43:18.039  INFO 8380 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@59309333: startup date [Sun Jun 03 18:43:18 CST 2018]; root of context hierarchy
2018-06-03 18:43:20.152  INFO 8380 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from class path resource [invoke-server-example.xml]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc.boot Logback ]
2018-06-03 18:43:20.645  INFO 8380 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc.boot Logback ]
2018-06-03 18:43:20.766  INFO 8380 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from class path resource [invoke-client-example.xml]
2018-06-03 18:43:22.872  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'com.alipay.sofa.runtime.spring.configuration.SofaRuntimeAutoConfiguration' of type [class com.alipay.sofa.runtime.spring.configuration.SofaRuntimeAutoConfiguration$$EnhancerBySpringCGLIB$$bc04971c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:22.904  WARN 8380 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloFutureServiceReference': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'sofaRuntimeContext': Requested bean is currently in creation: Is there an unresolvable circular reference?
2018-06-03 18:43:22.907  WARN 8380 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloCallbackServiceReference': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'sofaRuntimeContext': Requested bean is currently in creation: Is there an unresolvable circular reference?
2018-06-03 18:43:23.118  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'bindingConverterFactory' of type [class com.alipay.sofa.runtime.service.impl.BindingConverterFactoryImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:23.121  WARN 8380 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloFutureServiceReference': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'sofaRuntimeContext': Requested bean is currently in creation: Is there an unresolvable circular reference?
2018-06-03 18:43:23.123  WARN 8380 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloCallbackServiceReference': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'sofaRuntimeContext': Requested bean is currently in creation: Is there an unresolvable circular reference?
2018-06-03 18:43:23.295  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'bindingAdapterFactory' of type [class com.alipay.sofa.runtime.service.impl.BindingAdapterFactoryImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:23.298  WARN 8380 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloFutureServiceReference': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'sofaRuntimeContext': Requested bean is currently in creation: Is there an unresolvable circular reference?
2018-06-03 18:43:23.301  WARN 8380 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloCallbackServiceReference': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'sofaRuntimeContext': Requested bean is currently in creation: Is there an unresolvable circular reference?
2018-06-03 18:43:23.303  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sofaRuntimeProperties' of type [class com.alipay.sofa.runtime.spring.config.SofaRuntimeProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:23.309  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sofaRuntimeContext' of type [class com.alipay.sofa.runtime.spi.component.SofaRuntimeContext] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.runtime Logback ]
2018-06-03 18:43:23.442  INFO 8380 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.runtime Logback ]
2018-06-03 18:43:23.457  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'com.alipay.sofa.rpc.boot.SofaBootRpcAutoConfiguration' of type [class com.alipay.sofa.rpc.boot.SofaBootRpcAutoConfiguration$$EnhancerBySpringCGLIB$$f0635031] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:23.512  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'consumerConfigHelper' of type [class com.alipay.sofa.rpc.boot.runtime.adapter.helper.ConsumerConfigHelper] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:23.527  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'callbackImpl' of type [class com.alipay.sofa.rpc.samples.invoke.CallbackImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:23.531  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sofaBootRpcProperties' of type [class com.alipay.sofa.rpc.boot.config.SofaBootRpcProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:23.533  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'zookeeperConfigurator' of type [class com.alipay.sofa.rpc.boot.config.ZookeeperConfigurator] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:23.535  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'localFileConfigurator' of type [class com.alipay.sofa.rpc.boot.config.LocalFileConfigurator] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:23.535  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'registryConfigContainer' of type [class com.alipay.sofa.rpc.boot.container.RegistryConfigContainer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Logback ]
2018-06-03 18:43:23.655  INFO 8380 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Logback ]
2018-06-03 18:43:23.961  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'consumerConfigContainer' of type [class com.alipay.sofa.rpc.boot.container.ConsumerConfigContainer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:24.257  INFO 8380 --- [           main] o.a.c.f.imps.CuratorFrameworkImpl        : Starting
2018-06-03 18:43:24.267  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:zookeeper.version=3.4.6-1569965, built on 02/20/2014 09:09 GMT
2018-06-03 18:43:24.267  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:host.name=Program
2018-06-03 18:43:24.267  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.version=1.8.0_141
2018-06-03 18:43:24.267  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.vendor=Oracle Corporation
2018-06-03 18:43:24.267  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.home=C:\Program Files\Java\jdk1.8.0_141\jre
2018-06-03 18:43:24.268  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.class.path=C:\Program Files\Java\jdk1.8.0_141\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\rt.jar;D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-samples\target\classes;D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-starter\target\classes;C:\Users\Administrator\.m2\repository\com\alipay\sofa\sofa-rpc-all\5.4.0\sofa-rpc-all-5.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\bolt\1.4.1\bolt-1.4.1.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\1.7.21\slf4j-api-1.7.21.jar;C:\Users\Administrator\.m2\repository\io\netty\netty-all\4.1.25.Final\netty-all-4.1.25.Final.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\hessian\3.3.0\hessian-3.3.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\tracer-core\2.1.1\tracer-core-2.1.1.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-api\0.22.0\opentracing-api-0.22.0.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-noop\0.22.0\opentracing-noop-0.22.0.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-mock\0.22.0\opentracing-mock-0.22.0.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-util\0.22.0\opentracing-util-0.22.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\lookout\lookout-api\1.4.0\lookout-api-1.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\runtime-sofa-boot-starter\2.4.0\runtime-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-client\2.9.1\curator-client-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-framework\2.9.1\curator-framework-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-recipes\2.9.1\curator-recipes-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-jaxrs\3.0.12.Final\resteasy-jaxrs-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\spec\javax\annotation\jboss-annotations-api_1.1_spec\1.0.1.Final\jboss-annotations-api_1.1_spec-1.0.1.Final.jar;C:\Users\Administrator\.m2\repository\javax\activation\activation\1.1.1\activation-1.1.1.jar;C:\Users\Administrator\.m2\repository\org\apache\httpcomponents\httpclient\4.3.6\httpclient-4.3.6.jar;C:\Users\Administrator\.m2\repository\org\apache\httpcomponents\httpcore\4.3.3\httpcore-4.3.3.jar;C:\Users\Administrator\.m2\repository\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;C:\Users\Administrator\.m2\repository\commons-codec\commons-codec\1.6\commons-codec-1.6.jar;C:\Users\Administrator\.m2\repository\commons-io\commons-io\2.1\commons-io-2.1.jar;C:\Users\Administrator\.m2\repository\net\jcip\jcip-annotations\1.0\jcip-annotations-1.0.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-client\3.0.12.Final\resteasy-client-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-jackson-provider\3.0.12.Final\resteasy-jackson-provider-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-core-asl\1.9.12\jackson-core-asl-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-mapper-asl\1.9.12\jackson-mapper-asl-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-jaxrs\1.9.12\jackson-jaxrs-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-xc\1.9.12\jackson-xc-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-netty4\3.0.12.Final\resteasy-netty4-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-validator-provider-11\3.0.12.Final\resteasy-validator-provider-11-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\hibernate\hibernate-validator\5.0.1.Final\hibernate-validator-5.0.1.Final.jar;C:\Users\Administrator\.m2\repository\javax\validation\validation-api\1.1.0.Final\validation-api-1.1.0.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\logging\jboss-logging\3.1.1.GA\jboss-logging-3.1.1.GA.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\classmate\0.8.0\classmate-0.8.0.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\jaxrs-api\3.0.12.Final\jaxrs-api-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-multipart-provider\3.0.12.Final\resteasy-multipart-provider-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-jaxb-provider\3.0.12.Final\resteasy-jaxb-provider-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\com\sun\xml\bind\jaxb-impl\2.2.7\jaxb-impl-2.2.7.jar;C:\Users\Administrator\.m2\repository\com\sun\xml\bind\jaxb-core\2.2.7\jaxb-core-2.2.7.jar;C:\Users\Administrator\.m2\repository\javax\xml\bind\jaxb-api\2.2.7\jaxb-api-2.2.7.jar;C:\Users\Administrator\.m2\repository\com\sun\istack\istack-commons-runtime\2.16\istack-commons-runtime-2.16.jar;C:\Users\Administrator\.m2\repository\com\sun\xml\fastinfoset\FastInfoset\1.2.12\FastInfoset-1.2.12.jar;C:\Users\Administrator\.m2\repository\javax\xml\bind\jsr173_api\1.0\jsr173_api-1.0.jar;C:\Users\Administrator\.m2\repository\javax\mail\mail\1.5.0-b01\mail-1.5.0-b01.jar;C:\Users\Administrator\.m2\repository\org\apache\james\apache-mime4j\0.6\apache-mime4j-0.6.jar;C:\Users\Administrator\.m2\repository\javax\el\javax.el-api\2.2.5\javax.el-api-2.2.5.jar;C:\Users\Administrator\.m2\repository\org\glassfish\web\javax.el\2.2.6\javax.el-2.2.6.jar;C:\Users\Administrator\.m2\repository\com\alibaba\dubbo\2.4.10\dubbo-2.4.10.jar;C:\Users\Administrator\.m2\repository\org\jboss\netty\netty\3.2.5.Final\netty-3.2.5.Final.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\4.3.4.RELEASE\spring-beans-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\4.3.4.RELEASE\spring-core-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\1.4.2.RELEASE\spring-boot-autoconfigure-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\test-sofa-boot-starter\2.4.0\test-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\healthcheck-sofa-boot-starter\2.4.0\healthcheck-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\infra-sofa-boot-starter\2.4.0\infra-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\4.3.4.RELEASE\spring-context-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\4.3.4.RELEASE\spring-aop-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\4.3.4.RELEASE\spring-expression-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot\1.4.2.RELEASE\spring-boot-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-actuator\1.4.2.RELEASE\spring-boot-starter-actuator-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter\1.4.2.RELEASE\spring-boot-starter-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-logging\1.4.2.RELEASE\spring-boot-starter-logging-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-classic\1.1.7\logback-classic-1.1.7.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-core\1.1.7\logback-core-1.1.7.jar;C:\Users\Administrator\.m2\repository\org\slf4j\jcl-over-slf4j\1.7.21\jcl-over-slf4j-1.7.21.jar;C:\Users\Administrator\.m2\repository\org\slf4j\jul-to-slf4j\1.7.21\jul-to-slf4j-1.7.21.jar;C:\Users\Administrator\.m2\repository\org\slf4j\log4j-over-slf4j\1.7.21\log4j-over-slf4j-1.7.21.jar;C:\Users\Administrator\.m2\repository\org\yaml\snakeyaml\1.17\snakeyaml-1.17.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-actuator\1.4.2.RELEASE\spring-boot-actuator-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-web\1.4.2.RELEASE\spring-boot-starter-web-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\1.4.2.RELEASE\spring-boot-starter-tomcat-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\8.5.6\tomcat-embed-core-8.5.6.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\8.5.6\tomcat-embed-el-8.5.6.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\8.5.6\tomcat-embed-websocket-8.5.6.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.8.4\jackson-databind-2.8.4.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.8.0\jackson-annotations-2.8.0.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.8.4\jackson-core-2.8.4.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-web\4.3.4.RELEASE\spring-web-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-webmvc\4.3.4.RELEASE\spring-webmvc-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\com\alibaba\fastjson\1.2.47\fastjson-1.2.47.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\common\sofa-common-tools\1.0.12\sofa-common-tools-1.0.12.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-test\2.9.1\curator-test-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\apache\zookeeper\zookeeper\3.4.6\zookeeper-3.4.6.jar;C:\Users\Administrator\.m2\repository\log4j\log4j\1.2.16\log4j-1.2.16.jar;C:\Users\Administrator\.m2\repository\jline\jline\0.9.94\jline-0.9.94.jar;C:\Users\Administrator\.m2\repository\io\netty\netty\3.7.0.Final\netty-3.7.0.Final.jar;C:\Users\Administrator\.m2\repository\org\javassist\javassist\3.18.1-GA\javassist-3.18.1-GA.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-math\2.2\commons-math-2.2.jar;C:\Users\Administrator\.m2\repository\com\google\guava\guava\16.0.1\guava-16.0.1.jar;C:\Users\Administrator\.m2\repository\com\101tec\zkclient\0.10\zkclient-0.10.jar;D:\Program\JetBrains\IntelliJ\lib\idea_rt.jar
2018-06-03 18:43:24.269  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.library.path=C:\Program Files\Java\jdk1.8.0_141\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Java\jdk1.8.0_141\bin;C:\Program Files\Java\jdk1.8.0_141\jre\bin;C:\Program Files\Maven\bin;C:\Program Files (x86)\Git\cmd;C:\Program Files\MySQL\MySQL Utilities 1.6\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;;C:\Program Files\Mercurial;.
2018-06-03 18:43:24.270  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.io.tmpdir=C:\Users\ADMINI~1\AppData\Local\Temp\
2018-06-03 18:43:24.270  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.compiler=
2018-06-03 18:43:24.270  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:os.name=Windows 10
2018-06-03 18:43:24.270  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:os.arch=amd64
2018-06-03 18:43:24.270  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:os.version=10.0
2018-06-03 18:43:24.270  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:user.name=Administrator
2018-06-03 18:43:24.270  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:user.home=C:\Users\Administrator
2018-06-03 18:43:24.270  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:user.dir=D:\Program\Github\sofa-rpc-boot-projects
2018-06-03 18:43:24.272  INFO 8380 --- [           main] org.apache.zookeeper.ZooKeeper           : Initiating client connection, connectString=127.0.0.1:2181 sessionTimeout=60000 watcher=org.apache.curator.ConnectionState@4b1c0397
2018-06-03 18:43:24.374  INFO 8380 --- [127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn          : Opening socket connection to server 127.0.0.1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
2018-06-03 18:43:24.378  INFO 8380 --- [127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn          : Socket connection established to 127.0.0.1/127.0.0.1:2181, initiating session
2018-06-03 18:43:24.423  INFO 8380 --- [127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn          : Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x10001e7028f0003, negotiated timeout = 40000
2018-06-03 18:43:24.434  INFO 8380 --- [ain-EventThread] o.a.c.f.state.ConnectionStateManager     : State change: CONNECTED
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-06-03 18:43:24.700  INFO 8380 --- [ackService-3-T1] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-06-03 18:43:25.482  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'helloCallbackServiceReference' of type [class com.alipay.sofa.runtime.spring.factory.ReferenceFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:25.630  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'helloFutureServiceReference' of type [class com.alipay.sofa.runtime.spring.factory.ReferenceFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:25.790  INFO 8380 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'helloSyncServiceReference' of type [class com.alipay.sofa.runtime.spring.factory.ReferenceFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-03 18:43:27.129  INFO 8380 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8081 (http)
2018-06-03 18:43:27.158  INFO 8380 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2018-06-03 18:43:27.161  INFO 8380 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.6
2018-06-03 18:43:28.863  INFO 8380 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-06-03 18:43:28.864  INFO 8380 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 10825 ms
2018-06-03 18:43:29.378  INFO 8380 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2018-06-03 18:43:29.385  INFO 8380 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'metricsFilter' to: [/*]
2018-06-03 18:43:29.386  INFO 8380 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-06-03 18:43:29.386  INFO 8380 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-06-03 18:43:29.386  INFO 8380 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-06-03 18:43:29.387  INFO 8380 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2018-06-03 18:43:29.387  INFO 8380 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'webRequestLoggingFilter' to: [/*]
2018-06-03 18:43:29.387  INFO 8380 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'applicationContextIdFilter' to: [/*]
2018-06-03 18:43:30.579  INFO 8380 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@59309333: startup date [Sun Jun 03 18:43:18 CST 2018]; root of context hierarchy
2018-06-03 18:43:30.711  INFO 8380 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-06-03 18:43:30.714  INFO 8380 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-06-03 18:43:30.786  INFO 8380 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-03 18:43:30.787  INFO 8380 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-03 18:43:30.870  INFO 8380 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-03 18:43:31.416  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/logfile || /logfile.json],methods=[GET || HEAD]}" onto public void org.springframework.boot.actuate.endpoint.mvc.LogFileMvcEndpoint.invoke(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException
2018-06-03 18:43:31.423  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/mappings || /mappings.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:43:31.424  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/info || /info.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:43:31.427  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/trace || /trace.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:43:31.427  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/sofaboot/versions || /sofaboot/versions.json],produces=[application/json]}" onto public java.lang.Object com.alipay.sofa.infra.endpoint.SofaBootVersionEndpointMvcAdapter.invoke()
2018-06-03 18:43:31.428  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/autoconfig || /autoconfig.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:43:31.430  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/beans || /beans.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:43:31.432  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/configprops || /configprops.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:43:31.433  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/heapdump || /heapdump.json],methods=[GET],produces=[application/octet-stream]}" onto public void org.springframework.boot.actuate.endpoint.mvc.HeapdumpMvcEndpoint.invoke(boolean,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.io.IOException,javax.servlet.ServletException
2018-06-03 18:43:31.433  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/health/readiness || /health/readiness.json],produces=[application/json]}" onto public java.lang.Object com.alipay.sofa.healthcheck.service.SofaBootReadinessCheckMvcEndpoint.invoke(java.security.Principal)
2018-06-03 18:43:31.434  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/health || /health.json],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(java.security.Principal)
2018-06-03 18:43:31.437  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/dump || /dump.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:43:31.442  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
2018-06-03 18:43:31.442  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env || /env.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:43:31.444  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/metrics/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint.value(java.lang.String)
2018-06-03 18:43:31.444  INFO 8380 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/metrics || /metrics.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-03 18:43:31.696  INFO 8380 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-06-03 18:43:31.720  INFO 8380 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2018-06-03 18:43:33.884  INFO 8380 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8081 (http)
2018-06-03 18:43:33.891  INFO 8380 --- [           main] c.a.s.r.s.i.InvokeClientApplication      : Started InvokeClientApplication in 17.344 seconds (JVM running for 19.729)
./logs\tracelog\rpc-client-digest.log -> ./logs\tracelog\rpc-client-digest.log.2018-06-02
sync
future
callback client process:callback

(1)Sync同步调用
SOFARPC同步调用流程:
[1]创建服务引用配置类ConsumerConfig,设置ConsumerConfig实例应用信息配置、接口名称、直连调用地址以及连接超时时间,通过setInvokeType设置服务引用调用类型为RpcConstants.INVOKER_TYPE_SYNC(sync),默认服务引用调用类型invokeType为sync。客户端代理调用器ClientProxyInvoker实施Proxy拦截调用包装请求,默认客户端代理调用器DefaultClientProxyInvoker判断是否泛化调用根据请求方法调用类型设置请求调用类型invokeType:

/**
 * 调用方式:同步调用
 */
public static final String  INVOKER_TYPE_SYNC  = "sync";

protected void decorateRequest(SofaRequest request) {
    // 公共的设置
    super.decorateRequest(request);

    // 缓存是为了加快速度
    request.setTargetServiceUniqueName(serviceName);
    request.setSerializeType(serializeType == null ? 0 : serializeType);

    if (!consumerConfig.isGeneric()) {
        // 找到调用类型, generic的时候类型在filter里进行判断
        request.setInvokeType(consumerConfig.getMethodInvokeType(request.getMethodName()));
    }

    RpcInvokeContext invokeCtx = RpcInvokeContext.peekContext();
    RpcInternalContext internalContext = RpcInternalContext.getContext();
    if (invokeCtx != null) {
        // 如果用户设置了调用级别回调函数
        SofaResponseCallback responseCallback = invokeCtx.getResponseCallback();
        if (responseCallback != null) {
            request.setSofaResponseCallback(responseCallback);
            invokeCtx.setResponseCallback(null); // 一次性用完
            invokeCtx.put(RemotingConstants.INVOKE_CTX_IS_ASYNC_CHAIN,
                isSendableResponseCallback(responseCallback));
        }
        // 如果用户设置了调用级别超时时间
        Integer timeout = invokeCtx.getTimeout();
        if (timeout != null) {
            request.setTimeout(timeout);
            invokeCtx.setTimeout(null);// 一次性用完
        }
        // 如果用户指定了调用的URL
        String targetURL = invokeCtx.getTargetURL();
        if (targetURL != null) {
            internalContext.setAttachment(HIDDEN_KEY_PINPOINT, targetURL);
            invokeCtx.setTargetURL(null);// 一次性用完
        }
        // 如果用户指定了透传数据
        if (RpcInvokeContext.isBaggageEnable()) {
            // 需要透传
            BaggageResolver.carryWithRequest(invokeCtx, request);
            internalContext.setAttachment(HIDDEN_KEY_INVOKE_CONTEXT, invokeCtx);
        }
    }
    if (RpcInternalContext.isAttachmentEnable()) {
        internalContext.setAttachment(INTERNAL_KEY_APP_NAME, consumerConfig.getAppName());
        internalContext.setAttachment(INTERNAL_KEY_PROTOCOL_NAME, consumerConfig.getProtocol());
    }

    // 额外属性通过HEAD传递给服务端
    request.addRequestProp(RemotingConstants.HEAD_APP_NAME, consumerConfig.getAppName());
    request.addRequestProp(RemotingConstants.HEAD_PROTOCOL, consumerConfig.getProtocol());
}
rpc-config-default.json:
// 默认是否异步
"consumer.invokeType": "sync"

[2]服务引用配置类ConsumerConfig调用服务消费者启动类ConsumerBootstrap的refer()方法引用服务,消费者调用器ConsumerInvoker调用invoke()方法使用客户端发送数据给服务器执行客户端集群Cluster的doSendMsg()方法Sync同步调用:

/**
 * 调用客户端
 *
 * @param transport 客户端连接
 * @param request   Request对象
 * @return 调用结果
 * @throws SofaRpcException rpc异常
 */
protected SofaResponse doSendMsg(ProviderInfo providerInfo, ClientTransport transport,
                                 SofaRequest request) throws SofaRpcException {
    RpcInternalContext context = RpcInternalContext.getContext();
    // 添加调用的服务端远程地址
    RpcInternalContext.getContext().setRemoteAddress(providerInfo.getHost(), providerInfo.getPort());
    try {
        checkProviderVersion(providerInfo, request); // 根据服务端版本特殊处理
        String invokeType = request.getInvokeType();
        int timeout = resolveTimeout(request, consumerConfig, providerInfo);

        SofaResponse response = null;
        // 同步调用
        if (RpcConstants.INVOKER_TYPE_SYNC.equals(invokeType)) {
            long start = RpcRuntimeContext.now();
            try {
                response = transport.syncSend(request, timeout);
            } finally {
                if (RpcInternalContext.isAttachmentEnable()) {
                    long elapsed = RpcRuntimeContext.now() - start;
                    context.setAttachment(RpcConstants.INTERNAL_KEY_CLIENT_ELAPSE, elapsed);
                }
            }
        } else {
            throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR, "Unknown invoke type:" + invokeType);
        }
        return response;
    } catch (SofaRpcException e) {
        throw e;
    } catch (Throwable e) { // 客户端其它异常
        throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR, e);
    }
}

客户端集群Cluster根据请求调用类型判断是否为同步调用类型,客户端传输ClientTransport调用syncSend()方法指定超时时间范畴同步调用发送请求阻塞等待响应获取调用结果,基于ThreadLocal上下文传递RpcInternalContext记录客户端总耗时:

/**
 * 同步调用
 *
 * @param message 消息
 * @param timeout 超时时间
 * @return SofaResponse base message
 * @throws SofaRpcException SofaRpcException
 */
public abstract SofaResponse syncSend(SofaRequest message, int timeout) throws SofaRpcException;

Bolt客户端传输BoltClientTransport/H2&H2C客户端传输AbstractHttp2ClientTransport/第三方协议代理客户端传输AbstractProxyClientTransport同步调用syncSend过程:检查长连接,获取基于ThreadLocal上下文传递RpcInternalContext,[BoltClientTransport根据SofaRequest请求创建调用上下文],通过doInvokeSync()方法执行同步调用。

/**
 * 注意,bolt的实现只支持长连接共享模式。
 */
@Extension("bolt")
public class BoltClientTransport extends ClientTransport {
  public SofaResponse syncSend(SofaRequest request, int timeout) throws SofaRpcException {
    checkConnection();
    RpcInternalContext context = RpcInternalContext.getContext();
    InvokeContext boltInvokeContext = createInvokeContext(request);
    SofaResponse response = null;
    SofaRpcException throwable = null;
    try {
        beforeSend(context, request);
        response = doInvokeSync(request, boltInvokeContext, timeout);
        return response;
    } catch (Exception e) { // 其它异常
        throwable = convertToRpcException(e);
        throw throwable;
    } finally {
        afterSend(context, boltInvokeContext, request);
        if (EventBus.isEnable(ClientSyncReceiveEvent.class)) {
            EventBus.post(new ClientSyncReceiveEvent(transportConfig.getConsumerConfig(),
                transportConfig.getProviderInfo(), request, response, throwable));
        }
    }
 }

/**
 * 同步调用
 *
 * @param request       请求对象
 * @param invokeContext 调用上下文
 * @param timeoutMillis 超时时间(毫秒)
 * @return 返回对象
 * @throws RemotingException    远程调用异常
 * @throws InterruptedException 中断异常
 * @since 5.2.0
 */
 protected SofaResponse doInvokeSync(SofaRequest request, InvokeContext invokeContext, int timeoutMillis)
    throws RemotingException, InterruptedException {
    return (SofaResponse) RPC_CLIENT.invokeSync(url, request, invokeContext, timeoutMillis);
  }
}
/**
 * h2和h2c通用的客户端传输层
 */
public abstract class AbstractHttp2ClientTransport extends ClientTransport {
  public SofaResponse syncSend(SofaRequest request, int timeout) throws SofaRpcException {
    checkConnection();
    RpcInternalContext context = RpcInternalContext.getContext();
    try {
        beforeSend(context, request);
        return doInvokeSync(request, timeout);
    } catch (TimeoutException e) {
        throw timeoutException(request, timeout, e);
    } catch (SofaRpcException e) {
        throw e;
    } catch (Exception e) {
        throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR, e.getMessage(), e);
    } finally {
        afterSend(context, request);
    }
 }
 
 /**
 * 同步调用
 *
 * @param request 请求对象
 * @param timeout 超时时间(毫秒)
 * @return 返回对象
 * @throws InterruptedException 中断异常
 * @throws ExecutionException   执行异常
 * @throws TimeoutException     超时异常
 */
  protected SofaResponse doInvokeSync(SofaRequest request, int timeout) throws InterruptedException,
    ExecutionException, TimeoutException {
    HttpResponseFuture future = new HttpResponseFuture(request, timeout);
    AbstractHttpClientHandler callback = new SyncInvokeClientHandler(transportConfig.getConsumerConfig(),
        transportConfig.getProviderInfo(), future, request, RpcInternalContext.getContext(),
        ClassLoaderUtils.getCurrentClassLoader());
    future.setSentTime();
    doSend(request, callback, timeout);
    future.setSentTime();
    return future.getSofaResponse(timeout, TimeUnit.MILLISECONDS);
  }
}

/**
 * Abstract ProxyClientTransport for 3rd protocol, like cxf/resteasy.
 */
public abstract class AbstractProxyClientTransport extends ClientTransport {
  public SofaResponse syncSend(SofaRequest request, int timeout) throws SofaRpcException {
    RpcInternalContext context = RpcInternalContext.getContext();
    SofaResponse response = null;
    SofaRpcException throwable = null;
    try {
        beforeSend(context, request);
        if (EventBus.isEnable(ClientBeforeSendEvent.class)) {
            EventBus.post(new ClientBeforeSendEvent(request));
        }
        response = doInvokeSync(request, timeout);
        return response;
    } catch (InvocationTargetException e) {
        throwable = convertToRpcException(e);
        throw throwable;
    } catch (SofaRpcException e) {
        throwable = e;
        throw e;
    } catch (Exception e) {
        throwable = new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR,
            "Failed to send message to remote", e);
        throw throwable;
    } finally {
        afterSend(context, request);
        if (EventBus.isEnable(ClientSyncReceiveEvent.class)) {
            EventBus.post(new ClientSyncReceiveEvent(transportConfig.getConsumerConfig(),
                transportConfig.getProviderInfo(), request, response, throwable));
        }
    }
 }

/**
 * 同步调用
 *
 * @param request       请求对象
 * @param timeoutMillis 超时时间(毫秒)
 * @return 返回对象
 * @throws InvocationTargetException 反射调用异常
 * @since 5.2.0
 */
 protected SofaResponse doInvokeSync(SofaRequest request, int timeoutMillis)
    throws InvocationTargetException, IllegalAccessException {
    SofaResponse response = new SofaResponse();
    Method method = getMethod(request);
    if (method == null) {
        throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR,
            "Not found method :" + request.getInterfaceName() + "." + request.getMethodName());
    }
    Object o = method.invoke(proxy, request.getMethodArgs());
    response.setAppResponse(o);
    return response;
 }
}

Bolt客户端传输BoltClientTransport doInvokeSync同步调用通过RpcClient调用RPC远程连接RpcRemoting的invokeSync()方法根据调用请求URL获取检查远程连接,根据远程请求命令RemotingCommand和调用上下文InvokeContext创建InvokeFuture添加到远程连接的invokeFutureMap键值对,使用管道Channel的writeAndFlush(Object msg)方法异步发送客户端数据给服务端,并且添加监听器提供操作完成发送失败Future添加失败响应场景监听,InvokeFuture根据超时时间等待获取响应命令并且唤醒等待响应结果线程,响应命令解析反序列化返回响应对象结果:

/**
 * Synchronous rpc invocation.
* Notice! DO NOT modify the request object concurrently when this method is called. * * @param conn * @param request * @param invokeContext * @param timeoutMillis * @return * @throws RemotingException * @throws InterruptedException */ public Object invokeSync(Connection conn, Object request, InvokeContext invokeContext, int timeoutMillis) throws RemotingException, InterruptedException { RemotingCommand requestCommand = this.toRemotingCommand(request, conn, invokeContext, timeoutMillis); this.preProcessInvokeContext(invokeContext, requestCommand, conn); ResponseCommand responseCommand = (ResponseCommand)super.invokeSync(conn, requestCommand, timeoutMillis); responseCommand.setInvokeContext(invokeContext); Object responseObject = RpcResponseResolver.resolveResponseObject(responseCommand, RemotingUtil.parseRemoteAddress(conn.getChannel())); return responseObject; } /** * Synchronous invocation * * @param conn * @param request * @param timeoutMillis * @return * @throws InterruptedException * @throws RemotingException */ protected RemotingCommand invokeSync(final Connection conn, final RemotingCommand request, int timeoutMillis) throws RemotingException, InterruptedException { final InvokeFuture future = this.createInvokeFuture(request, request.getInvokeContext()); conn.addInvokeFuture(future); try { conn.getChannel().writeAndFlush(request).addListener(new ChannelFutureListener() { public void operationComplete(ChannelFuture f) throws Exception { if (!f.isSuccess()) { conn.removeInvokeFuture(request.getId()); future.putResponse(BaseRemoting.this.commandFactory.createSendFailedResponse(conn.getRemoteAddress(), f.cause())); BaseRemoting.logger.error("Invoke send failed, id={}", request.getId(), f.cause()); } } }); } catch (Exception var6) { conn.removeInvokeFuture(request.getId()); if (future != null) { future.putResponse(this.commandFactory.createSendFailedResponse(conn.getRemoteAddress(), var6)); } logger.error("Exception caught when sending invocation, id={}", request.getId(), var6); } RemotingCommand response = future.waitResponse((long)timeoutMillis); if (response == null) { conn.removeInvokeFuture(request.getId()); response = this.commandFactory.createTimeoutResponse(conn.getRemoteAddress()); logger.warn("Wait response, request id={} timeout!", request.getId()); } return response; } /** * Wait response with timeout. * * @param timeoutMillis * @return * @throws InterruptedException */ public ResponseCommand waitResponse(long timeoutMillis) throws InterruptedException { this.countDownLatch.await(timeoutMillis, TimeUnit.MILLISECONDS); return this.responseCommand; }

什么时候调用DefaultInvokeFuture的putResponse方法设置响应命令ResponseCommand?查看DefaultInvokeFuture的putResponse方法调用链:
SOFARPC源码解析-服务调用_第2张图片
DefaultInvokeFuture的putResponse方法调用链

DefaultInvokeFuture的putResponse方法调用链顶端是通过RpcRequestProcessor处理器ProcessTask处理任务调用,ProcessTask构造方法调用链顶端是通过RpcHandler处理器的channelRead方法读取管道Channel服务端响应返回结果。
(2)Future异步调用
参考SOFARPC Example示例模块(com.alipay.sofa.rpc.invoke.future):

package com.alipay.sofa.rpc.invoke.future;

import com.alipay.sofa.rpc.config.ApplicationConfig;
import com.alipay.sofa.rpc.config.ProviderConfig;
import com.alipay.sofa.rpc.config.ServerConfig;
import com.alipay.sofa.rpc.test.EchoService;
import com.alipay.sofa.rpc.test.EchoServiceImpl;
import com.alipay.sofa.rpc.test.HelloService;
import com.alipay.sofa.rpc.test.HelloServiceImpl;

public class FutureServerMain {

    public static void main(String[] args) {

        ApplicationConfig applicationConfig = new ApplicationConfig().setAppName("future-server");

        ServerConfig serverConfig2 = new ServerConfig()
            .setPort(22222)
            .setDaemon(false);

        ProviderConfig providerConfig = new ProviderConfig()
            .setApplication(applicationConfig)
            .setInterfaceId(HelloService.class.getName())
            .setRef(new HelloServiceImpl(1000))
            .setServer(serverConfig2);
        providerConfig.export();

        ProviderConfig providerConfig2 = new ProviderConfig()
            .setApplication(applicationConfig)
            .setInterfaceId(EchoService.class.getName())
            .setRef(new EchoServiceImpl())
            .setServer(serverConfig2);
        providerConfig2.export();
    }
}
package com.alipay.sofa.rpc.invoke.future;

import com.alipay.sofa.rpc.api.future.SofaResponseFuture;
import com.alipay.sofa.rpc.common.RpcConstants;
import com.alipay.sofa.rpc.config.ApplicationConfig;
import com.alipay.sofa.rpc.config.ConsumerConfig;
import com.alipay.sofa.rpc.context.RpcRuntimeContext;
import com.alipay.sofa.rpc.log.Logger;
import com.alipay.sofa.rpc.log.LoggerFactory;
import com.alipay.sofa.rpc.message.bolt.BoltResponseFuture;
import com.alipay.sofa.rpc.test.EchoService;
import com.alipay.sofa.rpc.test.HelloService;

/**
 * 

接口级别的Callback

*/ public class FutureClientMain { /** * slf4j Logger for this class */ private final static Logger LOGGER = LoggerFactory.getLogger(FutureClientMain.class); public static void main(String[] args) throws InterruptedException { ApplicationConfig applicationConfig = new ApplicationConfig().setAppName("future-client"); ConsumerConfig consumerConfig = new ConsumerConfig() .setApplication(applicationConfig) .setInterfaceId(HelloService.class.getName()) .setInvokeType(RpcConstants.INVOKER_TYPE_FUTURE) .setTimeout(50000) .setDirectUrl("bolt://127.0.0.1:22222?appName=future-server"); HelloService helloService = consumerConfig.refer(); ConsumerConfig consumerConfig2 = new ConsumerConfig() .setApplication(applicationConfig) .setInterfaceId(EchoService.class.getName()) .setInvokeType(RpcConstants.INVOKER_TYPE_FUTURE) .setTimeout(50000) .setDirectUrl("bolt://127.0.0.1:22222?appName=future-server"); EchoService echoService = consumerConfig2.refer(); LOGGER.warn("started at pid {}", RpcRuntimeContext.PID); while (true) { try { String s1 = helloService.sayHello("xxx", 22); LOGGER.warn("must null :{}", s1); BoltResponseFuture future1 = (BoltResponseFuture) SofaResponseFuture.getFuture(); String s2 = echoService.echoStr("yyy"); LOGGER.warn("must null :{}", s2); BoltResponseFuture future2 = (BoltResponseFuture) SofaResponseFuture.getFuture(); s1 = (String) future1.get(); LOGGER.warn("get future1: {}, elapse: {}", s1, future1.getElapsedTime()); s2 = (String) future2.get(); LOGGER.warn("get future2: {}, elapse: {}", s2, future2.getElapsedTime()); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } try { Thread.sleep(2000); } catch (Exception ignore) { } } } }

运行异步调用服务端示例类FutureServerMain查看异步调用服务端输出日志:

2018-06-03 17:55:39,466 main  INFO [com.alipay.sofa.rpc.context.RpcRuntimeContext:info:102] - Welcome! Loading SOFA RPC Framework : 5.4.0_20180530235405, PID is:4208
2018-06-03 17:55:39,806 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: fault-tolerance
2018-06-03 17:55:39,915 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer-resteasy
2018-06-03 17:55:41,136 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:97] - The module lookout does not need to be loaded.
2018-06-03 17:55:41,175 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer
2018-06-03 17:55:42,157 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultProviderBootstrap:infoWithApp:122] - [future-server]Export provider config : com.alipay.sofa.rpc.test.HelloService: with bean id rpc-cfg-0
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 17:55:43,673 main  INFO [com.alipay.sofa.common.log:report:30] - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 17:55:45,134 main  INFO [com.alipay.sofa.rpc.server.bolt.BoltServer:info:102] - Bolt server has been bind to 0.0.0.0:22222
2018-06-03 17:55:45,255 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultProviderBootstrap:infoWithApp:122] - [future-server]Export provider config : com.alipay.sofa.rpc.test.EchoService: with bean id rpc-cfg-1
2018-06-03 17:56:15,090 SOFA-SEV-BOLT-BIZ-22222-3-T1  INFO [com.alipay.sofa.rpc.tracer.Tracers:info:102] - Load tracer impl success: sofaTracer, com.alipay.sofa.rpc.tracer.sofatracer.RpcSofaTracer@33cb737a
name:xxx, age:22
C:\Users\Administrator\logs\tracelog\rpc-server-digest.log -> C:\Users\Administrator\logs\tracelog\rpc-server-digest.log.2018-06-02
name:xxx, age:22

运行异步调用客户端示例类FutureClientMain查看异步调用客户端输出日志:

2018-06-03 17:56:01,298 main  INFO [com.alipay.sofa.rpc.context.RpcRuntimeContext:info:102] - Welcome! Loading SOFA RPC Framework : 5.4.0_20180530235405, PID is:14812
2018-06-03 17:56:01,902 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: fault-tolerance
2018-06-03 17:56:02,442 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer-resteasy
2018-06-03 17:56:04,501 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:97] - The module lookout does not need to be loaded.
2018-06-03 17:56:04,540 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer
2018-06-03 17:56:05,855 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultConsumerBootstrap:infoWithApp:122] - [future-client]Refer consumer config : bolt://com.alipay.sofa.rpc.test.HelloService: with bean id rpc-cfg-0
2018-06-03 17:56:08,650 main  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [future-client]Add provider of com.alipay.sofa.rpc.test.HelloService, size is : 1
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 17:56:09,367 SOFA-CLI-CONN-com.alipay.sofa.rpc.test.HelloService-3-T1  INFO [com.alipay.sofa.common.log:report:30] - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 17:56:11,735 SOFA-CLI-CONN-com.alipay.sofa.rpc.test.HelloService-3-T1  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [future-client]Connect to com.alipay.sofa.rpc.test.HelloService provider:bolt://127.0.0.1:22222?appName=future-server success ! The connection is 127.0.0.1:22222 <-> 127.0.0.1:50693
2018-06-03 17:56:12,460 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultConsumerBootstrap:infoWithApp:122] - [future-client]Refer consumer config : bolt://com.alipay.sofa.rpc.test.EchoService: with bean id rpc-cfg-1
2018-06-03 17:56:12,463 main  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [future-client]Add provider of com.alipay.sofa.rpc.test.EchoService, size is : 1
2018-06-03 17:56:12,564 SOFA-CLI-CONN-com.alipay.sofa.rpc.test.EchoService-5-T1  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [future-client]Connect to com.alipay.sofa.rpc.test.EchoService provider:bolt://127.0.0.1:22222?appName=future-server success ! The connection is 127.0.0.1:22222 <-> 127.0.0.1:50693
2018-06-03 17:56:12,586 main  WARN [com.alipay.sofa.rpc.invoke.future.FutureClientMain:warn:142] - started at pid 14812
2018-06-03 17:56:12,650 main  INFO [com.alipay.sofa.rpc.tracer.Tracers:info:102] - Load tracer impl success: sofaTracer, com.alipay.sofa.rpc.tracer.sofatracer.RpcSofaTracer@1794d431
2018-06-03 17:56:14,331 main  WARN [com.alipay.sofa.rpc.invoke.future.FutureClientMain:warn:142] - must null :null
2018-06-03 17:56:14,380 main  WARN [com.alipay.sofa.rpc.invoke.future.FutureClientMain:warn:142] - must null :null
C:\Users\Administrator\logs\tracelog\rpc-client-digest.log -> C:\Users\Administrator\logs\tracelog\rpc-client-digest.log.2018-06-02
2018-06-03 17:56:16,147 main  WARN [com.alipay.sofa.rpc.invoke.future.FutureClientMain:warn:142] - get future1: hello xxx from server! age: 22, elapse: 3162
2018-06-03 17:56:16,147 main  WARN [com.alipay.sofa.rpc.invoke.future.FutureClientMain:warn:142] - get future2: yyy, elapse: 1130
2018-06-03 17:56:18,152 main  WARN [com.alipay.sofa.rpc.invoke.future.FutureClientMain:warn:142] - must null :null
2018-06-03 17:56:18,155 main  WARN [com.alipay.sofa.rpc.invoke.future.FutureClientMain:warn:142] - must null :null
2018-06-03 17:56:19,162 main  WARN [com.alipay.sofa.rpc.invoke.future.FutureClientMain:warn:142] - get future1: hello xxx from server! age: 22, elapse: 1013
2018-06-03 17:56:19,162 main  WARN [com.alipay.sofa.rpc.invoke.future.FutureClientMain:warn:142] - get future2: yyy, elapse: 17
2018-06-03 17:56:21,166 main  WARN [com.alipay.sofa.rpc.invoke.future.FutureClientMain:warn:142] - must null :null
2018-06-03 17:56:21,170 main  WARN [com.alipay.sofa.rpc.invoke.future.FutureClientMain:warn:142] - must null :null

SOFARPC异步调用流程:
[1]创建服务引用配置类ConsumerConfig,设置ConsumerConfig实例应用信息配置、接口名称、直连调用地址以及连接超时时间,通过setInvokeType设置服务引用调用类型为RpcConstants.INVOKER_TYPE_FUTURE(future):

/**
 * 调用方式:future
 */
public static final String  INVOKER_TYPE_FUTURE   = "future";

[2]服务引用配置类ConsumerConfig调用服务消费者启动类ConsumerBootstrap的refer()方法引用服务,消费者调用器ConsumerInvoker调用invoke()方法使用客户端发送数据给服务器执行客户端集群Cluster的doSendMsg()方法Future异步调用:

/**
 * 调用客户端
 *
 * @param transport 客户端连接
 * @param request   Request对象
 * @return 调用结果
 * @throws SofaRpcException rpc异常
 */
protected SofaResponse doSendMsg(ProviderInfo providerInfo, ClientTransport transport,
                                 SofaRequest request) throws SofaRpcException {
    RpcInternalContext context = RpcInternalContext.getContext();
    // 添加调用的服务端远程地址
    RpcInternalContext.getContext().setRemoteAddress(providerInfo.getHost(), providerInfo.getPort());
    try {
        checkProviderVersion(providerInfo, request); // 根据服务端版本特殊处理
        String invokeType = request.getInvokeType();
        int timeout = resolveTimeout(request, consumerConfig, providerInfo);

        SofaResponse response = null;
        // Future调用
        if (RpcConstants.INVOKER_TYPE_FUTURE.equals(invokeType)) {
            // 记录发送开始时间
            context.setAttachment(RpcConstants.INTERNAL_KEY_CLIENT_SEND_TIME, RpcRuntimeContext.now());
            // 开始调用
            ResponseFuture future = transport.asyncSend(request, timeout);
            // 放入线程上下文
            RpcInternalContext.getContext().setFuture(future);
            response = buildEmptyResponse(request);
        } else {
            throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR, "Unknown invoke type:" + invokeType);
        }
        return response;
    } catch (SofaRpcException e) {
        throw e;
    } catch (Throwable e) { // 客户端其它异常
        throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR, e);
    }
}

客户端集群Cluster根据请求调用类型判断是否为异步调用类型,基于ThreadLocal上下文传递RpcInternalContext记录发送开始时间,客户端传输ClientTransport调用asyncSend()方法指定超时范畴异步调用发送请求获取响应Future即调用get()方法进行获取响应或者注入监听器通知结果,并且提供给上下文传递RpcInternalContext,根据SofaRequest请求创建空响应调用结果:

/**
 * 异步调用
 *
 * @param message 消息
 * @param timeout 超时时间
 * @return 异步Future response future
 * @throws SofaRpcException SofaRpcException
 */
public abstract ResponseFuture asyncSend(SofaRequest message, int timeout) throws SofaRpcException;

Bolt客户端传输BoltClientTransport/H2&H2C客户端传输AbstractHttp2ClientTransport/第三方协议代理客户端传输AbstractProxyClientTransport[抛出短连接不支持异步RPC异常]异步调用asyncSend过程:检查长连接,获取基于ThreadLocal上下文传递RpcInternalContext,[BoltClientTransport根据SofaRequest请求创建调用上下文],通过doInvokeAsync()方法执行异步调用。

@Extension("bolt")
public class BoltClientTransport extends ClientTransport {
 public ResponseFuture asyncSend(SofaRequest request, int timeout) throws SofaRpcException {
    checkConnection();
    RpcInternalContext context = RpcInternalContext.getContext();
    InvokeContext boltInvokeContext = createInvokeContext(request);
    try {
        beforeSend(context, request);
        boltInvokeContext.put(RemotingConstants.INVOKE_CTX_RPC_CTX, context);
        return doInvokeAsync(request, context, boltInvokeContext, timeout);
    } catch (Exception e) {
        throw convertToRpcException(e);
    } finally {
        afterSend(context, boltInvokeContext, request);
    }
 }

/**
 * 异步调用
 *
 * @param request       请求对象
 * @param rpcContext    RPC内置上下文
 * @param invokeContext 调用上下文
 * @param timeoutMillis 超时时间(毫秒)
 * @throws RemotingException    远程调用异常
 * @throws InterruptedException 中断异常
 * @since 5.2.0
 */
 protected ResponseFuture doInvokeAsync(SofaRequest request, RpcInternalContext rpcContext,
                                       InvokeContext invokeContext, int timeoutMillis)
    throws RemotingException, InterruptedException {
    SofaResponseCallback listener = request.getSofaResponseCallback();
    if (listener != null) {
        // callback调用
        InvokeCallback callback = new BoltInvokerCallback(transportConfig.getConsumerConfig(),
            transportConfig.getProviderInfo(), listener, request, rpcContext,
            ClassLoaderUtils.getCurrentClassLoader());
        // 发起调用
        RPC_CLIENT.invokeWithCallback(url, request, invokeContext, callback, timeoutMillis);
        return null;
    } else {
        // future 转为 callback
        BoltResponseFuture future = new BoltResponseFuture(request, timeoutMillis);
        InvokeCallback callback = new BoltFutureInvokeCallback(transportConfig.getConsumerConfig(),
            transportConfig.getProviderInfo(), future, request, rpcContext,
            ClassLoaderUtils.getCurrentClassLoader());
        // 发起调用
        RPC_CLIENT.invokeWithCallback(url, request, invokeContext, callback, timeoutMillis);
        future.setSentTime();
        return future;
    }
 }
}
public abstract class AbstractHttp2ClientTransport extends ClientTransport {
 public ResponseFuture asyncSend(SofaRequest request, int timeout) throws SofaRpcException {
    checkConnection();
    RpcInternalContext context = RpcInternalContext.getContext();
    try {
        beforeSend(context, request);
        return doInvokeAsync(request, context, timeout);
    } catch (SofaRpcException e) {
        throw e;
    } catch (Exception e) {
        throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR, e.getMessage(), e);
    } finally {
        afterSend(context, request);
    }
 }

/**
 * 异步调用
 *
 * @param request       请求对象
 * @param rpcContext    RPC内置上下文
 * @param timeoutMillis 超时时间(毫秒)
 */
protected ResponseFuture doInvokeAsync(SofaRequest request, RpcInternalContext rpcContext, int timeoutMillis) {
    SofaResponseCallback listener = request.getSofaResponseCallback();
    if (listener != null) {
        AbstractHttpClientHandler callback = new CallbackInvokeClientHandler(transportConfig.getConsumerConfig(),
            transportConfig.getProviderInfo(), listener, request, rpcContext,
            ClassLoaderUtils.getCurrentClassLoader());
        doSend(request, callback, timeoutMillis);
        return null;
    } else {
        HttpResponseFuture future = new HttpResponseFuture(request, timeoutMillis);
        AbstractHttpClientHandler callback = new FutureInvokeClientHandler(transportConfig.getConsumerConfig(),
            transportConfig.getProviderInfo(), future, request, rpcContext,
            ClassLoaderUtils.getCurrentClassLoader());
        doSend(request, callback, timeoutMillis);
        future.setSentTime();
        return future;
    }
 }
}

Bolt客户端传输BoltClientTransport doInvokeAsync异步调用判断用户层调用级别服务回调类实例是否为空,因为Future调用方式未设置服务回调类实例,需要根据SofaRequst请求和超时时间构建BoltResponseFuture,以客户端服务发布配置、服务引用配置、BoltResponseFuture、SofaRequst请求、上下文传递RpcInternalContext以及当前类加载器构造Callback模式调用包装BoltFutureInvokeCallback转成Callback回调调用。BoltClientTransport通过RpcClient调用RPC远程连接RpcRemoting的invokeWithCallback()方法根据调用请求URL获取检查远程连接,根据远程请求命令RemotingCommand和调用上下文InvokeContext创建InvokeFuture绑定Rpc调用回调监听器RpcInvokeCallbackListener,InvokeFuture添加到远程连接的invokeFutureMap键值对,InvokeFuture新增计时器超时线程提供超时响应结果非正常执行异步调用回调任务,使用管道Channel的writeAndFlush(Object msg)方法异步发送客户端数据给服务端,并且添加监听器提供操作完成发送失败Future添加失败响应场景监听:

/**
 * Rpc invocation with callback.
* Notice! DO NOT modify the request object concurrently when this method is called. * * @param conn * @param request * @param invokeContext * @param invokeCallback * @param timeoutMillis * @throws RemotingException */ public void invokeWithCallback(final Connection conn, final Object request, final InvokeContext invokeContext, final InvokeCallback invokeCallback, final int timeoutMillis) throws RemotingException { RemotingCommand requestCommand = toRemotingCommand(request, conn, invokeContext, timeoutMillis); preProcessInvokeContext(invokeContext, requestCommand, conn); super.invokeWithCallback(conn, requestCommand, invokeCallback, timeoutMillis); } /** * Invocation with callback. * * @param conn * @param request * @param invokeCallback * @param timeoutMillis * @throws InterruptedException */ protected void invokeWithCallback(final Connection conn, final RemotingCommand request, final InvokeCallback invokeCallback, final int timeoutMillis) { final InvokeFuture future = createInvokeFuture(conn, request, request.getInvokeContext(), invokeCallback); conn.addInvokeFuture(future); try { //add timeout Timeout timeout = TimerHolder.getTimer().newTimeout(new TimerTask() { @Override public void run(Timeout timeout) throws Exception { InvokeFuture future = conn.removeInvokeFuture(request.getId()); if (future != null) { future.putResponse(commandFactory.createTimeoutResponse(conn .getRemoteAddress())); future.tryAsyncExecuteInvokeCallbackAbnormally(); } } }, timeoutMillis, TimeUnit.MILLISECONDS); future.addTimeout(timeout); conn.getChannel().writeAndFlush(request).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture cf) throws Exception { if (!cf.isSuccess()) { InvokeFuture f = conn.removeInvokeFuture(request.getId()); if (f != null) { f.cancelTimeout(); f.putResponse(commandFactory.createSendFailedResponse( conn.getRemoteAddress(), cf.cause())); f.tryAsyncExecuteInvokeCallbackAbnormally(); } logger.error("Invoke send failed. The address is {}", RemotingUtil.parseRemoteAddress(conn.getChannel()), cf.cause()); } } }); } catch (Exception e) { InvokeFuture f = conn.removeInvokeFuture(request.getId()); if (f != null) { f.cancelTimeout(); f.putResponse(commandFactory.createSendFailedResponse(conn.getRemoteAddress(), e)); f.tryAsyncExecuteInvokeCallbackAbnormally(); } logger.error("Exception caught when sending invocation. The address is {}", RemotingUtil.parseRemoteAddress(conn.getChannel()), e); } } /** * Create invoke future with {@link InvokeContext}. * @param conn * @param request * @param invokeContext * @param invokeCallback * @return */ protected InvokeFuture createInvokeFuture(Connection conn, RemotingCommand request, InvokeContext invokeContext, InvokeCallback invokeCallback) { return new DefaultInvokeFuture(request.getId(), new RpcInvokeCallbackListener( RemotingUtil.parseRemoteAddress(conn.getChannel())), invokeCallback, request .getProtocolCode().getFirstByte(), this.getCommandFactory(), invokeContext); }

RpcInvokeCallbackListener调用回调监听器使用onResponse()方法监听Rpc服务调用结果获取InvokeFuture的调用回调BoltFutureInvokeCallback并且启动回调线程执行CallbackTask任务阻塞等待获取响应命令反序列化,调用回调BoltFutureInvokeCallback调用onResponse()方法接收调用响应对象。RpcHandler处理器的channelRead()方法读取管道Channel服务端响应返回结果,调度RpcRequestProcessor处理器ProcessTask处理任务,RpcResponseProcessor处理器doProcess()方法使用DefaultInvokeFuture的executeInvokeCallback()方法执行调用回调,通过RpcInvokeCallbackListener调用回调监听器的onResponse()方法使用Callback模式包装BoltFutureInvokeCallback的onResponse()方法以BoltResponseFuture请求结果Future的setSuccess()方法设置服务调用正常响应返回结果:

public void onResponse(InvokeFuture future) {
    InvokeCallback callback = future.getInvokeCallback();
    if (callback != null) {
        CallbackTask task = new CallbackTask(this.getRemoteAddress(), future);
        if (callback.getExecutor() != null) {
            // There is no need to switch classloader, because executor is provided by user.
            try {
                callback.getExecutor().execute(task);
            } catch (RejectedExecutionException e) {
                logger.warn("Callback thread pool busy.");
            }
        } else {
            task.run();
        }
    }
}

class CallbackTask implements Runnable {

    InvokeFuture future;
    String       remoteAddress;

    /**
     * 
     */
    public CallbackTask(String remoteAddress, InvokeFuture future) {
        this.remoteAddress = remoteAddress;
        this.future = future;
    }

    /** 
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        InvokeCallback callback = future.getInvokeCallback();
        // a lot of try-catches to protect thread pool
        ResponseCommand response = null;

        try {
            response = (ResponseCommand) future.waitResponse(0);
        } catch (InterruptedException e) {
            String msg = "Exception caught when getting response from InvokeFuture. The address is "
                         + this.remoteAddress;
            logger.error(msg, e);
        }
        if (response == null || response.getResponseStatus() != ResponseStatus.SUCCESS) {
            try {
                Exception e;
                if (response == null) {
                    e = new InvokeException("Exception caught in invocation. The address is "
                                            + this.remoteAddress + " responseStatus:"
                                            + ResponseStatus.UNKNOWN, future.getCause());
                } else {
                    response.setInvokeContext(future.getInvokeContext());
                    switch (response.getResponseStatus()) {
                        case TIMEOUT:
                            e = new InvokeTimeoutException(
                                "Invoke timeout when invoke with callback.The address is "
                                        + this.remoteAddress);
                            break;
                        case CONNECTION_CLOSED:
                            e = new ConnectionClosedException(
                                "Connection closed when invoke with callback.The address is "
                                        + this.remoteAddress);
                            break;
                        case SERVER_THREADPOOL_BUSY:
                            e = new InvokeServerBusyException(
                                "Server thread pool busy when invoke with callback.The address is "
                                        + this.remoteAddress);
                            break;
                        case SERVER_EXCEPTION:
                            String msg = "Server exception when invoke with callback.Please check the server log! The address is "
                                         + this.remoteAddress;
                            RpcResponseCommand resp = (RpcResponseCommand) response;
                            resp.deserialize();
                            Object ex = resp.getResponseObject();
                            if (ex != null && ex instanceof Throwable) {
                                e = new InvokeServerException(msg, (Throwable) ex);
                            } else {
                                e = new InvokeServerException(msg);
                            }
                            break;
                        default:
                            e = new InvokeException(
                                "Exception caught in invocation. The address is "
                                        + this.remoteAddress + " responseStatus:"
                                        + response.getResponseStatus(), future.getCause());

                    }
                }
                callback.onException(e);
            } catch (Throwable e) {
                logger
                    .error(
                        "Exception occurred in user defined InvokeCallback#onException() logic, The address is {}",
                        this.remoteAddress, e);
            }
        } else {
            ClassLoader oldClassLoader = null;
            try {
                if (future.getAppClassLoader() != null) {
                    oldClassLoader = Thread.currentThread().getContextClassLoader();
                    Thread.currentThread().setContextClassLoader(future.getAppClassLoader());
                }
                response.setInvokeContext(future.getInvokeContext());
                RpcResponseCommand rpcResponse = (RpcResponseCommand) response;
                response.deserialize();
                try {
                    callback.onResponse(rpcResponse.getResponseObject());
                } catch (Throwable e) {
                    logger
                        .error(
                            "Exception occurred in user defined InvokeCallback#onResponse() logic.",
                            e);
                }
            } catch (CodecException e) {
                logger
                    .error(
                        "CodecException caught on when deserialize response in RpcInvokeCallbackListener. The address is {}.",
                        this.remoteAddress, e);
            } catch (Throwable e) {
                logger.error(
                    "Exception caught in RpcInvokeCallbackListener. The address is {}",
                    this.remoteAddress, e);
            } finally {
                if (oldClassLoader != null) {
                    Thread.currentThread().setContextClassLoader(oldClassLoader);
                }
            }
        } // enf of else
    } // end of run
}
public void onResponse(Object result) {
    if (rpcFuture == null) {
        return;
    }
    ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
    SofaResponse response = (SofaResponse) result;
    Throwable throwable = null;
    try {
        Thread.currentThread().setContextClassLoader(this.classLoader);
        RpcInternalContext.setContext(context);

        if (EventBus.isEnable(ClientAsyncReceiveEvent.class)) {
            EventBus.post(new ClientAsyncReceiveEvent(consumerConfig, providerInfo,
                request, response, null));
        }

        pickupBaggage(response);

        // do async filter after respond server
        FilterChain chain = consumerConfig.getConsumerBootstrap().getCluster().getFilterChain();
        if (chain != null) {
            chain.onAsyncResponse(consumerConfig, request, response, null);
        }

        recordClientElapseTime();
        if (EventBus.isEnable(ClientEndInvokeEvent.class)) {
            EventBus.post(new ClientEndInvokeEvent(request, response, null));
        }

        Object appResp = response.getAppResponse();
        if (response.isError()) { // rpc层异常
            SofaRpcException sofaRpcException = new SofaRpcException(
                RpcErrorType.SERVER_UNDECLARED_ERROR, response.getErrorMsg());
            rpcFuture.setFailure(sofaRpcException);
        } else if (appResp instanceof Throwable) { // 业务层异常
            throwable = (Throwable) appResp;
            rpcFuture.setFailure(throwable);
        } else {
            rpcFuture.setSuccess(appResp);
        }
    } finally {
        Thread.currentThread().setContextClassLoader(oldCl);
        RpcInvokeContext.removeContext();
        RpcInternalContext.removeAllContext();
    }
}
/**
 * 设置正常返回结果
 *
 * @param result 正常返回值
 */
public void setSuccess(V result) {
    if (this.isCancelled()) {
        this.releaseIfNeed(result);
    }
    if (setSuccess0(result)) {
        notifyListeners();
        return;
    }
    throw new IllegalStateException("complete already: " + this);
}

protected boolean setSuccess0(V result) {
    if (isDone()) {
        return false;
    }
    synchronized (this) {
        // Allow only once.
        if (isDone()) {
            return false;
        }
        if (this.result == null) {
            this.result = result;
        }
        this.setDoneTime();
        if (hasWaiters()) {
            notifyAll();
        }
    }
    return true;
}

透过Future异步调用机制使用基于ThreadLocal上下文传递RpcInvokeContext获取原生Java Future对象BoltResponseFuture,BoltResponseFuture通过原生Java Future的get()方法阻塞等待服务异步调用响应结果result:

BoltResponseFuture future = (BoltResponseFuture) SofaResponseFuture.getFuture();

/**
 * @return 原生 Java Future 对象
 * @throws SofaRpcException 当前线程上下文没有值的时候
 */
public static Future getFuture() throws SofaRpcException {
    return getFuture(false);
}

/**
 * @param clear 是否清除线程上下文
 * @return 原生 Java Future 对象
 * @throws SofaRpcException 当前线程上下文没有值的时候
 */
public static Future getFuture(boolean clear) throws SofaRpcException {
    RpcInvokeContext context = RpcInvokeContext.getContext();
    Future future = context.getFuture();
    if (future == null) {
        throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR,
            LogCodes.getLog(LogCodes.ERROR_RESPONSE_FUTURE_NULL,
                Thread.currentThread()));
    }
    if (clear) {
        context.setFuture(null);
    }
    return future;
}
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
    long realTimeOut = unit.toMillis(timeout);
    long remainTime = realTimeOut - (sentTime - genTime); // 剩余时间
    if (remainTime <= 0) { // 没有剩余时间不等待
        if (isDone()) { // 直接看是否已经返回
            return getNow();
        }
    } else { // 等待剩余时间
        if (await(remainTime, TimeUnit.MILLISECONDS)) {
            return getNow();
        }
    }
    this.setDoneTime();
    throw clientTimeoutException();
}
protected V getNow() throws ExecutionException {
    if (cause != null) {
        throw new ExecutionException(cause);
    } else {
        return (V) result;
    }
}
SOFARPC源码解析-服务调用_第3张图片
Future服务异步调用响应

(3)Callback回调调用
参考SOFARPC Example示例模块(com.alipay.sofa.rpc.invoke.callback):

package com.alipay.sofa.rpc.invoke.callback;

import com.alipay.sofa.rpc.config.ApplicationConfig;
import com.alipay.sofa.rpc.config.ProviderConfig;
import com.alipay.sofa.rpc.config.ServerConfig;
import com.alipay.sofa.rpc.test.HelloService;
import com.alipay.sofa.rpc.test.HelloServiceImpl;

public class CallbackServerMain {

    public static void main(String[] args) {

        ApplicationConfig applicationConfig = new ApplicationConfig().setAppName("future-server");

        ServerConfig serverConfig2 = new ServerConfig()
            .setPort(22222)
            .setDaemon(false);

        // C服务的服务端
        ProviderConfig CProvider = new ProviderConfig()
            .setApplication(applicationConfig)
            .setInterfaceId(HelloService.class.getName())
            .setRef(new HelloServiceImpl(1000))
            .setServer(serverConfig2);
        CProvider.export();
    }
}
package com.alipay.sofa.rpc.invoke.callback;

import com.alipay.sofa.rpc.common.RpcConstants;
import com.alipay.sofa.rpc.config.ApplicationConfig;
import com.alipay.sofa.rpc.config.ConsumerConfig;
import com.alipay.sofa.rpc.context.RpcRuntimeContext;
import com.alipay.sofa.rpc.core.exception.SofaRpcException;
import com.alipay.sofa.rpc.core.invoke.SofaResponseCallback;
import com.alipay.sofa.rpc.core.request.RequestBase;
import com.alipay.sofa.rpc.log.Logger;
import com.alipay.sofa.rpc.log.LoggerFactory;
import com.alipay.sofa.rpc.test.HelloService;

/**
 * 

接口级别的Callback

*/ public class CallbackClientMain { /** * slf4j Logger for this class */ private final static Logger LOGGER = LoggerFactory.getLogger(CallbackClientMain.class); public static void main(String[] args) throws InterruptedException { ApplicationConfig applicationConfig = new ApplicationConfig().setAppName("future-server"); ConsumerConfig consumerConfig = new ConsumerConfig() .setApplication(applicationConfig) .setInterfaceId(HelloService.class.getName()) .setInvokeType(RpcConstants.INVOKER_TYPE_CALLBACK) .setTimeout(5000) .setOnReturn(new SofaResponseCallback() { @Override public void onAppResponse(Object appResponse, String methodName, RequestBase request) { LOGGER.info("Interface get result: {}", appResponse); } @Override public void onAppException(Throwable throwable, String methodName, RequestBase request) { LOGGER.info("Interface get app exception: {}", throwable); } @Override public void onSofaException(SofaRpcException sofaException, String methodName, RequestBase request) { LOGGER.info("Interface get sofa exception: {}", sofaException); } }) // 不设置 调用级别设置 .setDirectUrl("bolt://127.0.0.1:22222?appName=future-server"); HelloService helloService = consumerConfig.refer(); LOGGER.warn("started at pid {}", RpcRuntimeContext.PID); try { for (int i = 0; i < 100; i++) { try { String s = helloService.sayHello("xxx", 22); LOGGER.warn("{}", s); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } try { Thread.sleep(2000); } catch (Exception e) { } } } catch (Exception e) { LOGGER.error("", e); } synchronized (CallbackClientMain.class) { while (true) { CallbackClientMain.class.wait(); } } } }
package com.alipay.sofa.rpc.invoke.callback;

import com.alipay.sofa.rpc.common.RpcConstants;
import com.alipay.sofa.rpc.config.ApplicationConfig;
import com.alipay.sofa.rpc.config.ConsumerConfig;
import com.alipay.sofa.rpc.context.RpcInvokeContext;
import com.alipay.sofa.rpc.context.RpcRuntimeContext;
import com.alipay.sofa.rpc.core.exception.SofaRpcException;
import com.alipay.sofa.rpc.core.invoke.SofaResponseCallback;
import com.alipay.sofa.rpc.core.request.RequestBase;
import com.alipay.sofa.rpc.log.Logger;
import com.alipay.sofa.rpc.log.LoggerFactory;
import com.alipay.sofa.rpc.test.HelloService;

/**
 * 

调用级别的Callback

*/ public class CallbackInvokeClientMain { /** * slf4j Logger for this class */ private final static Logger LOGGER = LoggerFactory.getLogger(CallbackInvokeClientMain.class); public static void main(String[] args) throws InterruptedException { ApplicationConfig applicationConfig = new ApplicationConfig().setAppName("future-server"); ConsumerConfig consumerConfig = new ConsumerConfig() .setApplication(applicationConfig) .setInterfaceId(HelloService.class.getName()) .setInvokeType(RpcConstants.INVOKER_TYPE_CALLBACK) .setTimeout(3000) //.setOnReturn() // 不设置 调用级别设置 .setDirectUrl("bolt://127.0.0.1:22222?appName=future-server"); HelloService helloService = consumerConfig.refer(); LOGGER.warn("started at pid {}", RpcRuntimeContext.PID); for (int i = 0; i < 100; i++) { try { RpcInvokeContext.getContext().setResponseCallback( new SofaResponseCallback() { @Override public void onAppResponse(Object appResponse, String methodName, RequestBase request) { LOGGER.info("Invoke get result: {}", appResponse); } @Override public void onAppException(Throwable throwable, String methodName, RequestBase request) { LOGGER.info("Invoke get app exception: {}", throwable); } @Override public void onSofaException(SofaRpcException sofaException, String methodName, RequestBase request) { LOGGER.info("Invoke get sofa exception: {}", sofaException); } } ); String s = helloService.sayHello("xxx", 22); LOGGER.warn("{}", s); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } try { Thread.sleep(2000); } catch (Exception e) { } } } }
package com.alipay.sofa.rpc.invoke.callback;

import com.alipay.sofa.rpc.common.RpcConstants;
import com.alipay.sofa.rpc.config.ApplicationConfig;
import com.alipay.sofa.rpc.config.ConsumerConfig;
import com.alipay.sofa.rpc.config.MethodConfig;
import com.alipay.sofa.rpc.context.RpcRuntimeContext;
import com.alipay.sofa.rpc.core.exception.SofaRpcException;
import com.alipay.sofa.rpc.core.invoke.SofaResponseCallback;
import com.alipay.sofa.rpc.core.request.RequestBase;
import com.alipay.sofa.rpc.log.Logger;
import com.alipay.sofa.rpc.log.LoggerFactory;
import com.alipay.sofa.rpc.test.HelloService;

import java.util.Collections;

/**
 * 

方法级别的Callback

*/ public class CallbackMethodClientMain { /** * slf4j Logger for this class */ private final static Logger LOGGER = LoggerFactory.getLogger(CallbackMethodClientMain.class); public static void main(String[] args) throws InterruptedException { ApplicationConfig applicationConfig = new ApplicationConfig().setAppName("future-server"); MethodConfig methodConfig = new MethodConfig(); methodConfig.setName("sayHello") .setInvokeType(RpcConstants.INVOKER_TYPE_CALLBACK) .setOnReturn(new SofaResponseCallback() { @Override public void onAppResponse(Object appResponse, String methodName, RequestBase request) { LOGGER.info("Method get result: {}", appResponse); } @Override public void onAppException(Throwable throwable, String methodName, RequestBase request) { LOGGER.info("Method get app exception: {}", throwable); } @Override public void onSofaException(SofaRpcException sofaException, String methodName, RequestBase request) { LOGGER.info("Method get sofa exception: {}", sofaException); } }); ConsumerConfig consumerConfig = new ConsumerConfig() .setApplication(applicationConfig) .setInterfaceId(HelloService.class.getName()) .setTimeout(5000) .setMethods(Collections.singletonList(methodConfig)) .setDirectUrl("bolt://127.0.0.1:22222?appName=future-server"); HelloService helloService = consumerConfig.refer(); LOGGER.warn("started at pid {}", RpcRuntimeContext.PID); try { for (int i = 0; i < 100; i++) { try { String s = helloService.sayHello("xxx", 22); LOGGER.warn("{}", s); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } try { Thread.sleep(2000); } catch (Exception e) { } } } catch (Exception e) { LOGGER.error("", e); } synchronized (CallbackMethodClientMain.class) { while (true) { CallbackMethodClientMain.class.wait(); } } } }

运行回调调用服务端示例类接口级别CallbackServerMain查看回调调用服务端输出日志:

2018-06-03 18:14:43,963 main  INFO [com.alipay.sofa.rpc.context.RpcRuntimeContext:info:102] - Welcome! Loading SOFA RPC Framework : 5.4.0_20180530235405, PID is:5640
2018-06-03 18:14:44,088 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: fault-tolerance
2018-06-03 18:14:44,291 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer-resteasy
2018-06-03 18:14:44,858 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:97] - The module lookout does not need to be loaded.
2018-06-03 18:14:44,861 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer
2018-06-03 18:14:44,913 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultProviderBootstrap:infoWithApp:122] - [future-server]Export provider config : com.alipay.sofa.rpc.test.HelloService: with bean id rpc-cfg-0
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 18:14:45,407 main  INFO [com.alipay.sofa.common.log:report:30] - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 18:14:48,876 main  INFO [com.alipay.sofa.rpc.server.bolt.BoltServer:info:102] - Bolt server has been bind to 0.0.0.0:22222
2018-06-03 18:14:57,701 SOFA-SEV-BOLT-BIZ-22222-3-T1  INFO [com.alipay.sofa.rpc.tracer.Tracers:info:102] - Load tracer impl success: sofaTracer, com.alipay.sofa.rpc.tracer.sofatracer.RpcSofaTracer@3a2888ed
name:xxx, age:22
name:xxx, age:22

运行回调调用客户端示例类接口级别CallbackClientMain查看回调调用客户端输出日志:

2018-06-03 18:14:52,109 main  INFO [com.alipay.sofa.rpc.context.RpcRuntimeContext:info:102] - Welcome! Loading SOFA RPC Framework : 5.4.0_20180530235405, PID is:8744
2018-06-03 18:14:52,207 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: fault-tolerance
2018-06-03 18:14:52,425 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer-resteasy
2018-06-03 18:14:53,003 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:97] - The module lookout does not need to be loaded.
2018-06-03 18:14:53,006 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer
2018-06-03 18:14:53,048 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultConsumerBootstrap:infoWithApp:122] - [future-server]Refer consumer config : bolt://com.alipay.sofa.rpc.test.HelloService: with bean id rpc-cfg-0
2018-06-03 18:14:53,284 main  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [future-server]Add provider of com.alipay.sofa.rpc.test.HelloService, size is : 1
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 18:14:53,649 SOFA-CLI-CONN-com.alipay.sofa.rpc.test.HelloService-3-T1  INFO [com.alipay.sofa.common.log:report:30] - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 18:14:56,616 SOFA-CLI-CONN-com.alipay.sofa.rpc.test.HelloService-3-T1  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [future-server]Connect to com.alipay.sofa.rpc.test.HelloService provider:bolt://127.0.0.1:22222?appName=future-server success ! The connection is 127.0.0.1:22222 <-> 127.0.0.1:51037
2018-06-03 18:14:57,007 main  WARN [com.alipay.sofa.rpc.invoke.callback.CallbackClientMain:warn:142] - started at pid 8744
2018-06-03 18:14:57,012 main  INFO [com.alipay.sofa.rpc.tracer.Tracers:info:102] - Load tracer impl success: sofaTracer, com.alipay.sofa.rpc.tracer.sofatracer.RpcSofaTracer@6d4b1c02
2018-06-03 18:14:57,404 main  WARN [com.alipay.sofa.rpc.invoke.callback.CallbackClientMain:warn:142] - null
2018-06-03 18:14:58,868 SOFA-RPC-CB-4-T1  INFO [com.alipay.sofa.rpc.invoke.callback.CallbackClientMain:info:102] - Interface get result: hello xxx from server! age: 22
2018-06-03 18:14:59,412 main  WARN [com.alipay.sofa.rpc.invoke.callback.CallbackClientMain:warn:142] - null
2018-06-03 18:15:00,421 SOFA-RPC-CB-4-T3  INFO [com.alipay.sofa.rpc.invoke.callback.CallbackClientMain:info:102] - Interface get result: hello xxx from server! age: 22

运行回调调用客户端示例类调用级别CallbackInvokeClientMain查看回调调用客户端输出日志:

2018-06-03 18:17:43,337 main  INFO [com.alipay.sofa.rpc.context.RpcRuntimeContext:info:102] - Welcome! Loading SOFA RPC Framework : 5.4.0_20180530235405, PID is:1292
2018-06-03 18:17:43,453 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: fault-tolerance
2018-06-03 18:17:43,634 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer-resteasy
2018-06-03 18:17:44,429 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:97] - The module lookout does not need to be loaded.
2018-06-03 18:17:44,434 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer
2018-06-03 18:17:44,515 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultConsumerBootstrap:infoWithApp:122] - [future-server]Refer consumer config : bolt://com.alipay.sofa.rpc.test.HelloService: with bean id rpc-cfg-0
2018-06-03 18:17:44,861 main  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [future-server]Add provider of com.alipay.sofa.rpc.test.HelloService, size is : 1
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 18:17:45,241 SOFA-CLI-CONN-com.alipay.sofa.rpc.test.HelloService-3-T1  INFO [com.alipay.sofa.common.log:report:30] - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 18:17:48,427 SOFA-CLI-CONN-com.alipay.sofa.rpc.test.HelloService-3-T1  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [future-server]Connect to com.alipay.sofa.rpc.test.HelloService provider:bolt://127.0.0.1:22222?appName=future-server success ! The connection is 127.0.0.1:22222 <-> 127.0.0.1:51151
2018-06-03 18:17:48,784 main  WARN [com.alipay.sofa.rpc.invoke.callback.CallbackInvokeClientMain:warn:142] - started at pid 1292
2018-06-03 18:17:48,790 main  INFO [com.alipay.sofa.rpc.tracer.Tracers:info:102] - Load tracer impl success: sofaTracer, com.alipay.sofa.rpc.tracer.sofatracer.RpcSofaTracer@6d4b1c02
2018-06-03 18:17:49,188 main  WARN [com.alipay.sofa.rpc.invoke.callback.CallbackInvokeClientMain:warn:142] - null
2018-06-03 18:17:50,858 SOFA-RPC-CB-4-T1  INFO [com.alipay.sofa.rpc.invoke.callback.CallbackInvokeClientMain:info:102] - Invoke get result: hello xxx from server! age: 22
2018-06-03 18:17:51,194 main  WARN [com.alipay.sofa.rpc.invoke.callback.CallbackInvokeClientMain:warn:142] - null
2018-06-03 18:17:52,206 SOFA-RPC-CB-4-T3  INFO [com.alipay.sofa.rpc.invoke.callback.CallbackInvokeClientMain:info:102] - Invoke get result: hello xxx from server! age: 22

运行回调调用客户端示例类方法级别CallbackMethodClientMain查看回调调用客户端输出日志:

2018-06-03 18:18:38,999 main  INFO [com.alipay.sofa.rpc.context.RpcRuntimeContext:info:102] - Welcome! Loading SOFA RPC Framework : 5.4.0_20180530235405, PID is:12104
2018-06-03 18:18:39,115 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: fault-tolerance
2018-06-03 18:18:39,282 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer-resteasy
2018-06-03 18:18:40,109 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:97] - The module lookout does not need to be loaded.
2018-06-03 18:18:40,113 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer
2018-06-03 18:18:40,204 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultConsumerBootstrap:infoWithApp:122] - [future-server]Refer consumer config : bolt://com.alipay.sofa.rpc.test.HelloService: with bean id rpc-cfg-0
2018-06-03 18:18:40,487 main  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [future-server]Add provider of com.alipay.sofa.rpc.test.HelloService, size is : 1
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 18:18:40,799 SOFA-CLI-CONN-com.alipay.sofa.rpc.test.HelloService-3-T1  INFO [com.alipay.sofa.common.log:report:30] - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 18:18:43,598 SOFA-CLI-CONN-com.alipay.sofa.rpc.test.HelloService-3-T1  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [future-server]Connect to com.alipay.sofa.rpc.test.HelloService provider:bolt://127.0.0.1:22222?appName=future-server success ! The connection is 127.0.0.1:22222 <-> 127.0.0.1:51178
2018-06-03 18:18:43,992 main  WARN [com.alipay.sofa.rpc.invoke.callback.CallbackMethodClientMain:warn:142] - started at pid 12104
2018-06-03 18:18:43,996 main  INFO [com.alipay.sofa.rpc.tracer.Tracers:info:102] - Load tracer impl success: sofaTracer, com.alipay.sofa.rpc.tracer.sofatracer.RpcSofaTracer@6093dd95
2018-06-03 18:18:44,345 main  WARN [com.alipay.sofa.rpc.invoke.callback.CallbackMethodClientMain:warn:142] - null
2018-06-03 18:18:45,527 SOFA-RPC-CB-4-T1  INFO [com.alipay.sofa.rpc.invoke.callback.CallbackMethodClientMain:info:102] - Method get result: hello xxx from server! age: 22
2018-06-03 18:18:46,351 main  WARN [com.alipay.sofa.rpc.invoke.callback.CallbackMethodClientMain:warn:142] - null
2018-06-03 18:18:47,364 SOFA-RPC-CB-4-T3  INFO [com.alipay.sofa.rpc.invoke.callback.CallbackMethodClientMain:info:102] - Method get result: hello xxx from server! age: 22

SOFARPC回调调用流程:
[1]创建服务引用配置类ConsumerConfig,设置ConsumerConfig实例应用信息配置、接口名称、直连调用地址以及连接超时时间,通过setInvokeType设置服务引用调用类型为RpcConstants. INVOKER_TYPE_CALLBACK(callback),支持接口级别[setOnReturn设置服务引用配置ConsumerConfig返回值之前的监听器,处理结果或者异常]、调用级别[不设置服务引用配置ConsumerConfig返回值之前的监听器,基于ThreadLocal上下文传递RpcInvokeContext通过setResponseCallback设置单次请求的指定回调方法]以及方法级别[创建方法级配置类MethodConfig,setOnReturn设置方法级配置MethodConfig返回值之前的监听器,setMethods服务引用配置ConsumerConfig方法配置]Callback回调:

/**
 * 调用方式:回调
 */
public static final String  INVOKER_TYPE_CALLBACK   = "callback";
/*接口级别Callback*/
ConsumerConfig<***Service> consumerConfig = new ConsumerConfig<***Service>()
    .setApplication(applicationConfig)
    .setInterfaceId(***Service.class.getName())
    .setInvokeType(RpcConstants.INVOKER_TYPE_CALLBACK)
    .setTimeout(5000)
    .setOnReturn(new SofaResponseCallback() {
        @Override
        public void onAppResponse(Object appResponse, String methodName, RequestBase request) {
            LOGGER.info("Interface get result: {}", appResponse);
        }

        @Override
        public void onAppException(Throwable throwable, String methodName, RequestBase request) {
            LOGGER.info("Interface get app exception: {}", throwable);
        }

        @Override
        public void onSofaException(SofaRpcException sofaException, String methodName,
                                    RequestBase request) {
            LOGGER.info("Interface get sofa exception: {}", sofaException);
        }
    }) 
    .setDirectUrl("bolt://host:port?appName=future-server");
/*调用级别Callback*/
ConsumerConfig<***Service> consumerConfig = new ConsumerConfig<***Service>()
    .setApplication(applicationConfig)
    .setInterfaceId(***Service.class.getName())
    .setInvokeType(RpcConstants.INVOKER_TYPE_CALLBACK)
    .setTimeout(5000)
    //.setOnReturn() // 不设置 调用级别设置
    .setDirectUrl("bolt://host:port?appName=future-server");
RpcInvokeContext.getContext().setResponseCallback(
    new SofaResponseCallback() {
        @Override
        public void onAppResponse(Object appResponse, String methodName, RequestBase request) {
            LOGGER.info("Invoke get result: {}", appResponse);
        }

        @Override
        public void onAppException(Throwable throwable, String methodName, RequestBase request) {
            LOGGER.info("Invoke get app exception: {}", throwable);
        }

        @Override
        public void onSofaException(SofaRpcException sofaException, String methodName,
                                    RequestBase request) {
            LOGGER.info("Invoke get sofa exception: {}", sofaException);
        }
    }
);
/*方法级别Callback*/
MethodConfig methodConfig = new MethodConfig();
methodConfig.setName("***")
    .setInvokeType(RpcConstants.INVOKER_TYPE_CALLBACK)
    .setOnReturn(new SofaResponseCallback() {
        @Override
        public void onAppResponse(Object appResponse, String methodName, RequestBase request) {
            LOGGER.info("Method get result: {}", appResponse);
        }

        @Override
        public void onAppException(Throwable throwable, String methodName, RequestBase request) {
            LOGGER.info("Method get app exception: {}", throwable);
        }

        @Override
        public void onSofaException(SofaRpcException sofaException, String methodName,
                                    RequestBase request) {
            LOGGER.info("Method get sofa exception: {}", sofaException);
        }
    });
ConsumerConfig<***Service> consumerConfig = new ConsumerConfig<***Service>()
    .setApplication(applicationConfig)
    .setInterfaceId(***Service.class.getName())
    .setInvokeType(RpcConstants.INVOKER_TYPE_CALLBACK)
    .setTimeout(5000)
    .setMethods(Collections.singletonList(methodConfig))
    .setDirectUrl("bolt://host:port?appName=future-server");

[2]服务引用配置类ConsumerConfig调用服务消费者启动类ConsumerBootstrap的refer()方法引用服务,消费者调用器ConsumerInvoker调用invoke()方法使用客户端发送数据给服务器执行客户端集群Cluster的doSendMsg()方法Callback回调调用:

/**
 * 调用客户端
 *
 * @param transport 客户端连接
 * @param request   Request对象
 * @return 调用结果
 * @throws SofaRpcException rpc异常
 */
protected SofaResponse doSendMsg(ProviderInfo providerInfo, ClientTransport transport,
                                 SofaRequest request) throws SofaRpcException {
    RpcInternalContext context = RpcInternalContext.getContext();
    // 添加调用的服务端远程地址
    RpcInternalContext.getContext().setRemoteAddress(providerInfo.getHost(), providerInfo.getPort());
    try {
        checkProviderVersion(providerInfo, request); // 根据服务端版本特殊处理
        String invokeType = request.getInvokeType();
        int timeout = resolveTimeout(request, consumerConfig, providerInfo);

        SofaResponse response = null;
        // Callback调用
        if (RpcConstants.INVOKER_TYPE_CALLBACK.equals(invokeType)) {
            // 调用级别回调监听器
            SofaResponseCallback sofaResponseCallback = request.getSofaResponseCallback();
            if (sofaResponseCallback == null) {
                SofaResponseCallback methodResponseCallback = consumerConfig
                    .getMethodOnreturn(request.getMethodName());
                if (methodResponseCallback != null) { // 方法的Callback
                    request.setSofaResponseCallback(methodResponseCallback);
                }
            }
            // 记录发送开始时间
            context.setAttachment(RpcConstants.INTERNAL_KEY_CLIENT_SEND_TIME, RpcRuntimeContext.now());
            // 开始调用
            transport.asyncSend(request, timeout);
            response = buildEmptyResponse(request);
        } else {
            throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR, "Unknown invoke type:" + invokeType);
        }
        return response;
    } catch (SofaRpcException e) {
        throw e;
    } catch (Throwable e) { // 客户端其它异常
        throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR, e);
    }
}

客户端集群Cluster根据请求调用类型判断是否为回调调用类型,获取SofaRequest请求调用级别服务回调监听器,回调监听器为空则获取服务引用配置ConsumerConfig方法级别服务回调监听器,方法级别服务回调监听器非空则设置SofaRequest请求服务回调监听器(优先级排序:调用级别->方法级别->接口级别),基于ThreadLocal上下文传递RpcInternalContext记录发送开始时间,客户端传输ClientTransport调用asyncSend()方法指定超时范畴回调调用发送请求,根据SofaRequest请求创建空响应调用结果。
Bolt客户端传输BoltClientTransport/H2&H2C客户端传输AbstractHttp2ClientTransport/第三方协议代理客户端传输AbstractProxyClientTransport[抛出短连接不支持异步RPC异常]回调调用asyncSend过程:检查长连接,获取基于ThreadLocal上下文传递RpcInternalContext,[BoltClientTransport根据SofaRequest请求创建调用上下文],通过doInvokeAsync()方法执行回调调用。
Bolt客户端传输BoltClientTransport doInvokeAsync回调调用判断用户层调用级别服务回调监听器是否为空,因为调用/方法级别Callback调用方式设置提供服务回调监听器,根据客户端服务发布配置、服务引用配置、服务回调监听器SofaResponseCallback、SofaRequst请求、上下文传递RpcInternalContext以及当前类加载器构建Callback模式调用包装BoltInvokerCallback绑定Rpc请求结果监听器
SofaResponseCallback。BoltClientTransport通过RpcClient调用RPC远程连接RpcRemoting的invokeWithCallback()方法根据调用请求URL获取检查远程连接,根据远程请求命令RemotingCommand和调用上下文InvokeContext创建InvokeFuture添加到远程连接的invokeFutureMap键值对,InvokeFuture新增计时器超时线程提供超时响应结果非正常执行回调调用回调任务,使用管道Channel的writeAndFlush(Object msg)方法异步发送客户端数据给服务端,并且添加监听器提供操作完成发送失败Future添加失败响应场景监听。
RpcInvokeCallbackListener调用回调监听器使用onResponse()方法监听Rpc服务调用结果获取InvokeFuture的调用回调BoltFutureInvokeCallback并且启动回调线程执行CallbackTask任务阻塞等待获取响应命令反序列化,调用回调BoltFutureInvokeCallback调用onResponse()方法接收调用响应对象。RpcHandler处理器的channelRead()方法读取管道Channel服务端响应返回结果,调度RpcRequestProcessor处理器ProcessTask处理任务,RpcResponseProcessor处理器doProcess()方法使用DefaultInvokeFuture的executeInvokeCallback()方法执行调用回调,通过RpcInvokeCallbackListener调用回调监听器的onResponse()方法使用Callback适配BoltInvokerCallback的onResponse()方法以SofaResponseCallback的onAppResponse()/onAppException()/onSofaException()方法实施返回响应调用结果自定义回调函数:

public void onResponse(Object result) {
    if (callback == null) {
        return;
    }
    ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
    SofaResponse response = (SofaResponse) result;
    Throwable throwable = null;
    try {
        Thread.currentThread().setContextClassLoader(this.classLoader);
        RpcInternalContext.setContext(context);

        if (EventBus.isEnable(ClientAsyncReceiveEvent.class)) {
            EventBus.post(new ClientAsyncReceiveEvent(consumerConfig, providerInfo,
                request, response, null));
        }

        pickupBaggage(response);

        // do async filter after respond server
        FilterChain chain = consumerConfig.getConsumerBootstrap().getCluster().getFilterChain();
        if (chain != null) {
            chain.onAsyncResponse(consumerConfig, request, response, null);
        }

        recordClientElapseTime();
        if (EventBus.isEnable(ClientEndInvokeEvent.class)) {
            EventBus.post(new ClientEndInvokeEvent(request, response, null));
        }

        Object appResp = response.getAppResponse();
        if (response.isError()) { // rpc层异常
            SofaRpcException sofaRpcException = new SofaRpcException(
                RpcErrorType.SERVER_UNDECLARED_ERROR, response.getErrorMsg());
            callback.onSofaException(sofaRpcException, request.getMethodName(), request);
        } else if (appResp instanceof Throwable) { // 业务层异常
            throwable = (Throwable) appResp;
            callback.onAppException(throwable, request.getMethodName(), request);
        } else {
            callback.onAppResponse(appResp, request.getMethodName(), request);
        }
    } finally {
        Thread.currentThread().setContextClassLoader(oldCl);
        RpcInvokeContext.removeContext();
        RpcInternalContext.removeAllContext();
    }
}
/**
 * 面向用户的Rpc请求结果监听器
 */
public interface SofaResponseCallback {
    /**
     * SOFA RPC will callback this method when server return response success
     *
     * @param appResponse response object
     * @param methodName the invoked method
     * @param request the invoked request object
     */
    public void onAppResponse(Object appResponse, String methodName, RequestBase request);

    /**
     * SOFA RPC will callback this method when server meet exception
     *
     * @param throwable app's exception
     * @param methodName the invoked method
     * @param request the invoked request
     */
    public void onAppException(Throwable throwable, String methodName, RequestBase request);

    /**
     * SOFA RPC will callback this method when framework meet exception
     *
     * @param sofaException framework exception
     *  @param methodName the invoked method
     * @param request the invoked request object
     */
    public void onSofaException(SofaRpcException sofaException, String methodName,
                                RequestBase request);
}
SOFARPC源码解析-服务调用_第4张图片
Callback服务回调调用响应

(4)Oneway单向调用
参考SOFARPC Example示例模块(com.alipay.sofa.rpc.invoke.oneway):

package com.alipay.sofa.rpc.invoke.oneway;

import com.alipay.sofa.rpc.config.ApplicationConfig;
import com.alipay.sofa.rpc.config.ProviderConfig;
import com.alipay.sofa.rpc.config.ServerConfig;
import com.alipay.sofa.rpc.test.EchoService;
import com.alipay.sofa.rpc.test.EchoServiceImpl;
import com.alipay.sofa.rpc.test.HelloService;
import com.alipay.sofa.rpc.test.HelloServiceImpl;

public class OnewayServerMain {

    public static void main(String[] args) {

        ApplicationConfig applicationConfig = new ApplicationConfig().setAppName("oneway-server");

        ServerConfig serverConfig2 = new ServerConfig()
            .setPort(22222)
            .setDaemon(false);

        ProviderConfig providerConfig = new ProviderConfig()
            .setApplication(applicationConfig)
            .setInterfaceId(HelloService.class.getName())
            .setRef(new HelloServiceImpl(1000))
            .setServer(serverConfig2);
        providerConfig.export();

        ProviderConfig providerConfig2 = new ProviderConfig()
            .setApplication(applicationConfig)
            .setInterfaceId(EchoService.class.getName())
            .setRef(new EchoServiceImpl())
            .setServer(serverConfig2);
        providerConfig2.export();
    }
}
package com.alipay.sofa.rpc.invoke.oneway;

import com.alipay.sofa.rpc.common.RpcConstants;
import com.alipay.sofa.rpc.config.ApplicationConfig;
import com.alipay.sofa.rpc.config.ConsumerConfig;
import com.alipay.sofa.rpc.context.RpcRuntimeContext;
import com.alipay.sofa.rpc.log.Logger;
import com.alipay.sofa.rpc.log.LoggerFactory;
import com.alipay.sofa.rpc.test.EchoService;
import com.alipay.sofa.rpc.test.HelloService;

/**
 * 接口级别的Callback
 */
public class OnewayClientMain {

    /**
     * slf4j Logger for this class
     */
    private final static Logger LOGGER = LoggerFactory.getLogger(OnewayClientMain.class);

    public static void main(String[] args) throws InterruptedException {

        ApplicationConfig applicationConfig = new ApplicationConfig().setAppName("oneway-client");

        ConsumerConfig consumerConfig = new ConsumerConfig()
            .setApplication(applicationConfig)
            .setInterfaceId(HelloService.class.getName())
            .setInvokeType(RpcConstants.INVOKER_TYPE_ONEWAY)
            .setTimeout(50000)
            .setDirectUrl("bolt://127.0.0.1:22222?appName=oneway-server");
        HelloService helloService = consumerConfig.refer();

        ConsumerConfig consumerConfig2 = new ConsumerConfig()
            .setApplication(applicationConfig)
            .setInterfaceId(EchoService.class.getName())
            .setInvokeType(RpcConstants.INVOKER_TYPE_ONEWAY)
            .setTimeout(50000)
            .setDirectUrl("bolt://127.0.0.1:22222?appName=oneway-server");
        EchoService echoService = consumerConfig2.refer();

        LOGGER.warn("started at pid {}", RpcRuntimeContext.PID);

        while (true) {
            try {
                String s1 = helloService.sayHello("xxx", 22);
                LOGGER.warn("must null :{}", s1);

                String s2 = echoService.echoStr("yyy");
                LOGGER.warn("must null :{}", s2);

            } catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
            }
            try {
                Thread.sleep(2000);
            } catch (Exception ignore) {
            }
        }

    }

}

运行单向调用服务端示例类OnewayServerMain查看单向调用服务端输出日志:

2018-06-03 18:23:16,397 main  INFO [com.alipay.sofa.rpc.context.RpcRuntimeContext:info:102] - Welcome! Loading SOFA RPC Framework : 5.4.0_20180530235405, PID is:4608
2018-06-03 18:23:16,554 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: fault-tolerance
2018-06-03 18:23:16,695 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer-resteasy
2018-06-03 18:23:17,181 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:97] - The module lookout does not need to be loaded.
2018-06-03 18:23:17,184 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer
2018-06-03 18:23:17,229 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultProviderBootstrap:infoWithApp:122] - [oneway-server]Export provider config : com.alipay.sofa.rpc.test.HelloService: with bean id rpc-cfg-0
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 18:23:17,760 main  INFO [com.alipay.sofa.common.log:report:30] - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 18:23:20,291 main  INFO [com.alipay.sofa.rpc.server.bolt.BoltServer:info:102] - Bolt server has been bind to 0.0.0.0:22222
2018-06-03 18:23:20,347 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultProviderBootstrap:infoWithApp:122] - [oneway-server]Export provider config : com.alipay.sofa.rpc.test.EchoService: with bean id rpc-cfg-1
2018-06-03 18:23:30,936 SOFA-SEV-BOLT-BIZ-22222-3-T2  INFO [com.alipay.sofa.rpc.tracer.Tracers:info:102] - Load tracer impl success: sofaTracer, com.alipay.sofa.rpc.tracer.sofatracer.RpcSofaTracer@28d8faed
name:xxx, age:22
name:xxx, age:22

运行单向调用客户端示例类OnewayClientMain查看单向调用客户端输出日志:

2018-06-03 18:23:25,581 main  INFO [com.alipay.sofa.rpc.context.RpcRuntimeContext:info:102] - Welcome! Loading SOFA RPC Framework : 5.4.0_20180530235405, PID is:1268
2018-06-03 18:23:25,764 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: fault-tolerance
2018-06-03 18:23:25,968 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer-resteasy
2018-06-03 18:23:26,605 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:97] - The module lookout does not need to be loaded.
2018-06-03 18:23:26,608 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer
2018-06-03 18:23:26,653 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultConsumerBootstrap:infoWithApp:122] - [oneway-client]Refer consumer config : bolt://com.alipay.sofa.rpc.test.HelloService: with bean id rpc-cfg-0
2018-06-03 18:23:27,044 main  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [oneway-client]Add provider of com.alipay.sofa.rpc.test.HelloService, size is : 1
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 18:23:27,407 SOFA-CLI-CONN-com.alipay.sofa.rpc.test.HelloService-3-T1  INFO [com.alipay.sofa.common.log:report:30] - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-03 18:23:29,797 SOFA-CLI-CONN-com.alipay.sofa.rpc.test.HelloService-3-T1  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [oneway-client]Connect to com.alipay.sofa.rpc.test.HelloService provider:bolt://127.0.0.1:22222?appName=oneway-server success ! The connection is 127.0.0.1:22222 <-> 127.0.0.1:51305
2018-06-03 18:23:30,185 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultConsumerBootstrap:infoWithApp:122] - [oneway-client]Refer consumer config : bolt://com.alipay.sofa.rpc.test.EchoService: with bean id rpc-cfg-1
2018-06-03 18:23:30,188 main  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [oneway-client]Add provider of com.alipay.sofa.rpc.test.EchoService, size is : 1
2018-06-03 18:23:30,288 SOFA-CLI-CONN-com.alipay.sofa.rpc.test.EchoService-5-T1  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [oneway-client]Connect to com.alipay.sofa.rpc.test.EchoService provider:bolt://127.0.0.1:22222?appName=oneway-server success ! The connection is 127.0.0.1:22222 <-> 127.0.0.1:51305
2018-06-03 18:23:30,310 main  WARN [com.alipay.sofa.rpc.invoke.oneway.OnewayClientMain:warn:142] - started at pid 1268
2018-06-03 18:23:30,317 main  INFO [com.alipay.sofa.rpc.tracer.Tracers:info:102] - Load tracer impl success: sofaTracer, com.alipay.sofa.rpc.tracer.sofatracer.RpcSofaTracer@1794d431
2018-06-03 18:23:30,661 main  WARN [com.alipay.sofa.rpc.invoke.oneway.OnewayClientMain:warn:142] - must null :null
2018-06-03 18:23:30,665 main  WARN [com.alipay.sofa.rpc.invoke.oneway.OnewayClientMain:warn:142] - must null :null
2018-06-03 18:23:32,670 main  WARN [com.alipay.sofa.rpc.invoke.oneway.OnewayClientMain:warn:142] - must null :null
2018-06-03 18:23:32,676 main  WARN [com.alipay.sofa.rpc.invoke.oneway.OnewayClientMain:warn:142] - must null :null

SOFARPC单向调用流程:
[1]创建服务引用配置类ConsumerConfig,设置ConsumerConfig实例应用信息配置、接口名称、直连调用地址以及连接超时时间,通过setInvokeType设置服务引用调用类型为RpcConstants.INVOKER_TYPE_ONEWAY(oneway):

/**
 * 调用方式:单向
 */
public static final String  INVOKER_TYPE_ONEWAY  = "oneway";

[2]服务引用配置类ConsumerConfig调用服务消费者启动类ConsumerBootstrap的refer()方法引用服务,消费者调用器ConsumerInvoker调用invoke()方法使用客户端发送数据给服务器执行客户端集群Cluster的doSendMsg()方法Oneway单向调用:

/**
 * 调用客户端
 *
 * @param transport 客户端连接
 * @param request   Request对象
 * @return 调用结果
 * @throws SofaRpcException rpc异常
 */
protected SofaResponse doSendMsg(ProviderInfo providerInfo, ClientTransport transport,
                                 SofaRequest request) throws SofaRpcException {
    RpcInternalContext context = RpcInternalContext.getContext();
    // 添加调用的服务端远程地址
    RpcInternalContext.getContext().setRemoteAddress(providerInfo.getHost(), providerInfo.getPort());
    try {
        checkProviderVersion(providerInfo, request); // 根据服务端版本特殊处理
        String invokeType = request.getInvokeType();
        int timeout = resolveTimeout(request, consumerConfig, providerInfo);

        SofaResponse response = null;
        // 单向调用
        if (RpcConstants.INVOKER_TYPE_ONEWAY.equals(invokeType)) {
            long start = RpcRuntimeContext.now();
            try {
                transport.oneWaySend(request, timeout);
                response = buildEmptyResponse(request);
            } finally {
                if (RpcInternalContext.isAttachmentEnable()) {
                    long elapsed = RpcRuntimeContext.now() - start;
                    context.setAttachment(RpcConstants.INTERNAL_KEY_CLIENT_ELAPSE, elapsed);
                }
            }
        } else {
            throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR, "Unknown invoke type:" + invokeType);
        }
        return response;
    } catch (SofaRpcException e) {
        throw e;
    } catch (Throwable e) { // 客户端其它异常
        throw new SofaRpcException(RpcErrorType.CLIENT_UNDECLARED_ERROR, e);
    }
}

客户端集群Cluster根据请求调用类型判断是否为单向调用类型,客户端传输ClientTransport调用oneWaySend()方法指定超时范畴单向调用发送请求,根据SofaRequest请求创建空响应调用结果,基于ThreadLocal上下文传递RpcInternalContext记录客户端总耗时:

/**
 * 单向调用
 *
 * @param message 消息
 * @param timeout 超时时间
 * @throws SofaRpcException SofaRpcException
 */
public abstract void oneWaySend(SofaRequest message, int timeout) throws SofaRpcException;

Bolt客户端传输BoltClientTransport/H2&H2C客户端传输AbstractHttp2ClientTransport[抛出不支持操作异常]/第三方协议代理客户端传输AbstractProxyClientTransport[抛出不支持操作异常]单向调用oneWaySend过程:检查长连接,获取基于ThreadLocal上下文传递RpcInternalContext,根据SofaRequest请求创建调用上下文,通过doOneWay()方法执行单向调用。

@Extension("bolt")
public class BoltClientTransport extends ClientTransport {
 public void oneWaySend(SofaRequest request, int timeout) throws SofaRpcException {
    checkConnection();
    RpcInternalContext context = RpcInternalContext.getContext();
    InvokeContext invokeContext = createInvokeContext(request);
    SofaRpcException throwable = null;
    try {
        beforeSend(context, request);
        doOneWay(request, invokeContext, timeout);
    } catch (Exception e) { // 其它异常
        throwable = convertToRpcException(e);
        throw throwable;
    } finally {
        afterSend(context, invokeContext, request);
        if (EventBus.isEnable(ClientSyncReceiveEvent.class)) {
            EventBus.post(new ClientSyncReceiveEvent(transportConfig.getConsumerConfig(),
                transportConfig.getProviderInfo(), request, null, throwable));
        }
    }
 }

/**
 * 同步调用
 *
 * @param request       请求对象
 * @param invokeContext 调用上下文
 * @param timeoutMillis 超时时间(毫秒)
 * @throws RemotingException    远程调用异常
 * @throws InterruptedException 中断异常
 * @since 5.2.0
 */
 protected void doOneWay(SofaRequest request, InvokeContext invokeContext, int timeoutMillis)
    throws RemotingException, InterruptedException {
    RPC_CLIENT.oneway(url, request, invokeContext);
 }
}

Bolt客户端传输BoltClientTransport doOneWay单向调用通过RpcClient调用RPC远程连接RpcRemoting的oneway()方法根据调用请求URL获取检查远程连接,使用管道Channel的writeAndFlush(Object msg)方法异步发送客户端数据给服务端,并且添加监听器提供操作完成发送失败打印ERROR日志场景监听:

/**
 * Oneway rpc invocation.
* Notice! DO NOT modify the request object concurrently when this method is called. * * @param conn * @param request * @param invokeContext * @throws RemotingException */ public void oneway(final Connection conn, final Object request, final InvokeContext invokeContext) throws RemotingException { RequestCommand requestCommand = (RequestCommand) toRemotingCommand(request, conn, invokeContext, -1); requestCommand.setType(RpcCommandType.REQUEST_ONEWAY); preProcessInvokeContext(invokeContext, requestCommand, conn); super.oneway(conn, requestCommand); } /** * Oneway invocation. * * @param conn * @param request * @throws InterruptedException */ protected void oneway(final Connection conn, final RemotingCommand request) { try { conn.getChannel().writeAndFlush(request).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture f) throws Exception { if (!f.isSuccess()) { logger.error("Invoke send failed. The address is {}", RemotingUtil.parseRemoteAddress(conn.getChannel()), f.cause()); } } }); } catch (Exception e) { if (null == conn) { logger.error("Conn is null"); } else { logger.error("Exception caught when sending invocation. The address is {}", RemotingUtil.parseRemoteAddress(conn.getChannel()), e); } } }

2.泛化调用
参考SOFARPC Example示例模块(com.alipay.sofa.rpc.invoke.generic):

package com.alipay.sofa.rpc.invoke.generic;

import com.alipay.sofa.rpc.config.ApplicationConfig;
import com.alipay.sofa.rpc.config.ProviderConfig;
import com.alipay.sofa.rpc.config.ServerConfig;

public class GenericServerMain {

    public static void main(String[] args) {
        ApplicationConfig applicationConfig = new ApplicationConfig().setAppName("generic-server");

        ServerConfig serverConfig2 = new ServerConfig()
            .setPort(22222)
            .setDaemon(false);

        ProviderConfig providerConfig = new ProviderConfig()
            .setApplication(applicationConfig)
            .setInterfaceId(TestGenericService.class.getName())
            .setRef(new TestGenericServiceImpl())
            .setServer(serverConfig2);
        providerConfig.export();
    }
}
package com.alipay.sofa.rpc.invoke.generic;

import com.alipay.hessian.generic.model.GenericObject;
import com.alipay.sofa.rpc.api.GenericService;
import com.alipay.sofa.rpc.config.ApplicationConfig;
import com.alipay.sofa.rpc.config.ConsumerConfig;
import com.alipay.sofa.rpc.context.RpcRuntimeContext;
import com.alipay.sofa.rpc.log.Logger;
import com.alipay.sofa.rpc.log.LoggerFactory;

public class GenericClientMain {

    private static final Logger LOGGER = LoggerFactory.getLogger(GenericClientMain.class);

    public static void main(String[] args) {
        ApplicationConfig applicationConfig = new ApplicationConfig().setAppName("generic-client");

        ConsumerConfig consumerConfig = new ConsumerConfig()
            .setApplication(applicationConfig)
            .setInterfaceId(TestGenericService.class.getName())
            .setGeneric(true)
            .setTimeout(50000)
            .setDirectUrl("bolt://127.0.0.1:22222?appName=generic-server");
        GenericService testService = consumerConfig.refer();

        LOGGER.warn("started at pid {}", RpcRuntimeContext.PID);

        while (true) {
            try {
                String s1 = (String) testService.$invoke("echoStr", new String[] { "java.lang.String" },
                    new Object[] { "1111" });
                LOGGER.warn("generic return :{}", s1);

                GenericObject genericObject = new GenericObject(
                    "com.alipay.sofa.rpc.invoke.generic.TestObj");
                genericObject.putField("str", "xxxx");
                genericObject.putField("num", 222);

                GenericObject o2 = (GenericObject) testService.$genericInvoke("echoObj",
                    new String[] { "com.alipay.sofa.rpc.invoke.generic.TestObj" },
                    new Object[] { genericObject });
                LOGGER.warn("generic return :{}", o2);

                TestObj o3 = testService.$genericInvoke("echoObj",
                    new String[] { "com.alipay.sofa.rpc.invoke.generic.TestObj" },
                    new Object[] { genericObject }, TestObj.class);
                LOGGER.warn("generic return :{}", o3);

            } catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
            }
            try {
                Thread.sleep(2000);
            } catch (Exception ignore) {
            }
        }

    }
}

运行泛化调用服务端示例类GenericServerMain查看泛化调用服务端输出日志:

2018-06-02 22:25:22,746 main  INFO [com.alipay.sofa.rpc.context.RpcRuntimeContext:info:102] - Welcome! Loading SOFA RPC Framework : 5.4.0_20180530235405, PID is:12556
2018-06-02 22:25:24,285 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: fault-tolerance
2018-06-02 22:25:25,259 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer-resteasy
2018-06-02 22:25:26,899 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:97] - The module lookout does not need to be loaded.
2018-06-02 22:25:26,930 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer
2018-06-02 22:25:27,450 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultProviderBootstrap:infoWithApp:122] - [generic-server]Export provider config : com.alipay.sofa.rpc.invoke.generic.TestGenericService: with bean id rpc-cfg-0
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-02 22:25:29,737 main  INFO [com.alipay.sofa.common.log:report:30] - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-02 22:25:33,102 main  INFO [com.alipay.sofa.rpc.server.bolt.BoltServer:info:102] - Bolt server has been bind to 0.0.0.0:22222
2018-06-02 22:38:26,495 SOFA-SEV-BOLT-BIZ-22222-3-T1  INFO [com.alipay.sofa.rpc.tracer.Tracers:info:102] - Load tracer impl success: sofaTracer, com.alipay.sofa.rpc.tracer.sofatracer.RpcSofaTracer@7a34d8b5
2018-06-02 22:38:26,575 SOFA-SEV-BOLT-BIZ-22222-3-T1  INFO [com.alipay.sofa.rpc.invoke.generic.TestGenericServiceImpl:info:102] - receive str: 1111
2018-06-02 22:38:27,046 SOFA-SEV-BOLT-BIZ-22222-3-T2  INFO [com.alipay.sofa.rpc.invoke.generic.TestGenericServiceImpl:info:102] - receive obj: TestObj{str='xxxx', num=222}
2018-06-02 22:38:27,174 SOFA-SEV-BOLT-BIZ-22222-3-T3  INFO [com.alipay.sofa.rpc.invoke.generic.TestGenericServiceImpl:info:102] - receive obj: TestObj{str='xxxx', num=222}
2018-06-02 22:38:29,194 SOFA-SEV-BOLT-BIZ-22222-3-T4  INFO [com.alipay.sofa.rpc.invoke.generic.TestGenericServiceImpl:info:102] - receive str: 1111
2018-06-02 22:38:29,202 SOFA-SEV-BOLT-BIZ-22222-3-T5  INFO [com.alipay.sofa.rpc.invoke.generic.TestGenericServiceImpl:info:102] - receive obj: TestObj{str='xxxx', num=222}
2018-06-02 22:38:29,212 SOFA-SEV-BOLT-BIZ-22222-3-T6  INFO [com.alipay.sofa.rpc.invoke.generic.TestGenericServiceImpl:info:102] - receive obj: TestObj{str='xxxx', num=222}

运行泛化调用客户端示例类GenericClientMain查看泛化调用客户端输出日志:

2018-06-02 22:38:15,849 main  INFO [com.alipay.sofa.rpc.context.RpcRuntimeContext:info:102] - Welcome! Loading SOFA RPC Framework : 5.4.0_20180530235405, PID is:7640
2018-06-02 22:38:16,833 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: fault-tolerance
2018-06-02 22:38:17,444 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer-resteasy
2018-06-02 22:38:18,655 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:97] - The module lookout does not need to be loaded.
2018-06-02 22:38:18,667 main  INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: sofaTracer
2018-06-02 22:38:19,470 main  INFO [com.alipay.sofa.rpc.bootstrap.DefaultConsumerBootstrap:infoWithApp:122] - [generic-client]Refer consumer config : bolt://com.alipay.sofa.rpc.invoke.generic.TestGenericService: with bean id rpc-cfg-0
2018-06-02 22:38:21,322 main  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [generic-client]Add provider of com.alipay.sofa.rpc.invoke.generic.TestGenericService, size is : 1
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-02 22:38:22,119 SOFA-CLI-CONN-com.alipay.sofa.rpc.invoke.generic.TestGenericService-3-T1  INFO [com.alipay.sofa.common.log:report:30] - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-06-02 22:38:24,058 SOFA-CLI-CONN-com.alipay.sofa.rpc.invoke.generic.TestGenericService-3-T1  INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - [generic-client]Connect to com.alipay.sofa.rpc.invoke.generic.TestGenericService provider:bolt://127.0.0.1:22222?appName=generic-server success ! The connection is 127.0.0.1:22222 <-> 127.0.0.1:53301
2018-06-02 22:38:24,901 main  WARN [com.alipay.sofa.rpc.invoke.generic.GenericClientMain:warn:142] - started at pid 7640
2018-06-02 22:38:25,024 main  INFO [com.alipay.sofa.rpc.tracer.Tracers:info:102] - Load tracer impl success: sofaTracer, com.alipay.sofa.rpc.tracer.sofatracer.RpcSofaTracer@7cd62f43
2018-06-02 22:38:26,952 main  WARN [com.alipay.sofa.rpc.invoke.generic.GenericClientMain:warn:142] - generic return :1111
2018-06-02 22:38:27,095 main  WARN [com.alipay.sofa.rpc.invoke.generic.GenericClientMain:warn:142] - generic return :{type: com.alipay.sofa.rpc.invoke.generic.TestObj, fields: {num=222, str=xxxx}}
2018-06-02 22:38:27,188 main  WARN [com.alipay.sofa.rpc.invoke.generic.GenericClientMain:warn:142] - generic return :TestObj{str='xxxx', num=222}
2018-06-02 22:38:29,197 main  WARN [com.alipay.sofa.rpc.invoke.generic.GenericClientMain:warn:142] - generic return :1111
2018-06-02 22:38:29,207 main  WARN [com.alipay.sofa.rpc.invoke.generic.GenericClientMain:warn:142] - generic return :{type: com.alipay.sofa.rpc.invoke.generic.TestObj, fields: {num=222, str=xxxx}}
2018-06-02 22:38:29,215 main  WARN [com.alipay.sofa.rpc.invoke.generic.GenericClientMain:warn:142] - generic return :TestObj{str='xxxx', num=222}

参考sofa-rpc-boot-projects范例模块(com.alipay.sofa.rpc.samples.generic):




    



    
        
    

package com.alipay.sofa.rpc.samples.generic;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;

@ImportResource({ "classpath:generic-server-example.xml" })
@SpringBootApplication
public class GenericServerApplication {

    public static void main(String[] args) {

        SpringApplication springApplication = new SpringApplication(GenericServerApplication.class);
        ApplicationContext applicationContext = springApplication.run(args);
    }
}
package com.alipay.sofa.rpc.samples.generic;

import com.alipay.hessian.generic.model.GenericObject;
import com.alipay.sofa.rpc.api.GenericService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;

@ImportResource({ "classpath:generic-client-example.xml" })
@SpringBootApplication
public class GenericClientApplication {

    public static void main(String[] args) {

        //change port to run in local machine
        System.setProperty("server.port", "8081");

        SpringApplication springApplication = new SpringApplication(GenericClientApplication.class);
        ApplicationContext applicationContext = springApplication.run(args);

        GenericService sampleGenericServiceReference = (GenericService) applicationContext
            .getBean("sampleGenericServiceReference");

        GenericObject genericObject = new GenericObject(
            "com.alipay.sofa.rpc.samples.generic.SampleGenericParamModel");
        genericObject.putField("name", "Bible");

        GenericObject genericResult = (GenericObject) sampleGenericServiceReference.$genericInvoke("sayGeneric",
            new String[] { "com.alipay.sofa.rpc.samples.generic.SampleGenericParamModel" },
            new Object[] { genericObject });

        System.out.println(genericResult.getType());
        System.out.println(genericResult.getField("name"));
        System.out.println(genericResult.getField("value"));

        String result = (String) genericResult.getField("value");

        System.out.println("invoke result:" + result);

        if ("sample generic value".equalsIgnoreCase(result)) {
            System.out.println("generic invoke success");
        } else {
            System.out.println("generic invoke fail");
        }

    }
}

运行泛化调用服务端范例类GenericServerApplication查看泛化调用服务端输出日志:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.2.RELEASE)

Sofa-Middleware-Log SLF4J : Actual logging.path is [ ./logs ]
2018-06-02 23:26:32.427  INFO 1236 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual logging.path is [ ./logs ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.infra Logback ]
2018-06-02 23:26:32.442  INFO 1236 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.infra Logback ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.healthcheck Logback ]
2018-06-02 23:26:32.714  INFO 1236 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.healthcheck Logback ]
2018-06-02 23:26:32.761  INFO 1236 --- [           main] c.a.s.r.s.g.GenericServerApplication     : Starting GenericServerApplication on Program with PID 1236 (D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-samples\target\classes started by Administrator in D:\Program\Github\sofa-rpc-boot-projects)
2018-06-02 23:26:32.762  INFO 1236 --- [           main] c.a.s.r.s.g.GenericServerApplication     : No active profile set, falling back to default profiles: default
2018-06-02 23:26:32.851  INFO 1236 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@59309333: startup date [Sat Jun 02 23:26:32 CST 2018]; root of context hierarchy
2018-06-02 23:26:35.088  INFO 1236 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from class path resource [generic-client-example.xml]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc.boot Logback ]
2018-06-02 23:26:35.486  INFO 1236 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc.boot Logback ]
2018-06-02 23:26:35.611  INFO 1236 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from class path resource [generic-server-example.xml]
2018-06-02 23:26:36.882  INFO 1236 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'com.alipay.sofa.runtime.spring.configuration.SofaRuntimeAutoConfiguration' of type [class com.alipay.sofa.runtime.spring.configuration.SofaRuntimeAutoConfiguration$$EnhancerBySpringCGLIB$$99aaf0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:26:37.031  INFO 1236 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'bindingConverterFactory' of type [class com.alipay.sofa.runtime.service.impl.BindingConverterFactoryImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:26:37.091  INFO 1236 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'bindingAdapterFactory' of type [class com.alipay.sofa.runtime.service.impl.BindingAdapterFactoryImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:26:37.097  INFO 1236 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sofaRuntimeProperties' of type [class com.alipay.sofa.runtime.spring.config.SofaRuntimeProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:26:37.110  INFO 1236 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sofaRuntimeContext' of type [class com.alipay.sofa.runtime.spi.component.SofaRuntimeContext] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.runtime Logback ]
2018-06-02 23:26:37.178  INFO 1236 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.runtime Logback ]
2018-06-02 23:26:37.191  INFO 1236 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'com.alipay.sofa.rpc.boot.SofaBootRpcAutoConfiguration' of type [class com.alipay.sofa.rpc.boot.SofaBootRpcAutoConfiguration$$EnhancerBySpringCGLIB$$34f86405] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:26:37.236  INFO 1236 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'consumerConfigHelper' of type [class com.alipay.sofa.rpc.boot.runtime.adapter.helper.ConsumerConfigHelper] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:26:37.242  INFO 1236 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sofaBootRpcProperties' of type [class com.alipay.sofa.rpc.boot.config.SofaBootRpcProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:26:37.244  INFO 1236 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'zookeeperConfigurator' of type [class com.alipay.sofa.rpc.boot.config.ZookeeperConfigurator] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:26:37.246  INFO 1236 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'localFileConfigurator' of type [class com.alipay.sofa.rpc.boot.config.LocalFileConfigurator] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:26:37.246  INFO 1236 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'registryConfigContainer' of type [class com.alipay.sofa.rpc.boot.container.RegistryConfigContainer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Logback ]
2018-06-02 23:26:37.288  INFO 1236 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Logback ]
2018-06-02 23:26:37.589  INFO 1236 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'consumerConfigContainer' of type [class com.alipay.sofa.rpc.boot.container.ConsumerConfigContainer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:26:37.717  INFO 1236 --- [           main] o.a.c.f.imps.CuratorFrameworkImpl        : Starting
2018-06-02 23:26:37.725  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:zookeeper.version=3.4.6-1569965, built on 02/20/2014 09:09 GMT
2018-06-02 23:26:37.726  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:host.name=Program
2018-06-02 23:26:37.726  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.version=1.8.0_141
2018-06-02 23:26:37.726  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.vendor=Oracle Corporation
2018-06-02 23:26:37.726  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.home=C:\Program Files\Java\jdk1.8.0_141\jre
2018-06-02 23:26:37.726  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.class.path=C:\Program Files\Java\jdk1.8.0_141\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\rt.jar;D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-samples\target\classes;D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-starter\target\classes;C:\Users\Administrator\.m2\repository\com\alipay\sofa\sofa-rpc-all\5.4.0\sofa-rpc-all-5.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\bolt\1.4.1\bolt-1.4.1.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\1.7.21\slf4j-api-1.7.21.jar;C:\Users\Administrator\.m2\repository\io\netty\netty-all\4.1.25.Final\netty-all-4.1.25.Final.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\hessian\3.3.0\hessian-3.3.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\tracer-core\2.1.1\tracer-core-2.1.1.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-api\0.22.0\opentracing-api-0.22.0.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-noop\0.22.0\opentracing-noop-0.22.0.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-mock\0.22.0\opentracing-mock-0.22.0.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-util\0.22.0\opentracing-util-0.22.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\lookout\lookout-api\1.4.0\lookout-api-1.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\runtime-sofa-boot-starter\2.4.0\runtime-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-client\2.9.1\curator-client-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-framework\2.9.1\curator-framework-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-recipes\2.9.1\curator-recipes-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-jaxrs\3.0.12.Final\resteasy-jaxrs-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\spec\javax\annotation\jboss-annotations-api_1.1_spec\1.0.1.Final\jboss-annotations-api_1.1_spec-1.0.1.Final.jar;C:\Users\Administrator\.m2\repository\javax\activation\activation\1.1.1\activation-1.1.1.jar;C:\Users\Administrator\.m2\repository\org\apache\httpcomponents\httpclient\4.3.6\httpclient-4.3.6.jar;C:\Users\Administrator\.m2\repository\org\apache\httpcomponents\httpcore\4.3.3\httpcore-4.3.3.jar;C:\Users\Administrator\.m2\repository\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;C:\Users\Administrator\.m2\repository\commons-codec\commons-codec\1.6\commons-codec-1.6.jar;C:\Users\Administrator\.m2\repository\commons-io\commons-io\2.1\commons-io-2.1.jar;C:\Users\Administrator\.m2\repository\net\jcip\jcip-annotations\1.0\jcip-annotations-1.0.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-client\3.0.12.Final\resteasy-client-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-jackson-provider\3.0.12.Final\resteasy-jackson-provider-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-core-asl\1.9.12\jackson-core-asl-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-mapper-asl\1.9.12\jackson-mapper-asl-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-jaxrs\1.9.12\jackson-jaxrs-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-xc\1.9.12\jackson-xc-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-netty4\3.0.12.Final\resteasy-netty4-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-validator-provider-11\3.0.12.Final\resteasy-validator-provider-11-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\hibernate\hibernate-validator\5.0.1.Final\hibernate-validator-5.0.1.Final.jar;C:\Users\Administrator\.m2\repository\javax\validation\validation-api\1.1.0.Final\validation-api-1.1.0.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\logging\jboss-logging\3.1.1.GA\jboss-logging-3.1.1.GA.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\classmate\0.8.0\classmate-0.8.0.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\jaxrs-api\3.0.12.Final\jaxrs-api-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-multipart-provider\3.0.12.Final\resteasy-multipart-provider-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-jaxb-provider\3.0.12.Final\resteasy-jaxb-provider-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\com\sun\xml\bind\jaxb-impl\2.2.7\jaxb-impl-2.2.7.jar;C:\Users\Administrator\.m2\repository\com\sun\xml\bind\jaxb-core\2.2.7\jaxb-core-2.2.7.jar;C:\Users\Administrator\.m2\repository\javax\xml\bind\jaxb-api\2.2.7\jaxb-api-2.2.7.jar;C:\Users\Administrator\.m2\repository\com\sun\istack\istack-commons-runtime\2.16\istack-commons-runtime-2.16.jar;C:\Users\Administrator\.m2\repository\com\sun\xml\fastinfoset\FastInfoset\1.2.12\FastInfoset-1.2.12.jar;C:\Users\Administrator\.m2\repository\javax\xml\bind\jsr173_api\1.0\jsr173_api-1.0.jar;C:\Users\Administrator\.m2\repository\javax\mail\mail\1.5.0-b01\mail-1.5.0-b01.jar;C:\Users\Administrator\.m2\repository\org\apache\james\apache-mime4j\0.6\apache-mime4j-0.6.jar;C:\Users\Administrator\.m2\repository\javax\el\javax.el-api\2.2.5\javax.el-api-2.2.5.jar;C:\Users\Administrator\.m2\repository\org\glassfish\web\javax.el\2.2.6\javax.el-2.2.6.jar;C:\Users\Administrator\.m2\repository\com\alibaba\dubbo\2.4.10\dubbo-2.4.10.jar;C:\Users\Administrator\.m2\repository\org\jboss\netty\netty\3.2.5.Final\netty-3.2.5.Final.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\4.3.4.RELEASE\spring-beans-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\4.3.4.RELEASE\spring-core-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\1.4.2.RELEASE\spring-boot-autoconfigure-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\test-sofa-boot-starter\2.4.0\test-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\healthcheck-sofa-boot-starter\2.4.0\healthcheck-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\infra-sofa-boot-starter\2.4.0\infra-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\4.3.4.RELEASE\spring-context-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\4.3.4.RELEASE\spring-aop-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\4.3.4.RELEASE\spring-expression-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot\1.4.2.RELEASE\spring-boot-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-actuator\1.4.2.RELEASE\spring-boot-starter-actuator-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter\1.4.2.RELEASE\spring-boot-starter-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-logging\1.4.2.RELEASE\spring-boot-starter-logging-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-classic\1.1.7\logback-classic-1.1.7.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-core\1.1.7\logback-core-1.1.7.jar;C:\Users\Administrator\.m2\repository\org\slf4j\jcl-over-slf4j\1.7.21\jcl-over-slf4j-1.7.21.jar;C:\Users\Administrator\.m2\repository\org\slf4j\jul-to-slf4j\1.7.21\jul-to-slf4j-1.7.21.jar;C:\Users\Administrator\.m2\repository\org\slf4j\log4j-over-slf4j\1.7.21\log4j-over-slf4j-1.7.21.jar;C:\Users\Administrator\.m2\repository\org\yaml\snakeyaml\1.17\snakeyaml-1.17.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-actuator\1.4.2.RELEASE\spring-boot-actuator-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-web\1.4.2.RELEASE\spring-boot-starter-web-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\1.4.2.RELEASE\spring-boot-starter-tomcat-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\8.5.6\tomcat-embed-core-8.5.6.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\8.5.6\tomcat-embed-el-8.5.6.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\8.5.6\tomcat-embed-websocket-8.5.6.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.8.4\jackson-databind-2.8.4.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.8.0\jackson-annotations-2.8.0.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.8.4\jackson-core-2.8.4.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-web\4.3.4.RELEASE\spring-web-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-webmvc\4.3.4.RELEASE\spring-webmvc-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\com\alibaba\fastjson\1.2.47\fastjson-1.2.47.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\common\sofa-common-tools\1.0.12\sofa-common-tools-1.0.12.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-test\2.9.1\curator-test-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\apache\zookeeper\zookeeper\3.4.6\zookeeper-3.4.6.jar;C:\Users\Administrator\.m2\repository\log4j\log4j\1.2.16\log4j-1.2.16.jar;C:\Users\Administrator\.m2\repository\jline\jline\0.9.94\jline-0.9.94.jar;C:\Users\Administrator\.m2\repository\io\netty\netty\3.7.0.Final\netty-3.7.0.Final.jar;C:\Users\Administrator\.m2\repository\org\javassist\javassist\3.18.1-GA\javassist-3.18.1-GA.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-math\2.2\commons-math-2.2.jar;C:\Users\Administrator\.m2\repository\com\google\guava\guava\16.0.1\guava-16.0.1.jar;C:\Users\Administrator\.m2\repository\com\101tec\zkclient\0.10\zkclient-0.10.jar;D:\Program\JetBrains\IntelliJ\lib\idea_rt.jar
2018-06-02 23:26:37.727  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.library.path=C:\Program Files\Java\jdk1.8.0_141\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Java\jdk1.8.0_141\bin;C:\Program Files\Java\jdk1.8.0_141\jre\bin;C:\Program Files\Maven\bin;C:\Program Files (x86)\Git\cmd;C:\Program Files\MySQL\MySQL Utilities 1.6\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;;C:\Program Files\Mercurial;.
2018-06-02 23:26:37.727  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.io.tmpdir=C:\Users\ADMINI~1\AppData\Local\Temp\
2018-06-02 23:26:37.728  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.compiler=
2018-06-02 23:26:37.728  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:os.name=Windows 10
2018-06-02 23:26:37.728  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:os.arch=amd64
2018-06-02 23:26:37.728  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:os.version=10.0
2018-06-02 23:26:37.728  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:user.name=Administrator
2018-06-02 23:26:37.728  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:user.home=C:\Users\Administrator
2018-06-02 23:26:37.728  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:user.dir=D:\Program\Github\sofa-rpc-boot-projects
2018-06-02 23:26:37.731  INFO 1236 --- [           main] org.apache.zookeeper.ZooKeeper           : Initiating client connection, connectString=127.0.0.1:2181 sessionTimeout=60000 watcher=org.apache.curator.ConnectionState@16fe9c29
2018-06-02 23:26:37.768  INFO 1236 --- [127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn          : Opening socket connection to server 127.0.0.1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
2018-06-02 23:26:37.771  INFO 1236 --- [127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn          : Socket connection established to 127.0.0.1/127.0.0.1:2181, initiating session
2018-06-02 23:26:37.833  INFO 1236 --- [127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn          : Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x10001e7028f0000, negotiated timeout = 40000
2018-06-02 23:26:37.845  INFO 1236 --- [ain-EventThread] o.a.c.f.state.ConnectionStateManager     : State change: CONNECTED
2018-06-02 23:26:37.891  WARN 1236 --- [           main] org.apache.curator.utils.ZKPaths         : The version of ZooKeeper being used doesn't support Container nodes. CreateMode.PERSISTENT will be used instead.
2018-06-02 23:26:38.691  INFO 1236 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sampleGenericServiceReference' of type [class com.alipay.sofa.runtime.spring.factory.ReferenceFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:26:53.798  INFO 1236 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2018-06-02 23:26:53.851  INFO 1236 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2018-06-02 23:26:53.947  INFO 1236 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.6
2018-06-02 23:26:55.152  INFO 1236 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-06-02 23:26:55.153  INFO 1236 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 22302 ms
2018-06-02 23:26:56.117  INFO 1236 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2018-06-02 23:26:56.188  INFO 1236 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'metricsFilter' to: [/*]
2018-06-02 23:26:56.198  INFO 1236 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-06-02 23:26:56.198  INFO 1236 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-06-02 23:26:56.204  INFO 1236 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-06-02 23:26:56.205  INFO 1236 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2018-06-02 23:26:56.207  INFO 1236 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'webRequestLoggingFilter' to: [/*]
2018-06-02 23:26:56.207  INFO 1236 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'applicationContextIdFilter' to: [/*]
2018-06-02 23:27:00.395  INFO 1236 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@59309333: startup date [Sat Jun 02 23:26:32 CST 2018]; root of context hierarchy
2018-06-02 23:27:01.364  INFO 1236 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-06-02 23:27:01.368  INFO 1236 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-06-02 23:27:01.714  INFO 1236 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-02 23:27:01.714  INFO 1236 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-02 23:27:01.999  INFO 1236 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-02 23:27:04.421  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/health/readiness || /health/readiness.json],produces=[application/json]}" onto public java.lang.Object com.alipay.sofa.healthcheck.service.SofaBootReadinessCheckMvcEndpoint.invoke(java.security.Principal)
2018-06-02 23:27:04.435  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/dump || /dump.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:04.436  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/sofaboot/versions || /sofaboot/versions.json],produces=[application/json]}" onto public java.lang.Object com.alipay.sofa.infra.endpoint.SofaBootVersionEndpointMvcAdapter.invoke()
2018-06-02 23:27:04.442  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/trace || /trace.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:04.453  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/mappings || /mappings.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:04.457  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/heapdump || /heapdump.json],methods=[GET],produces=[application/octet-stream]}" onto public void org.springframework.boot.actuate.endpoint.mvc.HeapdumpMvcEndpoint.invoke(boolean,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.io.IOException,javax.servlet.ServletException
2018-06-02 23:27:04.474  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/metrics/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint.value(java.lang.String)
2018-06-02 23:27:04.475  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/metrics || /metrics.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:04.477  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/logfile || /logfile.json],methods=[GET || HEAD]}" onto public void org.springframework.boot.actuate.endpoint.mvc.LogFileMvcEndpoint.invoke(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException
2018-06-02 23:27:04.483  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
2018-06-02 23:27:04.484  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env || /env.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:04.485  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/health || /health.json],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(java.security.Principal)
2018-06-02 23:27:04.490  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/beans || /beans.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:04.496  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/info || /info.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:04.498  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/autoconfig || /autoconfig.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:04.500  INFO 1236 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/configprops || /configprops.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:05.084  INFO 1236 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-06-02 23:27:05.161  INFO 1236 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-06-02 23:27:06.128  INFO 1236 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-06-02 23:27:11.373  INFO 1236 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2018-06-02 23:27:11.388  INFO 1236 --- [           main] c.a.s.r.s.g.GenericServerApplication     : Started GenericServerApplication in 40.159 seconds (JVM running for 43.778)

运行泛化调用客户端范例类GenericClientApplication查看泛化调用客户端输出日志:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.2.RELEASE)

Sofa-Middleware-Log SLF4J : Actual logging.path is [ ./logs ]
2018-06-02 23:26:59.572  INFO 13708 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual logging.path is [ ./logs ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.infra Logback ]
2018-06-02 23:26:59.594  INFO 13708 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.infra Logback ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.healthcheck Logback ]
2018-06-02 23:27:00.052  INFO 13708 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.healthcheck Logback ]
2018-06-02 23:27:00.179  INFO 13708 --- [           main] c.a.s.r.s.g.GenericClientApplication     : Starting GenericClientApplication on Program with PID 13708 (D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-samples\target\classes started by Administrator in D:\Program\Github\sofa-rpc-boot-projects)
2018-06-02 23:27:00.181  INFO 13708 --- [           main] c.a.s.r.s.g.GenericClientApplication     : No active profile set, falling back to default profiles: default
2018-06-02 23:27:00.444  INFO 13708 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@4c12331b: startup date [Sat Jun 02 23:27:00 CST 2018]; root of context hierarchy
2018-06-02 23:27:04.610  INFO 13708 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from class path resource [generic-server-example.xml]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc.boot Logback ]
2018-06-02 23:27:05.133  INFO 13708 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc.boot Logback ]
2018-06-02 23:27:05.361  INFO 13708 --- [           main] o.s.b.f.xml.XmlBeanDefinitionReader      : Loading XML bean definitions from class path resource [generic-client-example.xml]
2018-06-02 23:27:08.260  INFO 13708 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'com.alipay.sofa.runtime.spring.configuration.SofaRuntimeAutoConfiguration' of type [class com.alipay.sofa.runtime.spring.configuration.SofaRuntimeAutoConfiguration$$EnhancerBySpringCGLIB$$d986ce61] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:27:09.510  INFO 13708 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'bindingConverterFactory' of type [class com.alipay.sofa.runtime.service.impl.BindingConverterFactoryImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:27:09.882  INFO 13708 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'bindingAdapterFactory' of type [class com.alipay.sofa.runtime.service.impl.BindingAdapterFactoryImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:27:09.885  INFO 13708 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sofaRuntimeProperties' of type [class com.alipay.sofa.runtime.spring.config.SofaRuntimeProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:27:09.892  INFO 13708 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sofaRuntimeContext' of type [class com.alipay.sofa.runtime.spi.component.SofaRuntimeContext] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.runtime Logback ]
2018-06-02 23:27:10.115  INFO 13708 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.runtime Logback ]
2018-06-02 23:27:10.145  INFO 13708 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'com.alipay.sofa.rpc.boot.SofaBootRpcAutoConfiguration' of type [class com.alipay.sofa.rpc.boot.SofaBootRpcAutoConfiguration$$EnhancerBySpringCGLIB$$de58776] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:27:10.242  INFO 13708 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'consumerConfigHelper' of type [class com.alipay.sofa.rpc.boot.runtime.adapter.helper.ConsumerConfigHelper] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:27:10.265  INFO 13708 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sofaBootRpcProperties' of type [class com.alipay.sofa.rpc.boot.config.SofaBootRpcProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:27:10.272  INFO 13708 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'zookeeperConfigurator' of type [class com.alipay.sofa.rpc.boot.config.ZookeeperConfigurator] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:27:10.277  INFO 13708 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'localFileConfigurator' of type [class com.alipay.sofa.rpc.boot.config.LocalFileConfigurator] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:27:10.279  INFO 13708 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'registryConfigContainer' of type [class com.alipay.sofa.rpc.boot.container.RegistryConfigContainer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Logback ]
2018-06-02 23:27:10.620  INFO 13708 --- [           main] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Logback ]
2018-06-02 23:27:11.172  INFO 13708 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'consumerConfigContainer' of type [class com.alipay.sofa.rpc.boot.container.ConsumerConfigContainer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:27:16.049  INFO 13708 --- [           main] o.a.c.f.imps.CuratorFrameworkImpl        : Starting
2018-06-02 23:27:16.077  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:zookeeper.version=3.4.6-1569965, built on 02/20/2014 09:09 GMT
2018-06-02 23:27:16.077  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:host.name=Program
2018-06-02 23:27:16.078  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.version=1.8.0_141
2018-06-02 23:27:16.078  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.vendor=Oracle Corporation
2018-06-02 23:27:16.078  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.home=C:\Program Files\Java\jdk1.8.0_141\jre
2018-06-02 23:27:16.079  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.class.path=C:\Program Files\Java\jdk1.8.0_141\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_141\jre\lib\rt.jar;D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-samples\target\classes;D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-starter\target\classes;C:\Users\Administrator\.m2\repository\com\alipay\sofa\sofa-rpc-all\5.4.0\sofa-rpc-all-5.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\bolt\1.4.1\bolt-1.4.1.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\1.7.21\slf4j-api-1.7.21.jar;C:\Users\Administrator\.m2\repository\io\netty\netty-all\4.1.25.Final\netty-all-4.1.25.Final.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\hessian\3.3.0\hessian-3.3.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\tracer-core\2.1.1\tracer-core-2.1.1.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-api\0.22.0\opentracing-api-0.22.0.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-noop\0.22.0\opentracing-noop-0.22.0.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-mock\0.22.0\opentracing-mock-0.22.0.jar;C:\Users\Administrator\.m2\repository\io\opentracing\opentracing-util\0.22.0\opentracing-util-0.22.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\lookout\lookout-api\1.4.0\lookout-api-1.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\runtime-sofa-boot-starter\2.4.0\runtime-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-client\2.9.1\curator-client-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-framework\2.9.1\curator-framework-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-recipes\2.9.1\curator-recipes-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-jaxrs\3.0.12.Final\resteasy-jaxrs-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\spec\javax\annotation\jboss-annotations-api_1.1_spec\1.0.1.Final\jboss-annotations-api_1.1_spec-1.0.1.Final.jar;C:\Users\Administrator\.m2\repository\javax\activation\activation\1.1.1\activation-1.1.1.jar;C:\Users\Administrator\.m2\repository\org\apache\httpcomponents\httpclient\4.3.6\httpclient-4.3.6.jar;C:\Users\Administrator\.m2\repository\org\apache\httpcomponents\httpcore\4.3.3\httpcore-4.3.3.jar;C:\Users\Administrator\.m2\repository\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;C:\Users\Administrator\.m2\repository\commons-codec\commons-codec\1.6\commons-codec-1.6.jar;C:\Users\Administrator\.m2\repository\commons-io\commons-io\2.1\commons-io-2.1.jar;C:\Users\Administrator\.m2\repository\net\jcip\jcip-annotations\1.0\jcip-annotations-1.0.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-client\3.0.12.Final\resteasy-client-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-jackson-provider\3.0.12.Final\resteasy-jackson-provider-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-core-asl\1.9.12\jackson-core-asl-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-mapper-asl\1.9.12\jackson-mapper-asl-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-jaxrs\1.9.12\jackson-jaxrs-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\codehaus\jackson\jackson-xc\1.9.12\jackson-xc-1.9.12.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-netty4\3.0.12.Final\resteasy-netty4-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-validator-provider-11\3.0.12.Final\resteasy-validator-provider-11-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\hibernate\hibernate-validator\5.0.1.Final\hibernate-validator-5.0.1.Final.jar;C:\Users\Administrator\.m2\repository\javax\validation\validation-api\1.1.0.Final\validation-api-1.1.0.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\logging\jboss-logging\3.1.1.GA\jboss-logging-3.1.1.GA.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\classmate\0.8.0\classmate-0.8.0.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\jaxrs-api\3.0.12.Final\jaxrs-api-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-multipart-provider\3.0.12.Final\resteasy-multipart-provider-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\org\jboss\resteasy\resteasy-jaxb-provider\3.0.12.Final\resteasy-jaxb-provider-3.0.12.Final.jar;C:\Users\Administrator\.m2\repository\com\sun\xml\bind\jaxb-impl\2.2.7\jaxb-impl-2.2.7.jar;C:\Users\Administrator\.m2\repository\com\sun\xml\bind\jaxb-core\2.2.7\jaxb-core-2.2.7.jar;C:\Users\Administrator\.m2\repository\javax\xml\bind\jaxb-api\2.2.7\jaxb-api-2.2.7.jar;C:\Users\Administrator\.m2\repository\com\sun\istack\istack-commons-runtime\2.16\istack-commons-runtime-2.16.jar;C:\Users\Administrator\.m2\repository\com\sun\xml\fastinfoset\FastInfoset\1.2.12\FastInfoset-1.2.12.jar;C:\Users\Administrator\.m2\repository\javax\xml\bind\jsr173_api\1.0\jsr173_api-1.0.jar;C:\Users\Administrator\.m2\repository\javax\mail\mail\1.5.0-b01\mail-1.5.0-b01.jar;C:\Users\Administrator\.m2\repository\org\apache\james\apache-mime4j\0.6\apache-mime4j-0.6.jar;C:\Users\Administrator\.m2\repository\javax\el\javax.el-api\2.2.5\javax.el-api-2.2.5.jar;C:\Users\Administrator\.m2\repository\org\glassfish\web\javax.el\2.2.6\javax.el-2.2.6.jar;C:\Users\Administrator\.m2\repository\com\alibaba\dubbo\2.4.10\dubbo-2.4.10.jar;C:\Users\Administrator\.m2\repository\org\jboss\netty\netty\3.2.5.Final\netty-3.2.5.Final.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\4.3.4.RELEASE\spring-beans-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\4.3.4.RELEASE\spring-core-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\1.4.2.RELEASE\spring-boot-autoconfigure-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\test-sofa-boot-starter\2.4.0\test-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\healthcheck-sofa-boot-starter\2.4.0\healthcheck-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\infra-sofa-boot-starter\2.4.0\infra-sofa-boot-starter-2.4.0.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\4.3.4.RELEASE\spring-context-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\4.3.4.RELEASE\spring-aop-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\4.3.4.RELEASE\spring-expression-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot\1.4.2.RELEASE\spring-boot-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-actuator\1.4.2.RELEASE\spring-boot-starter-actuator-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter\1.4.2.RELEASE\spring-boot-starter-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-logging\1.4.2.RELEASE\spring-boot-starter-logging-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-classic\1.1.7\logback-classic-1.1.7.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-core\1.1.7\logback-core-1.1.7.jar;C:\Users\Administrator\.m2\repository\org\slf4j\jcl-over-slf4j\1.7.21\jcl-over-slf4j-1.7.21.jar;C:\Users\Administrator\.m2\repository\org\slf4j\jul-to-slf4j\1.7.21\jul-to-slf4j-1.7.21.jar;C:\Users\Administrator\.m2\repository\org\slf4j\log4j-over-slf4j\1.7.21\log4j-over-slf4j-1.7.21.jar;C:\Users\Administrator\.m2\repository\org\yaml\snakeyaml\1.17\snakeyaml-1.17.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-actuator\1.4.2.RELEASE\spring-boot-actuator-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-web\1.4.2.RELEASE\spring-boot-starter-web-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\1.4.2.RELEASE\spring-boot-starter-tomcat-1.4.2.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\8.5.6\tomcat-embed-core-8.5.6.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\8.5.6\tomcat-embed-el-8.5.6.jar;C:\Users\Administrator\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\8.5.6\tomcat-embed-websocket-8.5.6.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.8.4\jackson-databind-2.8.4.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.8.0\jackson-annotations-2.8.0.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.8.4\jackson-core-2.8.4.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-web\4.3.4.RELEASE\spring-web-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-webmvc\4.3.4.RELEASE\spring-webmvc-4.3.4.RELEASE.jar;C:\Users\Administrator\.m2\repository\com\alibaba\fastjson\1.2.47\fastjson-1.2.47.jar;C:\Users\Administrator\.m2\repository\com\alipay\sofa\common\sofa-common-tools\1.0.12\sofa-common-tools-1.0.12.jar;C:\Users\Administrator\.m2\repository\org\apache\curator\curator-test\2.9.1\curator-test-2.9.1.jar;C:\Users\Administrator\.m2\repository\org\apache\zookeeper\zookeeper\3.4.6\zookeeper-3.4.6.jar;C:\Users\Administrator\.m2\repository\log4j\log4j\1.2.16\log4j-1.2.16.jar;C:\Users\Administrator\.m2\repository\jline\jline\0.9.94\jline-0.9.94.jar;C:\Users\Administrator\.m2\repository\io\netty\netty\3.7.0.Final\netty-3.7.0.Final.jar;C:\Users\Administrator\.m2\repository\org\javassist\javassist\3.18.1-GA\javassist-3.18.1-GA.jar;C:\Users\Administrator\.m2\repository\org\apache\commons\commons-math\2.2\commons-math-2.2.jar;C:\Users\Administrator\.m2\repository\com\google\guava\guava\16.0.1\guava-16.0.1.jar;C:\Users\Administrator\.m2\repository\com\101tec\zkclient\0.10\zkclient-0.10.jar;D:\Program\JetBrains\IntelliJ\lib\idea_rt.jar
2018-06-02 23:27:16.509  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.library.path=C:\Program Files\Java\jdk1.8.0_141\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Java\jdk1.8.0_141\bin;C:\Program Files\Java\jdk1.8.0_141\jre\bin;C:\Program Files\Maven\bin;C:\Program Files (x86)\Git\cmd;C:\Program Files\MySQL\MySQL Utilities 1.6\;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;;C:\Program Files\Mercurial;.
2018-06-02 23:27:16.509  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.io.tmpdir=C:\Users\ADMINI~1\AppData\Local\Temp\
2018-06-02 23:27:16.510  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.compiler=
2018-06-02 23:27:16.510  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:os.name=Windows 10
2018-06-02 23:27:16.510  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:os.arch=amd64
2018-06-02 23:27:16.510  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:os.version=10.0
2018-06-02 23:27:16.510  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:user.name=Administrator
2018-06-02 23:27:16.511  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:user.home=C:\Users\Administrator
2018-06-02 23:27:16.511  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:user.dir=D:\Program\Github\sofa-rpc-boot-projects
2018-06-02 23:27:16.514  INFO 13708 --- [           main] org.apache.zookeeper.ZooKeeper           : Initiating client connection, connectString=127.0.0.1:2181 sessionTimeout=60000 watcher=org.apache.curator.ConnectionState@6124287a
2018-06-02 23:27:17.613  INFO 13708 --- [127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn          : Opening socket connection to server 127.0.0.1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
2018-06-02 23:27:17.617  INFO 13708 --- [127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn          : Socket connection established to 127.0.0.1/127.0.0.1:2181, initiating session
2018-06-02 23:27:17.643  INFO 13708 --- [127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn          : Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x10001e7028f0001, negotiated timeout = 40000
2018-06-02 23:27:17.654  INFO 13708 --- [ain-EventThread] o.a.c.f.state.ConnectionStateManager     : State change: CONNECTED
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-06-02 23:27:17.968  INFO 13708 --- [ricService-3-T1] com.alipay.sofa.common.log               : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-06-02 23:27:20.058  INFO 13708 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'sampleGenericServiceReference' of type [class com.alipay.sofa.runtime.spring.factory.ReferenceFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-06-02 23:27:21.352  INFO 13708 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8081 (http)
2018-06-02 23:27:21.384  INFO 13708 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2018-06-02 23:27:21.387  INFO 13708 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.6
2018-06-02 23:27:23.164  INFO 13708 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-06-02 23:27:23.164  INFO 13708 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 22720 ms
2018-06-02 23:27:23.970  INFO 13708 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2018-06-02 23:27:23.986  INFO 13708 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'metricsFilter' to: [/*]
2018-06-02 23:27:23.987  INFO 13708 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-06-02 23:27:23.988  INFO 13708 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-06-02 23:27:23.989  INFO 13708 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-06-02 23:27:23.989  INFO 13708 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2018-06-02 23:27:23.989  INFO 13708 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'webRequestLoggingFilter' to: [/*]
2018-06-02 23:27:23.990  INFO 13708 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'applicationContextIdFilter' to: [/*]
2018-06-02 23:27:25.649  INFO 13708 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@4c12331b: startup date [Sat Jun 02 23:27:00 CST 2018]; root of context hierarchy
2018-06-02 23:27:25.881  INFO 13708 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-06-02 23:27:25.884  INFO 13708 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-06-02 23:27:25.989  INFO 13708 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-02 23:27:25.989  INFO 13708 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-02 23:27:26.130  INFO 13708 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-06-02 23:27:27.489  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/logfile || /logfile.json],methods=[GET || HEAD]}" onto public void org.springframework.boot.actuate.endpoint.mvc.LogFileMvcEndpoint.invoke(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException
2018-06-02 23:27:27.498  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/mappings || /mappings.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:27.500  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/trace || /trace.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:27.504  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/health || /health.json],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(java.security.Principal)
2018-06-02 23:27:27.506  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/autoconfig || /autoconfig.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:27.511  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/sofaboot/versions || /sofaboot/versions.json],produces=[application/json]}" onto public java.lang.Object com.alipay.sofa.infra.endpoint.SofaBootVersionEndpointMvcAdapter.invoke()
2018-06-02 23:27:27.517  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/info || /info.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:27.519  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/health/readiness || /health/readiness.json],produces=[application/json]}" onto public java.lang.Object com.alipay.sofa.healthcheck.service.SofaBootReadinessCheckMvcEndpoint.invoke(java.security.Principal)
2018-06-02 23:27:27.529  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/metrics/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint.value(java.lang.String)
2018-06-02 23:27:27.530  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/metrics || /metrics.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:27.533  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/heapdump || /heapdump.json],methods=[GET],produces=[application/octet-stream]}" onto public void org.springframework.boot.actuate.endpoint.mvc.HeapdumpMvcEndpoint.invoke(boolean,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.io.IOException,javax.servlet.ServletException
2018-06-02 23:27:27.535  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/beans || /beans.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:27.540  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/dump || /dump.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:27.549  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
2018-06-02 23:27:27.549  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/env || /env.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:27.552  INFO 13708 --- [           main] o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/configprops || /configprops.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-06-02 23:27:28.092  INFO 13708 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-06-02 23:27:28.124  INFO 13708 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2018-06-02 23:27:29.278  INFO 13708 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8081 (http)
2018-06-02 23:27:29.287  INFO 13708 --- [           main] c.a.s.r.s.g.GenericClientApplication     : Started GenericClientApplication in 32.494 seconds (JVM running for 34.704)
com.alipay.sofa.rpc.samples.generic.SampleGenericResultModel
Bible
sample generic value
invoke result:sample generic value
generic invoke success

SOFARPC泛化调用流程:
(1)创建服务引用配置类ConsumerConfig,设置ConsumerConfig实例应用信息配置、接口名称、直连调用地址以及连接超时时间,通过setGeneric设置服务引用是否泛化调用为true:

/**
 * 是否泛化调用
 */
protected boolean generic;
/**
 * Sets generic.
 *
 * @param generic the generic
 * @return the generic
 */
public ConsumerConfig setGeneric(boolean generic) {
    this.generic = generic;
    return this;
}

(2)服务引用配置类ConsumerConfig调用引用服务refer()方法获取泛化调用接口GenericService代理对象引用,通过泛化服务GenericService代理对象调用$invoke/$genericInvoke()方法发起服务泛化调用:

/**
 * 泛化调用的接口
* */ public interface GenericService { /** * 泛化调用 * * @param methodName 调用方法名 * @param argTypes 参数类型 * @param args 方法参数,参数不能是GenericObject类型 * @return 正常类型(不能是GenericObject类型) */ Object $invoke(String methodName, String[] argTypes, Object[] args); /** * 支持参数类型无法在类加载器加载情况的泛化调用 * * @param methodName 调用方法名 * @param argTypes 参数类型 * @param args 方法参数,参数类型支持GenericObject * @return 除了JDK等内置类型,其它对象是GenericObject类型 */ Object $genericInvoke(String methodName, String[] argTypes, Object[] args); /** * 支持参数类型无法在类加载器加载情况的泛化调用 * * @param methodName 调用方法名 * @param argTypes 参数类型 * @param args 方法参数,参数类型支持GenericObject * @param clazz 返回类型 * @return 返回指定的T类型返回对象 */ T $genericInvoke(String methodName, String[] argTypes, Object[] args, Class clazz); /** * 支持参数类型无法在类加载器加载情况的泛化调用 * * @param methodName 调用方法名 * @param argTypes 参数类型 * @param args 方法参数,参数类型支持GenericObject * @param context 上下文,传递超时以及LDC相关信息 * @return 除了JDK等内置类型,其它对象是GenericObject类型 * @deprecated Use RpcInvokeContext instead of GenericContext */ @Deprecated Object $genericInvoke(String methodName, String[] argTypes, Object[] args, GenericContext context); /** * 支持参数类型无法在类加载器加载情况的泛化调用 * * @param methodName 调用方法名 * @param argTypes 参数类型 * @param args 方法参数,参数类型支持GenericObject * @param clazz 返回类型 * @param context GenericContext * @return 返回指定的T类型返回对象 * @deprecated Use RpcInvokeContext instead of GenericContext */ @Deprecated T $genericInvoke(String methodName, String[] argTypes, Object[] args, Class clazz, GenericContext context); }

服务消费者启动类ConsumerBootstrap引用服务客户端集群Cluster构造调用端的执行链加载客户端泛化调用处理过滤器ConsumerGenericFilter,过滤器ConsumerGenericFilter调用needToLoad()方法根据包装调用器服务引用是否泛化调用配置判断是否自动加载添加到执行链过滤器列表:

/**
 * 构造执行链
 *
 * @param filters     包装过滤器列表
 * @param lastInvoker 最终过滤器
 * @param config      接口配置
 */
protected FilterChain(List filters, FilterInvoker lastInvoker, AbstractInterfaceConfig config) {
    // 调用过程外面包装多层自定义filter
    // 前面的过滤器在最外层
    invokerChain = lastInvoker;
    if (CommonUtils.isNotEmpty(filters)) {
        loadedFilters = new ArrayList();
        for (int i = filters.size() - 1; i >= 0; i--) {
            try {
                Filter filter = filters.get(i);
                if (filter.needToLoad(invokerChain)) {
                    invokerChain = new FilterInvoker(filter, invokerChain, config);
                    // cache this for filter when async respond
                    loadedFilters.add(filter);
                }
            } catch (Exception e) {
                LOGGER.error("Error when build filter chain", e);
                throw new SofaRpcRuntimeException("Error when build filter chain", e);
            }
        }
    }
}
/**
 * 是否自动加载
 *
 * @param invoker 调用器
 * @return 是否加载本过滤器
 */
public boolean needToLoad(FilterInvoker invoker) {
    ConsumerConfig consumerConfig = (ConsumerConfig) invoker.getConfig();
    return consumerConfig.isGeneric();
}

代理调用器FilterInvoker服务调用invoke()方法加载客户端泛化调用处理过滤器ConsumerGenericFilter(优先级排序order=-18000,优先级低)的invoke()方法使用getSerializeFactoryType()方法判断方法名是否为$invoke/$genericInvoke获取序列化工厂类型即普通序列化(序列化反序列化均使用SofaSerializerFactory)/泛型序列化(序列化反序列化均使用SofaGenericSerializerFactory)添加到请求额外属性,根据调用方法名、参数类型以及方法参数修正请求对象,根据调用器服务引用配置获取方法调用类型修正请求调用类型,调用器按照请求对象设置执行服务调用:

/**
 * 客户端泛化调用处理filter
 */
@Extension(value = "consumerGeneric", order = -18000)
@AutoActive(consumerSide = true)
public class ConsumerGenericFilter extends Filter {

    /**
     * 方法名 $invoke
     */
    private static final String METHOD_INVOKE         = "$invoke";
    /**
     * 方法名 $genericInvoke
     */
    private static final String METHOD_GENERIC_INVOKE = "$genericInvoke";

    public SofaResponse invoke(FilterInvoker invoker, SofaRequest request) throws SofaRpcException {
        try {
            String type = getSerializeFactoryType(request.getMethodName(), request.getMethodArgs());
            request.addRequestProp(RemotingConstants.HEAD_GENERIC_TYPE, type);

            // 修正请求对象
            Object[] genericArgs = request.getMethodArgs();
            String methodName = (String) genericArgs[0];
            String[] argTypes = (String[]) genericArgs[1];
            Object[] args = (Object[]) genericArgs[2];

            request.setMethodName(methodName);
            request.setMethodArgSigs(argTypes);
            request.setMethodArgs(args);

            // 修正类型
            ConsumerConfig consumerConfig = (ConsumerConfig) invoker.getConfig();
            String invokeType = consumerConfig.getMethodInvokeType(methodName);
            request.setInvokeType(invokeType);
            request.addRequestProp(RemotingConstants.HEAD_INVOKE_TYPE, invokeType);

            return invoker.invoke(request);
        } catch (SofaRpcException e) {
            throw e;
        } catch (Exception e) {
            throw new SofaRpcException(RpcErrorType.CLIENT_FILTER, e.getMessage(), e);
        }
    }

    private String getSerializeFactoryType(String method, Object[] args) throws SofaRpcException {
        if (METHOD_INVOKE.equals(method)) {
            // 方法名为 $invoke
            return RemotingConstants.SERIALIZE_FACTORY_NORMAL;
        } else if (METHOD_GENERIC_INVOKE.equals(method)) {
            if (args.length == 3) {
                // 方法名为$genericInvoke,且长度为3
                return RemotingConstants.SERIALIZE_FACTORY_GENERIC;
            } else if (args.length == 4) {
                // 方法名为$genericInvoke,且长度为4
                if (args[3] instanceof GenericContext) {
                    return RemotingConstants.SERIALIZE_FACTORY_GENERIC;
                }
                // 第四个参数是类型定义
                if (args[3] instanceof Class) {
                    return RemotingConstants.SERIALIZE_FACTORY_MIX;
                }
            } else if (args.length == 5) {
                // 方法名为$genericInvoke,且长度为5
                return RemotingConstants.SERIALIZE_FACTORY_MIX;
            }
        }
        throw new SofaRpcException(RpcErrorType.CLIENT_FILTER, "Unsupported method of generic service");
    }
}

消费者调用器ConsumerInvoker调用invoke()方法使用Client发送数据给Server执行同步/单向/Callback/Future服务调用过程,Bolt客户端长连接BoltClientTransport创建调用上下文InvokeContext根据请求泛化调用属性设置调用上下文是否泛化调用:

protected InvokeContext createInvokeContext(SofaRequest request) {
    InvokeContext invokeContext = new InvokeContext();
    invokeContext.put(InvokeContext.BOLT_CUSTOM_SERIALIZER, request.getSerializeType());
    invokeContext.put(RemotingConstants.HEAD_TARGET_SERVICE, request.getTargetServiceUniqueName());
    invokeContext.put(RemotingConstants.HEAD_METHOD_NAME, request.getMethodName());
    String genericType = (String) request.getRequestProp(RemotingConstants.HEAD_GENERIC_TYPE);
    if (genericType != null) {
        invokeContext.put(RemotingConstants.HEAD_GENERIC_TYPE, genericType);
    }
    return invokeContext;
}

Sofa RPC Bolt协议的对象序列化/反序列化SofaRpcSerialization序列化/反序列化SofaRequest请求/SofaResponse响应内容获取调用上下文InvokeContext是否泛化调用配置,序列化/反序列化器SofaHessianSerializer编码/解码SofaRequest请求/SofaResponse响应根据SerializeType泛化调用信息采用SofaHessianSerializer实例构造方法初始化的泛化序列化/反序列化工厂GenericMultipleClassLoaderSofaSerializerFactory/GenericSingleClassLoaderSofaSerializerFactory设置Hessian2Output/Hessian2Input序列化工厂,Hessian2Output/Hessian2Input根据序列化工厂获取序列化/反序列化器编码/解码SofaRequest请求/SofaResponse响应:

public  boolean serializeContent(Request request, InvokeContext invokeContext)
    throws SerializationException {
    if (request instanceof RpcRequestCommand) {
        RpcRequestCommand requestCommand = (RpcRequestCommand) request;
        Object requestObject = requestCommand.getRequestObject();
        if (requestObject instanceof SofaRequest) {
            byte serializerCode = requestCommand.getSerializer();
            try {
                Map header = (Map) requestCommand.getRequestHeader();
                if (header == null) {
                    header = new HashMap();
                }
                putKV(header, RemotingConstants.HEAD_GENERIC_TYPE,
                    (String) invokeContext.get(RemotingConstants.HEAD_GENERIC_TYPE));

                Serializer rpcSerializer = com.alipay.sofa.rpc.codec.SerializerFactory
                    .getSerializer(serializerCode);
                AbstractByteBuf byteBuf = rpcSerializer.encode(requestObject, header);
                request.setContent(byteBuf.array());
                return true;
            } catch (Exception ex) {
                throw new SerializationException(ex.getMessage(), ex);
            } finally {
                recordSerializeRequest(requestCommand, invokeContext);
            }
        }
        return true;
    }
    return false;
}
public  boolean deserializeContent(Request request)
    throws DeserializationException {
    if (request instanceof RpcRequestCommand) {
        RpcRequestCommand requestCommand = (RpcRequestCommand) request;
        Object header = requestCommand.getRequestHeader();
        if (!(header instanceof Map)) {
            throw new DeserializationException("Head of request is null or is not map");
        }
        Map headerMap = (Map) header;
        byte[] content = requestCommand.getContent();
        if (content == null || content.length == 0) {
            throw new DeserializationException("Content of request is null");
        }
        try {
            String service = headerMap.get(RemotingConstants.HEAD_SERVICE);
            ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();

            ClassLoader serviceClassLoader = ReflectCache.getServiceClassLoader(service);
            try {
                Thread.currentThread().setContextClassLoader(serviceClassLoader);

                Serializer rpcSerializer = com.alipay.sofa.rpc.codec.SerializerFactory
                    .getSerializer(requestCommand.getSerializer());
                SofaRequest sofaRequest = new SofaRequest();
                rpcSerializer.decode(new ByteArrayWrapperByteBuf(requestCommand.getContent()),
                    sofaRequest, headerMap);
                requestCommand.setRequestObject(sofaRequest);
            } finally {
                Thread.currentThread().setContextClassLoader(oldClassLoader);
            }

            return true;
        } catch (Exception ex) {
            throw new DeserializationException(ex.getMessage(), ex);
        } finally {
            recordDeserializeRequest(requestCommand);
        }
    }
    return false;
}
/**
 * Generic Serializer Factory
 */
protected SerializerFactory genericSerializerFactory;
/**
 * Instantiates a new Sofa hessian serializer.
 */
public SofaHessianSerializer() {
    boolean enableMultipleClassLoader = RpcConfigs.getBooleanValue(RpcOptions.MULTIPLE_CLASSLOADER_ENABLE);
    serializerFactory = getSerializerFactory(enableMultipleClassLoader, false);
    genericSerializerFactory = getSerializerFactory(enableMultipleClassLoader, true);
    if (RpcConfigs.getBooleanValue(RpcOptions.SERIALIZE_BLACKLIST_ENABLE) &&
        SofaConfigs.getBooleanValue(SofaOptions.CONFIG_SERIALIZE_BLACKLIST, true)) {
        ClassNameResolver resolver = new ClassNameResolver();
        resolver.addFilter(new NameBlackListFilter(BlackListFileLoader.SOFA_SERIALIZE_BLACK_LIST, 8192));
        serializerFactory.setClassNameResolver(resolver);
        genericSerializerFactory.setClassNameResolver(resolver);
    }
}
/**
 * Gets serializer factory.
 *
 * @param multipleClassLoader the multiple class loader
 * @param generic             the generic
 * @return the serializer factory
 */
protected SerializerFactory getSerializerFactory(boolean multipleClassLoader, boolean generic) {
    if (generic) {
        return multipleClassLoader ? new GenericMultipleClassLoaderSofaSerializerFactory() :
            new GenericSingleClassLoaderSofaSerializerFactory();
    } else {
        return multipleClassLoader ? new MultipleClassLoaderSofaSerializerFactory() :
            new SingleClassLoaderSofaSerializerFactory();
    }
}
/**
 * Do encode SofaRequest
 *
 * @param sofaRequest 请求
 * @param context     上下文
 * @return byte数据 abstract byte buf
 */
protected AbstractByteBuf encodeSofaRequest(SofaRequest sofaRequest, Map context) {
    try {
        UnsafeByteArrayOutputStream outputStream = new UnsafeByteArrayOutputStream();
        Hessian2Output output = new Hessian2Output(outputStream);

        // 根据SerializeType信息决定序列化器
        boolean genericSerialize = context != null &&
            isGenericRequest(context.get(RemotingConstants.HEAD_GENERIC_TYPE));
        if (genericSerialize) {
            output.setSerializerFactory(genericSerializerFactory);
        } else {
            output.setSerializerFactory(serializerFactory);
        }

        output.writeObject(sofaRequest);
        final Object[] args = sofaRequest.getMethodArgs();
        if (args != null) {
            for (Object arg : args) {
                output.writeObject(arg);
            }
        }
        output.close();

        return new ByteStreamWrapperByteBuf(outputStream);
    } catch (IOException e) {
        throw buildSerializeError(e.getMessage(), e);
    }
}
/**
 * Do decode SofaResponse
 *
 * @param data    AbstractByteBuf
 * @param context 上下文
 * @return 响应 sofa response
 * @throws SofaRpcException 序列化出现异常
 */
protected SofaResponse decodeSofaResponse(AbstractByteBuf data, Map context)
    throws SofaRpcException {
    try {
        UnsafeByteArrayInputStream inputStream = new UnsafeByteArrayInputStream(data.array());
        Hessian2Input input = new Hessian2Input(inputStream);
        // 根据SerializeType信息决定序列化器
        Object object;
        boolean genericSerialize = context != null && isGenericResponse(
            context.get(RemotingConstants.HEAD_GENERIC_TYPE));
        if (genericSerialize) {
            input.setSerializerFactory(genericSerializerFactory);
            GenericObject genericObject = (GenericObject) input.readObject();
            SofaResponse sofaResponse = new SofaResponse();
            sofaResponse.setErrorMsg((String) genericObject.getField("errorMsg"));
            sofaResponse.setAppResponse(genericObject.getField("appResponse"));
            sofaResponse.setResponseProps((Map) genericObject.getField("responseProps"));
            object = sofaResponse;
        } else {
            input.setSerializerFactory(serializerFactory);
            object = input.readObject();
        }
        input.close();
        return (SofaResponse) object;
    } catch (IOException e) {
        throw buildDeserializeError(e.getMessage(), e);
    }
}

解析总结
SOFARPC同步/异步/回调/单向调用通过setInvokeType设置服务引用调用类型(默认为同步调用),服务引用配置ConsumerConfig调用refer()方法引用服务使用Client发送数据给Server执行客户端集群Cluster的doSendMsg()方法按照调用类型采取指定调用方式,客户端传输ClientTransport调用syncSend/asyncSend/oneWaySend方法指定超时范畴按照配置调用类型发送请求,Bolt客户端传输BoltClientTransport doInvokeAsync回调调用判断用户层调用级别服务回调监听器是否为空,因为调用/方法级别Callback调用方式设置提供服务回调监听器,根据客户端服务发布配置、服务引用配置、服务回调监听器SofaResponseCallback、SofaRequst请求、上下文传递RpcInternalContext以及当前类加载器构建Callback模式调用包装BoltFutureInvokeCallback/BoltInvokerCallback。Bolt客户端传输BoltClientTransport通过RpcClient调用RPC远程连接RpcRemoting的invokeSync/invokeWithCallback/oneway方法根据调用请求URL获取检查远程连接,使用管道Channel的writeAndFlush(Object msg)方法异步发送客户端数据给服务端,并且添加监听器提供操作完成发送失败异常场景监听。
SOFARPC泛化调用通过setGeneric设置服务引用配置是否泛化调用为true,服务引用配置ConsumerConfig引用服务获取泛化调用接口GenericService代理对象,通过泛化服务GenericService代理发起服务泛化调用,客户端泛化调用处理过滤器ConsumerGenericFilter判断是否自动加载添加到执行链过滤器,代理调用器FilterInvoker服务调用加载客户端泛化调用处理过滤器获取序列化工厂类型添加到请求额外属性,Bolt长连接BoltClientTransport设置调用上下文InvokeContext是否泛化调用,SofaRpcSerialization序列化/反序列化通过序列化/反序列化器SofaHessianSerializer采用GenericMultipleClassLoaderSofaSerializerFactory/GenericSingleClassLoaderSofaSerializerFactory获取泛化序列化/反序列化器编码/解码请求/响应内容,通过GenericObject持有Map类型fields变量描述参数,使用getField方法获取结果类的属性值,使用getType方法获取结果类的全类名。

你可能感兴趣的:(SOFARPC源码解析-服务调用)