什么是微服务,第1张

什么是微服务

微服务架构的系统是一个分布式的系统,按业务进行划分为独立的服务单元,解决单体系统的不足,同时也满足越来越复杂的业务需求。

一单体架构

11什么是单体架构 

在软件设计的时候经常提到和使用经典的3层模型,即表现层,业务逻辑层,数据访问层。虽然在软件设计中划分了3层模型,但是对业务场景没有划分,一个典型的单体架构就是将所有的业务场景的表现层,业务逻辑层,数据访问层放在一个工程中最终经过编译,打包,部署在一台服务器上。此时服务架构如图: 

12单体架构存在的不足 

在小型应用的初期,访问量小的时候这种架构的性价比还是比较高的,开发速度快,成本低,但是随着业务的发展,逻辑越来越复杂,代码量越来越大,代码得可读性和可维护性越来越低。用户的增加,访问量越来越多单体架构的应用并发能力十分有限。可能会有人想到将单体应用进行集群部署,并增加负载均衡服务器,再来个缓存服务器和文件服务器,数据库再搞个读写分离。这种架构如图:

这种架构虽然有一定的并发能力,及应对一定复杂业务,但是依然没有改变系统为单体架构的事实。大量的业务必然会有大量的代码,代码得可读性和可维护性依然很差。如果面对海量的用户,它的并发能力依然不够。基于以上单体架构系统的不足,提出了微服务架构。

二微服务

21什么是微服务 

说了这么多现在来看看到底什么是微服务。微服务最初是由Martin Fowler提出来的他的理解如下:

     微服务架构就是将单一程序开发成一个微服务,每个微服务运行在自己的进程中,并使用轻量级的机制通信,通常是HTTP RESTFUL API。这些服务围绕业务能力来划分,并通过自动化部署机制来独立部署。这些服务可以使用不同的编程语言,不同数据库,以保证最低限度的集中式管理。

1

总结起来微服务就是将一个单体架构的应用按业务划分为一个个的独立运行的程序即服务,它们之间通过HTTP协议进行通信(也可以采用消息队列来通信,如RoocketMQ,Kafaka等),可以采用不同的编程语言,使用不同的存储技术,自动化部署(如Jenkins)减少人为控制,降低出错概率。服务数量越多,管理起来越复杂,因此采用集中化管理。例如Eureka,Zookeeper等都是比较常见的服务集中化管理框架。

22微服务的优势 

1)将复杂的业务拆分成多个小的业务,每个业务拆分成一个服务,将复杂的问题简单化。利于分工,降低新人的学习成本。 

2)微服务系统是分布式系统,业务与业务之间完全解耦,随着业务的增加可以根据业务再拆分,具有极强的横向扩展能力。面对搞并发的场景可以将服务集群化部署,加强系统负载能力。 

3)服务间采用HTTP协议通信,服务与服务之间完全独立。每个服务可以根据业务场景选取合适的编程语言和数据库。 

4)微服务每个服务都是独立部署的,每个服务的修改和部署对其他服务没有影响。

23微服务和SOA的关系 

SOA即面向服务的架构,SOA是根据企业服务总线(ESB)模式来整合集成大量单一庞大的系统,微服务可以说是SOA的一种实现,将复杂的业务组件化。但它比ESB实现的SOA更加的轻便敏捷和简单。

简单地说,微服务架构就是以业务域或业务功能为边界,将一个大而全的应用拆分为可以独立开发,独立部署,独立测试,独立运行的一组小的应用,并且使用轻量级,通用的机制在这组应用间进行通信。

主流的微服务包括:

1、SpringCloud

Spring Cloud , 来自Spring,具有Spring 社区的强大支撑,还有Netflix强大的后盾与技术输出。Netflix作为一家成功实践微服务架构的互联网公司在几年前就把几乎整个微服务框架栈开源贡献给了社区,这些框架开源的整套服务架构套件是Spring Cloud的核心。

- Eureka:服务注册发现框架;

- Zuul:服务网关;

- Karyon:服务端框架;

