Gatling‑Dubbo 2.0: High‑Performance Dubbo Load‑Testing Plugin
Gatling‑Dubbo 2.0 is a Gatling‑based load‑testing plugin that replaces generic Dubbo invocations with real API calls, offering richer scenario orchestration, traffic models, native throttling, lower resource use, and higher concurrency, while providing Action, Check, and DSL components illustrated through a complete mixed‑scenario simulation.
This article introduces gatling‑dubbo2.0 , a Gatling‑based load‑testing plugin for Dubbo that works with normal API calls instead of generic invocation. It explains why generic invocation is less representative for production performance and presents the new plugin as a more accurate solution.
The plugin offers several advantages over JMeter:
Stronger scenario orchestration, supporting multiple concurrent business flows such as normal orders, group‑buy, and flash‑sale.
Ability to set traffic models inside a scenario (e.g., funnel model from browsing → add‑to‑cart → order → payment).
No extra plugins required; native support for pressure models like target RPS or gradual ramp‑up.
Lower resource consumption and higher concurrency capability.
1. Plugin Main Components
Action and ActionBuild
These parts issue Dubbo requests, validate results, and log information for report generation. ActionBuild is a DSL‑helper for Action .
Check and CheckBuild
Validation uses json path similar to HTTP checks. A custom DubboCheck is also provided for non‑JSON responses.
DSL
The plugin supplies a domain‑specific language that simplifies writing Dubbo load‑testing scripts.
1.1 Action
class DubboAction[A](requestName: Expression[String], f: Session => A, executor: ExecutorService, objectMapper: ObjectMapper, checks: List[DubboCheck], coreComponents: CoreComponents, throttled: Boolean, next: Action) extends ExitableAction with NameGen { ... }
The execute method runs the request asynchronously, records start/end times, logs success or failure, and applies throttling if enabled.
override def execute(session: Session): Unit = recover(session) {... (full method body omitted for brevity) ...
1.2 Check
Checks are implemented using json path . The plugin defines DubboCheck as a type alias of Check[String] and provides a custom check class for string‑based validation:
case class DubboCustomCheck(func: String => Boolean, failureMessage: String = "Dubbo check failed") extends DubboCheck {Its check method returns NoopCheckResultSuccess on success or a Failure with the provided message.
1.3 DSL
The top‑level DSL is defined in DubboDsl and includes:
def dubbo[A](requestName: Expression[String], f: Session => A) = DubboProcessBuilder[A](requestName, f)An implicit conversion turns a DubboProcessBuilder into an ActionBuilder so it can be used directly in Gatling scenarios.
2. Example Script
A complete Gatling simulation demonstrates how to configure Dubbo services, feed dynamic parameters from a JSON file, and define mixed scenarios with randomSwitch and throttling:
class Mix extends Simulation { val application = new ApplicationConfig() application.setName("gatling-dubbo") // Initialize AService val referenceAService = new ReferenceConfig[AService] referenceAService.setApplication(application) referenceAService.setUrl("dubbo://IP:PORT/com.xxx.service.AService") referenceAService.setInterface(classOf[AService]) val aService = referenceAService.get() // Initialize BService (similar) val jsonFileFeeder = jsonFile("data.json").shuffle.circular val mixScenario = scenario("scenario of mix") .forever("tripsCount") { feed(jsonFileFeeder) .randomSwitch(11d -> exec(dubbo("com.xxx.service.AService.aMethod", fAMethod).check(jsonPath("$.success").is("true")))) .randomSwitch(4d -> exec(dubbo("com.yyy.service.BService.bMethod", fBMethod).check(jsonPath("$.success").is("true")))) } setUp(mixScenario.inject(constantUsersPerSec(100) during (10 seconds)) .throttle(reachRps(1000) in (1 seconds), holdFor(120 seconds)))The helper functions fAMethod and fBMethod build request objects from session attributes and invoke the corresponding Dubbo methods.
def fAMethod(session: Session): Object = { val aParam = new AParam() aParam.setName("A Name") aParam.setAId(session.attributes("aId").asInstanceOf[Integer].toLong) aService.aMethod(aParam) } def fBMethod(session: Session): Object = { val bParam = new BParam() bParam.setAge(26) bParam.setBId(session.attributes("bId").asInstanceOf[Integer].toLong) bService.bMethod(bParam) }2.2 Test Data
Dynamic parameters are stored in a JSON array, each object containing all values needed for a single request. Example:
[ {"aId": 160, "bId": 859296}, {"aId": 160, "bId": 1019040}, {"aId": 160, "bId": 1221792} ]2.3 Sample Report
The generated report includes baseline performance evaluation and centralized throttling verification, illustrated with charts (images omitted).
Finally, the article contains a recruitment notice and related reading links, which are not part of the technical content.
Youzan Coder
Official Youzan tech channel, delivering technical insights and occasional daily updates from the Youzan tech team.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.