This article is limited in length and is intended to contribute to Arthas. Some details are not covered in this article. Further communication is available if you are interested.

I haven’t written a technology sharing blog for a long time, because I found a good tool and couldn’t help sharing it. The protagonists here are the Artahs. The arthas usage documentation is quite detailed, and I’m going to focus on just one summary of arthas usage.

1 Background

In a large team, there are many historical or objective factors that cause the stack to be inconsistent, and we run into such a problem. The old project uses the Dubbo protocol of the Dubbo framework for service interaction, while the new project uses the HTTP protocol of the FeignClient framework of the SpringCloud architecture for service interaction. Then two problems need to be solved.

  • Problem 1 is that the Dubbo service needs to support both dubbo and HTTP
  • Problem 2 is that feignClient framework can call HTTP protocol of Dubbo service without loss (lossless means that Dubbo can realize dynamic service awareness to FeignClient caller and load balancing does not need secondary development)

2 Solution

With these goals in mind, we need to find a way to solve the problem. The first problem is easier to fix, as Dubbo itself provides HTTP leaks. The problem was solved by upgrading the old project Dubbo and configuring both protocols. But for question 2, we can list the problems we encountered. The dubbo registry uses the zk registry and the springcloud project uses the eureka registry. By the way, I also want to praise feignClient framework, feignClient access service threshold is very low, so it is compatible with many languages, environment and other differences, that is, as long as the HTTP protocol interface FeignClient can call. In fact, through the FeignClient directly call dubbo service HTTP protocol interface can work, but can not achieve load balancing, failure transfer and other capabilities. So with that said, let’s sum it up.

  • The HTTP protocol that connects directly to the Dubbo framework project through FeignClient now works properly
  • A distributed environment needs to address the drawbacks of direct connection (no load balancing, no failover, no dynamic expansion, etc.). However, an analysis of the eureka source code opens the door to the fact that eureka is actually a standalone component and provides the ability to register services manually (even without modifying the source code). The solution is to introduce the Eureka component in the Dubbo project and manually register the service with Eureak so that feignClient can call it without loss.

Enter arthas

In order to provide the dubbo framework project with the ability to register eureka, and be able to do gracefully online and offline. We relied primarily on the Container extension in Dubbo’s SPI extension capabilities. The code is as follows:

class EurekaDubboContainer implements Container {... }Copy the code

One more important thing to do with the above code is to declare the full path of the Container. Meta-inf/dubbo/org. Apache. Dubbo. Container. The container: XXX = com. XXX. XxxContainer. When we configure the code spring = com. XXX. EurekaDubboContainer. When everything was ready, we started the project and found no abnormal output and the process was perfect. But feignClient couldn’t be called at all. The most important thing was that there was no abnormal output during the startup process. After a lot of verification, I found Arthas just when I was getting desperate. Arthas was able to view object property values in memory and how to execute objects. Through the previous dubbo registration process source code analysis:

com.alibaba.dubbo.common.extension.ExtensionLoader#loadFile

} catch (Throwable t) {
	IllegalStateException e = new IllegalStateException("Failed to load extension class(interface: " + type + ", class line: " + line + ") in " + url + ", cause: " + t.getMessage(), t);
	exceptions.put(line, e);
}
Copy the code

During dubbo startup, the container configured in the meta-INF jar is scanned from the jar. The exception is stored directly in the loader class during loading. I guess the exception is not thrown because of container isolation. For now, my main goal is to analyze why the extensions I defined tend not to start. After arthas was deployed I started on the analytical path.

  • Sc -d *.EurekaDubboContainer Indicates that the class is loaded properly.
  • EurekaDubboContainer found that the loaded class code is also normal.
  • Ognl ‘# loader = @ com. Alibaba. Dubbo. Container. The Main @ loader, # loader. CachedInstances’ found the problem here, The normal loaded Container will be stored in the cachedInstances domain of the ExtensionLoader (the default Spring, log4j exists), but my custom container is not found
  • Ognl ‘# loader = @ com. Alibaba. Dubbo. Container. The Main @ loader, # loader. Exceptions’ here found all of the reasons for the success of no load, a statement in the exceptions.

From the above analysis, it becomes apparent that the key specified in meta-INF is duplicated. I still don’t fully understand that ‘XXX’ on the SPI document in Dubbo means custom. Everything goes according to plan after you change the key here.

End of 4

Through a wave of operations, we found that there is no solution that can not be solved from the technical point of view, but we just need to think more and think more about ways to find a solution. This includes how to view non-static fields in load instances using ogNL on Arthas. It is not possible to get an instance directly because it does not exist in the arthas context, so the alternative is to get the instance through Main’s static field and get the value of the non-static field through the instance variable. Technology has not stopped, may you and I progress together. Contribute meager strength to open source. If interested in the details of the friend, can leave a message exchange.