Backend Development 6 min read

Design of a Lightweight RPC Service for Product Benefit Aggregation with Low CPU Usage and High Maintainability

This article explains the design of a compact RPC service that aggregates product benefit information, detailing how Sirector thread scheduling reduces CPU consumption and how abstract handlers and Spring prototype beans improve code maintainability and extensibility.

JD Retail Technology
JD Retail Technology
JD Retail Technology
Design of a Lightweight RPC Service for Product Benefit Aggregation with Low CPU Usage and High Maintainability

The "Merchant Card Aggregation Service" is a small RPC application that unifies queries for product promotions, free‑shipping, pricing, regional stock, delivery eligibility, and other benefit points. The article focuses on its code design, emphasizing low CPU usage through efficient Sirector thread scheduling and high maintainability via abstract handler architecture.

The service uses the sirector‑core component to execute EventHandler.onEvent methods in parallel threads. Common upstream request logic such as UMP monitoring and feature switches are encapsulated in an abstract class AbstractBenefitHandler . Concrete benefit handlers inherit from this class and only need to implement their specific logic.

How CPU usage is reduced

The isSwitchOn method in AbstractBenefitHandler decides whether a handler should be scheduled. By checking feature switches (e.g., DUCC) and request parameters (e.g., presence of a four‑level address), unnecessary thread creation is avoided, cutting down scheduler overhead and CPU consumption. Example implementation:

@Override
public boolean isSwitchOn() {
    boolean superSwitchOn = super.isSwitchOn();
    if (!superSwitchOn) {
        return false;
    } else {
        // Only enable when a four‑level address is provided
        String area = seckillBenefitRequest.getSeckillParam().getArea();
        return !StringUtils.isBlank(area) && area.contains("_") && area.split("_").length >= 4;
    }
}

Handlers are collected, filtered by isSwitchOn , and then executed by a Sirector<MiaoShaEvent> instance:

List
handlerNames = Lists.newArrayList("areaStockHandler", "partitionProductsHandler");
List
handlerList = handlerNames.stream()
    .map(name -> applicationContext.getBean(name, AbstractBenefitHandler.class)
        .setBenefitRequestAndBizName(request, "demoAppName"))
    .filter(AbstractBenefitHandler::isSwitchOn)
    .collect(Collectors.toList());
Sirector
sirector = new Sirector<>(bigSeckillEventProcessThreadPool);
AbstractBenefitHandler[] eventHandlersArr = new AbstractBenefitHandler[handlerList.size()];
handlerList.toArray(eventHandlersArr);
sirector.begin(eventHandlersArr);
sirector.ready();
sirector.publish(new MiaoShaEvent(), 500); // parallel execution of onEvent

How maintainability is improved

Common UMP monitoring code resides in the parent class onEvent , which delegates to child‑specific onEvent0 . This reduces repetitive boilerplate across handlers. Each handler implements a short fillResponseInfo method to populate a ResponseVO with its benefit data, keeping individual handler code concise.

@Override
public void fillResponseInfo(List
bftInfoList) {
    if (MapUtils.isNotEmpty(areaStockMap)) {
        for (BftInfo result : bftInfoList) {
            String skuId = result.getBaseInfo().getSkuId();
            if (areaStockMap.containsKey(skuId)) {
                result.getCommonInfo().setAreaStock(areaStockMap.get(skuId));
            }
        }
    }
}

Batch processing is performed with a simple stream call:

handlerList.forEach(h -> h.fillResponseInfo(bftInfoList));

Handlers are defined as Spring prototype beans, retrieved via applicationContext.getBean , eliminating hard‑coded new statements. Adding a new benefit point only requires implementing a new AbstractBenefitHandler subclass and registering it as a bean.

Overall, the design achieves low CPU overhead through conditional thread scheduling and promotes maintainability by centralizing common logic, using short handler implementations, and leveraging Spring's prototype bean mechanism.

backendJavaRPCCPU optimizationmaintainabilityThread Scheduling
JD Retail Technology
Written by

JD Retail Technology

Official platform of JD Retail Technology, delivering insightful R&D news and a deep look into the lives and work of technologists.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.