郑海山,刘燕文
(厦门大学 信息与网络中心,福建 厦门 361005)
随着信息化的建设与发展,高校信息化系统数量越来越多,系统越来越庞大,功能也越来越复杂[1],建设和运行维护模式是一个很大的挑战。高校信息化系统大部分基于传统的三层BS 架构,各个系统之间类似烟囱式结构,数据共享较为困难,一般需要借助数据交换平台进行数据共享[2]。有些高校基于面向服务体系结构(Service-oriented Architecture,SOA)的理念对数字校园进行改造[3-5]。过往的SOA 实现大部分依托于XML(Extensible Markup Language,可扩展标记语言)、SOAP(Simple Object Access Protocol,简单对象访问协议)、WSDL(Web Services Description Language,网络服务描述语言)等标准,系统整体较为庞大。近年来,基于API(Application Program Interface)的微服务架构开始流行起来,比如互联网公司普遍采用了基于API 的微服务架构[6-7]。基于API 的微服务架构[8]更为轻量级,开发维护较为简单。
信息化系统基于微服务开发存在诸多优点,例如可大批量部署,原先应用部署在同一台机器,横向扩展较为困难,使用API 开发后计算可以在多台服务器内分散。核心API 开发完成后,对于不同的终端比如PC、移动客户端、微信等调用均可实行一次开发,多次使用而无需改变业务功能,只需要调整前端显示逻辑即可。对于数据共享,基于API 提供可以克服原先数据库共享数据只能以只读方式共享的问题。对业务的操作逻辑通过调用API,可以做权限和数据校验等安全性判断,也可以对调用进行跟踪,实时性也更高。通过API 的版本化,可以提供多个版本共存,对外提供统一的接口,隐藏内部实现逻辑。通过统一的API 网关,业务也无需实现重复的验证、授权、缓存、熔断、日志等功能。然而现在存量信息系统的改造不是一朝一夕可以完成的。
本文分析了高校信息化系统的现状,并对信息化系统和数据共享存在的问题提出了解决方法,认为在保留原有所有模式的情况下,高校信息化系统应采取逐步迁移升级的方法尽快向API 架构迁移[9]。通过对开源API网关的测试、部署方法研究、测试应用编写,验证了基于微服务的开发模式更适应未来高校信息化的发展。
高校信息化系统大部分还是基于传统的三层BS 架构,各个系统由不同外包厂商开发,技术能力参差不齐,系统建设周期不同,上线时间不一,各个系统比较独立,属于烟囱式结构。而互联网公司由于自有开发团队,统一技术架构。互联网公司已经将大部分应用基于API 架构进行开发。高校信息化系统可分为两种类型:一种是类似教务系统、学工系统、人事系统、科研系统、财务系统等,这些业务系统业务较为复杂,业务大部分功能由业务部门管理员使用;另一种是网盘、即时通讯、自助打印等业务系统,这些业务系统定制化程度不高,功能较为简单,普通师生使用较多,有移动端,起步较晚。第一种系统一般采取高内聚的开发模式,由于管理员需要频繁查询调用数据,所以系统架构必须直接对数据库进行操作,数据在系统内流转,只有少部分结果数据需要共享给其他系统。而第二种相对独立,一般会采用技术更先进的API 架构开发,同时支持多个不同客户端。
高校的数据共享目前主要还在采用包括离线传递、数据库视图开放、共享库同步等机制。离线传递的实时性不高,数据使用无法管控。数据库视图开放需要数据库直接面对第三方业务系统开放,安全性较低。第三方业务系统的访问也会对数据库性能造成影响,数据使用过程无法管控。共享库同步存在同步周期时间问题,实时性不高,只能共享部分数据,第三方业务系统较难对数据进行更新。
高校的信息化系统应当尽快向API 迁移,但是对于第一种系统,要进行整体API 改造难度较大,成本很高,受益也很低。很多高校依赖第三方外包公司,改造进度受制于外包公司。老牌的外包公司存在较久,业务沉淀较深,应用开发较早,技术框架较老,更新需要较长周期。
所以较为可行的方案应当是逐步迁移。对于第二种的系统,应当采购技术较为先进,有API 开放功能的系统。对于第一种系统,如果无法整体迁移到API 架构,也应当尝试对部分业务功能开发API。高校目前在广泛开展一站式服务门户网站建设[10],一站式服务门户不再以业务来区分系统,而是以角色或服务来开发不同颗粒度的功能。通过管理功能和服务功能分开,面向管理人员的可采取原有模式,而面对受众较广的师生员工的需求开发出API,在一站式门户对外提供服务。
使用API 改造数据共享也可以解决数据拥有者对数据的授权问题。高校内数据可分为三种:第一种是公开的数据,诸如组织机构名称和代码,任何人应当均可通过API 访问;第二种为需要权限获取的代码,诸如教务系统某位教师的任课信息,应当可授权比如人事系统调用;第三种为师生员工的个人隐私数据,诸如消费记录、成绩等,应当可通过师生员工显式授权后开放给第三方调用。通过API 和OAuth2(Open Authorization v2,开放式授权第二版)的授权模式可以解决这些问题,促进高校内应用生态环境的健康发展。
在提供API 数据共享模式后,原有的包括离线传递、数据库视图开放、共享库同步也不会消失,以上三种共享方法也会存在一定的使用场景,因为API 倾向于传递较小的数据量,对于需要获取大量数据进行实时或离线分析不存在优势。
基于API 的微服务架构可以改变传统烟囱式架构在部署和扩展方面的局限性。微服务各个服务可以独立部署,服务可以使用不同的语言和数据库开发,对外隐藏实现细节并独立演化。然而新技术也会带来新问题,微服务服务数量增加,服务之间关系复杂。微服务的开发、测试、部署、接入服务平台、验证、授权、访问频率控制、缓存、状态、监控、熔断、日志、版本化、服务终止等一系列全生命周期管理问题都需要研究。通过引入API 网关[11],在一个集中的位置部署API 网关,可以解决以上问题。
基于API 的新应用系统应当尽量采用前后端完全分离的技术开发。前端指运行在浏览器进行页面展示的HTML、CSS、JavaScript 等代码,后端指运行在远程服务器内的业务逻辑。通过前后端完全分离,前后端工程师可以在约定好的API 接口上独立开发。前端展示可以适配PC 端和移动端等浏览器而无需修改后端业务逻辑代码。通过编写单页应用,前端所有代码均可独立缓存,加快渲染速度,前后端API 数据传输量小,减少用户的流量耗用。前后端分离增强了代码的可维护性,极大地提高了开发效率。
为了让师生员工可以将自己的数据对第三方应用进行授权,原有的统一身份认证除了提供SSO(Single Sign On,单点登录)功能外,还应当扩展出OAuth2 的授权功能。
API 的输出格式应当支持包括JSON、XML 等格式,并推荐使用JSON 较为轻量级的格式。
图1 基于API 网关开发的系统整体架构
图1 为基于API 网关开发的系统整体架构,在架构内,包含以下主要角色和功能:
(1)API 网关:提供API 接入、验证、授权、访问频率控制、缓存、状态、监控、熔断、日志、版本化、服务终止等一系列全生命周期管理功能。提供SSL 卸载。
(2)API 服务提供者:旧业务系统根据新需求开发出API,或者新开发的业务系统应当要求同步提供API。
(3)API 管理:对API 网关进行管理。
(4)认证方式提供者:高校原有的统一身份认证系统,并扩展OAuth2 功能。
(5)API 门户:统一的位置发布API,详细的说明文档对API 约定、调用方法、测试流程等进行说明。
(6)API 调用者:对API 服务提供者提供的API 进行消费。
(7)日志分析:对系统涉及到的所有服务进行日志记录和分析。
(8)监控:对API 的运行和性能指标进行监控。
(9)安全和规范:一系列API 提供者和调用者需要遵守的关于安全开发和安全提供数据的最佳实践细则。
相同功能的开源软件很多,对其进行选择以满足业务功能的最大化为原则。如果无法全部满足,应当选择只需通过少量扩展即可满足业务的开源软件。一般开源软件更新较快,必须时时跟踪开源软件的开发进度,并在一段时间后重新评估并选择是否进行切换迁移或者继续保留原软件。应当选择社区活跃度高、安全更新和功能开发及时的开源软件。表1 和表2 为常用API 开源软件的比较。
通过综合比较以上开源API 网关软件,我们最终选定了Kong。Kong 较为轻量级,功能基本上可以满足API 网关主要需求。Kong缺少的分析统计功能可以使用其他开源软件补充。
由于系统涉及到较多开源软件,操作系统层面有Ubuntu,API 网关为Kong,数据库为Cassandra、MySQL,缓存为Redis、Memcached,监控有Elasticsearch、Logstash、Kibana、Prometheus、Grafana、Icinga2,文档生成格式为MkDocs、Swagger Editor,测试API 提供者和消费者使用Apache2、Nginx、Python、Django、Flask。需要对所有开源软件进行安装和配置,还需要对所有系统进行安全加固,所以我们使用自动化部署工具Ansible 实现基础架构一键部署。
在部署时应当考虑安全性和各系统性能要求,对所有应用进行分析,规划好部署位置。为可横向扩展预留空间。由于各个软件之间交互复杂,在部署时应当根据最小权限原则规划严格的防火墙规则。Kong 管理端口只允许管理员IP 访问。API 只开放443 端口,强制要求HTTPS。API 服务提供者只允许API 网关和监控系统访问。所有后台监控和日志分析只允许管理员IP 访问。数据库和缓存只允许本机访问或者特定的服务器IP 访问。
表1 开源API 网关社区活跃度比较
表2 开源API 网关功能比较
Kong 提供有基本认证、密钥认证、OAuth2 认证、HMAC 认证、JWT 认证、LDAP 认证等方法,在高校内,可只使用密钥认证、OAuth2 认证和JWT 认证。对于获取类似高校整体组织架构、课程列表、教师授课列表等,可以直接使用密钥认证的模式。如果是需要师生员工授权的数据等则使用OAuth2 认证模式。如果开发前后端完全分离的应用则可使用JWT 认证。Kong 的OAuth2 认证需要我们自行实现认证和授权功能。
为了更安全,对API 消费者要求提供访问的服务器IP 地址,加入Kong 的IP 限制和ACL 控制内,提高系统的安全性。对于API 消费者请求的API,限制合适的访问频率和请求大小限制,以避免一定程度的数据泄露风险。
Kong 的统计和分析功能为非开源产品,所以需要自行根据日志做分析,由于Kong 有完善的日志,只需要配置Kong 发送日志到Elasticsearch 或者Prometheus 等开源软件,则可自行对Log 进行分析。同时日志也写入文本文件保存,方便今后使用大数据平台诸如Hadoop等分析。
对于API 消费者调用后端的服务,Kong 支持从HTTP Header 内的Host 字段、URL 的Path 路径字段和HTTP 方法3 个途径进行路由,由于API 还涉及版本不同,版本也需加入路由。如果使用Host 字段,调试不够方便,API 地图不够清晰。如果将API 版本使用HTTP Header 传递,对于API 消费者比较简单,只需要替换HTTP Header 无需更换URL Path 即可使用不同的API版本,然而也会导致API 地图不够清晰、API 提供者适配也较为麻烦的问题。为了简化架构,我们统一只使用Path 路径字段进行路由,同时API 的版本直接体现在URL 内,版本由API 提供者自行路由。
在API 挂接时,Kong 提供strip_path 变量控制传递到后端API 服务器是否带上路由的URL Path,比如API消费者访问/jwc/course_list,如果strip_path 为True 的话,后端API 服务器的地址则为/course_list,推荐所有API 路由均设置strip_path 为True,此项配置可以对后端API 服务器隐藏Kong API 地图信息,方便今后挂接到不同API 网关。
对于API 挂接的,API 提供者可以选择只挂接一个总的服务入口,或者将服务内的所有API 端点全部挂接到Kong,然而这势必造成Kong 配置数据膨胀,对于API的调节较为麻烦,为了简化操作,我们统一规定,每个API 提供者建议只提供2 类的服务,一类是使用密钥认证的API 族群,一类是使用OAuth2 的API 族群,这种情况下授权API 消费者只需对应不同的API 消费者授权不同的API 服务族群。当然,这样也造成了API 消费者可以消费某个URL Path 路径下面的所有API。所以对于特殊的API,也允许API 提供者挂接多个重复的API。表3 为厦门大学部分API 挂接路由示例。
表3 API 挂接路由示例
对于Kong 的使用,应当通读文档,对每个配置项均做测试,并找出符合自己学校需求的配置项。
API 网关实际上是API 提供者和消费者之间的桥梁,应当搭建完善的帮助网站,API 提供者可以在门户发布API 功能,消费者可以浏览API 功能。同时为提供者和消费者约定建议,遵循一定的规范。在书写API 文档时我们建议统一采用Swagger 文档格式。通过提供Swagger 文档,API 消费者可以无需编写代码,使用工具即可自动生成所使用编程语言的API 调用SDK,也可以即时在浏览器内做API 调用测试。对于API 的编码,由于API 实质上也是Web 应用程序,也会有Web 应用程序所有存在的安全弱点,所以我们提供了Web 应用程序安全编写的所有规范和检查点。
为了更方便让API 可以进行消费,API 门户应指导API 提供者编写Swagger 格式文档,方便API 消费者浏览和测试API,方便了API 提供者和API 消费者之间进行沟通。
API 提供者到API 网关之间的流量应当使用HTTPS加密,为了系统安全,应当只允许API 网关访问API 提供者服务器的HTTPS 端口。
API 的所有权限交由API 网关处理,API 提供者应当信任API 网关发送的任何信息,业务相关的OAuth2的ID 从API 网关获取。API 的版本也遵守Kong 的配置,在URL 内硬编码版本信息,返回的数据格式以JSON 为主。
API 消费者需要知道API 网关提供了哪些API,通过API 门户可以让API 消费者阅读API 列表,通过Swagger 提供的API 格式文档测试调用API。同时提供帮助文件,指导API 消费者对API 进行测试以及搭建Mock 服务器测试。指导API 消费者申请API 账户、申请提高调用频率等。
日志分析分为以下几种:
(1)信息安全等级保护合规的系统安全加固和攻击溯源准备,必须将所有服务器的日志保存到远程。具体实现为在所有服务器上安装Filebeat,把所有服务器相关系统日志写入Elasticsearch,使用Kibana 图形化界面分析查看和检索。
(2)所有业务数据,包括API 访问日志、Nginx 日志、Kong 日志,定期Logrotate 轮换日志,并使用Filebeat 写入Elasticsearch 数据库,可作为调试查错使用,同时所有业务日志每天拷贝一份到远程NFS 服务器以方便今后可能的Hadoop 大数据分析。
监控分为以下几种监控:
(1)监控所有服务器的CPU、内存、硬盘、进程、网络流量,使用Metricbeat、Packetbeat,传输进入Elasticsearch,可以分析系统性能,网络流量是否剧增等分析是否存在大量数据API 泄露。
(2)监控所有服务器的可用性。使用Icinga2,监控所有服务器的Ping、SSH 管理端口和Web 端口,在服务器出故障之前提前得到通知。
(3)监控API 提供者服务的可用性。通过在API 网关添加一个监控账户,授权可只读访问所有API,也可要求API 提供者提供特定的可用性状态API,使用Icinga2 定期对API 进行访问测试。
(4)监控各个API 调用的频率。通过将Kong 的日志传入到Elasticsearch,分析API 调用频率。可使用Kibana分析查看API 调用频率与设置的调用频率的差别,可以比较不同或相同业务内不同API 的调用频率,找出最受欢迎的API 服务等等。
厦门大学基于Kong 建立了API 网关,提供了API门户。同时也以API 提供者和API 消费者角色建立了应用,测试整个开发流程,实现了基于微服务开发模式的落地[12]。
以API 提供者角色从主数据中心内读取各种数据,完成了基于OAuth2 授权的在借图书、一卡通余额和消费记录、WIFI 上线下线提醒、教职员工工资查询、学生成绩查询、免费米饭消费查询等功能。
以API 消费者角色开发了免费米饭消费分析和微服务微信公众号,两个系统均采用前后端完全分离的架构,调用API 网关的数据展示给用户。在开发过程中,基于Kong 完善的日志,原先在单体应用内较难定位的各函数执行时间等参数,在日志层即可看到各个API 调用的频率、执行的时间,可以有针对性地对API 进行性能调优、缓存、查错等。
通过开发实践,我们验证了基于API 网关开发应用的流程,API 编写完成可以为各个不同应用开发者调用,提高了代码重用性,通过前后端完全分离,提高了开发速度,通过API 门户,为API 提供者和API 消费者之间搭建起了桥梁。同时,由于系统有完善的日志和监控,使得系统更为安全。
本文通过分析高校信息化系统的现状,给出了解决方法,并通过选择Kong API 网关,搭建了厦门大学API平台,建立了API 开发门户平台,搭建起API 提供者和API 消费者之间的桥梁,通过引入Elasticsearch、Prometheus 等开源软件填补Kong 开源版本没有提供的日志统计分析功能,并编写了免费米饭消费分析和微服务微信公众号,验证了新信息化系统开发模式的合理性。开源软件变化较快,应当时时跟踪多个不同的开源软件,以便进行迁移,目前架构没有使用到服务自发现等功能,今后应当加入Consul、etcd、Zookeeper 等服务自动发现机制,并最终过渡到基于服务网格的架构[13]。