- Ribbon:客户端框架;

- Hystrix:服务容错组件;

- Archaius:服务配置组件;

- Servo:Metrics组件;

- Blitz4j:日志组件;

2、Dubbo

Dobbo是一个分布式服务框架,是阿里开放的微服务化治理框架,致力于提高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。其核心部分(官网)

- 远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求-响应”模式的信息交换方式;

- 集群容错: 提供基于接口方法的透明远程过程调用,包括多协议支持,以及软负载均衡,失败容错,地址路由,动态配置等集群支持;

- 自动发现: 基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。

Dubbo 也是采用全 Spring 配置方式,透明化接入应用,对应用没有任何 API 侵入,只需用 Spring 加载 Dubbo的配置即可,Dubbo 基于 Spring 的 Schema 扩展进行加载。当然也支持官方不推荐的 API 调用方式。

3、lstio

lstio 作为用于微服务聚合层管理的新锐项目,是Google、IBM、Lyft(海外共享出行公司、Uber劲敌),首个共同联合开源的项目,提供了统一的连接,安全,管理和监控微服务的方案。

目前首个测试版是针对Kubernetes环境的,社区宣称在未来几个月内会为虚拟机和Cloud Foundry 等其他环境增加支持。lstio将 流量管理添加到微服务中,并为增值功能(如安全性、监控、路由、连接管理和策略)创造了基础。

- HTTP、gRPC 和 TCP 网络流量自动负载均衡;

- 提供了丰富的路由规则,实现细颗粒度的网络流量行为控制;

- 流量加密、服务件认证,以及强身份声明;

- 全范围(Fleet-wide)的策略执行;

- 深度遥测和报告。

将一个单体应用拆分成一组微小的服务组件,每个微小的服务组件运行在自己的进程上,组件之间通过如RESTful API这样的轻量级机制进行交互,这些服务以业务能力为核心,用自动化部署机制独立部署,另外,这些服务可以用不同的语言进行研发,用不同技术来存储数据

通过以上的定义描述,我们可以基本确定给出微服务的节特征:

用微服务来进行实践到生产项目中,首先要考虑一些问题。比如下图的微服务业务架构:

在上图图表展示的架构图中,我们假设将业务商户服务A、订单服务B和产品服务C分别拆分为一个微服务应用,单独进行部署。此时,我们面临很多要可能出现的问题要解决,比如:

1、客户端如何访问这些服务?

2、每个服务之间如何进行通信?

3、多个微服务,应如何实现?

4、如果服务出现异常宕机,该如何解决?

以上这些都是问题,需要一个个解决。

在单体应用开发中,所有的服务都是本地的,前端UI界面,移动端APP程序可以直接访问后端服务器程序。

现在按功能拆分成独立的服务,跑在独立的进程中。如下图所示:

此时,后台有N个服务,前台就需要记住管理N个服务,一个服务 下线 更新 升级 ,前台和移动端APP就要重新部署或者重新发包,这明显不服务我们拆分的理念。尤其是对当下业务需求的飞速发展,业务的变更是非常频繁的。

除了访问管理出现困难以外,N个小服务的调用也是一个不小的网络开销。另外,一般微服务在系统内部,通常是无状态的,而我们的用户在进行业务操作时,往往是跨业务模块进行操作,且需要是有状态的,在此时的这个系统架构中,也无法解决这个问题。传统的用来解决用户登录信息和权限管理通常有一个统一的地方维护管理(OAuth),我们称之为授权管理。

基于以上列出的问题,我们采用一种叫做网关(英文为API Gateway)的技术方案来解决这些问题,网关的作用主要包括:

网关(API Gateway)可以有很多广义的实现办法,可以是一个软硬一体的盒子,也可以是一个简单的MVC框架,甚至是一个Nodejs的服务端。他们最重要的作用是为前台(通常是移动应用)提供后台服务的聚合,提供一个统一的服务出口,解除他们之间的耦合,不过API Gateway也有可能成为 单点故障 点或者性能的瓶颈。

最终,添加了网关(API Gateway)的业务架构图变更为如下所示:

所有的微服务都是独立部署,运行在自己的进程容器中,所以微服务与微服务之间的通信就是IPC(Inter Process Communication),翻译为进程间通信。进程间通信的方案已经比较成熟了,现在最常见的有两大类: 同步调用、异步消息调用

同步调用

同步调用比较简单,一致性强,但是容易出调用问题,性能体验上也会差些,特别是调用层次多的时候。同步调用的有两种实现方式:分别是 REST RPC

基于REST和RPC的特点,我们通常采用的原则为: 向系统外部暴露采用REST,向系统内部暴露调用采用RPC方式。

异步消息的方式在分布式系统中有特别广泛的应用,他既能减低调用服务之间的耦合,又能成为调用之间的缓冲,确保消息积压不会冲垮被调用方,同时能保证调用方的服务体验,继续干自己该干的活,不至于被后台性能拖慢。需要付出的代价是一致性的减弱,需要接受数据 最终一致性 ,所谓的最终一致性就是只可能不会立刻同步完成,会有延时,但是最终会完成数据同步;还有就是后台服务一般要实现 幂等性 ,因为消息发送由于性能的考虑一般会有重复(保证消息的被收到且仅收到一次对性能是很大的考验)。最后就是必须引入一个独立的 Broker,作为中间代理池。

常见的异步消息调用的框架有:Kafaka、Notify、MessageQueue。

最终,大部分的服务间的调用架构实现如下所示:

在微服务架构中,一般每一个服务都是有多个拷贝,来做负载均衡。一个服务随时可能下线,也可能应对临时访问压力增加新的服务节点。这就出现了新的问题:

这就是服务的发现、识别与管理问题。解决多服务之间的识别,发现的问题一般是通过注册的方式来进行。

具体来说:当服务上线时,服务提供者将自己的服务注册信息注册到某个专门的框架中,并通过心跳维持长链接,实时更新链接信息。服务调用者通过服务管理框架进行寻址,根据特定的算法,找到对应的服务,或者将服务的注册信息缓存到本地,这样提高性能。当服务下线时,服务管理框架会发送服务下线的通知给其他服务。

常见的服务管理框架有:Zookeeper等框架。

如上的问题解决方案有两种具体的实现,分别是: 基于客户端的服务注册与发现 基于服务端的服务注册与发现

优点是架构简单,扩展灵活,只对服务注册器依赖。缺点是客户端要维护所有调用服务的地址,有技术难度,一般大公司都有成熟的内部框架支持。

优点是所有服务对于前台调用方透明,一般小公司在云服务上部署的应用采用的比较多。

前面提到,单体应用开发中一个很大的风险是,把所有鸡蛋放在一个篮子里,一荣俱荣,一损俱损。而分布式最大的特性就是网络是不可靠的。通过微服务拆分能降低这个风险,不过如果没有特别的保障,结局肯定是噩梦。

因此,当我们的系统是由一系列的服务调用链组成的时候,我们必须确保任一环节出问题都不至于影响整体链路。相应的手段有很多,比如说:

按Alt + 回车键,将会生成eureka-serverzip,解压缩后得到一个maven 项目,将该项目录入IDE。

我们首先来看一下pom文件,可以看出项目中引用了spring-cloud-starter-netflix-eureka-server, 并且springboot 的版本号为:212RELEASE, Spring Cloud的版本号为:GreenwichRC2RC2 表示还没有正式发布,只是第二个Release Candidate。

接下来我们只需要两个步骤,

a、修改EurekaServerApplication, 在@SpringBootApplication的注解上面,加入一个新的注解:@EnableEurekaServer

b、在resources 目录中加入applicationyml 文件, 并配置以下信息:

一个简单的Eureka 注册中心就已经可以使用了,我们运行一下这个spring boot 应用,找开浏览器:localhost:8761,即可看到我们的注册中心就已经运行启来了。并且EUREKA-SERVER也注册到自己的注册中心了。

单节点的注册中心已经搭建完毕,但单节点的注册中心存在单点故障的可能,不能用于生产环境。生产环境的Eureka一般采用集群方式进行部署。

通过clientserviceUrldefaultZone配置多个peer节点,因为是在单机上测试,所以修改了host文件,并且使用不同的端口号来启动注册中心。正式的生产环境请根据自己的实际情况进行配置,比如:第一台Eureka的IP地址为:1921680100,则defaultZone配置其他三台注册中心http://1921680101:8761/eureka/,http://1921680102:8761/eureka/,http://1921680103:8761/eureka/

依次启动4台注册中心,打开网页:http://localhost:8764

可以看到其它三台注册中心已经出现在已注册的replicas和可用的replicas列表里边。

如上图所示,4台注册中心,每台注册中心需要配置其他三台服务器,以Eureka 1为例,其配置如下:

注册中心是本应该是无状态的,可以横向扩展。但由于每台注册中心的配置都不一样,所以扩展起来比较麻烦,需要修改配置文件,这样就无法做到快速的扩容。

微服务客户端需要配置注册中心的地址,使用的是如下的配置:

由于配置的是固定的IP地址,如果我们要扩容注册中心,增加新的注册中心节点,那我们就需要修改微服务客户端的配置文件,将新的注册中心节点进入的服务器列表中。试想一下,如果有几十个微服务,每个微服务有4个节点,那将会要修改上百个配置文件。很显然这种方式不太可取,从软件设计角度来说,违反了开闭原则。

其实Eureka 注册中心还有另一种高可用配置方式,基于DNS。Eureka天生就可以部署在像AWS这样的公有云上,并且可以跨Region,跨Available Zone部署。虽然我们不用部署在云端,依然可以利用这一特性,我们可以把Region看作我们数据中心的机房,Avaiable Zone 看作是机房中的网络区域,结合内部DNS服务来实现高可用的注册中心。

画重点:

a region: default,配置地区

b useDnsForFetchingServiceUrls,表示基于DNS获取服务信息

c eurekaServerDNSName: eurekatxzqcomcn,配置域名服务器名称

键:txtdefaulteurekatxzqcomcn 值:shenzheneurekatxzqcomcn

键:txtshenzheneurekatxzqcomcn 值:17218101 17218102 17218103 17218104

第一条记录表示,default 区域,包含了哪些可用区,我们用shenzhen表示是深圳机房,txt记录的值就设置为:shenzheneurekatxzqcomcn

第二第记录表示 , shenzhen机房有哪些服务器,多台服务器使用空格格开。

如果在本地测试,需要搭建一台自己的DNS服务器,可以参考我的另一篇文章: 基于Docker快速搭建DNS Server

Client View是指DNS服务应用到哪一个网段,比如:17218100/24网段的IP连接到BIND服务器,才会解析指定的域名。

在添加域名的时候,需要指定Client View,这里我们选择我们刚刚创建的View_17218100,指的是只有在这个网段的IP访问这台DNS服务器,才能解析。

添加完一级域名后我们刷一下这个ZONE,然后设置一下本地DNS服务器

DNS域名服务器验证通过后,我们接下来就可以在为这个域名添加我们所需要的txt 记录了。

到这里我们的准备工作就已经基本完成了。使用Maven将注册中心编译成,输出jar包。新建一个Eureka的docker镜像,并启动4个容器。基于DNS的注册中心就搭建完毕了。

你只需要对DNS记录进行变更,就可以实现动态的、快速扩容/缩容了。

关于如何将Eureka部署到Docker,请参考另一篇文章:

早在2013年的时候,docker就已经发行,然而那会还是很少人了解docker。一直到2014年,Martin Fowler提出了微服务的概念,两个不相干的技术终于走在了一起,创造了今天的辉煌!

近几年来,很多互联网关系开始跟风,构建docker+微服务的架构体系。然而,根据笔者观察发现,有些童鞋在使用过程中,只是会用,而根本不了解为什么使用docker,反正对他们来说,公司让用就用!而某些公司呢,虽然用上了docker,然而运维方式并没有发生改变,白白浪费了docker的大好性能

过去:曾记得12年那会,部门要上一个项目。那会,我是这么干的。直接去线上服务器,拷贝一个tomcat,然后改端口号,然后部署应用到webapps文件夹下,重启就好。而且我可以摸着良心说,现在还有很多传统企业是这么做的。

那么这么做的缺点?

很明显,应用之间相互影响。一个应用出现问题,该应用把线程池给拖垮了,这个服务器上的其他应用一起凉凉。一个大型应用拆分为几十个微服务,分别交由不同的团队开发,不同团队之间水平参差不齐。如果还采用这种部署方式,你的应用和某个坑爹团队的应用部署在了同一台服务器上,至于结果,我相信你懂的。

现在:用上了docker容器后,将Docker可以将我们的应用程序打包封装到一个容器中,该容器包含了应用程序的代码、运行环境、依赖库、配置文件等必需的资源。容器之间达到进程级别的隔离,在容器中的操作,不会影响道宿主机和其他容器,这样就不会出现应用之间相互影响的情形!

微服务架构,主要是中间层分解,将系统拆分成很多小应用(微服务),微服务可以部署在不同的服务器上,也可以部署在相同的服务器不同的容器上。当应用的故障不会影响到其他应用,单应用的负载也不会影响到其他应用,其代表框架有 Spring cloud、Dubbo 等。

微服务 Microservices 之父,马丁福勒,对微服务大概的概述如下:就目前而言,对于微服务业界并没有一个统一的、标准的定义(While there is no precise definition of this architectural style ) 。但通常在其而言,微服务架构是一种架构模式或者说是一种架构风格,它提倡将单一应用程序划分成一组小的服务,每个服务运行独立的自己的进程中,服务之间互相协调、互相配合,为用户提供最终价值。服务之间采用轻量级的通信机制互相沟通(通常是基于 HTTP 的 RESTful API ) 。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建,可以有一个非常轻量级的集中式管理来协调这些服务。可以使用不同的语言来编写服务,也可以使用不同的数据存储。

六种常见的微服务架构模式:

1、聚合器微服务设计模式

聚合器调用多个服务实现应用程序所需的功能。它可以是一个简单的Web页面,将检索到的数据进行处理展示。它也可以是一个更高层次的组合微服务,对检索到的数据增加业务逻辑后进一步发布成一个新的微服务,这符合DRY原则。另外,每个服务都有自己的缓存和数据库。如果聚合器是一个组合服务,那么它也有自己的缓存和数据库。聚合器可以沿X轴和Z轴独立扩展。

2、代理微服务设计模式

这是聚合模式的一个变种,在这种情况下,客户端并不聚合数据,但会根据业务需求的差别调用不同的微服务。代理可以仅仅委派请求,也可以进行数据转换工作。

3、链式微服务设计模式

这种模式在接收到请求后会产生一个经过合并的响应,在这种情况下,服务A接收到请求后会与服务B进行通信,类似地,服务B会同服务C进行通信。所有服务都使用同步消息传递。在整个链式调用完成之前,客户端会一直阻塞。因此,服务调用链不宜过长,以免客户端长时间等待。

4、分支微服务设计模式

这种模式是聚合器模式的扩展,允许同时调用两个微服务链。

5、数据共享微服务设计模式

自治是微服务的设计原则之一,就是说微服务是全栈式服务。但在重构现有的“单体应用(monolithic application)”时,SQL数据库反规范化可能会导致数据重复和不一致。因此,在单体应用到微服务架构的过渡阶段,可以使用这种设计模式,在这种情况下,部分微服务可能会共享缓存和数据库存储。不过,这只有在两个服务之间存在强耦合关系时才可以。对于基于微服务的新建应用程序而言,这是一种反模式。

6、异步消息传递微服务设计模式

虽然REST设计模式非常流行,但它是同步的,会造成阻塞。因此部分基于微服务的架构可能会选择使用消息队列代替REST请求/响应。

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » 什么是微服务

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情