dubbo source code analysis 5 -- ServiceBean publishing service

Keywords: Dubbo socket snapshot Zookeeper

Publishing service ServiceBean

Release entrance

  • ServiceBean implements the afterpropertieset() method of the interface InitializingBean
public void afterPropertiesSet() throws Exception {
    //Set provider, application, registers
    //Publishing service 
    if (!isDelay()) {
       export();
    }
}
  • If the service has not been published, start publishing
public void onApplicationEvent(ApplicationEvent event) {
    if (ContextRefreshedEvent.class.getName().equals(event.getClass().getName())) {
    if (isDelay() && ! isExported() && ! isUnexported()) {
            export();
        }
    }
}

It is doExportUrls() that really starts to publish services;

Really start publishing services

  • Get the url address of the registry
  • Loop protocol, registering url with protocol
private void doExportUrls() {
   //Get the url address of the registry
   List<URL> registryURLs = loadRegistries(true);
   //<dubbo:protocol name="dubbo" port="20880" id="dubbo" />
   for (ProtocolConfig protocolConfig : protocols) {
       doExportUrlsFor1Protocol(protocolConfig, registryURLs);
   }
}

Get the url address of the registry

<dubbo:registry protocol="zookeeper" address="10.118.22.25:2181" />
/**registry://224.5.6.7:1234/com.alibaba.dubbo.registry
          .RegistryService?application=demo-provider&dubbo=2.0.0&pid=2964
          &qos.port=22222&registry=multicast&timestamp=1523178188368
          **/
protected List<URL> loadRegistries(boolean provider) {
  List<URL> registryList = new ArrayList<URL>();
  if (registries != null && !registries.isEmpty()) {
      for (RegistryConfig config : registries) {
          String address = config.getAddress();
          Map<String, String> map = new HashMap<String, String>();
          //Assembly dubbo version number, protocol is dubbo, application
           registryList.add(url);
      }
  }
}

Register url with protocol

a) Assemble dubbo version number, application, interface, methods, ip address and port number
dubbo://10.118.14.178:20890/com.test.ITestService?anyhost=true&application=testservice&default.cluster=failfast&default.timeout=60000&dubbo=2.8.4
&generic=false
&interface=com.test.ITestService&logger=slf4j&methods=test,save&pid=8832&revision=1.0-SNAPSHOT&side=provider&timestamp=1523602774419&version=1.0.0

b) Exposure services
1) If there is a registry, assemble the assembled url address into
registry://10.118.22.25:2181/com.alibaba.dubbo.registry.RegistryService?application=testservice&dubbo=2.8.4&export= dubbo://10.118.14.178:20890/com.test.ITestService?anyhost=true&application=testservice&default.cluster=failfast&default.timeout=60000&dubbo=2.8.4
&generic=false
&interface=com.test.ITestService&logger=slf4j&methods=test,save&pid=8832&revision=1.0-SNAPSHOT&side=provider&timestamp=1523602774419&version=1.0.0
Go to the RegistryProtocol protocol
2) There is no registration center, so according to the agreement dubbo, go dubbo protocol

private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, 
   List<URL> registryURLs) {
//Assemble url
    //Default is dubbo protocol
    String name = protocolConfig.getName();
    if (name == null || name.length() == 0) {
        name = "dubbo";
    }
    Map<String, String> map = new HashMap<String, String>();
    //Assemble dubbo version number, application and interface(com.alibaba.dubbo.demo.DemoService)
    //,side (provider)...
    //Get all method names in the interface
    String[] methods = Wrapper.getWrapper(interfaceClass).getMethodNames()
    //Methods in assembly interface (sayhello)
HashSet<String>(Arrays.asList(methods)), ","));
    //Assembly binding ip
    String host = this.findConfigedHosts(protocolConfig, registryURLs, map);
    //Assembly port No. 20880
    Integer port = this.findConfigedPorts(protocolConfig, name, map);

    URL url = new URL(name, host, port, (contextPath == null 
    || contextPath.length() == 0 ? "" : contextPath + "/") + path, map);
    //<dubbo:protocol name="dubbo" port="20890" id="dubbo" />
    //If the agreement is local, there is no need to register
    if ("injvm".equals(protocolConfig.getName())) {
       protocolConfig.setRegister(false);
        map.put("notify", "false");
    }
