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去實現,思想都是一樣的,技術實現不同而已。

如果覺得有用,大家可以關注我,也可以下方留言互動一起探討。



分享到:


相關文章: