preface

  • Contact dubbo distributed framework development also has a period of time, which in order to solve some problems encountered in the project, but also deliberately learn dubbo service exposure and service introduction of some source knowledge points. Recently, dubbo’s implicit parameter technology was used in the process of project development, but several pits were found to be very prone to errors in use and a mistake would be a production accident. Now I would like to record them.

Dubbo implicit parameters before understanding the context of Dubbo

  • What is context information for Dubbo? Here is a summary of my understanding:

    The context holds the environment information required during the current invocation. All configuration information is converted to parameters of the URL. The RpcContext class is the context for Dubbo, but it is only a temporary state logger at the ThreadLocal level. The state of the RpcContext changes when an RPC request is received or initiated. For example, A calls B, and B calls C. The RpcContext of machine B records the information about A calling B before B calls C, and the information about B calling C after B calls C.

  • For example, if we want to get the host information of the service caller, we can get the host information of the current consumer of the service from the service provider, and the code is as follows:

    // Get the caller's host information
    String serverIP = RpcContext.getContext().getRemoteHost();
    Copy the code

Implicit attachment for Dubbo context

  • I don’t know if you have encountered a parameter that needs to be passed to the downstream service during development (such as JWT to identify the current user request, global traceId to record the whole link trace of the distributed system). When this is required, it is not possible to modify the parameter signature of the method, which is coupled to the business. At this point, Dubbo’s implicit parameter attachment might be needed. What is attachment? You can think of it as an extension point in the Dubbo protocol. A bit like Http, we can customize the request headers. In Dubbo, we can also customize the parameters in RPC requests.

  • For example: the user in the execution of the order business, will eventually go through the background order services, inventory services and other services. Now there is a requirement: in the order service, it is clear which user created the order. In the case of inventory services, it is important to know exactly which of the user’s actions resulted in the reduction of the item. The core of the whole requirement is to know who the operator is! Assuming that the project uses JWT technology to record the status of the user, the order service and inventory service must know the JWT string, which can be decoded to know which user initiated the current request. In such a scenario, using dubbo’s implicit parameters would do the trick. The pseudo-code implemented is as follows:

    RpcContext.getContext().setAttachment("jwt"."XXXXXXXXXXJWT string XXXXXXXX");
    // Dubbo RPC calls the inventory service to reduce the inventory
    warehouseService.decrement();
    // Dubbo RPC calls the order service: creates the order
    orderService.create();
    Copy the code

    Here is a summary of several characteristics of attachment in use:

    1. Key names cannot be named with small humps, as downstream services will serialize the key to all lowercase (Dubbo 2.6.x, fixed in 2.7.x).

    2. After implicit parameters are set, they take effect only in the first RPC request and cannot be obtained in subsequent RPC requests

    Because attachment has the above two characteristics, so we are prone to the following two errors:

    Fallibility 1 Make mistakes easily 2
    We are inwarehouseService.decrement()The downstream service can smoothly obtain JWT parameters from the Attachment, while inorderService.create()JWT parameters can not be successfully obtained from attachment in the downstream service of In this case, the key added to the Attachment is JWT, which is OK. But if we set key to the big hump name, for example:userJwt. After a series of Dubbo treatments, inwarehouseService.decrement()The Key in the Attachment in the rpcContext object in the downstream service has becomeuserjwt, the parameter whose key is JWT cannot be obtained.

Third, screen out the best solution

  • For error 1, we have three implementation schemes, whose corresponding scheme strategies are as follows:

    plan advantages disadvantages
    Scenario 1: Execute the RPC manually before each RPC initiationRpccontext.getcontext ().setAttachment(" JWT ", "XXXXXXXXXXJWT string XXXXXXXX ");code It solves the problem, but it’s not optimal Increased coding complexity and code duplication.
    Option 2: Use spring AOP’s before mechanism to put JWT into the Attachment before executing RPC to initiate remote services Can solve problems Dubbo’s remote call objects are already heavy, and adding a layer of proxies now is not conducive to locating the problem.
    Scheme 3: Dubbo’s filter mechanism is used to add a layer of filter to the specified remote service. The logic of filter is to add JWT to the Attachment A better solution takes full advantage of the Filter extension provided by the Dubbo framework itself. This is also a more general solution, as is the way traceId works with full link tracing. (recommended) The code is not very readable, and Filter, like AOP, is decoupled, making it difficult to locate problems.
  • For error 2, the easiest way to do this without extending the source code is to change the way the key is named. There are two ways to do this:

    Method 1 Reference Dubbo source org.apache.dubbo.common.constants.Com monConstants class to add to the URL in the key way of command, with multiple words.Do distinguish
    Way 2 Use custom symbols to separate words, such as_, and #Such symbols. This approach also differentiates the key from whether it is a self-added key or a built-in key from the Dubbo framework.

Four,

  • Rule of thumb: When making code changes that involve implicit parameters, always test them. If a link is ignored, it is easy to cause production accidents
  • If you find my article useful, please like it and follow it. :laughing:
  • I’m a slow walker, but I never walk backwards