SOFA RPC源码解析之RPC服务发布、引用、调用和响应流程

版权声明: https://blog.csdn.net/beyondself_77/article/details/81072907

1. SOFA RPC源码解析

1.1 SOFA RPC服务发布、引用、调用和响应流程

1.1.1 服务发布流程

   对于不同类型的SOFABoot服务,如Jvm服务、Rest服务、Bolt服务或Dubbo服务,服务发布的主流程如下:

   1. 定义SOFABoot服务:

  • 在SpringXML文件中使用标签sofa-service定义服务;
  • 在Java类中使用注解@SofaService定义服务;
  • 在Java类中使用ServiceParam定义服务。

    2. 解析SOFABoot服务:

  • 使用ServiceDefinitionParser解析SpringXML文件中标签sofa-service,转换为ServiceFactoryBean;
  • 使用ServiceAnnotationBeanPostProcessor处理注解@SofaService;
  • 使用ServiceClientImpl处理ServiceParam。

   3. 创建服务组件:

  • 在ServiceFactoryBean类afterPropertiesSet方法中,处理SOFABoot服务相关的配置,最终创建服务组件ServiceComponent;
  • 在ServiceAnnotationBeanPostProcessor类processSofaService方法中,处理SOFABoot服务相关的配置,最终创建服务组件ServiceComponent;
  • 在ServiceClientImpl类service方法中,处理SOFABoot服务相关的配置,最终创建服务组件ServiceComponent。

    4.注册服务组件:

    在组件管理器ComponentManagerImpl中注册服务组件ServiceComponent:

  • 调用组件ServiceComponent类的register方法,更新组件状态为registered
  • 调用组件ServiceComponent类的resolve方法,更新组件状态为resolved;
  • 调用组件ServiceComponent的activate方法,更新组件状态为activated。

   5. 激活服务组件:

   把组件状态改为activated之前,需要调用activateBinding方法激活组件。

   6. 发布SOFABoot服务-BindingAdapter:

   在activateBinding方法中,针对SOFABoot服务的服务类型,使用相应的BindingAdapter接口实现(如:JvmBindingAdapter、RestBindingAdapter、BoltBindingAdapter、DubboBindingAdapter),调用其outBinding方法对外发布服务。

    7. 发布SOFABoot服务:

    在outBinding方法中:

  • 对于JVM服务,直接返回null,JVM服务发布结束;
  • 对于Dubbo服务,直接返回Boolean.TRUE。Dubbo服务在SOFA RPC组件启动时,由SofaBootRpcStartListener监听SOFA RPC组件启动事件SofaBootRpcStartEvent,并调用ProviderConfigContainer的exportAllDubboProvideConfig方法发布所有Dubbo类型的服务;
  • 对于Rest服务、Bolt服务,调用ProviderConfig类export方法,暴露服务。

   8. 发布SOFABoot服务- ProviderBootstrap:

   在export方法中,针对SOFABoot服务的服务类型,使用相应的ProviderBootstrap接口实现(如:RestProviderBootstrap、BoltProviderBootstrap、DubboProviderBootstrap),调用其export方法,对外暴露不同类型的服务。

1.1.2 服务引用流程

   对于不同类型的SOFABoot服务,如Jvm服务、Rest服务、Bolt服务或Dubbo服务,服务引用的主流程如下:

   1. 定义SOFABoot服务引用:

  • 在SpringXML文件中使用标签sofa-reference定义服务引用;
  • 在Java类中使用注解@SofaReference定义服务引用;
  • 在Java类中使用ReferenceParam定义服务引用。

   2. 解析SOFABoot服务引用:

  • 使用ReferenceDefinitionParser解析SpringXML文件中标签sofa-reference,转换为ReferenceFactoryBean;
  • 使用ServiceAnnotationBeanPostProcessor处理注解@SofaReference;
  • 使用ReferenceClientImpl处理ReferenceParam。

   3. 创建服务引用组件:

  • 在ReferenceFactoryBean类afterPropertiesSet方法中,处理SOFABoot服务相关的配置,最终创建服务引用组件ReferenceComponent;
  • 在ServiceAnnotationBeanPostProcessor类processSofaService方法中,处理SOFABoot服务相关的配置,最终创建服务引用组件ReferenceComponent;
  • 在ReferenceClientImpl类reference方法中,处理SOFABoot服务相关的配置,最终创建服务引用组件ReferenceComponent。

   4. 注册服务组件:

   在组件管理器ComponentManagerImpl中注册服务组件ReferenceComponent:

  • 调用组件ReferenceComponent类的register方法,更新组件状态为registered
  • 调用组件ReferenceComponent类的resolve方法,更新组件状态为resolved;
  • 调用组件ReferenceComponent的activate方法,更新组件状态为activated。

   5. 创建服务代理对象:

   把组件状态改为activated之前,需要创建服务代理对象。

    6. 创建服务代理对象-BindingAdapter:

   在createProxy方法中,针对SOFABoot服务的服务类型,使用相应的BindingAdapter接口实现(如:JvmBindingAdapter、RestBindingAdapter、BoltBindingAdapter、DubboBindingAdapter),调用其inBinding方法创建服务代理对象。

    7. 创建服务代理对象-BindingAdapter:

    在inBinding方法中:

  • 对于JVM服务,直接调用createServiceProxy方法,使用Spring AOP代理工厂ProxyFactory创建JVM服务代理对象,handler为JvmServiceInvoker,JVM服务引用结束;
  • 对于Rest服务、Bolt服务、Dubbo服务,调用ConsumerConfig类refer方法,创建服务代理对象。

    8. 创建服务代理对象-ConsumerBootstrap:

   在refer方法中,针对SOFABoot服务的服务类型,使用相应的ConsumerBootstrap接口实现(如:RestConsumerBootstrap、BoltConsumerBootstrap、DubboConsumerBootstrap),调用其refer方法,为不同类型的服务创建JDK代理对象。

