饿了么异地多活技术实现(二)API-Router的设计与实现

背景:

饿了么随着业务量的增长,单个数据中心的容量无法支撑全部流量,同时传统机房冷备份方式的缺陷,促使饿了么异地多活应运而生;而作为多活重要组件之一的API-Router,扮演着客户端入口流量到后端机房路由的重要角色,当一个机房出现故障甚至宕机,可以实现机房快速切换。

 

设计目标:

1、入口流量可以根据sharding key规则路由到对应的机房(准确的说是ezone);

2、配合机房切换规则,能实现流量的转移;

3、尽可能的实现高性能、高可用、高并发,保护后端服务、削峰填谷;

前两点,主要是API-Router所需要实现的主要功能;第三点,是面对饿了么业务体量成倍的上涨带来的挑战所需要解决的问题;因此,API-Router定位为一个HTTP反向代理和负载均衡器,在此基础上实现路由的分发。

 

一、流量路由实现篇:

API-Router根据业务分集群部署在云上,参考饿了么异地多活的整体架构,API-Router的物理架构如下,

1、API-Router从Router控制台获取维护的每个域名的ezone到数据中心地址的映射关系;

2、API-Router将订阅GZS的关于shard到机房ezone的路由表;

3、API-Router在内存中,将请求头中的sharding key(地理位置、商户ID、订单ID),根据一套sharding规则,计算出shard;最常见的一种规则算法是,根据用户的经纬度,通过地里围栏算法,计算出相应的多边形,而这个多边形提前被分配了一个shard;

3、根据前3步,API-Router就拥有了sharding key-->shard-->ezone-->数据中心的映射表,最后将请求转发到对应的数据中心上;

 

流量转移的实现:

当后端机房故障时,API-Router会根据GZS主动推送的shard到ezone映射关系变更的消息,实现流量到ezone的切换,从而保证了服务的高可用;

 

二、技术实现篇:

API-Router采用了基于Netty的全后端异步非阻塞模型,以此来尽可能减少请求在这一层上的网络损耗,Epoll的特性使其支持更高的连接数,同时采取一些保护后端服务的措施来保证整个服务链路的稳定运行。

 

1、削峰填谷:

从架构图上可知,API-Router处于网站的入口,因此在这一层对流量进行削峰填谷,可以对后端服务免受瞬时流量的冲击起很大的保护作用。

每个http请求过来,首先会根据路由规则计算出后端的upstream,每个upstream对应一个scheduler,然后在scheduler里面依次通过信号量来限并发、通过入队列排队来堆积请求,从而实现流量的整形,示意图如下:

2、连接复用

随着饿了么用户量增长,客户端到router机器连接数越来越高,鉴于TCP连接对性能的影响,router到后端采用了连接池复用技术,因此减少了到后端的连接数(以生产某机器为例,前端到Router连接数在10w左右,经过连接复用到后端减少到140+),示意图如下:

3、热加载filter,处理request & response

API-Router作为处于网站链路最前端的一个Proxy,会有很多需要处理请求/响应的需求。为此,我们实现了一个类似拦截器链的功能,每个拦截器称之为Filter,可以拦截request和response,然后对其做一些类似限流、熔断、反爬虫、白名单、跨域等处理。而每个filter都是动态从控制台下发的,根据自定义的ClassLoader实现修改然后被动态加载到JVM,从而减少了发布的次数。Filter的示意图如下:

 

4、多协议支持

API-Router目前支持了包括

  • http/https
  • websocket
  • grpc
  • http2
  • TCP

5、更多

为了进一步提升单节点每秒所承载的流量,降低资源损耗,我们还从以下等方面实现无阻塞,提高性能。

  • 异步日志
  • 异步心跳
  • 异步打点
  • 异步Filter
  • 异步链接创建

展望未来:

1、针对饿了么外卖订单高峰低谷波动特点,实现服务器资源分钟级动态扩容和缩容,提高资源利用率;

2、进一步提供高系统的可用性,防爬、防刷、防网络攻击;

 

作者介绍

罗辉, 2015年加入饿了么, 现任饿了么框架工具部资深工程师, 负责饿了么API-Router项目。

编辑于 2018-01-03

反向代理

负载均衡

网站架构

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
vue-router的实现原理是利用浏览器提供的接口window.history和window.location.hash来实现路由功能。具体来说,vue-router通过配置mode属性来选择使用哪个接口实现路由功能。mode属性有两个选项:hash和history。当mode为hash时,vue-router使用window.location.hash来监听URL的变化,并根据URL的hash值来匹配对应的组件。当mode为history时,vue-router使用HTML5的history API来监听URL的变化,并根据URL的路径来匹配对应的组件。通过这种方式,vue-router能够在不刷新页面的情况下更新视图,实现前端路由的功能。\[1\]\[2\] 另外,vue-router还支持懒加载的实现方式。最常用的懒加载方式是通过import()来实现。通过在路由配置中使用import()来动态加载组件,可以实现按需加载,提高应用的性能。例如,可以将组件的import语句放在路由配置中的component属性中,当路由被访问时,才会动态加载对应的组件。这种方式可以减少初始加载的资源量,提高应用的加载速度。\[3\] #### 引用[.reference_title] - *1* [vue-router实现原理](https://blog.csdn.net/mengweiping/article/details/101068638)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [超详细的vue-router原理](https://blog.csdn.net/jiangjialuan2/article/details/124799307)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值