How JD’s New Asynchronous Rendering Cut Latency from 1000ms to 15ms
This article examines how JD’s activity system evolved its web architecture—introducing full‑page Redis and disk caching, asynchronous rendering, and OpenResty—resulting in a latency drop from around 1000 ms to under 15 ms and dramatically lower CPU usage.
Background
JD activity system provides online editable promotional pages, serving billions of page views. High timeliness and flexibility made it a major traffic entry. Growing traffic demands a more efficient and stable architecture, focusing on page‑view performance.
Web Architecture Evolution and Current State
Browsing Service
Cache is added to expensive operations, e.g., Redis cache for database queries. Whole‑page Redis cache stores rendered pages; subsequent requests can fetch static pages directly.
Additional CDN and Nginx proxy_cache reduce origin traffic.
Old architecture includes Browsing Service, Interface Service, and Static Service. Interface Service handles real‑time and personalized data via front‑end API calls. Direct Redis reads and external API calls can be optimized with Nginx+Lua (OpenResty).
Performance Comparison of Old and New Architecture
Old Browsing Service TP99 ~1000 ms, high CPU (≈45 %) and memory usage.
New Architecture (2016 618) TP99 8 ms for mobile, ~15 ms for PC, CPU ~1 %.
New Architecture Exploration
Asynchronous Rendering and Browsing
Render pages once, store full HTML in Redis or disk, and serve it asynchronously to browsers.
Problems and Solutions
When external data changes, a timer‑based re‑render is triggered only for pages that have been accessed, using a cache key to limit work.
New Architecture Details
Engine Service renders pages and writes them to Redis or disk.
View Service (Redis version) reads full page from Redis and returns it.
View Service (Disk version) reads static HTML from local disk.
Comparison:
Redis version – simple integration, excellent performance, but depends on Redis availability.
Disk version – independent of external services, higher TPS for small page sets, but I/O grows with data size.
Solution: use URL hash distribution, Nginx+Lua (OpenResty) for asynchronous I/O, and combine disk with Redis backup.
Conclusion
All variants share asynchronous rendering and browsing, isolating business logic in the Engine, allowing the View to remain stateless. The architecture reduces latency by over 100×, improves stability, and can support billions of PVs with a modest Docker fleet.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Efficient Ops
This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.
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.
