-
Notifications
You must be signed in to change notification settings - Fork 20
Open
Description
背景
路由、负载均衡等都属于扩展SPI,目前客户的路由策略都是写死在mosn中,通过将路由能力抽象成插件的机制,允许根据不同的场景去做灵活的定制。
写死在mosn中有一些弊端:
- 需要单独维护定制的分支,并且需要重新build mosn,客户增长,代码膨胀不利维护
- 客户自定义策略,需要原厂研发去编写
什么是路由?
通俗来讲,就是根据一定算法,去筛选目标地址集合得到期望目标地址子集。路由插件化要做的事情:
将编写筛选的算法 开放出去,让客户自行决策,给定目标地址集合,返回目标地址子集。
收益:
- 完善Sofa Mesh插件扩展产品矩阵,丰富扩展场景
- 支持灵活路由策略,配合智能代码生成,增加产品差异化竞争能力
目标
- 支持路由plugin级别扩展
- 支持路由动态配置推送: 动态路由
- 支持router chain机制
思路
开源侧提供route api, 商业版提供插件装载,形成产品能力,实现灵活扩展
方案设计
开源侧Route SPI ( 放到extensions,api无异议,商业版做完验证,提交pr )
package router
import (
"context"
"mosn.io/api"
)
// RouteFactory create router handler for filter hosts
type RouteFactory interface {
// Name router factory name
// Route factory will be registered as unique component
Name() string
// Order parameter is used to sort multiple route plugins.
// The default value is 0. The smaller the value, the earlier the route plugin is executed.
Order() int
// Configurator Dynamic route configuration push is supported
Configurator() Configurator
// CreateRouter create route handler with config
// Configurator returns the latest route configuration for conf
CreateRouter(ctx context.Context, conf map[string]interface{}) Handler
}
// Handler host list filter handler
type Handler interface {
// Route filtering by request and invokers address list returns the final list of available services
// meta: All hosts must contain the same tag, if any
Route(ctx context.Context, request api.HeaderMap, invokers []api.HostInfo) (meta api.Metadata, hosts []api.HostInfo)
}
// Configurator Route configuration dynamic push feature
type Configurator interface {
// Configure Transform dynamic configuration into programmable objects
// The transformed object is passed to the RouterFactory CreateRouter
// When dynamic configuration is pushed, Configure will be invoked.
Configure(factory string, config string)
// Configuration This is the route configuration after the latest conversion
Configuration() map[string]interface{}
}------ 以下在商业版mosn中实现, 开源无需关注-----
商业版脚手架支持
yiji@yiji-2 build % tree
.
├── codecs
│ ├── bolt
│ │ ├── codec-bolt-fa3442c8.so
│ │ ├── codec-bolt.md5
│ │ ├── egress_bolt.json
│ │ ├── ingress_bolt.json
│ │ └── metadata.json
│ └── bundle
│ └── support
│ └── routers // 会在插件包包含激活的 路由插件so和配置
├── image
│ └── Dockerfile
└── sidecar
└── binary
├── mosn
└── mosn-1.26.0-fdc2aa702.md5
商业版mosn route适配
- mosn启动会装载包含路由插件的大包,启动期间注册RouteFactory
- mosn去对接动态配置中心,收到动态推送 会查找RouteFactory 触发 Configurator配置解析,当下一次请求能够感知到最新的路由配置
因为mosn框架要实现路由必须满足RouteHandler接口,但是ClusterManager、ClusterSnapshot、HandlerStatus 开源api、pkg迁不出去:
type RouteHandler interface {
// IsAvailable returns HandlerStatus represents the handler will be used/not used/stop next handler check
IsAvailable(context.Context, ClusterManager) (ClusterSnapshot, HandlerStatus)
// Route returns handler's route
Route() api.Route
}目前商业版是通过CloudRouteHandlerCreator去生成RouteHandler:
type CloudRouteHandlerCreator interface {
RouterSpec
CreateRouterHandler(ctx context.Context, headers types.HeaderMap, routers types.Routers) types.RouteHandler
}
因此需要针对插件的RouteFactory创建对应的factory.name -> CloudRouteHandlerCreator:
// 支持插件路由handler包装
// 负责解析路由动态配置,并且在实例化RouteHandler进行配置传递
type ConfiguratorRouteHandler interface {
CloudRouteHandlerCreator
// 返回关联的plugin factory
// CloudRouteHandlerCreator返回的RouteHandler 会调用 RouteFactory创建的plugin handler
RouteFactory() RouteFactory
}
// 实现RouteHandler接口,负责调用RouteFactory的plugin handler
type RouteHandlerAdaptor struct {
conf map[string]interface{} // dynamic conf
pluginHandler router.Handler // user extension router spi
routers types.Routers // routers
headers types.HeaderMap // request
route api.Route // match header key-value route
snapshot types.ClusterSnapshot // cluster snapshot
}
func (r *RouteHandlerAdaptor) IsAvailable(ctx context.Context, manager types.ClusterManager) (types.ClusterSnapshot, types.HandlerStatus) {
// invoke plugin route here...
r.pluginHandler.Route(ctx context.Context, request api.HeaderMap, invokers []api.HostInfo)
}Metadata
Metadata
Assignees
Labels
No labels