8583 over http

N年前曾有一个架构设计的案例。

一、需求

【背景】

当时集团有10万名一线员工,每名一线员工工作都手持一个基于Android系统定制的移动设备(下文简称A设备)。类似于手机,通过SIM卡可进行网络通信。其上安装多个应用,支持多种业务。A设备其中一个附件设备可支持刷卡支付业务,简称此应用为pos应用。另有一个用于无卡支付的应用,简称为pay应用。由于发展历程的原因,两个应用都是符合ISO8583协议要求,但对8583部分可自定义的字段由于业务场景的不同,有不同的自定义实现。而且这两个应用由不同的开发团队实现,无法兼容。A设备除了pos应用、pay应用还部署了很多集团旗下其它子公司的应用。pay应用、pos应用作为前端,其对应的后端应用系统也是不同的。而根据业务发展趋势,后续的业务类型会更多,而自定义的8583报文协议已经显示出力不从心。特别是从3G网络升级到4G网络,A设备承载的业务将增加图像等多媒体信息。

【需求】

由于集团发展战略的需要,要进一步加强终端设备的管控,将只允许A设备通过https直接接入集团私有云,再由集团的私有云接到原有机房服务器。如何设计一个改造方案,能以尽可能低的成本完成集团要求并支持未来发展需要?

原有的部署:pos app / pay app ----( 8583协议基于tcp短连接 )----> bff ----(hessian rpc ) ----> ms 。
要求的部署:A设备(pos app / pay app) ---- ( https ) ----> 集团的私有云 ---->公司 SF网络区。

【补充】

  1. 8583协议是基于ISO8583报文国际标准的包格式的通讯协议,8583包最多由128个字段域组成,每个域都有统一的规定,并有定长与变长之分。8583包前面一段为位图,它是打包解包确定字段域的关键。8583协议都是请求响应式,没有会话状态关联多个请求。客户端发起一个请求,服务器端对应的接收请求,验证请求,处理请求,响应结果。8583报文是二进制数据的格式。

  2. bff是一个Backend for Frontend前置网关性质的应用系统,负责解释8583报文,编排串联并调用rpc微服务,再将rpc微服务响应的结果,编码成8583报文响应给前端。前端app 通过8583协议访问bff前置系统。而其中的8583协议是BFF基于mima框架TCP短链接实现的,TCP有SSL安全层。一次请求与响应,就对应于一次TCP连接的打开与关闭。bff前面有F5负载均衡器。

  3. ms在这里是指后端的多个微服务架构风格的应用系统,支持hessian 协议,micro-service-a, micro-service-b, micro-service-c... 。bff与ms都部署在公司Server Farms 网络区,此网络区与私有云有专线连接。

二、分析

  1. pay app + pos app 需要支持数千的TPS。
    并发请求不是太高。但A设备有10万,维持10万的长连接成本较高,是没有太多必要的。
  2. 8583报文最大不超过10KB。
    对私有云至SF网络区的专线带宽有些要求。
  3. 基本属于重构的范围,不涉及业务功能的变化。但需要支持发展趋势。一是一线员工需要假设一定的增长速度。二是随着A设备全部升级为4G网络,能承载的业务也更多种多样,8583报文的灵活性不及restful。
  4. 已自定义的8583报文,按MESSAGE_TYPE+PROCESSING_CODE计算,包括请求与答复,按1000类报文评估。
    如果全部都直接改造系统代码,改为restful风格的URL形式,显然是开发与测试成本极大的。想要更低成本的解决方案,就必须保留8583报文原本的编码解码逻辑,将其报文内容通过https传输。

三、架构方案

【设计思路】

基于以上需求分析,架构方案的主要思路是:8583 over http。
将8583二进制报文内容基于https协议传输。即在HTTP服务器的配置文件中增加一种自定义的MIME( Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。例如content-type可命名为"application/pay8583", ”application/pos8583“。只要自已的http服务器能识别即可。如果http服务器不方便修改,采用application/octet-stream的content-type也是可行的。但需要另外定义一个http头部字段标识具体是哪一种8583自定义报文格式。

在集团私有云部署3台Nginx服务器,使其成下面的访问链路:

A设备(pos app / pay app) ---- ( 8583 over https ) ----> 私有云Nginx ----(8583 over http)----> bff ----(hessian rpc ) ----> ms 。

【pos app / pay app 改造】

  1. 将原本的TCP(SSL)连接改为 https连接。按下文Nginx要求,增加请求及响应时的http首部字段。
  2. 8583报文不需要改动,以二进制格式通过https传输。

【私有云部署Nignx】

Nginx前可利用私有云已有的负载均衡器(例如可能的LVS-DR + Keepalive)。

  1. 修改Nginx配置文件 mime.types。使其支持content-type "application/pay8583",对于自定义的content-type,只支持post请求方法,不支持GET/PUT/DELETE/HEAD等请求方法。

  2. 修改nginx.conf 的http配置块,修改keepalive_timeout保持与前端一定时长的连接。

  3. 修改nginx.conf 的server配置块,配置https ssl_certificate。Nginx可以卸载SSL层,转换为普通的http长连接给到BFF。

  4. 修改nginx.conf 的location配置块,proxy_pass。
    根据context反向代理至对应的bff。例如 https://domain-name/pos 转发至pos-bff,https://domain-name/pay转发至pay-bff,https://domain-name/biz-new转发至新的业务。不同的context可以对应到不同的前端app/ 不同的业务类型 / 不同的子公司。biz-new可以采用新的restful风格。domain-name/pay的业务可以在未来长期的系统功能迭代过程中,慢慢的逐步的将8583报文转换为restful风格。如果原有业务长期没有变化,则保持为8583格式。

  5. 保持与BFF的长连接。

proxy_http_version 1.1;
proxy_set_header Connection "";
keepalive 16;
  1. 转发客户端真实IP
proxy_set_header X-Real-IP $remote_addr;
  1. 请求时,Nginx应该转发这些首部字段: Host, Accept, User-Agent, Connection, Keep-Alive, Content-Type, Content-Length。

  2. 响应时,Nginx应该转发这些首部字段:Connection, Keep-Alive, Cache-Control,Content-Type, Content-Length。

【BFF改造】

  1. 需要增加一个DispatcherServlet,用于从http post的request body获得8583报文,转交给BFF原有的解码器。

  2. 增加一个Header8583Filter,用于检查下面 8583 over https 设计中所要求的 HTTP 首部字段, 不合法时返回 400 状态码, 合法时设置响应首部。
    Accept应该为”application/pay8583“,User-Agent应该为”<device_name>-<app_name>-version“,Content-Type应该为”application/pay8583“,Cache-Control应该为” no-cache“。
    当BFF编排微服务, 发生了 Hessian 超时或其它意外异常时, 应当响应500状态码。 严禁将服务器异常堆栈信息返回终端设备。

  3. 待上线验证没问题后,逐步移除mina 框架。 改造后的方案不再使用 mina 框架, 而是利用了 Servlet 容器对于 Http 协议的支持。并且原本的大量的 TCP 短连接,已有私有云服务器 nginx 承接,转变为少量的 http 长连接。

  4. 禁用Cookie,BFF不需要HttpSession。

  5. 8583报文不需要改动,后续ms都不需要有任何改动。最大限度的减少开发的工程量。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容