最近Jerry参与了SAP Commerce Cloud的标准开发,我们调用微软云平台Azure上创建Lambda Function的Restful API来创建Lambda Function:
在开发过程中发现该API工作不太稳定,同样的输入,时不时会返回HTTP 400 Bad Request:Encountered an error (InternalServerError) from host runtime
这个错误并不是总能重现。
通过排查,最后我们确认这个问题和我们调用API的代码无关,于是给Azure报了一个bug:
在分析定位问题时,不由得让我怀念起以前在ABAP On-Premise上做开发的一个便利之处——大多数问题都可以通过在ABAP应用服务器端调试来找到根源。
本文记录了2016年时,SAP成都研究院CRM开发团队在开发SAP CRM Fiori应用时的一些技术讨论,关于HTTP请求的响应状态码的差异。
当时我们用Chrome打开SAP Fiori应用,在Chrome开发者工具的network标签里,观察到有的请求响应码为HTTP 200,有的却是HTTP 304.
HTTP 200和HTTP 304理论上的差异解析,网上一搜一大把:
https://stackoverflow.com/questions/1665082/what-is-the-difference-between-http-status-code-200-cache-vs-status-code-304
本文我们从一个实际的例子出发,观察ABAP服务器分别是在何种情况下,返回HTTP 200和304这两个状态码的,帮助大家加深理解。
分几种情况进行讨论。
首先进行第一轮测试。
将这种来自SAP UI5标准库文件的url粘贴到浏览器里访问:
https://:7080/sap/bc/ui5_ui5/ui2/ushell/resources/20160308134900/sap/fiori/core-min-0.js
得到HTTP 200状态码:
大家想过没有,上图高亮的HTTP响应头部字段,比如last-modified, 是在ABAP服务器上哪段代码里被填充的?
灵活运用Jerry 文章 SAP错误消息调试之七种武器:让所有的错误消息都能被定位 介绍的办法,顺利通过调试的方式,找到准确的位置如下:
上述代码的逻辑:
(1) 第九行,服务器试图从HTTP请求的头部字段中,提取名为If-Modified-Since的字段值,因为这是我第一次请求该JavaScript文件,而这个字段的值逻辑上应该等于第一次请求到达服务器后,从服务器返回的响应结构里名为last-modified字段的值。
在我的第一轮测试里,因为是第一次请求该文件,HTTP请求头部没有包含If-Modified-Since字段,所以服务器解析出的值为空,即变量lv_modified_since为空。
(2) 在我使用的ABAP服务器上,JavaScript文件core-min-0.js最后修改的时间戳为20160316205045. 因此,两个变量lv_change_time_char和lv_change_time_string都被附上了这个值。
下面第20行代码展示了前文HTTP 200状态码的截图里,HTTP响应字段cache-control被填充的地方。
之前Chrome浏览器里打开的url:
https://:7080/sap/bc/ui5_ui5/ui2/ushell/resources/20160308134900/sap/fiori/core-min-0.js
不用关闭这个浏览器窗口,直接按F5刷新,这次收到的响应码不再是HTTP 200 OK,而是HTTP 304 Not Modified.
为什么会产生这种差异呢?按F5之后仔细观察请求头部,发现第二次请求,浏览器发出的HTTP请求里,If-Modified-Since字段包含的就是第一个请求里从服务器端返回的last-modified字段值。
按F5刷新的这个请求到了服务器端,这一次ABAP服务器成功解析出请求字段If-Modified-Since的值:
将客户端发送过来的这个If-Modified-Since时间戳,同服务器端该文件最后修改的时间戳进行比较(即下图第26行AND后的第二个判断条件),发现二者相等,因此在第28行返回HTTP 304 Not Modified.
关掉Chrome,再打开,再访问同一url,此时Chrome直接从自身的cache里返回该JavaScript文件,而不是向ABAP服务器上发起请求。因此服务器上所有ABAP断点均不会触发。
再回到Jerry遇到的那个Azure上执行function创建API遇到的HTTP 400 Bad request的incident,至本文发稿时为止还是未能得到解决。
尽管Azure的Function Host运行时也是开源的,但不能调试,我拿着这些海量代码也没辙,目前Github上看到的就有多达967个开着的issue.
从开发者遇到问题后调试定位这个角度上说,还是ABAP On-Premises方便啊。
感谢阅读。
要获取更多Jerry的原创文章,请关注公众号"汪子熙":
ABAP专题
Jerry的ABAP, Java和JavaScript乱炖
ABAP开发人员未来应该学些什么
Jerry 2017年的五一小长假:8种经典排序算法的ABAP实现
Jerry的ABAP原创技术文章合集
300行ABAP代码实现一个最简单的区块链原型
使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数
在SAP云平台的CloudFoundry环境下消费ABAP On-Premise OData服务
ABAP vs Java, 蛙泳 vs 自由泳
聊聊C语言和ABAP
动手使用ABAP Channel开发一些小工具,提升日常工作效率
我用ABAP做过的那些无聊的事情
不喜欢SAP GUI?那试试用Eclipse进行ABAP开发吧
使用Visual Studio Code编写和激活ABAP代码
你的ABAP程序给佛祖开过光么?来试试Jerry这个小技巧
在SAP云平台ABAP编程环境上编写第一段ABAP程序
SAP官方发布的ABAP编程规范
ABAP Code Inspector那些隐藏的功能,您都知道吗?
还在用ABAP进行SAP产品的二次开发?来了解下这种全新的二次开发理念吧
ABAP Netweaver体内的那些寄生式编程语言
从SAP社区上的一篇博客开始,聊聊SAP产品命名背后的那份情怀
云端的ABAP Restful服务开发
如何在SAP云平台ABAP编程环境里把CDS view暴露成OData服务
使用abapGit在ABAP On-Premises系统和SAP云平台ABAP环境之间进行代码传输
30分钟用Restful ABAP Programming模型开发一个支持增删改查的Fiori应用
Jerry带您了解Restful ABAP Programming模型系列之二:Action和Validation的实现
Jerry带您了解Restful ABAP Programming模型系列之三:云端ABAP应用调试
SAP云平台上的ABAP编程环境里如何消费第三方服务
ABAP开发者上云的时候到了 - 现在大家可以免费使用SAP云平台ABAP环境的试用版了
学而不思则罔 - SAP云平台ABAP编程环境的由来和适用场景
SAP云平台里的三叉戟应用
如何基于Restful ABAP Programming模型开发并部署一个支持增删改查的Fiori应用
SAP 2019 TechEd Key Note解读:云时代下SAP从业人员如何做二次开发?
有哪些ABAP关键字和语法,到了ABAP云环境上就没办法用了?
ABAP开发环境终于支持以驼峰命名法自动格式化ABAP变量名了
利用ABAP 740的新关键字REDUCE完成一个实际工作任务
一段让人瑟瑟发抖的ABAP代码
昨日万圣节ABAP怪兽级代码谜团,公布答案啦
介绍一种在ABAP内核态进行内表高效拷贝的方法
使用SAP Cloud Application Programming模型开发OData的一个实际例子
当ABAP遇见普罗米修斯
使用ABAP绘制可伸缩矢量图
ABAP开发环境语法高亮的那些事儿
SAP错误消息调试之七种武器:让所有的错误消息都能被定位
使用ABAP操作Excel的几种方法
SAP GUI里的收藏夹事务码管理工具
SAP GUI和Windows注册表
有了Debug权限就能干坏事?小心了,你的一举一动尽在系统监控中
ABAP CCDEF, CCIMP, CCMAC, CCAU, CMXXX这些东东是什么鬼
实现ABAP条件断点的三种方式
使用SAT跟踪监控从浏览器打开的SAP应用的性能和调用栈
一个13年ABAP老兵的建议:了解这些基础知识,对ABAP开发有百利而无一害
SAP ABAP Netweaver容器化, 不可能完成的任务吗?
SAP产品增强技术回顾
SAP API开发方法大全
浅谈Java和SAP ABAP的静态代理和动态代理,以及ABAP面向切面编程的尝试