03.26 (原创)Asp.Net mvc webapi 实现微服务网关路由转发功能

前面几篇讲了微服务的诸多介绍以及一些开源的网关,开源虽好,但有时跟团队用的技术栈和平台不一样,而且有些开源的网关功能太多,学习成本太高,远远高于自研的成本,因为有时,我们仅仅需要网关某几个的功能,比如路由转发、接口鉴权等等。今天,小编就来结合Asp.Net mvc webapi技术分享下微服务网关中路由转发功能的实现。


首先来张网关的总体架构或说是设计图:

(原创)Asp.Net mvc webapi 实现微服务网关路由转发功能

nginx+asp.net webapi+redis+sqlserver+mongodb

nginx作为反向代理服务器,将比如http://www.xxx.com/apigateway/后面的地址统一转发给api网关站点。

然后到了api网关这里,由于api网关用的是webapi,在这个站点后面的路由就是asp.net webapi的路由机制了(还是利用asp.net mvc的路由机制,在用当下webapi技术来套一层皮吐出restful风格的api接口)。

那大家会问,那这么多接口,难道来一个接口就要修改下路由配置文件然后在发布吗?

答案肯定不是这样的。从上图中,有个MSSQL,这个就是我们把mvc中的路由映射关系持久化存储在MSSQL数据库中,但是每次请求都去关系型数据库MSSQL查接口,性能也是不理想,所以,我们可以把接口缓存到像Redis这种内存数据库中。然后请求的跟踪日志存储在MongoDB中,方便网关集群分布式部署时,好查日志。

当时,原理是这样,这里比较关键的一点是,那么nginx到底该转发到webapi中的哪个接口呢?

我们是这样设计的,所有经过nginx的请求(当时路径前缀是http://www.xxx.com/apigateway/)统一转发到webapi中ApigatewayController/Reroute方法中,关键是这部该如何实现了。这里用到两个过滤器:

(原创)Asp.Net mvc webapi 实现微服务网关路由转发功能

(原创)Asp.Net mvc webapi 实现微服务网关路由转发功能


public class NotFoundControllerSelector : DefaultHttpControllerSelector

{

public NotFoundControllerSelector(HttpConfiguration configuration)

: base(configuration)

{

}

public override HttpControllerDescriptor SelectController(HttpRequestMessage request)

{

HttpControllerDescriptor decriptor = null;

try

{

decriptor = base.SelectController(request);

}

catch (HttpResponseException ex)

{

var code = ex.Response.StatusCode;

if (code != HttpStatusCode.NotFound)

throw;

var routeValues = request.GetRouteData().Values;

routeValues["controller"] = "ApiGateway";

routeValues["action"] = "ReRoute";

decriptor = base.SelectController(request);

}

return decriptor;

}

}


public class NotFoundActionSelector : ApiControllerActionSelector

{

public NotFoundActionSelector()

{

}

public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)

{

HttpActionDescriptor decriptor = null;

try

{

decriptor = base.SelectAction(controllerContext);

}

catch (HttpResponseException ex)

{

var code = ex.Response.StatusCode;

if (code != HttpStatusCode.NotFound && code != HttpStatusCode.MethodNotAllowed)

throw;

var routeData = controllerContext.RouteData;

routeData.Values["action"] = "ReRoute";

IHttpController httpController = new CoreController();

controllerContext.Controller = httpController;

controllerContext.ControllerDescriptor = new HttpControllerDescriptor(controllerContext.Configuration, "ApiGatway", httpController.GetType());

decriptor = base.SelectAction(controllerContext);

}

return decriptor;

}

}

经过上面两个过滤器,就会将http://www.xxx.com/apigateway/api/后面的所有请求转发到http://www.xxx.com/apigateway/api/apigatway/reroute/

在reroute这个action你就可以实现网关的所有功能了,比如查Redis(MSSQL)、找到对应接口。。。

(原创)Asp.Net mvc webapi 实现微服务网关路由转发功能

当然,做得优雅一点,可以用流水线的方式:

(原创)Asp.Net mvc webapi 实现微服务网关路由转发功能

当然,这只是C#语言实现的一部分,你也可以用java或Go或Node.js去实现,思想都是一样的,技术实现不同而已。

如果觉得有用,大家可以关注我,也可以下方留言互动一起探讨。



分享到:


相關文章: