微服务

传统开发中的景象

程序员们日以继夜,诠释着披星戴月的含义,却不断的沉沦在重复搭建环境、重复系统部署、重复环境验证、重复代码开发等等的炼狱之中,“感觉身体被掏空”的绝望如影随形。
大型软件项目已成为大量代码的随机而无序的堆积。工程师一旦完成项目,就恐避之不及,不愿再去碰自己几个月来夜以继日的劳动成果。

微服务架构

微服务的概念源于 2014 ,服务架构是一种架构模式,需要几个基础的服务治理组件相互协作,包括服务注册与发现、服务消费、负载均衡、断路器、智能路由、配置管理等。

Restful

REST — REpresentational State Transfer 表现层状态转移,是一种架构风格,不是技术体系。
URL定位资源,用HTTP动词(GET,POST,DELETE,PUT)描述操作。
即通过HTTP动词来实现资源的状态扭转:

  • GET 获取资源
  • POST 新建资源(也可用于更新资源)
  • PUT 更新资源
  • DELETE 删除资源,有的业务系统中,删除只做逻辑删除,即只设置资源为已删除状态。

GET、PUT、DELETE操作是幂等的,安全和幂等的意义在于:当某个操作没有达到预期的目标时,我们可以不停的重试这个操作,而不会对资源产生副作用。
创建操作可以使用POST,也可以使用PUT,区别在于POST是作用在一个集合资源之上的(/uri),而PUT操作是作用在一个具体资源之上的(/uri/xxx),可以理解为,如果URL可以在客户端确定那么就使用PUT,如果是在服务端确定那么就使用POST。
现在也有的设计只用GET和POST,把具体操作写在uri中。

幂等

在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“setTrue()”函数就是一个幂等函数,无论多少次执行其结果都是一样的。

保证幂等性主要是三点:
1.对于每个请求必须有一个唯一的标识
2.每次处理完请求之后,必须有一个记录标识这个请求处理过了
3.每次接收请求需要进行判断,判断之前是否处理过

CAP理论

任何分布式系统在一致性、可用性、分区容错性三方面不能兼得,最多得其二,因此任何分布式系统的设计只是在三者中的不同取舍。
Consistency(一致性):所有节点上数据时刻同步
Availability(可用性):在一定时间能响应客户端的请求
Partition tolerance(分区容错):允许出现网络分区

分区

分区是指网络分区,分布式系统中各节点不再连通。一个分布式系统里面,节点组成的网络本来应该是连通的。然而可能因为一些故障,使得有些节点之间不连通了,整个网络就分成了几块区域,数据就散布在了这些不连通的区域中。
当一个数据项只在一个节点中保存,那么分区出现后,和这个节点不连通的部分就访问不到这个数据了。这时分区就是无法容忍的。提高分区容忍性的办法就是一个数据项复制到多个节点上。
然而,把数据复制到多个节点会带来一致性的问题。要保证一致,每次写操作就都要等待全部节点写成功,而这等待又会带来可用性的问题。
总的来说就是,数据存在的节点越多,分区容忍性越高,但要复制更新的数据就越多,一致性就越难保证。为了保证一致性,更新所有节点数据所需要的时间就越长,可用性就会降低。
实际上这在分布式系统中一般认为P是必须的,所以AC需要权衡。
满足AC意味着网络分区不能发生;而当存在网络分区时,将不再同时保证AC。有一个等价的理论:在一个不可靠的分布式环境中,无法同时满足活性(A)和安全性(C)。

微服务实践

服务拆分原则:
(1)横向拆分。按照不同的业务域进行拆分,形成独立的业务领域微服务集群。
(2)纵向拆分。把一个业务功能里的不同模块或者组件进行拆分。把公共组件拆分成独立的原子服务,下沉到底层,形成相对独立的原子服务层。
做好微服务的分层:梳理和抽取核心应用、公共应用,作为独立的服务下沉到核心和公共能力层,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
微服务的拆分力度需与具体业务相结合,总的原则是服务内部高内聚,服务之间低耦合

微服务在实践上根据业务域来拆分出微服务,根据功能拆分出可被组合的功能模块。

微服务架构是一种架构模式或者架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

微服务vs传统开发:
部署方式不同,在微服务上自动化运维不可不上。

如何解决微服务架构中的身份验证问题?
http://mt.sohu.com/20161221/n476556655.shtml

模块化与微服务

正确的组织方式是:独立出来各个业务无关功能的静态模块或动态服务,方便各项目的各子系统快速集成。包括:短信发送功能,数据库模块,权限验证功能,公共方法模块等。保持模块功能单一性,使工程不引入无关的功能模块。
阿里云中也提供收费的短信发送服务。
独立服务不会出现包冲突,独立模块不用单独部署服务。微服务是加强了的模块化。
最终策略:优先使用Maven模块化组合,当模块化不能满足时,再升级模块为微服务。

模块化还是微服务 – 为什么说大部分团队微服务化都走入了陷阱
http://www.sohu.com/a/149458799_256833

当系统需要提升处理能力时,可选择重置扩展架构和水平扩展架构,

心得:
微服务架构,需要每个人完整完善的完成相关服务。
不同的语言和开发环境对编码过程中的严谨程度要求不一样。
前后端分离,要根据数据存储特点,数据传输效率定义接口。
在编码前要有充分反复的需求分析、开发设计和程序设计。
不要过度设计,利用程序自动化,减少和局部化手工工作,减少代码重复冗余。
注明采用特殊设计或特殊编码方式的原因。
不要留下设计和技术债务。

对服务四种分类

不同服务迁移的优先级不同:

  • 基础服务,是一些基础组件,与具体的业务无关。比如:短信服务、邮件服务。最容易摘出来做微服务,是第一优先级分离出来的服务。
  • 业务服务,是一些垂直的业务系统,只处理单一的业务类型,比如:风控系统、积分系统、合同系统。这类服务职责比较单一,根据业务情况来选择是否迁移,比如突然有需求对积分系统进行大优化,则趁机将积分系统进行改造,是第二优先级分离出来的服务。
  • 前置服务,前置服务一般为服务的接入或者输出服务,比如网站的前端服务、app 的服务接口,是第三优先级分离出来的服务。
  • 组合服务,组合服务是涉及到了具体的业务,比如买标过程,需要调用很多垂直的业务服务,这类的服务一般放到最后再进行微服务化架构来改造,因为这类服务最为复杂,除非涉及到大的业务逻辑变更,否则是不会轻易进行迁移。

每个微服务都有自己独立的数据库,那么后台管理的联合查询怎么处理?有如下三种处理方案:

  • 严格按照微服务的划分来做,微服务相互独立,各微服务数据库也独立,后台需要展示数据时,调用各微服务的接口来获取对应的数据,再进行数据处理后展示出来,这是标准的用法,也是最麻烦的用法。
  • 将业务相关的表放到一个库中,将业务无关的表严格按照微服务模式来拆分,这样既可以使用微服务,也避免了数据库各种切换导致后台统计难以实现,是一个折中的方案。
  • 数据库严格按照微服务的要求来切分,以满足业务高并发,实时或者准实时将各微服务数据库数据同步到 NoSQL 数据库中,在同步的过程中进行数据清洗,用来满足后台业务系统的使用,推荐使用 Mongodb、Hbase 等。

开放API接口签名验证,让你的接口从此不再裸奔
https://blog.csdn.net/qq_18495465/article/details/79248608

使用Spring Cloud Gateway替换Zuul的时候发现Swagger并不支持以WebFlux为底层的Gateway,无法集成,运行报错。
https://blog.csdn.net/ttzommed/article/details/81103609

微服务中数据库访问的解决方案
保持每个微服务的持久化数据是私有的并且只能通过该服务的API访问。一个服务的数据库实际上作为该服务实现的一部分,它不能直接地被其它服务访问。通过另一个服务的api来访问它的数据。
保持服务持久化数据的私有有一些不同的方式,可以使用下面的三种方式:
Private-tables-per-service —— 每个服务有一个只能被该服务访问的表集。
Schema-per-service —— 每个服务有一个私有的数据库schema。
Database-server-per-service —— 每个服务有自己的数据库服务器。
Private-tables-per-service和schema-per-service的开销是最低的。使用schema-per-service比较有吸引力,因为该方式让所有权比较清楚。某些高吞吐量服务可能需要它们自己的数据库服务器。创建一些边界壁垒来加强模块化是个好主意。例如,可以给每个服务分配不同的数据库用户ID,并且使用数据库访问控制机制比如授权。没有某种边界壁垒来实施封装,开发人员总会被诱惑去绕过某个服务的API而去直接访问它的数据。

https://www.jianshu.com/p/cd726b32342e

发表评论