Practical Evolution of a Financial Microservice API Gateway Using Netflix Zuul
Facing rapid growth in car‑finance services, the article describes how a monolithic system was transformed into a microservice architecture with a Netflix Zuul API gateway, detailing its features, dynamic configuration, routing, integration with Consul, thread model, and future improvements.
As the car‑finance business expanded quickly, the original monolithic architecture could no longer meet development speed requirements, prompting a migration to a microservice architecture in early 2018 that split the system into more than 40 services.
Key pain points identified were the need for each client to maintain its own service routing table and duplicated development of common functions such as authentication and authorization across services. Introducing a service gateway addressed these issues by providing a unified entry point.
What is a gateway? An API gateway is the sole traffic entry for a microservice system, encapsulating internal service calls and offering common capabilities like authentication, permission control, load balancing, rate limiting, circuit breaking, and gray releases. An analogy with a movie theater illustrates how the gateway routes requests to appropriate services.
Advantages of an API gateway
Without a gateway, clients must call multiple microservices directly, increasing client complexity, and each service must implement identical non‑business features. Introducing a gateway reduces client complexity, centralizes routing configuration, and provides shared functionalities.
Technology selection
Various commercial and open‑source gateway solutions exist (Tyk, Kong, Orange, api‑umbrella, apiaxle, Netflix Zuul, Nginx+Lua). Because the financial system relies heavily on the Java ecosystem and Spring, Netflix Zuul was chosen as the gateway implementation.
Zuul overview
Zuul, an open‑source API gateway from Netflix, handles request routing and filtering. It integrates with Consul, Ribbon, Hystrix, and Spring Cloud, offering a JVM‑based router and load balancer.
Zuul’s core consists of four standard filter types that correspond to typical request lifecycles:
PRE – executed before routing (e.g., authentication, service selection).
ROUTING – routes the request to a downstream service.
POST – runs after routing (e.g., adding headers, collecting metrics).
ERROR – handles errors occurring in other phases.
The filter lifecycle is illustrated in the following diagram:
Financial gateway practice
Initial challenges included static route configuration requiring manual YML edits, duplicated non‑business logic across services, and separate gateways for each business line leading to resource waste.
To address these, the team consolidated all business gateways into a single cluster, leveraged the cloud platform’s traffic grouping for isolation, and introduced a database‑backed dynamic configuration for routes and feature components. Configuration changes are propagated via a message queue, enabling plug‑in style extensions.
Dynamic configuration evolution
Static configurations were replaced with a dynamic, database‑driven approach. The responsibility‑chain pattern was used to assemble filter chains at runtime based on database entries, allowing real‑time updates without code changes.
Dynamic routing
Zuul’s default routing relies on static YML files, which is unsuitable for frequent service additions. By extending SimpleRouteLocator, the team fetched routing data from a database, enabling dynamic route discovery.
<span>@Override</span>
<span>public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {</span>
<span> ...</span>
<span> // 路由预处理(pre阶段)</span>
<span> preRoute();</span>
<span> ...</span>
<span> // 路由阶段(route阶段)</span>
<span> route();</span>
<span> ...</span>
<span> // 请求响应阶段(post阶段)</span>
<span> postRoute();</span>
<span> ...</span>
<span>}</span>Routing filters such as RibbonRoutingFilter and SimpleHostRoutingFilter determine which routing strategy to apply based on context values.
<span>//RibbonRoutingFilter</span>
<span>ctx.getRouteHost() == null && ctx.get(SERVICE_ID_KEY) != null && ctx.sendZuulResponse();</span>
<span>// SimpleHostRoutingFilter</span>
<span>RequestContext.getCurrentContext().getRouteHost() != null && RequestContext.getCurrentContext().sendZuulResponse();</span>Route definitions are now stored in the database and loaded via a custom locator:
<span>@Override</span>
<span>public Map<String, ZuulRoute> loadLocateRoute() {</span>
<span> List<ZuulRouteDto> zuulRouteDtos = getZuulRoutes();</span>
<span> Map<String, ZuulRoute> handle = handle(zuulRouteDtos);</span>
<span> return handle;</span>
<span>}</span>To support hot‑refresh of routes, the custom locator implements RefreshableRouteLocator and listens for RoutesRefreshedEvent to invoke doRefresh():
<span>protected void doRefresh() {</span>
<span> this.routes.set(locateRoutes());</span>
<span>}</span>Integration with Consul as a service registry eliminated manual route configuration and domain‑name requests. Each Docker container runs a Consul agent that registers its IP and port, enabling the gateway to discover services automatically.
Gateway internal thread model
Zuul 1.x processes each request synchronously on a servlet thread, which simplifies design and debugging but can exhaust thread pools under slow downstream services.
Future outlook
The gateway will be re‑implemented on Netty to overcome the limitations of the synchronous servlet model, and it will incorporate performance monitoring and health‑metric analysis for all inbound services.
References
Zuul GitHub: https://github.com/Netflix/zuul/wiki
Zuul source code: https://github.com/Netflix/zuul/tree/1.x
Author: Peng Haibin, a developer in the automotive finance technology department, responsible for gateway construction and development.
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.
58 Tech
Official tech channel of 58, a platform for tech innovation, sharing, and communication.
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.
