今天的文章来自李贝宁(Ben),SAP成都研究院的资深程序猿和架构师。html
做为成都研究院里同时精通Java, JavaScript和ABAP这三门编程语言的数位同事之一,Ben曾经前后担任了成都CRM Fiori开发团队,S4CRM开发团队和还没有发布的某款云产品开发团队的架构师。前端
Ben在这三个团队的职责都是产品架构设计和部分功能代码的编写,以及组内其余同事的代码审查。正则表达式
除了自身架构设计和编程相关的技能过硬以外,Ben在传业授道解惑方面也颇有心得。Ben是SAP研究院内部的Agile Software Enginnering教练,也是SAP成都研究院若干内部培训课程的讲师。他的课程帮助了不少刚刚走出大学校园的年轻同事们从在学校书写玩具代码到走向真正的企业软件开发的专业之路。数据库
每位同时精通数门风格大相径庭的编程语言的开发人员,总有本身的一套心得和办法,把这些语言融为一体,为本身所用。那么Ben又是如何作到的呢?或许能够从Ben的业余爱好看出点端倪。Ben喜欢足球和围棋,而且水平在业余爱好者里不算太差。能同时驾驭这一动一静,一刚一柔,一阳一阴的两个爱好,除了Ben之外,我能想到的也就只有这几位高手了:express
1. 人到中年,把降龙十八掌练到超过洪七公造诣的大侠郭靖。npm
岂知郭靖近二十年来勤练九阴真经,初时真力还不显露,数十招后,降龙十八掌的劲力忽强忽弱,忽吞忽吐,从至刚之中竟生出至柔的妙用,那已经是洪七公当年所领悟不到的神功编程
2. 左手短刀,右手长鞭的峨眉美女掌门周芷若。json
周芷若取出软鞭,右手一抖,鞭子登时卷成十多个大大小小的圈子,好看已极,左手翻处,青光闪动,露出了一柄短刀。群雄昨日已见识了她软鞭的威力,不意她左手尚能同时用刀,一长一短,一柔一刚,那是两般截然相异的兵刃。群雄惊佩之下,精神都为之一振。后端
3. 天微星九纹龙史进。api
水浒传里虽然有几位武力值爆表的好汉,好比卢俊义,史文恭,林冲这些,可是书中他们从始至终都只使用一种武器。而史大郎在战场上和别人拼命时,曾前后使用了三种不一样的武器,其中还包含中国古代武将不多有敢尝试的高难度武器——流星锤。
史进大怒道:“贼回子敢如此猖獗!”便轮着三尖两刃四窍八环刀,直取兰生。兰生急举独足铜人,敌住史进。两下各显武艺,奋勇大斗。
史进换了一支点钢丈八蛇矛,骤马出来。哈芸生见了,便挺着手中五股托天叉,一马冲来,直取史进。二人也不打话,两马相交,叉矛并举,一来一去。只见史进那枝矛,忽高忽低,忽前忽后,忽左冲,忽右掠,挥身上下,满是一片矛影。
说时迟,那时快,史进早已手提流星锤,换了一匹高头大马,赶到阵前。兰生飞起铜人打去,沙冕二人一齐攒上。史进耍圆那颗流星锤,挡住三人。
书中提到的史大郎在八十万禁军教头王进的指导下,十八般武艺样样精通,果真名不虚传。
而李贝宁,在SAP成都研究院三支分别使用Java, JavaScript和ABAP的开发团队里都被任命为架构师,技术的全面性不输于史大郎。
据我所知李贝宁喜欢的球星是被球迷冠以“拼命三郎”,“铁人”称号的内德维德,喜欢他在球场上不惜体力奔跑那种铁血做风。李贝宁但愿本身在球场上也能作一个像内德维德那样的拼命三郎。
Jerry不是球迷,只知道咱历史上也有一位拼命三郎:
做为一个八零后,Jerry幼年在这些卡片上没少花钱。若是您有一样的收藏爱好,欢迎后台交流。
下面是李贝宁的正文。
你们好,我叫李贝宁,也能够叫我Ben, 目前在SAP成都研究院某云产品项目组担任高级开发工程师和架构师。
我是09年加入SAP的, 以前在上海花旗集团软件中心作了4年银行系统开发, 进到SAP以后先在SAP上海研究院工做了两年,于11年末转到了SAP成都研究院直至如今,算起来在成都呆了快七年了。
除了编程以外,我还有两个铁打不动的爱好,足球和围棋,水平嘛分别算得上小区球星级和街道业余高手级... 我认为这两件事一个能够保持身体上的活力,一个能够保持头脑上的活力,因此至今一直坚持每周踢一场球和下几盘棋的节奏,固然同时也做为工做之余的放松。
这篇文章就SAP Hybris某款正在开发的云产品在SAP云平台上用到的一个组件Application Router(如下简称App Router)作一个介绍。
SCP App Router是SAP云平台(如下简称SCP)上的核心模块之一,做为独立运行在SCP Cloud Foundry环境中的一个应用程序,它主要支持如下两大核心功能:
反向代理:将外部请求分发给SCP Cloud Foundry环境内不一样的应用程序。
安全集成:和SCP Cloud Foundry上的核心安全组件UAA无缝集成,提供了用户认证,会话管理等安全相关的功能。
说到这里您也许立刻会想到Nginx,一款优秀的开源Web服务器,用来作相似反向代理的功能。若是个人应用程序想要用Nginx,可不能够呢?其实SCP并无限制只能用App Router——它是一个彻底开放的平台,您能够部署任意你想要的组件为应用程序服务,只是SAP在上面已经提供了一系列的基础设施组件,这套SAP原生组件之间提供了更佳的集成和协同,App Router就是其中之一。
App Router是一个用Node.js构建的标准的Web应用。
众所周知Node.js做为一门开放的技术环境,在构建基于HTTP的Web应用上有先天的优点: 简单,高效。而且Node.js通过近几年的快速迭代和发展,已经很是成熟和稳定,再加上开源社区提供了丰富的库,Node.js已经成为了服务器端强大的应用开发环境。SAP选择Node.js做为其云战略平台上的核心组件的技术栈,从这个选择咱们也能看出SAP在云战略上的思路是逐步走向开放。
您或许会问,Node.js是单线程模型,根据上面的示例图,全部对于部署在SCP Cloud Foundry上的后端访问都经过App Router,这会带来性能问题吗?其实这是对于Node.js运行时模型的一个误解,参考一张Node.js的运行时架构图:
Node.js对于应用程序端只提供了单线程的编程模型,可是其底层的运行架构并不是是单线程模型。在Node.js中各类HTTP访问,数据库的读写,文件IO的访问都是以异步的方式代理给了底层的V8引擎,主线程不会被阻塞,而底层V8引擎具有很是强大的并发处理能力,会迅速将各个事件并发的处理结果经过事件轮询的方式返回给主线程。只要在Node.js的主线程中不作大量的CPU运算(好比大规模业务逻辑运算,科学计算等),这样的Node.js应用程序是能够具有良好的性能的。
而App Router刚好具备上述所说的那些一典型特征:在用户认证中将识别用户身份和权限的工做代理给Cloud Foundry UAA来作,业务请求转发给各个独立的部署Cloud Foundry应用,本身仅仅作一些简单的HTTP参数的转换和校验,请求的转发,以及请求响应的返回。
在App Router上路由的实现是经过定义一系列destination来实现的,具体来讲就是在App Router的xs-app.json中配置route和destination,以及在manifest.yml中配置对应destination的url:
manifest.yml:
简单解释一下主要的参数:
Routes
source:能够是一个URL,也能够是一个正则表达式,定义了当前的route是匹配什么样的请求路径
target: 当前请求如何被重写到目标地址
destination: 当前请求路由到manifest中的哪一个目标地址
authenticationType: 有三种选择,xsuaa, none和basic,xsuaa和none分别表明了是否对当前请求在App Router上作用户安全认证,下一节会具体介绍。Basic是和SAP HANA集成的时候提供默认的安全验证支持。
Destination
Name:用来跟xs-app.json中的destination配置相匹配
URL:目标应用程序真实的Clould Foundry地址
ForwardAuthToken: 若是请求中带有oauth token,是否将oauth token转发给目标应用程序. App Router也支持oauth token的部分校验功能,因此用户也能够根据具体状况选择不转发oauth token,就在App Router端校验
除了基本的路由功能,App Router还提供了丰富的Web应用程序相关的功能支持,好比链接管理,session管理,扩展http头,跨域,Web Socket等等。
如上一节提到的,App Router在路由的时候提供了用户的安全认证支持。将路由的Authentication Type配置为xsuaa,App Router则会检查前端发过来的请求是否带有合法的session。若是没有,App Router会将用户导向SCP UAA的用户认证界面,当用户从新认证成功以后,会生成新的合法session,并将此session返回给前端应用程序。
整个认证的流程是是SCP App Router和SCP UAA协同完成的,SCP UAA是SAP对Cloud Foundry上提供的安全组件UAA (User Account and Authentication Service)的一个封装,Cloud Foundry UAA是一个实现了标准Oauth 2.0协议的authorization server,SAP在此基础上作了一些自定义的加强,可是在接口上和原生的UAA保持了一致,这样能够尽量的对OAuth Client端程序提供兼容性。
Cloud Foundry UAA官方文档:
https://docs.cloudfoundry.org/api/uaa/version/4.10.0/index.html#overview
SCP标准的OAuth2.0流程:
若是熟悉OAuth2.0协议,从这张流程图上很快就能看出App Router和UAA之间是经过Authorization Code Grant Flow来交互的,在交互过程当中它们分别充当了OAuth Client和OAuth Server的角色。
关于OAuth2.0,请参见: https://oauth.net/2/
看到这里您也许会问,为何不是前端浏览器做为OAuth Client?除了安全性的考虑, App Router将OAuth流程对前端隐藏的另外一个好处是,各类前端应用程序不须要知道UAA上诸如Client ID, Client Secret的细节,提供了更好的安全性。
其次还有SAP在产品层面的考量,为了其标准的产品在UI技术上的一致性,包括SCP上的产品在内大多数都是基于SAP UI5来构建前端UI,而UI5又是基于HTML5技术而来,即这些产品都是基于浏览器的富客户端应用。如此一来,在标准的App Router里面实现OAuth2.0流程可使SAP的各类前端应用并不须要关注认证流程的细节。如上图所示,App Router在完成了认证流程并最终拿到token以后,并无将token返回给浏览器端,而是在App Router上生成一个session,而且将session和token关联起来,App Router在这里起到一个中介者的角色,对于前端统一用session进行交互,对于后端统一用token进行交互。
SCP除了将标准的实现默认支持浏览器端应用程序外,做为一个开放的平台,固然也支持移动端原生应用程序的集成,这里不做赘述,具体细节能够参考SCP的开发文档。
App Router上的session管理利用了Node.js的session-express框架,默认将session缓存在instance memory中(下图第79行):
而后采用session stickiness策略来保证在多实例部署的状况下,相同会话的请求会被发送到同一个实例上以保证会话能继续进行。
Session Stickiness:
https://stackoverflow.com/questions/10494431/sticky-and-non-sticky-sessions
这样作的好处是既利用了instance memory的高性能,也能够在必定程度上保证高可靠性。不过代价是牺牲了动态伸缩的能力,一旦某个App Router实例上还有正在使用中的session,这个实例就不能被关闭。
好在App Router使用的是开源的express-session框架,该框架并不是只能将session存储在instance memory中,在Node.js开源社区已经提供了多种express-session的外部存储方案。至少在技术上,能够将App Router提供的instance memory存储替换为外部存储,而不须要作太多的定制化开发,这样一来多个App Router实例就能够共享同一套session存储。
只要说到SAP的产品,extensibility是一个不可避免的话题,这是由SAP的业务是面向企业级客户这一特质决定的。SAP也一直致力于从平台到框架,再到上层的产品,尽量多的给SAP客户提供良好的可扩展性。App Router一样也不例外,由于直接使用了Node.js的connect框架,这是一款自己就提供了丰富扩展的中间件框架,能够经过可插拔的方式对Node.js的请求和响应提供过滤和拦截,具体你们能够参考connect的主页。
App Router基于connect,固然App Router的用户就能够直接得到connect提供的各类中间件,除此以外App Router还提供了本身的一些中间件:
是否是很是简单和直接?使用这些中间件而不须要修改原生App Router里面的代码。
这里再也不对App Router上的各类中间件一一赘述,具体细节能够参考App Router的Github文档。
总结说来,App Router是一款设计简单,使用方便,提供了良好可扩展性的反向代理组件,为广大SAP用户在SCP上开发应用程序提供了更多的选择和方便。
感谢你们阅读。
要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码: