CSE RPC流程分析

1 使用方法

1.1 Provider

使用示例如下:

@RpcSchema(schemaId = "hello")
//@RpcSchema
public class HelloImpl implements Hello {
   
   

  @Override
  public String sayHi(String name) {
   
   
    return "Hello " + name;
  }

  @Override
  public String sayHello(Person person) {
   
   
    return "Hello person " + person.getName();
  }
}

1.2 Consumer

使用示例如下:

@Component
public class CustomHandlerCustomerMain {
   
   
    // 表示使用的provider的信息
    @RpcReference(microserviceName = "customerhandler", schemaId = "hello")
    private static Hello hello;

    public static void main(String[] args) throws InterruptedException {
   
   
        BeanUtils.init();

        System.out.println(hello.sayHi("Java Chassis"));
        Person person = new Person();
        person.setName("ServiceComb/Java Chassis");
        System.out.println(hello.sayHello(person));
        sleep(1000);
        
    }
}

2 信息初始化

cse和spring的启动过程此处省略。

2.1 Consumer初始化过程

RpcReferenceProcessor类扫描RpcReference注解:

@Component
public class RpcReferenceProcessor implements BeanPostProcessor, EmbeddedValueResolverAware {
   
   
  private StringValueResolver resolver;

  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   
   
    // 1 扫描所有field,处理扩展的field标注,递归扫描所有声明变量
    ReflectionUtils.doWithFields(bean.getClass(), new ReflectionUtils.FieldCallback() {
   
   
      public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
   
   
        processConsumerField(bean, field);
      }
    });

    return bean;
  }

  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
   
   
    return bean;
  }

  protected void processConsumerField(Object bean, Field field) {
   
   
    RpcReference reference = field.getAnnotation(RpcReference.class);
    if (reference == null) {
   
   
      return;
    }
	// 2 添加了RpcReference注解的变量都会进入该方法
    handleReferenceField(bean, field, reference);
  }

  @Override
  public void setEmbeddedValueResolver(StringValueResolver resolver) {
   
   
    this.resolver = resolver;
  }

  private void handleReferenceField(Object obj, Field field,
      RpcReference reference) {
   
   
    String microserviceName = reference.microserviceName();
    // 3 解析microserviceName,可以使用通配符
    microserviceName = resolver.resolveStringValue(microserviceName);

    PojoReferenceMeta pojoReference = new PojoReferenceMeta();
    pojoReference.setMicroserviceName(microserviceName);
    pojoReference.setSchemaId(reference.schemaId());
    // 4 所有interface接口信息,创建代理使用
    pojoReference.setConsumerIntf(field.getType());
    // 5 创建动态代理对象
    pojoReference.afterPropertiesSet();

    ReflectionUtils.makeAccessible(field);
    // 6 设置对象为动态代理对象
    ReflectionUtils.setField(field, obj, pojoReference.getProxy());
  }
}

其中,第5步,pojoReference.afterPropertiesSet(),创建动态代理,PojoReferenceMeta类的实现如下:

public class PojoReferenceMeta implements FactoryBean<Object>, InitializingBean {
   
   
  // 原始数据
  private String microserviceName;

  private String schemaId;
  // consumerIntf意思是consumer interface
  private Class<?> consumerIntf;

  // 根据intf创建出来的动态代理
  // TODO:未实现本地优先(本地场景下,应该跳过handler机制)
  private Object proxy;
  ......

  @Override
  public void afterPropertiesSet() {
   
   
    if (consumerIntf == null) {
   
   
      throw new ServiceCombException(
          String.format(
              "microserviceName=%s, schemaid=%s, \n"
                  + "do not support implicit interface anymore, \n"
                  + "because that caused problems:\n"
                  + "  1.the startup process relies on other microservices\n"
                  + "  2.cyclic dependent microservices can not be deployed\n"
                  + "suggest to use @RpcReference or "
                  + "<cse:rpc-reference id=\"...\" microservice-name=\"...\" schema-id=\"...\" interface=\"...\"></cse:rpc-reference>.",
              microserviceName,
              schemaId));
    }

    proxy = Invoker.createProxy(microserviceName, schemaId, consumerIntf);
  }
}

其中,创建proxy过程在Invoker类中实现,Invoker类如下:

public class Invoker implements InvocationHandler {
   
   
  protected final PojoConsumerMetaRefresher metaRefresher;

  protected final PojoInvocationCreator invocationCreator;

  protected final DefaultMethodMeta defaultMethodMeta = new DefaultMethodMeta();

  protected InvocationCaller invocationCaller;
  
  // 创建动态代理的实现
  @SuppressWarnings("unchecked")
  public static <T> T createProxy(String microserviceName, String schemaId, Class<?> consumerIntf) {
   
   
    Invoker invoker = new Invoker(microserviceName, schemaId, consumerIntf);
    // 创建代理,调用方法时,会调用其中的public Object invoke(Object proxy, Method method, Object[] args)方法
    // Proxy的实现为java.lang.reflect.Proxy
    return (T) Proxy.newProxyInstance(consumerIntf.getClassLoader(), new Class<?>[] {
   
   consumerIntf}, invoker);
  }

  public Invoker(String microserviceName, String schemaId, Class<?> consumerIntf) {
   
   
    this.metaRefresher = createInvokerMeta(microserviceName, schemaId, consumerIntf);
    this.invocationCreator = createInvocationCreator();
  }

  protected PojoConsumerMetaRefresher createInvokerMeta(String microserviceName, String schemaId,
      Class<?> consumerIntf) {
   
   
    return new PojoConsumerMetaRefresher(microserviceName, schemaId, consumerIntf);
  }

  public PojoInvocationCreator createInvocationCreator() {
   
   
    return new PojoInvocationCreator();
  }

  protected InvocationCaller createInvocationCaller() {
   
   
    if (SCBEngine.getInstance().isFilterChainEnabled()) {
   
   
      return new FilterInvocationCaller();
    }

    return new HandlerInvocationCaller();
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   
   
    if (method.isDefault()) {
   
   
      return defaultMethodMeta.getOrCreateMethodHandle(proxy, method)
          .invokeWithArguments(args);
    }
    SCBEngine.getInstance().ensureStatusUp();
    prepareInvocationCaller();
    return invocationCaller.call(method, metaRefresher, invocationCreator, args);
  }

  protected void prepareInvocationCaller() {
   
   
    if (invocationCaller != null) {
   
   
      return;
    }

    this.invocationCaller = createInvocationCaller();
  }
}

后面,还会进行更加深入的介绍,初始化过程到此结束。

2.2 Provider初始化过程

在CSE初始化过程中,会调用如下过程:

public class SCBEngine {
   
   
    // 类的构造方法
    protected SCBEngine() {
   
   
        ......
        producerProviderManager = new ProducerProviderManager(this);
        serviceRegistryListener = new ServiceRegistryListener(this);
    }
    // 初始化过程中调用方法
    private void doRun() throws Exception {
   
   
      createProducerMicroserviceMeta();

      triggerEvent(EventType.BEFORE_PRODUCER_PROVIDER);
      producerProviderManager.init();
      triggerEvent(EventType.AFTER_PRODUCER_PROVIDER);

      ......
      RegistrationManager.INSTANCE.run();
    }
}

ProducerProviderManager类的部分实现过程如下:

public class ProducerProviderManager {
   
   
    private List<ProducerProvider> producerProviderList = new ArrayList<>(
          SPIServiceUtils.getOrLoadSortedService(ProducerProvider.class));
    
    public void init() {
   
   
      registerProducerMetas(producerMetas);

      for (ProducerProvider provider : producerProviderList) {
   
   
        List<ProducerMeta> producerMetas = provider.init();
        if (producerMetas == null) {
   
   
          LOGGER.warn("ProducerProvider {} not provide any producer.", provider.getClass().getName());
          continue;
        }

        registerProducerMetas(producerMetas);
      }
    }
}

producerProviderList通过SPI方式初始化,SPI的配置信息如下:

org.apache.servicecomb.provider.pojo.PojoProducerProvider

在ProducerProviderManager的init方法中,对producerProviderList进行逐一init初始化和处理。

RpcSchema注解使用PojoProducerProvider进行扫描,PojoProducerProvider的init方法如下:

@Override
public List<ProducerMeta> init() {
   
   
  // for some test cases, there is no spring context
  if (BeanUtils.getContext() == null) {
   
   
    return Collections.emptyList();
  }

  PojoProducers pojoProducers = BeanUtils.getContext().getBean(PojoProducers.class);
  for (ProducerMeta producerMeta : pojoProducers.getProducerMetas()) {
   
   
    PojoProducerMeta pojoProducerMeta = (PojoProducerMeta) producerMeta;
    // cse 提供了多种provider,pojoprovider实现方式不需要单独初始化
    initPojoProducerMeta(pojoProducerMeta);
  }

  return pojoProducers.getProducerMetas();
}

PojoProducers扫描RpcSchema注解,并将接口契约信息保存入类的producerMetas变量中,PojoProducers的实现过程如下:

public class PojoProducers implements BeanPostProcessor {
   
   
  private List<ProducerMeta> producerMetas = new ArrayList<>();

  public synchronized void registerPojoProducer(PojoProducerMeta pojoProducer) {
   
   
    producerMetas.add(pojoProducer);
  }
  ......

  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
   
   
    processProvider(beanName, bean);

    return bean;
  }

  protected void processProvider(String beanName, Object bean) {
   
   
    // aop后,新的实例的父类可能是原class,也可能只是个proxy,父类不是原class
    // 所以,需要先取出原class,再取标注
    Class<?> beanCls = BeanUtils.getImplClassFromBean(bean);
    if (beanCls == null) {
   
   
      return;
    }
    RpcSchema rpcSchema = beanCls.getAnnotation(RpcSchema.class);
    if (rpcSchema == null) {
   
   
      return;
    }
	// 如果未设置schemaId,则会使用路径名称作为schemaId
    String schemaId = rpcSchema.schemaId();
    if (StringUtils.isEmpty(schemaId)) {
   
   
      Class<?>[] intfs = beanCls.getInterfaces();
      if (intfs.length == 1) {
   
   
        schemaId = intfs[0].getName();
      } else {
   
   
        throw new Error("Must be schemaId or implements only one interface"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值