preface
Hello everyone, today we start sharing – Dubbo special Dubbo token validation and Elegant downtime. In the previous section we introduce the Dubbo delays and viscous connection, understand what is delay and viscous connection and daily usage scenarios and principle, at the same time, we know that delay connection is in conjunction with the instance objects to create communication connection, viscous connection is as far as possible the use of the connection has been created, they all have similar to reduce the connection to create. This chapter discusses the lighter topics of token validation and elegant downtime. What is a token? And what does it do? . So let’s get started fast!
1. Introduction to token verification and elegant downtime
To start with what a token is, let’s discuss what a token is through a small example from life. For example: our friends often go out by train, so we must first buy train tickets, and then we take the train tickets to the security gate to check the ticket, we can take the train if the check is successful, if the check fails, we can not take the train. The train ticket here is what we call a token, and only when we get a valid token can we have the authority or qualification to do the following things.
So what is an elegant shutdown? The simple understanding is to exit the application after the normal processing is complete, but if we use kill -9 PID or other forced shutdown command, the graceful shutdown will not be performed, only when the kill PID is passed, it will be executed. In my Dubbo is done gracefully by ShutdownHook in the JDK.
2. Configuration mode
Dubbo is configured using XML, annotations, and configuration files:
2.1 Configuration mode of token authentication
XML configuration:
- Global Settings
<! -- Random token, generated using UUID -->
<dubbo:provider token="true" />
Copy the code
or
<! -- Fixed token, equivalent to password -->
<dubbo:provider token="123456" />
Copy the code
- Service Level Settings
<! -- Random token, generated using UUID -->
<dubbo:service interface="com.muke.dubbocourse.common.api.BookFacade" token="true" />
Copy the code
or
<! -- Fixed token, equivalent to password -->
<dubbo:service interface="com.muke.dubbocourse.common.api.BookFacade" token="123456" />
Copy the code
Annotation: Service level Settings
@DubboService(token = "true")
//@Service(token = "true")
Copy the code
Configuration file: global configuration
dubbo.provider.token=true
Copy the code
2.2 Graceful shutdown configuration mode
In Dubbo, attribute configuration and encoding are mainly used:
Attribute configuration:
# dubbo.properties
dubbo.service.shutdown.wait=15000
Copy the code
Encoding mode:
DubboShutdownHook.destroyAll();
Copy the code
** For container deployment scenarios such as Tomcat, it is recommended to invoke the following code by extending ContextListener, etc., to achieve elegant downtime
3. Application scenarios
Let’s take a look at the use scenario for token validation and elegant downtime in Dubbo. First of all, the scenario described in Dubbo is that token authentication controls permissions in the registry to decide whether to issue tokens to consumers, which prevents consumers from bypassing the registry to access providers. In addition, the registry provides flexibility to change authorization methods without modifying or upgrading providers. Elegant downtime in Dubbo attention is also used for resource recycling processing, etc. Here we discuss common usage scenarios:
-
Usage scenario of token authentication: From the description of Dubbo token authentication scenario, we can know that the consumer access interface can be authorized to access through tokens, that is, we can dynamically adjust the registration information through self-expansion to support dynamic access control of interface permissions.
-
Graceful shutdown usage scenarios: Close the underlying network connection resources, cache operation resources, and so on when the Dubbo application exits.
4. Example demonstration
Let’s take the book list as an example to demonstrate token validation. The project structure is as follows:
Let’s look at the dubo-provider-xml.xml configuration on the service consumer side:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="demo-provider" metadata-type="remote"/>
<dubbo:registry address=Zookeeper: / / "127.0.0.1:2181"/>
<bean id="bookFacade" class="com.muke.dubbocourse.tokenverify.provider.BookFacadeImpl"/>
<! -- Expose local service as Dubbo service -->
<dubbo:service interface="com.muke.dubbocourse.async.api.BookFacade" ref="bookFacade" token="12345"/>
</beans>
Copy the code
Above we enable the service level token configuration token=”12345″ set the token fixed value. Let’s look at the service consumer configuration file dubo-consumer-xml.xml:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="demo-consumer" logger="log4j"/>
<dubbo:registry address=Zookeeper: / / "127.0.0.1:2181"/>
<! --1. Get a service reference from the registry -->
<! -- <dubbo:reference id="bookFacade" interface="com.muke.dubbocourse.common.api.BookFacade">-->
<! -- </dubbo:reference>-->
<! The url directly specifies the machine and port of the service provider.
<dubbo:reference id="bookFacade"
interface="com.muke.dubbocourse.common.api.BookFacade" url="dubbo://localhost:20890">
</dubbo:reference>
</beans>
Copy the code
In the XML above, if we use the first approach to access our bookFacade service normally, if we use the second direct approach to bypass the registry we get the following error:
Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: / 192.168.101.8:20890 under caused by: java.net.ConnectException: Connection refused at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)Copy the code
Since token authentication is enabled for our service, the token will fail to be authenticated if called directly bypassing the registry.
5. Principle analysis
Next, we will analyze the source code of the token validation in Dubbo.
Token parsing process:
When our server service exposure method is called org. Apache. Dubbo. Config. # ServiceConfig doExportUrlsFor1Protocol its core code is as follows:
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
/ /...
// Obtain the token value configured on the service provider, for example: token="123456"
if(ConfigUtils.isEmpty(token) && provider ! =null) {
token = provider.getToken();
}
if(! ConfigUtils.isEmpty(token)) {// A random token value is generated if the value is: true or default
if (ConfigUtils.isDefault(token)) {
map.put(TOKEN_KEY, UUID.randomUUID().toString());
} else {
// Set it to the configured token valuemap.put(TOKEN_KEY, token); }}//init serviceMetadata attachments
serviceMetadata.getAttachments().putAll(map);
/ /...
}
Copy the code
In the code above we can see that we get the token value from our configuration and register it with the registry, generating a random token value if the configuration value is: true or default, otherwise using the configured token value.
Token usage process:
Before the invocation request from the service consumer reaches the service provider, it will pass through some filters, including the verification filter for token. The core code is as follows:
public class TokenFilter implements Filter { @Override public Result invoke(Invoker
invoker, Invocation inv) throws RpcException { String token = invoker.geturl ().getParameter(TOKEN_KEY); // Obtain token Parameter Value String token = invoker.geturl ().getparameter (TOKEN_KEY); if (ConfigUtils.isNotEmpty(token)) { Class
serviceType = invoker.getInterface(); Map
attachments = inv.getAttachments(); String remoteToken = (attachments == null ? null : attachments.get(TOKEN_KEY)); // Verify that the token carried by the consumer is equal to the token of the service provider. token.equals(remoteToken)) { throw new RpcException("Invalid token! Forbid invoke remote service " + serviceType + " method " + inv.getMethodName() + "() from consumer " + RpcContext.getContext().getRemoteHost() + " to provider " + RpcContext.getContext().getLocalHost()); } } return invoker.invoke(inv); }}
,>
Copy the code
The token is validated through the above filter, calling the following executor if it passes, and throwing an exception if it fails.
6. Summary
In this section, we learned about token validation and graceful downtime in Dubbo, as well as common usage scenarios and ways to use them. At the same time, we also analyze Dubbo’s token verification principle through sample demonstration and source code analysis. The core idea of token verification is to put the token provided by the service provider or randomly generated token into the registry for management, and then the service consumer obtains the token and carries the token when calling the service provider, and the service provider carries the token according to the token carried by the consumer. Dubbo uses the JDK’s ShutdownHook for elegant downtime.
The highlights of this lesson are as follows:
-
Understand token validation and elegant downtime in Dubbo
-
Learn about token validation and elegant downtime usage
-
Learn about token validation and elegant downtime usage scenarios
-
Understand the principle of token validation in Dubbo
The author
Personally engaged in the financial industry, I have worked in chongqing’s first-class technical team of Yiji Pay, Sijian Technology and an online car hailing platform, and now I am working in a bank responsible for the construction of unified payment system. I have a strong interest in the financial industry. It also practices big data, data storage, automated integration and deployment, distributed microservices, responsive programming, and artificial intelligence. At the same time, he is also keen on technology sharing, creating public accounts and blog sites to share knowledge system. Concern public number: young IT male get latest technical article push!
Blog: Youngitman.tech