扫码关注公众号:芋道源码

发送: 百事可乐
获取永久解锁本站全部文章的链接

《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 https://www.jianshu.com/p/47816d0f1317 「鋒Nic」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

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

img

服务调用基础通信模型.png

(1)Sync同步调用

同步调用方式,客户端发起调用后等待服务端返回结果再进行后续的操作,是SOFARPC的默认调用方式,无需进行任何设置即可。当前线程发起调用后阻塞请求线程,需要在指定的超时时间内等到响应结果才能完成本次调用。如果超时时间内没有得到响应结果,那么抛出超时异常。Sync同步调用模式最常用,注意要根据对端的处理能力合理设置超时时间。

(2)Future异步调用

客户端发起调用后不会等待服务端的结果,继续执行后面的业务逻辑。服务端返回响应结果被SOFARPC缓存,当客户端需要响应结果的时候需要主动获取结果,调用过程不会阻塞线程,获取结果的过程阻塞线程,目前支持bolt协议:

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

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

<sofa:reference id="sampleFacadeReferenceBolt" interface="com.alipay.sofa.rpc.bean.SampleFacade" >
<sofa:binding.bolt>
<sofa:global-attrs type="future"/>
</sofa:binding.bolt>
</sofa:reference>
<sofa:reference id="helloFutureServiceReference" interface="com.alipay.sofa.rpc.samples.invoke.HelloFutureService">
<sofa:binding.bolt>
<sofa:global-attrs type="future"/>
</sofa:binding.bolt>
</sofa:reference>

如上设置为异步调用的方式。客户端获取响应结果有两种方式: (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<HelloService> consumer = new ConsumerConfig<HelloService>()
.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自动执行该回调类:

<bean id="callback" class="xxx.xxx.sofaResponseCallbackImpl"/>
<sofa:reference id="sampleFacadeReferenceBolt" interface="com.alipay.sofa.rpc.bean.SampleFacade">
<sofa:binding.bolt>
<sofa:global-attrs type="callback" callback-ref="callback"/>
</sofa:binding.bolt>
</sofa:reference>
<bean id="callbackImpl" class="com.alipay.sofa.rpc.samples.invoke.CallbackImpl"/>
<sofa:reference id="helloCallbackServiceReference" interface="com.alipay.sofa.rpc.samples.invoke.HelloCallbackService">
<sofa:binding.bolt>
<sofa:global-attrs type="callback" callback-ref="callbackImpl"/>
</sofa:binding.bolt>
</sofa:reference>

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

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

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

<bean id="callback" class="xxx"/>
<sofa:reference id="sampleFacadeReferenceBolt" interface="com.alipay.sofa.rpc.bean.SampleFacade" local-first="false">
<sofa:binding.bolt>
<sofa:global-attrs type="oneway"/>
</sofa:binding.bolt>
</sofa:reference>
<sofa:reference id="helloOneWayServiceReference" interface="com.alipay.sofa.rpc.samples.invoke.HelloOneWayService">
<sofa:binding.bolt>
<sofa:global-attrs type="oneway"/>
</sofa:binding.bolt>
</sofa:reference>

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

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

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

ConsumerConfig<GenericService> consumerConfig = new ConsumerConfig<GenericService>()
.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属性声明完成接口的描述。

<sofa:reference id="sampleGenericServiceReference" interface="com.alipay.sofa.rpc.api.GenericService">
<sofa:binding.bolt>
<sofa:global-attrs generic-interface="com.alipay.sofa.rpc.samples.generic.SampleGenericService"/>
</sofa:binding.bolt>
</sofa:reference>

(2)参数描述:由于客户端没有调用服务的参数类,因此通过GenericObject进行描述,GenericObject持有Map<String, Object>类型的变量,能够通过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):

<!-- invoke sync-->
<bean id="helloSyncServiceImpl" class="com.alipay.sofa.rpc.samples.invoke.HelloSyncServiceImpl"/>
<sofa:service ref="helloSyncServiceImpl" interface="com.alipay.sofa.rpc.samples.invoke.HelloSyncService">
<sofa:binding.bolt/>
</sofa:service>
<!-- invoke future -->
<bean id="helloFutureServiceImpl" class="com.alipay.sofa.rpc.samples.invoke.HelloFutureServiceImpl"/>
<sofa:service ref="helloFutureServiceImpl" interface="com.alipay.sofa.rpc.samples.invoke.HelloFutureService">
<sofa:binding.bolt/>
</sofa:service>
<!-- invoke callback -->
<bean id="helloCallbackServiceImpl" class="com.alipay.sofa.rpc.samples.invoke.HelloCallbackServiceImpl"/>
<sofa:service ref="helloCallbackServiceImpl" interface="com.alipay.sofa.rpc.samples.invoke.HelloCallbackService">
<sofa:binding.bolt/>
</sofa:service>
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=<NA>
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<java.util.Map<java.lang.String, java.lang.Object>> 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=<NA>
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<java.util.Map<java.lang.String, java.lang.Object>> 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键值对<invokeId,future>,使用管道Channel的writeAndFlush(Object msg)方法异步发送客户端数据给服务端,并且添加监听器提供操作完成发送失败Future添加失败响应场景监听,InvokeFuture根据超时时间等待获取响应命令并且唤醒等待响应结果线程,响应命令解析反序列化返回响应对象结果:

/**
* Synchronous rpc invocation.<br>
* 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方法调用链:

img

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<HelloService> providerConfig = new ProviderConfig<HelloService>()
.setApplication(applicationConfig)
.setInterfaceId(HelloService.class.getName())
.setRef(new HelloServiceImpl(1000))
.setServer(serverConfig2);
providerConfig.export();

ProviderConfig<EchoService> providerConfig2 = new ProviderConfig<EchoService>()
.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;

/**
* <p>接口级别的Callback</p>
*/
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<HelloService> consumerConfig = new ConsumerConfig<HelloService>()
.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<EchoService> consumerConfig2 = new ConsumerConfig<EchoService>()
.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键值对<invokeId,future>,InvokeFuture新增计时器超时线程提供超时响应结果非正常执行异步调用回调任务,使用管道Channel的writeAndFlush(Object msg)方法异步发送客户端数据给服务端,并且添加监听器提供操作完成发送失败Future添加失败响应场景监听:

/**
* Rpc invocation with callback.<br>
* 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;
}
}

img

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<HelloService> CProvider = new ProviderConfig<HelloService>()
.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;

/**
* <p>接口级别的Callback</p>
*/
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<HelloService> consumerConfig = new ConsumerConfig<HelloService>()
.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;

/**
* <p>调用级别的Callback</p>
*/
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<HelloService> consumerConfig = new ConsumerConfig<HelloService>()
.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;

/**
* <p>方法级别的Callback</p>
*/
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<HelloService> consumerConfig = new ConsumerConfig<HelloService>()
.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键值对<invokeId,future>,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<T> {
/**
* 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);
}

img

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<HelloService> providerConfig = new ProviderConfig<HelloService>()
.setApplication(applicationConfig)
.setInterfaceId(HelloService.class.getName())
.setRef(new HelloServiceImpl(1000))
.setServer(serverConfig2);
providerConfig.export();

ProviderConfig<EchoService> providerConfig2 = new ProviderConfig<EchoService>()
.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<HelloService> consumerConfig = new ConsumerConfig<HelloService>()
.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<EchoService> consumerConfig2 = new ConsumerConfig<EchoService>()
.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.<br>
* 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<TestGenericService> providerConfig = new ProviderConfig<TestGenericService>()
.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<GenericService> consumerConfig = new ConsumerConfig<GenericService>()
.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):

<!-- generic -->
<bean id="sampleGenericServiceImpl" class="com.alipay.sofa.rpc.samples.generic.SampleGenericServiceImpl"/>
<sofa:service ref="sampleGenericServiceImpl" interface="com.alipay.sofa.rpc.samples.generic.SampleGenericService">
<sofa:binding.bolt/>
</sofa:service>
<!-- generic -->
<sofa:reference jvm-first="false" id="sampleGenericServiceReference" interface="com.alipay.sofa.rpc.api.GenericService">
<sofa:binding.bolt>
<sofa:global-attrs generic-interface="com.alipay.sofa.rpc.samples.generic.SampleGenericService"/>
</sofa:binding.bolt>
</sofa:reference>
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=<NA>
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<java.util.Map<java.lang.String, java.lang.Object>> 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=<NA>
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<java.util.Map<java.lang.String, java.lang.Object>> 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<T> setGeneric(boolean generic) {
this.generic = generic;
return this;
}

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

/**
* 泛化调用的接口<br>
*
*/
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> T $genericInvoke(String methodName, String[] argTypes, Object[] args, Class<T> 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> T $genericInvoke(String methodName, String[] argTypes, Object[] args, Class<T> clazz, GenericContext context);
}

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

/**
* 构造执行链
*
* @param filters 包装过滤器列表
* @param lastInvoker 最终过滤器
* @param config 接口配置
*/
protected FilterChain(List<Filter> filters, FilterInvoker lastInvoker, AbstractInterfaceConfig config) {
// 调用过程外面包装多层自定义filter
// 前面的过滤器在最外层
invokerChain = lastInvoker;
if (CommonUtils.isNotEmpty(filters)) {
loadedFilters = new ArrayList<Filter>();
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 <Request extends RequestCommand> 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<String, String> header = (Map<String, String>) requestCommand.getRequestHeader();
if (header == null) {
header = new HashMap<String, String>();
}
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 <Request extends RequestCommand> 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<String, String> headerMap = (Map<String, String>) 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<String, String> 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<String, String> 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<String, String>) 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<String, Object>类型fields变量描述参数,使用getField方法获取结果类的属性值,使用getType方法获取结果类的全类名。

文章目录