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®istry=multicast×tamp=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×tamp=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×tamp=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);
}