//Exposure service
    String scope = url.getParameter(Constants.SCOPE_KEY);
    //Configured as none not exposed
    if (! Constants.SCOPE_NONE.toString().equalsIgnoreCase(scope)) {
        //Local exposure when the configuration is not remote (if the configuration is remote, only remote services will be exposed)
        if (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {
            exportLocal(url);
        }
        //If the configuration is not local, the remote service will be exposed
        if (! Constants.SCOPE_LOCAL.toString().equalsIgnoreCase(scope) ){
            //Go to the Registry protocol
            if (registryURLs != null && registryURLs.size() > 0
                        && url.getParameter("register", true)) {   
               for (URL registryURL : registryURLs) {
                   Exporter<?> exporter = protocol.export(invoker);
                   exporters.add(exporter);
               }  
            }else {
                //Take dubbo agreement
                Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) 
                interfaceClass, url);
                Exporter<?> exporter = protocol.export(invoker);
                exporters.add(exporter);
            }
        }
    }
}

Expose local service, do not operate

private void exportLocal(URL url) {
   if (!Constants.LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
   /**Assemble the local url 
   injvm://127.0.0.1/com.test.ITestService?anyhost=true&application=testService&
   default.cluster=failfast&default.timeout=60000&dubbo=2.8.4&generic=false
   &interface=com.test.ITestService&logger=slf4j&methods=
  test,save&version=1.0.0
   **/
       URL local = URL.valueOf(url.toFullString())
               .setProtocol("injvm")
               .setHost("127.0.0.1")
               .setPort(0);
      //Put the implementation class of the interface into ThreadLocalcom.test.ITestService
       ServiceClassHolder.getInstance().pushServiceClass(getServiceClass(ref));

       Exporter<?> exporter = protocol.export(
               proxyFactory.getInvoker(ref, (Class) interfaceClass, local));
       exporters.add(exporter);
   }
}

Get host ip binding

1) Take Dubbo: host in the protocol
2) Take the local address InetAddress.getLocalHost().getHostAddress();
3) The address of the circular registration center. The successful connection is the ip address

private String findConfigedHosts(ProtocolConfig protocolConfig, 
   List<URL> registryURLs, Map<String, String> map) {
//1. <dubbo:protocol host="">
String host = protocolConfig.getHost();
 if (provider != null && (host == null || host.length() == 0)) {
     host = provider.getHost();
 }
 boolean anyhost = false;
 if (NetUtils.isInvalidLocalHost(host)) {
     anyhost = true;
     try {
        // 2. Get local
         host = InetAddress.getLocalHost().getHostAddress();
     } catch (UnknownHostException e) {
         logger.warn(e.getMessage(), e);
     }
     if (NetUtils.isInvalidLocalHost(host)) {
         //3. Address of circular registration center, whether it can be connected
      if (registryURLs != null && registryURLs.size() > 0) {
         for (URL registryURL : registryURLs) {
            try {
               Socket socket = new Socket();
               try {
                   SocketAddress addr = new InetSocketAddress(registryURL.getHost(),
                    registryURL.getPort());
                   socket.connect(addr, 1000);
                   host = socket.getLocalAddress().getHostAddress();
                   break;
               } finally {
                   try {
                       socket.close();
                   } catch (Throwable e) {}
               }
            } catch (Exception e) {
                logger.warn(e.getMessage(), e);
            }
          }
      }
      if (NetUtils.isInvalidLocalHost(host)) {
          host = NetUtils.getLocalHost();
      }
   }
 }
   map.put("bind_ip", hostToBind);
}

Posted by danf_1979 on Mon, 30 Mar 2020 12:53:21 -0700