为了统一规范好系统与系统之间的接口调用关系,我们开发了“接口中心”这个服务。其主要作用是统一接口暴露,统一鉴权配置,统一日志记录,最后可以通过图形报表形成调用关系图。
那么我们在1.0版本的逻辑图如下:
接口中心搭建完毕后,基本解决了,服务与服务之间的接口统一管理等问题。
但是由于接口通讯太过于集中,导致请求高峰期接口中心可能宕机。这种集中化管理也违背了微服务的设计初衷。
待解决的问题:
1、如何让接口之间的调用与接口中心尽量解耦。
2、在微服务架构的前提下如何集中控制接口的鉴权问题,而做到尽量少的影响微服务的本身架构体系。
3、如何让调用方尽量不感知调用的鉴权过程。(因为接口能不能被访问是被调用方的事情,如我去张三家里串门,让不让我进门是张三的事情一样。)
我们尝试着通过下图解决这些问题,姑且叫2.0版本:
说明:
1、接口中心完成暴露和接口鉴权配置提交后统一放在redis上面。
2、由接口的发布方(服务B)完成鉴权和校验最后响应请求。
3、通过MQ异步的方式来实现日志记录,做到日志记录与接口请求解耦。
4、服务B 都引用接口中心的jar包来完成服务之间的调用。
另外一种处理方法类似dubbo的服务调度方式:
1、也是接口中心完成暴露和接口鉴权配置提交后统一放在redis上面。
2、由服务A来到redis拿到允许访问的接口地址,再向服务提供者发起请求。
3、任然通过MQ异步的方式来实现日志记录,做到日志记录与接口请求解耦。
最后是日志记录表:
CREATE TABLE `api_access_log` (
`log_id` int(11) NOT NULL AUTO_INCREMENT,
`request_id` varchar(32) NOT NULL COMMENT '请求id',
`api_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '接口编码',
`call_system_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '调用服务名称',
`public_system_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '被调用服务名称',
`api_call_link` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'API调用URI(含根路径)',
`api_public_link` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'API发布URI链接(含根路径)',
`http_req_type` varchar(10) DEFAULT NULL COMMENT 'http访问类型 get post ...',
`access_time` datetime DEFAULT NULL COMMENT '访问时间',
`access_duration` int(11) DEFAULT NULL COMMENT '访问时长(毫秒)',
`res_http_code` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '返回HTTP状态码',
`via_value` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '路由值'
PRIMARY KEY (`log_id`),
KEY `api_access_log_access_time_index` (`access_time`)
) ENGINE=InnoDB AUTO_INCREMENT=31741865 DEFAULT CHARSET=utf8mb4 COMMENT='访问日志表';
其中在微服务多层级调用中比较重要的是request_id,我们认为一个前端访问可能涉及到微服务中的多层逐级的请求,这种逐级的请求为了有可追溯性,我们定义request_id保持一致,通过日志表中的request_id和相关信息我们可以解析出一个请求过程。
注:如果我们将日志记录在es里面效率应该会更高!对于大量数据的处理es的优势比mysql高很多!
思考:接口中心对接口进行统一管理真的有意义吗?接口中心到底要达到的目的是什么?
事实上在长达一年半的接口中心使用过程中,我们并没有基于什么原因禁止或者限制某个服务不能访问某个接口,因为我们认为内部服务之间的访问是安全可信的,而整个集群服务对外的安全可以依赖于系统网关的鉴权,而不需要在接口中心来考虑。而真正需要鉴权、限流等操作的是来自外部系统的访问。而2.0版本虽然将鉴权的逻辑与接口中心解耦开了,但是被访问系统仍然需要耗时去判断访问接口的权限问题,这会导致每个接口都需要损耗一定的时间去判断访问权限,这是一定程度的对资源的浪费。如果如下图改一下会怎样?
我们可以增加的日志分析模块,我们认为接口访问的日志记录还是很有用处的。首先,通过日志记录可以找到一整串请求链,特别是微服务这种一个线程里面动辄几个到几十个对于其他服务的请求,在排查问题的时候必不可少。其次,日志记录还可以分析出每个接口的请求频率,这样就方便服务器资源的调配。
那么当服务越来越多,服务容量,服务资源的浪费等问题的逐步显现,对于信息化内部真正需要治理和关注的不是鉴权问题,而是资源的合理利用。此时需要一个对各个服务的使用情况进行分析和配置的“调度中心”来实施服务集群的管理,以提高集群的可用性和使用效率。而此时资源调度和服务治理的面向服务的架构逻辑“SOA”登场。