主题:微服务的安全认证
一、认识微服务
1.1 微服务的出道
软件架构(Software Architecture)是有关软件整体结构与组件的抽象描述。
根据软件系统在运行期的表现风格和部署结构,可以粗略地将其划分为两大类:“单体架构”(Monolithic Architecture)、“分布式架构”(Distributed Architecture)。
四个时期:单体结构、垂直架构、SOA架构、微服务架构
(A)单体架构
当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。这种将所有功能都部署在一个web容器中运行的系统就叫做单体架构(也叫:巨石型应用)。
<span style="font-size:14pt;">简单单体模式</span>
代码层面没有拆分,所有的业务逻辑都在一个项目(Project)里打包成一个二进制的编译后文件,通过这个文件进行部署,并提供业务能力。最典型的就是LAMP系统(Linux+PHP+Apache+MySQL),这种部署结构过于庞大,导致业务系统启动很慢。
随着网站的上线,访问量逐步上升,单台机器的性能遇到瓶颈的时候,最先采取的是:web 服务器和数据库服务器拆分开来,这样做的话不仅提高了单机的负载能力,也提高了整个系统的容灾能力。
随着访问量的继续不断增加,单台应用服务器已经无法满足我们的需求。 假设数据库服务器还没有遇到性能问题,那我们可以通过增加应用服务器的方式来将应用服务器集群化,这样就可以将用户请求分流到各个服务器中,从而达到继续提升系统负载能力的目的。此时各个应用服务器之间没有直接的交互,他们都是依赖数据库各自对外提供服务。
集群架构(属于水平拓展) 相当于把同一个项目部署到多个服务器上(相当于复制备份),然后通过负载均衡服务器nginx将请求分别均衡的派发到不同的tomcat服务器上,不同服务器上运行的是同一个web项目。
特点:
1、所有的功能集成在一个项目工程中。
2、所有的功能打一个war包部署到服务器。
3、通过部署应用集群和数据库集群来提高系统的性能。
优点:
项目架构简单,前期开发成本低,周期短,小型项目的首选。
缺点:
1、全部功能集成在一个工程中,对于大型项目不易开发、扩展及维护。
2、单点容错率低,并发能力差。
<span style="font-size:14pt;">垂直架构</span>
当访问量逐渐增大,单一应用无法满足需求,此时为了应对更高的并发和业务需求,我们根据业务功能对系统进行拆分。
<span style="color: blue; font-size: 12pt">MVC 模式</span>
系统内每个模块的功能组件按照不同的职责划分为模型(Model)、视图(View)、控制器(Controller)等角色,并以此来组织研发实现工作,整个系统由多个模块组成,每个模块又由这种不同的部分组成。
SpringMVC的流程简略示意图:
利用框架可以简化各层的开发:表现层使用SpringMVC或者Struts2,持久层使用Mybatis或Hibernate,使用spring管理表现层,业务层和持久层三层之间的关系。
<span style="color: blue; font-size: 12pt">前后端分离模式</span>
将前后端代码耦合的设计改为前端逻辑和后端逻辑独立编写实现的处理模式;
只要数据接口保持稳定不变,那么前后端系统可以各自独立发展和维护。目前最主流的三种前端开发框架(React、AngularJS、Vue),都遵循着这种设计理念。
特点:
1、以单体结构规模的项目为单位进行垂直划分,一个大项目拆分成一个一个单体结构项目。
2、项目之间的接口多为数据同步功能,如:数据库之间通过网络接口进行数据库同步。
优点:
1、系统拆分实现了流量分担,解决了并发问题
2、可以针对不同模块进行优化
3、方便水平扩展,负载均衡,容错率提高
4、系统间相互独立
缺点:
1、服务之间相互调用,如果某个服务的端口或者ip地址发生改变,调用的系统得手动改变
2、搭建集群之后,实现负载均衡比较复杂
(B)分布式架构(RPC)
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式调用是关键。
分布式架构就是多个子系统互相协作才能完成整个业务流程,系统之间需要进行通信。分布式系统作为一个整体对用户提供服务,而整个系统的内部的协作对用户来说是透明的,用户就像是只使用一个系统 一样。分布式系统中的多台计算机之间在空间位置上可以随意分布,同时,机器的分布情况也会随时变动。
RPC(Remote Procedure Call)它是一种进程间通信方式,允许像调用本地服务一样调用远程服务, ——从远程主机调用一个过程/函数。 两台服务器A、B,分别部署不同的应用a,b。当A服务器想要调用B服务器上应用b提供的函数或方法的时候,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义传达调用的数据。 2006年之后,随着移动互联网的发展,各种智能终端的普及,远程分布式调用已经成为主流,RPC框架也如雨后春笋般诞生,开源和自研的RPC框架的普及标志着传统垂直应用架构时代的终结。
分布式的演进
分布式架构的应用
- 分布式文件系统
例如:出名的有 Hadoop 的 HDFS, 还有 google的 GFS , 淘宝的 TFS 等
- 分布式缓存
例如:memcache , hbase, mongdb 等
- 分布式数据库
例如:mysql, mariadb, postgreSql 等
……
优点:
将基础服务进行了抽取,系统间相互调用 (RPC Remote Procedure Call 远程过程调用),提高了代码复用和开发效率
<span style="font-size:14pt;">面向服务架构(SOA)</span>
分布式出现的问题
服务越来越多,需要管理每个服务的地址
调用关系错综复杂,难以理清依赖关系
服务过多,服务状态难以管理,无法根据服务情况动态管理
<span style="color: blue; font-size: 15pt">资源调度和治理中心(SOA Service-Oriented Architecture)</span>
SOA( 面向服务架构),是一种开发思想 ,是一种松耦合框架,不是一种具体的开发技术,让软件超越开发语言
SOA 要做什么?
1、服务注册中心,实现服务自动注册和发现,无需人为记录服务地址
2、服务自动订阅,服务列表自动推送,服务调用透明化,无需关心依赖关系
3、动态监控服务状态监控报告,人为控制服务状态
SOA中有一个服务注册中心,所有的服务都会在这里进行注册,表明自己提供了哪些服务。当一个请求到来时,会先负载均衡,分流到某个具体的服务器,服务器在调用后端服务的时候,会先去服务注册中心获取数据,缓存到本地并查找服务地址,最后才是真正的远程服务调用(RPC SOA的具体实现方式)。
缺点:
服务间会有依赖关系,一旦某个环节出错会影响较大
服务关系复杂,运维、测试部署困难
<span style="font-size:14pt;">微服务架构(MSA)</span>
Martin Fowler与James Lewis于2014年共同提出 微服务架构思想 的文章—《Microservices》
简而言之,微服务架构风格是一种将单个应用程序开发为一套小型服务的方法,每个小型服务都在自己的流程中运行,并与轻量级机制(通常是HTTP资源API)进行通信。这些服务围绕业务功能构建,可通过全自动部署机制独立部署。这些服务至少集中管理,可以用不同的编程语言编写,并使用不同的数据存储技术。 ——————— 来自google无责任翻译
<center>
<span style="color: blue;font-size: 17pt" >
** 微服务就是一个轻量级的服务治理方案 **
</span>
<span style="color: blue; font-size: 17pt" >
** 是SOA思想的一种更加简单、轻便、敏捷的实现 **
</span>
<span style="color: green; font-size: 14pt" >
** 微服务架构 = 80%的SOA服务架构思想 + 100%的组件化架构思想 + 80%的领域建模思想 **
</span>
</center>
微服务的特点
-
按照业务划分成独立运行的程序,即服务单元
根绝Martin Fowler的定义,微服务的“微”是按照业务划分。传统的软件开发模式通常由UI团队、服务端团队数据库团队和运维团队构成,并相应的将软件按照职能划分为各个模块。通常开发人员都是各司其职,很少能跨职能去工作。如果是按照业务来划分服务,每个服务都要独立的UI、服务端、数据库和运维,所以就需要跨职能团队,一个团队负责一个服务的所有工作。当这个负责这个服务的团队只有1~2人的时候,就对开发人员提出了更高的要求。
-
服务之间通过HTTP协议互相通信
微服务单元独立部署,并运行在各自的进程中,微服务单元之间的通信方式一般倾向于使用HTTP这种简单的通讯机制,更多的时候是使用Restful API。不同服务可以采用不同语言,部署在不同平台。
服务与服务之间也可以通过轻量级的消息总线来通信,例如RabbitMQ,Kafka等。通过发送消息或者订阅消息来达到服务于服务之间的通信的目的。(弊端:会有失败)
通信的数据格式:JSON、XML、Protobuf (序列化后的二进制数据)
-
微服务的数据库独立
服务与服务之间是无耦合,数据库也是独立的。典型的微服务架构就是每个微服务都有自己独立的数据库,数据库之间没有任何联系。单个业务的数据量少,易于维护和迁移。每个数据库所使用的数据存储技术可以根据业务需要来选择。
- 自动化部署
可以用不同的编程语言
可以用不同的存储技术
服务集中化管理
微服务是一个分布式系统
微服务的优点
优点:
1、服务拆分粒度更细,有利于资源重复利用,提高开发效率。
2、可以更加精准的制定每个服务的优化方案,提高系统可维护性。
3、微服务架构采用去中心化思想,服务之间采用RESTful等轻量协议通信,相比ESB更轻量。
4、适用于互联网时代,产品迭代周期更短。
微服务的设计原则
四个原则推荐给大家:
-
(1) AKF拆分原则
AKF扩展立方体(参考《The Art of Scalability》),是一个叫AKF的公司的技术专家抽象总结的应用扩展的三个维度。理论上按照这三个扩展模式,可以将一个单体系统,进行无限扩展。
X 轴 :指的是水平复制,很好理解,就是讲单体系统多运行几个实例,做个集群加负载均衡的模式。
Z 轴 :是基于类似的数据分区,比如一个互联网打车应用突然或了,用户量激增,集群模式撑不住了,那就按照用户请求的地区进行数据分区,北京、上海、四川等多建几个集群。
Y 轴 :就是我们所说的微服务的拆分模式,就是基于不同的业务拆分。
-
(2) 前后端分离
推荐的模式是最好直接采用物理分离的方式部署,进一步促使进行更彻底的分离。不要继续以前的服务端模板技术,比如JSP ,把Java JS HTML CSS 都堆到一个页面里,稍复杂的页面就无法维护。这种分离模式的方式有几个好处:
- 前后端技术分离,可以由各自的专家来对各自的领域进行优化,这样前端的用户体验优化效果会更好。
- 分离模式下,前后端交互界面更加清晰,就剩下了接口和模型,后端的接口简洁明了,更容易维护。
- 前端多渠道集成场景更容易实现,后端服务无需变更,采用统一的数据和模型,可以支撑前端的web UI\ 移动App等访问。
-
(3) 无状态服务
对于无状态服务,首先说一下什么是状态:如果一个数据需要被多个服务共享,才能完成一笔交易,那么这个数据被称为状态。进而依赖这个“状态”数据的服务被称为有状态服务,反之称为无状态服务。
那么这个无状态服务原则并不是说在微服务架构里就不允许存在状态,表达的真实意思是要把有状态的业务服务改变为无状态的计算类服务,那么状态数据也就相应的迁移到对应的“有状态数据服务”中。
场景说明:例如我们以前在本地内存中建立的数据缓存、Session缓存,到现在的微服务架构中就应该把这些数据迁移到分布式缓存中存储,让业务服务变成一个无状态的计算节点。迁移后,就可以做到按需动态伸缩,微服务应用在运行时动态增删节点,就不再需要考虑缓存数据如何同步的问题。
-
Restful通信风格
作为一个原则来讲本来应该是个“无状态通信原则”,在这里我们直接推荐一个实践优选的Restful 通信风格 ,因为他有很多好处:
- 无状态协议HTTP,具备先天优势,扩展能力很强。例如需要安全加密是,有现成的成熟方案HTTPS可用。
- JSON 报文序列化,轻量简单,人与机器均可读,学习成本低,搜索引擎友好。
- 语言无关,各大热门语言都提供成熟的Restful API框架,相对其他的一些RPC框架生态更完善。
当然在有些特殊业务场景下,也需要采用其他的RPC框架,如Thrift、Avro-rpc、Grpc。但绝大多数情况下Restful就足够用了。
微服务应用平台的运行视图
微服务容器
微服务带来的难题
- 微服务的复杂度
- 分布式事物
- 服务的划分
- 服务的部署
1.2 第一代微服务架构
[图片上传失败...(image-f835a6-1551540278906)]
[图片上传失败...(image-d62dd3-1551540278906)]
微服务工具包,为开发者提供了在分布式系统的配置管理、
服务发现、断路器、智能路由、微代理、控制总线等开发工具包
Spring Cloud包含了多个子项目,比如:Spring Cloud Config、
Spring Cloud Netflix、Spring Cloud CloudFoundry、
Spring Cloud AWS、Spring Cloud Security、Spring Cloud Commons、
Spring Cloud Zookeeper、Spring Cloud CLI等项目
[图片上传失败...(image-a0dcc7-1551540278906)]
这是一个完整的Spring Cloud生态简图。
Spring Cloud是一个基于Spring Boot实现的微服务架构开发工具。它为微服务架构中涉及的服务治理、断路器、负载均衡、配置管理、控制总线和集群状态管理等操作提供了一种简单的开发方式。
1、外部或者内部的非Spring Cloud项目都统一通过API网关(Zuul)来访问内部服务。
2、网关接收到请求后,从注册中心(Eureka)获取可用服务。
3、由Ribbon进行均衡负载后,分发到后端的具体实例。
4、微服务之间通过Feign进行通信处理业务。
5、Hystrix负责处理服务超时熔断。
6、Turbine监控服务间的调用和熔断相关指标。
(图中没有画出配置中心,配置中心管理各微服务不同环境下的配置文件。)
二、安全认证
2.1 什么是认证?
2.2 常见的认证方案
三、微服务安全认证方案
安全认证方面,我们基于Spring Security结合OAuth2再加上JWT (Json Web Token)做安全令牌,实现统一的安全认证与鉴权,使得微服务之间能够按需隔离和安全互通。后续在统一认证和权限方面我们产品会陆续推出较完善并且扩展性良好的微服务组件,可以作为微服务平台的公共的认证和鉴权服务。 再啰嗦一句,认证鉴权一定是个公共的服务,而不是多个系统各自建设。
3.1 Spring Boot Security
现在的好多项目都是基于APP移动端以及前后端分离的项目,之前基于Session的前后端放到一起的项目已经慢慢失宠并淡出我们视线,尤其是当基于Spring Cloud的微服务架构以及Vue、React单页面应用流行起来后,情况更甚。为此基于前后端分离的项目用户认证也受到众人关注的一个焦点,不同以往的基于Session用户认证,基于Token的用户认证是目前主流选择方案(至于什么是Token认证,网上有相关的资料,大家可以看看),而且基于Java的两大认证框架有Apache Shiro和Spring Security,我在此就不讨论孰优孰劣的,大家可自行百度看看,本文主要讨论的是基于Spring Security的用户认证。
3.1.1 什么是Spring Boot Security
3.1.2 微服务案例展示
3.2 Spring Cloud OAuth2
3.2.1 什么是OAuth2?
3.2.2 OAuth2模型初探
3.3 Spring Security OAuth2 + JWT
3.3.1 什么是JWT?
3.3.2 微服务案例展示
3.4 Spring Security OAuth2 + JWT+Redis
3.4.1 什么是Redis?
3.4.2 微服务案例展示
四、综合案例展示
4.1 Spring Cloud 微服务架构
4.2 使用Spring Cloud构建微服务的综合案例
附录
1、资源链接
2、参考文章
[1] 微服务的4个设计原则和19个解决方案 http://server.51cto.com/Micro-551054.htm
[2] 图解分布式架构 https://www.cnblogs.com/dump/p/8125539.html
[3] 负载均衡基础知识 (https://www.cnblogs.com/danbing/p/7459224.html) https://www.cnblogs.com/danbing/p/7459224.html
[4] Martin Fowler提出微服务 https://martinfowler.com/articles/microservices.html
[5] 引领新未来SOA服务框架,未来发展的方向 https://blog.csdn.net/u011687186/article/details/52126212
[6] 什么是分布式系统,如何学习分布式系统 https://www.cnblogs.com/xybaby/p/7787034.html
[7] Web Service学习https://www.cnblogs.com/xdp-gacl/p/4048937.html
[8] 什么是微服务架构?微服务架构与SOA架构区别 https://www.shsxt.com/it/java/1299.html
[9] 微服务数据管理(译):每个服务一个数据库模式 https://www.jianshu.com/p/cd726b32342e
[10] 微服务架构下的数据一致性保证 https://www.cnblogs.com/duanxz/p/7866516.html