Backend Development 43 min read

Rearchitecting Bilibili Live Broadcast Platform: From Legacy PHP to Go with Domain‑Driven Design and Hexagonal Architecture

The article details Bilibili’s migration of its legacy PHP live‑broadcast service to Go microservices using Domain‑Driven Design and Hexagonal architecture, describing event‑storming, six‑layer tactical design, TDD, traffic‑mirroring migration, and resulting higher reliability, lower latency, and improved maintainability.

Bilibili Tech
Bilibili Tech
Bilibili Tech
Rearchitecting Bilibili Live Broadcast Platform: From Legacy PHP to Go with Domain‑Driven Design and Hexagonal Architecture

This article presents a comprehensive case study of the redesign and migration of Bilibili's live‑broadcast ("开播") platform. It begins with a background overview of the live‑streaming business, distinguishing the "watch" (C‑end) and "broadcast" (B‑end) scenarios, and explains why the broadcast subsystem is a critical backbone similar to an order system in e‑commerce.

The existing PHP‑based broadcast service suffered from heavy technical debt: tangled business logic, poor readability, outdated transaction‑script design, lack of automated tests, and an overall technology stack that no longer matched the company's direction. These issues caused high maintenance costs, frequent incidents, and difficulty in knowledge sharing.

To address these problems, the team adopted Domain‑Driven Design (DDD) as the guiding methodology. Key domain concepts such as "Domain Event", "Domain Knowledge", "Strategic Design", and "Tactical Design" are introduced, and a detailed glossary of terminology is provided. An event‑storming workshop was used to model the core broadcast use‑case, identify actors, commands, and events, and define bounded contexts (Core, General, Supporting sub‑domains).

The architectural evolution moves from a monolithic PHP service to a set of Go microservices built on Hexagonal (Ports & Adapters) architecture. The new layers include Transporter (external adapters), Data Source Adapters (repositories & infrastructure), Application (use‑case orchestration), and Domain (business logic). Design patterns shift from transaction‑script ("spaghetti code") to rich domain models with clear responsibilities.

Six‑layer tactical design introduces clean separation of concerns, enabling better testability, maintainability, and extensibility. The team also embraces Test‑Driven Development (TDD), writing unit tests first, then implementing interfaces, and finally adding integration tests. Coverage exceeds 70 % with critical paths at 100 %.

Migration is performed safely through traffic‑mirroring and event‑sourcing. Requests are duplicated to both old and new services; the new service initially runs in a read‑only mode (no side‑effects) while both services emit key events for comparison. Gradual rollout phases—event reporting, traffic mirroring, and final gray release—are orchestrated with strict SOPs.

Extensive automated testing (UTDD, ATDD) and continuous verification uncovered dozens of discrepancies and performance issues, which were resolved before full production rollout. The final system achieved higher SLA (99.99 %+), reduced latency, and improved observability via event‑sourcing dashboards.

Business outcomes include better knowledge sharing, reduced development effort, higher reliability, and a reusable migration pattern for future legacy‑to‑Go transitions. The article concludes with reflections on the importance of treating every codebase as future legacy and maintaining modern engineering practices.

Live StreamingmicroservicesTestingBackend DevelopmentDomain-Driven Designsystem migrationhexagonal architecture
Bilibili Tech
Written by

Bilibili Tech

Provides introductions and tutorials on Bilibili-related technologies.

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.