魏东红,王其才,商 超
(中国电子科技集团公司 第五十四研究所,河北 石家庄 050000)
微服务架构的概念由Martin和James在2014年正式提出,有别于传统的单应用服务架构与SOA(Service-Oriented Architecture,面向服务架构)。单应用架构的所有业务逻辑及实现全部在一个工程中,开发方式简单,但耦合性强,随着系统的升级,复杂度也越来越高,后期维护成本较大[1];SOA将系统的逻辑功能进行服务化拆分,降低了服务之间的耦合性;微服务架构是在SOA的基础上逐渐发展而来,将系统的逻辑功能进一步细化拆分,变为多个高内聚、低耦合的微型服务,可由不同的团队、不同的编程语言、不同的设计模式、不同的存储数据库开发和维护,每个微服务使用独立的进程进行部署[2],微服务之间采用轻量级的通信机制进行数据交互。相比SOA,微服务的分解粒度更细、通信机制轻量化、开发迭代速度快、服务测试可实现自动化[3]。
微服务架构一般分为注册中心、微服务(含网关)、数据库等,如图1所示。
图1 微服务架构
鉴于目前存在的服务功能划分不清晰问题,本文探讨一种通用的Web系统设计架构,将微服务架构细化分解,能够满足大多数使用场景,如图2所示。
图2 Web系统架构设计
Web系统架构主要分为注册中心、网关、登录认证、反向代理、消息中间件、各类功能性微服务,贯穿服务访问全流程,微服务、注册中心、代理等均可以Docker容器的方式快速发布部署与启动[4]。
微服务通过注册中心有机结合在一起,未使用注册中心时,需要将调用系统的地址写入配置中,以便调用系统提供的服务接口。微服务启动时,向注册中心注册,注册中心会维护微服务的健康状态以及调用信息,接口调用时,系统无需事先知道对方的地址和端口等信息,通过与注册中心的交互,可获取对方微服务的信息,进行接口的调用,例如Spring Cloud中的Feign接口,只需配置对应的服务名即可。常用的注册中心有Zookeeper,Consul,Eureka,Nacos等。
反向代理将浏览器端的请求映射至对应的微服务或静态文件,获取前端静态文件(HTML,JS,CSS等)、通过Ajax交互数据、连接认证服务器均可通过代理进行地址映射,一般的软件设计中,采用Nginx代理。Nginx实现了负载均衡,在服务集群部署的情况下,多个微服务可分担负载,避免因为某个服务下线引起系统崩溃。
服务网关对Web浏览器的请求进行统一转发,将浏览器端的请求和后台微服务群体隔离,同时集成认证服务的配置,实现用户鉴权,未通过认证的请求重定向至登录界面,用户登录后,网关对浏览器请求进行转发,并将数据返回至浏览器呈现。鉴于服务网关的统一转发功能,可记录用户的操作日志,便于分析用户行为,监控请求及服务的运行情况,对客户端请求进行熔断和限流处理等。常用的服务网关有Spring Cloud Gateway,Kong,Dubbo Proxy等。
Web管理系统通常进行登录认证,网关登录认证可采用外部的认证服务,也可单独实现,由于系统中可能存在多个微服务具备管理页面,因此需要实现单点登录(SingleSignOn,SSO)功能,用户登录系统后,可获得整个系统相关服务的访问权限,访问互相信任的服务页面,无需二次登录,提升用户体验。登录认证可与网关相配合,常用的认证服务协议有CAS,OAuth2,WebAuth等。
消息中间件实现了微服务之间的解耦,同时满足应用服务的扩展需求,微服务之间可通过消息机制进行通信,服务发布者可直接将消息发送给消息中间件,无需等待处理消息的服务是否启动,且支持多个消息的消费者,减少了繁杂的、相似的代码,随后消息中间件将消息存放在若干队列中,消息的消费者读取消息队列后,对关注消息进行处理,目前常用的消息中间件有Activemq,Rabbitmq等。
事件通知类微服务主要负责监听写入消息中间件的事件,将事件转化为数据处理的通知(包括对数据进行处理、前端数据的推送呈现等),然后在消息中间件中发布消息主题与内容,订阅该主题的微服务可获取消息内容进行处理,这样做可以将事件产生与处理彻底解耦,方便数据处理方式的改进和替换。
页面类微服务主要包括页面相关的静态文件和数据推送相关服务,目前Nodejs,Webpack,Npm,Spring Boot等工具均能很好地实现前端服务的独立开发,当前比较流行的前端开发框架有Vue,Angular,React等[5],这些框架的出现使得开发更为便捷,易于实现前后端服务的分离。前后台分离能够使团队更加专注于前端或后端的开发,工作职责更加明确,有助于提升团队技术水平和研发能力。
数据处理类微服务主要负责系统的复杂数据处理,包含数据整合、算法、视图模型等。由于该类微服务需要经常进行复杂处理和计算,占用的资源较其他微服务多,因此需要部署在性能较高的节点,此类微服务是系统的核心,保证服务的稳定性、可靠性尤为重要,通常通过集群部署和负载均衡配置,缓解该类服务的运行压力。
数据访问类微服务主要负责数据库的持久化操作,进行数据存储、获取、简单统计等操作。该类服务直接面向数据库,可配置Hibernate,MyBatis,Spring JPA等持久化工具,简化程序,其接收其他微服务的数据访问请求,能够进行数据模型转换、存储数据和返回微服务所需的数据。
接口适配类微服务主要负责处理与外部系统或设施的接口,每个服务可进行单独配置,由于系统接口多种多样,数据也千差万别,因此接口适配类微服务数量繁多,对同一类别的数据,如何统一数据模型是降低系统复杂度的关键因素,接口适配一般为双向服务:(1)通过接口获取数据之后进行简单处理,然后将数据发送至数据处理类微服务或数据访问类微服务。(2)接收内部微服务的数据,将数据处理为外部系统所需格式,并通过接口进行数据发送。
下面以停车场监控为例,说明基于微服务的Web系统设计架构实现方式,系统架构如图3所示。
图3 停车场监控微服务架构
监视流程如下:
(1)用户在客户端访问停车场监控系统界面,访问请求通过Nginx代理至服务网关,服务网关通过约定的请求消息头判断用户是否已经登录,若未登录,则将请求重定向至认证服务提供的统一登录界面,并带有源请求路径信息。
(2)用户输入登录名和密码,并成功登录,页面随机跳转至停车场车位监控页面。
(3)停车场车位监控页面发送请求获取停车位和停车位占用信息,服务网关将请求转发至数据处理服务,数据处理服务调用数据访问服务接口从数据库获取数据,通过一定的方式处理后,将数据视图返回至监控界面,在前端生成各类视图。
(4)点开停车场的视频控制管理界面,由于用户已经登录系统,获得了相关系统的授权信息,可以直接访问视频控制界面,对视频设备进行控制,无需二次登录。
(5)当停车情况发生改变时,例如车辆驶入或离开停车位,传感器适配微服务接收传感器的变化数据,判断变化内容,根据变化内容生成事件,存入消息中间件,同时调用数据访问微服务将变化内容存入数据库中。事件通知微服务监听事件的发生,生成页面推送更新消息;Web微服务监听页面更新消息并将更新推送至前端监控页面,页面经过数据处理后显示变化信息。
(6)用户退出系统后,之前的登录信息在认证服务注销,此时监控页面、监控录像均不可查看。
目前微服务架构还存在多种待优化问题,本文通过将统一认证服务纳入Web系统架构,实现系统的单点登录功能,避免用户二次登录,将微服务按照功能分为服务网关、事件通知、数据处理、数据访问、接口适配,各类服务职责明确,边界清晰,有利于进行微服务的设计。微服务之间通过消息中间件的方式实现服务之间异步交互,使服务之间进一步解耦,并以停车场监控系统为例,对系统架构进行解释说明,为进行Web系统的开发提供了一种架构设计方案。