1.1.3 客户端调用流程

   客户端以Java类本地方法调用方式调用SOFA RPC远程服务的主要流程如下:

   1. 从Spring应用上下文获取实现某个指定接口的类的代理对象(实现方式:1、采用JDK的Proxy动态创建代理对象;2、采用Javassist动态创建代理对象。此两种方式创建的代理对象都继承了java.lang.reflect.Proxy类,实现了指定接口);

   2. 通过获取的代理对象,调用指定接口的某个方法:

  • 对于JDK Proxy创建的代理对象,在指定接口的方法实现中,会调用JDKInvocationHandler类invoke方法。在invoke方法中,会根据接口名称、方法名称、参数类型、参数值,构造SofaRequest请求,然后调用invoker接口的实现类DefaultClientProxyInvoker的invoke方法,发起客户端调用;
  • 对于Javassist创建的代理对象,在指定接口的方法实现中,会直接根据接口名称、方法名称、参数类型、参数值,构造SofaRequest请求,然后调用invoker接口的实现类DefaultClientProxyInvoker的invoke方法,发起客户端调用;

   3. 在DefaultClientProxyInvoker的invoke方法中,调用某个Cluster接口的实现类的invoke方法,如FailoverCluster的invoke方法;

    4. 在FailoverCluster的invoke方法中,调用FilterChain的invoke方法;

    5. 依次调用FilterChain执行链上所有Filter的FilterInvoker对象(除最后一个外)的invoke方法;

    6. 调用FilterChain执行链上最后一个FilterInvoker对象ConsumerInvoker的invoke方法;

    7. 在ConsumerInvoker的invoke方法中,调用FailoverCluster的sendMsg方法;

    8. 在FailoverCluster的sendMsg方法中,调用ClientTransport接口实现类的doSendMsg方法,如RestClientTransport;

    9. 在ClientTransport接口实现类的doSendMsg方法中,根据调用方式,如同步调用、单向调用、Callback调用、Future调用,分别调用ClientTransport相关的方法,如:syncSend、oneWaySend、asyncSend等;

    10. 以RestClientTransport的syncSend方法为例,在syncSend方法中调用doInvokeSync方法;

    11. 在RestClientTransport的doInvokeSync方法中,通过反射机制,调用指定接口的代理对象proxy的某个方法。例如:proxy为PersonService接口的代理对象,handler为实现了Java动态代理java.lang.reflect.InvocationHandler接口的org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy;

    12. 在ClientProxy类invoke方法中,调用org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker的invoke方法;

    13. 在ClientInvoker的invoke方法中,调用ClientInvocation的invoke方法;

    14. 在ClientInvocation的invoke方法中,调用ApacheHttpClient4Engine类invoke方法;

    15. 在ApacheHttpClient4Engine类invoke方法中,最终调用org.apache.http.impl.client.DefaultHttpClient类execute方法,完成restful风格的远程服务调用。

1.1.4 服务端响应流程

      服务端接收到客户端发起的SOFA RPC服务请求,其处理请求的方式依据不同的服务端实现技术,其处理流程各不相同。

      此处以Restful请求为例,简单介绍一下主要流程。SOFA RPC采用com.alipay.sofa.rpc.server.rest.SofaNettyJaxrsServer作为服务器,而SofaNettyJaxrsServer采用Netty4作为网络通讯层。Restful服务请求的主要处理流程如下:

  1. Netty4监听指定的接口;
  2. Netty4接收客户端restful类型服务请求,经过一系统Netty4上行处理器(如:自定义非HTTP类型ChannelInboundHandler、HttpRequestDecoder、HttpObjectAggregator、自定义HTTP类型ChannelInboundHandler、RestEasyHttpRequestDecoder)处理,把客户端请求封装成NettyHttpRequest对象;
  3. 调用Netty4最后一个上行处理器SofaRestRequestHandler的channelRead0方法,开始处理客户端业务请求;
  4. 在SofaRestRequestHandler的channelRead0方法中,调用org.jboss.resteasy.plugins.server.netty.RequestDispatcher的service方法,分发Http请求;
  5. 在RequestDispatcher的service方法中,调用com.alipay.sofa.rpc.server.rest.SofaSynchronousDispatcher的invoke(HttpRequest request)方法;
  6. 在SofaSynchronousDispatcher的invoke方法中,调用SofaSynchronousDispatcher的invoke(HttpRequest request, HttpResponse response, ResourceInvoker invoker)方法;
  7. 在SofaSynchronousDispatcher的invoke方法中,调用SofaResourceMethodInvoker的invoke方法;
  8. 在SofaResourceMethodInvoker的invoke方法中,调用com.alipay.sofa.rpc.server.rest.SofaResourceFactory的createResource方法,获取响应Http请求的目标对象,此处为PersonServiceImpl的一个实例;
  9. 调用org.jboss.resteasy.core.MethodInjectorImpl的invoke方法,通过Java反射机制,调用目标类上指定的方法,此处为PersonService的sayName方法。到此为止,请求处理完成,并返回处理结果。

猜你喜欢

转载自blog.csdn.net/beyondself_77/article/details/81072907