微服务介绍与consul应用入门

1. 什么是微服务

1.1 微服务的由来

微服务最早由Martin Fowler与James Lewis于2014年共同提出,微服务架构风格是一种使用一套小服务来开发单个应用的方式途径,每个服务运行在自己的进程中,并使用轻量级机制通信,通常是HTTP API,这些服务基于业务能力构建,并能够通过自动化部署机制来独立部署,这些服务使用不同的编程语言实现,以及不同数据存储技术,并保持最低限度的集中式管理。

1.2 微服务的概念

微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。
微服务架构的思考是从与整体应用对比而产生的。
微服务架构对比整体式架构

其中,对应用组件封装的方式是整体架构与微服务架构的主要差异,微服务架构将相关联的业务逻辑及数据放在一起形成独立的边界,其目的是能在不影响其他应用组件(微服务)的情况下更快地交付并推出市场。

微服务应用对比整体式应用

1.3 微服务一些重要特性

  • 通过服务实现应用的组件化
    微服务架构中将组件定义为可被独立替换和升级的软件单元,在应用架构设计中通过将整体应用切分成可独立部署及升级的微服务方式进行组件化设计

  • 围绕业务能力组织服务
    微服务团队的组织结构必须是跨功能的(如:既管应用,也管数据库)、强搭配的DevOps开发运维一体化团队

  • “去中心化”治理
    整体式应用往往倾向于采用单一技术平台,微服务架构则鼓励使用合适的工具完成各自的任务,每个微服务可以考虑选用最佳工具完成(如不同的编程语言)

  • “去中心化”数据管理
    微服务架构倡导采用多样性持久化(PolyglotPersistence)的方法,让每个微服务管理其自有数据库,并允许不同微服务采用不同的数据持久化技术

  • 基础设施自动化
    云化及自动化部署等技术极大地降低了微服务构建、部署和运维的难度,通过应用持续集成和持续交付等方法有助于达到加速推出市场的目的

  • 故障处理设计
    微服务架构所带来的一个后果是必须考虑每个服务的失败容错机制。因此,微服务非常重视建立架构及业务相关指标的实时监控和日志机制

2. 为什么需要微服务

在传统的IT行业软件大多都是各种独立系统的堆砌,随着系统规模的扩大,暴露出的问题越来越多,总结来说就是扩展性差,可靠性不高,维护成本高;而微服务架构一定程度能解决上面问题。

微服务与单体架构区别:

(1)单体架构所有的模块全都耦合在一块,代码量大,维护困难,微服务每个模块就相当于一个单独的项目,代码量明显减少,遇到问题也相对来说比较好解决。

(2)单体架构所有的模块都共用一个数据库,存储方式比较单一,微服务每个模块都可以使用不同的存储方式(比如有的用redis,有的用mysql等),数据库也是单个模块对应自己的数据库。

(3)单体架构所有的模块开发所使用的技术一样,微服务每个模块都可以使用不同的开发技术,开发模式更灵活。

3. 如何实践微服务

当实际项目实践微服务时,需要思考以下几个问题。

3.1 API Gateway

传统的开发方式,所有的服务都是本地的,UI可以直接调用。现在按功能拆分成独立的服务,跑在独立的进程上。客户端UI访问这些服务就会有一些问题。

如后台有N个服务,前台就需要记住管理N个服务,一个服务下线/更新/升级,前台就要重新部署,这明显不符合我们拆分的理念;另外,N个小服务的调用也是一个不小的网络开销;还有一般微服务在系统内部,通常是无状态的,用户登录信息和权限管理最好有一个统一的地方维护管理(OAuth)。
所以,一般在后台N个服务和UI之间一般会一个代理或者叫API Gateway。他的作用是为前台提供后台服务的聚合,提供一个统一的服务出口,解除他们之间的耦合

3.2 服务间调用

因为所有的微服务都是独立的进程上,服务间的通信一般有两种方式REST,RPC。
一般REST基于HTTP,更容易实现,更容易被接受,服务端实现技术也更灵活些,各个语言都能支持,同时能跨客户端,对客户端没有特殊的要 求,只要封装了HTTP的SDK就能调用,所以相对使用的广一些。RPC也有自己的优点,传输协议更高效,安全更可控,特别在一个公司内部,如果有统一个的开发规范和统一的服务框架时,他的开发效率优势更明显些。

3.3 服务发现

在微服务架构中,一般每一个服务都是有多个拷贝,来做负载均衡。一个服务随时可能下线,也可能应对临时访问压力增加新的服务节点。服务之间如何相互感知?服务如何管理?这就是服务发现的问题了。一般有两类做法,也各有优缺点。基本都是通过zookeeper等类似技术做服务注册信息的分布式管理。当服务上线时,服务提供者将自己的服务信息注册到ZK(或类似框架),并通过心跳维持长链接,实时更新链接信息。服务调用者通过ZK寻址,根据可定制算法,找到一个服务,还可以将服务信息缓存在本地以提高性能。当服务下线时,ZK会发通知给服务客户端。
服务发现

3.4 服务注册

服务之间需要创建一种服务发现机制,用于帮助服务之间互相感知彼此的存在。服务启动时会将自身的服务信息注册到注册中心,并订阅自己需要消费的服务。
服务注册中心是服务发现的核心。它保存了各个可用服务实例的网络地址(IPAddress和Port)。服务注册中心必须要有高可用性和实时更新功能。

3.5 微服务开发框架

目前微服务的最常用的四个开发框架:

1.Spring Cloud: http://projects.spring.io/spring-cloud(现在非常流行的微服务架构)

2.Dubbo:http://dubbo.io (阿里巴巴开源)

3.Dropwizard:http://www.dropwizard.io (关注单个微服务的开发)

4.Consul、etcd&etc.(微服务的模块)

4. consul简介

4.1 consul定义

Consul是一个用来实现分布式系统的服务发现与配置的开源工具。他主要由多个组成部分:

  • 服务发现:客户端通过Consul提供服务,客户端可以使用Consul发现服务的提供者。使用类似DNS或者HTTP,应用程序和可以很轻松的发现他们依赖的服务。

  • 检查健康:Consul客户端可以提供与给定服务相关的健康检查(Web服务器返回200 ok)或者本地节点(“内存利用率低于90%”)。这些信息可以监控集群的运行情况,并且使访问远离不健康的主机组件。

  • 键值对存储:应用程序可以使用Cousul的层级键值对。

  • 多数据中心:Consul有开箱及用的多数据中心。

数据中心

4.2 Consul术语

  • 代理(agent):代理是Consul集群上每个成员的守护进程,它是由consul agent开始运行。代理能够以客户端或服务器模式运行。由于所有节点都必须运行代理,所以将节点引用为客户端或服务器更为简单,但还有其他实例的代理。所有代理可以运行DNS或HTTP接口,并负责运行检查和保持服务同步。

  • 客户端:客户端可以将所有RPC请求转发到服务器的代理。客户端是相对无状态的。客户端执行的唯一后台活动是LANgossip池。它消耗最小的资源开销和少量的网络带宽。

  • 服务器端:服务器端是具有扩展的功能的代理,它主要参与维护集群状态,响应RPC查询,与其他数据中心交换WAN gossip ,以及向上级或远程数据中心转发查询。

  • 数据中心:虽然数据中心的定义似乎很明显,但仍有一些细微的细节必须考虑。我们将一个数据中心定义为一个私有、低延迟和高带宽的网络环境。这不包括通过公共互联网的通信,但是为了我们的目的,单个EC2区域内的多个可用区域将被视为单个数据中心的一部分

  • Gossip:consul是建立在serf之上的,它提供了一个完整的gossip协议,用在很多地方。Serf提供了成员,故障检测和事件广播。Gossip的节点到节点之间的通信使用了UDP协议。

  • LAN Gossip:指在同一局域网或数据中心的节点上的LAN Gossip池。

  • WAN Gossip:指包含服务器的WAN Gossip池,这些服务器在不同的数据中心,通过网络进行通信。

5. consul应用

5.1 安装consul

Consul 下载地址:https://www.consul.io/downloads.html, 下载后解压就是一个可执行的二进制文件consul,配置好环境变量,检查 consul 是否可用:
检查consul

5.2 运行Agent

为了简单起见,我们现在将以开发模式启动Consul代理。 这种模式对于快速简单地启动单节点Consul环境非常有用。 它并不打算在生产中使用,因为它不会持续任何状态。
运行Agent

从上图看出,Consul代理已经启动并输出了一些日志数据。 从日志数据中,可以看到我们的代理正在服务器模式下运行,并声称拥有集群领导权。 此外,当地成员已被标记为该集群的健康成员。

(1) 集群成员
在另一个终端运行consul members,可以看到Consul集群的成员。 应该只看到一个成员(你自己):
集群成员

(2) http查看节点信息
查看节点信息

(3) DNS接口查询节点信息
查询节点信息

(4)停止Agent

可以使用Ctrl-C(中断信号)正常停止代理。 中断代理之后,您应该看到它离开集群并关闭。
通过优雅地离开,Consul通知其他集群成员该节点离开。 如果强行杀死了代理进程,则集群的其他成员将检测到该节点失败。 成员离开时,其服务和检查将从目录中删除。 当一个成员失败时,其健康被简单地标记为关键,但不会从目录中删除。 Consul将自动尝试重新连接到失败的节点,使其能够从特定的网络条件恢复,而不再联系离开的节点。

5.3 consul 常用命令

命令 解释 示例
agent 运行一个consul agent consul agent -dev
join 将agent加入到consul集群 consul join IP
members 列出consul cluster集群中的members l consul members
leave 将节点移除所在集群 consul consul leave

consul agent 命令的常用选项,如下:

-data-dir

作用:指定agent储存状态的数据目录,这是所有agent都必须的,对于server尤其重要,因为他们必须持久化集群的状态

-config-dir

作用:指定service的配置文件和检查定义所在的位置,通常会指定为”某一个路径/consul.d”(通常情况下,.d表示一系列配置文件存放的目录)

-config-file

作用:指定一个要装载的配置文件,该选项可以配置多次,进而配置多个配置文件(后边的会合并前边的,相同的值覆盖)

-dev

作用:创建一个开发环境下的server节点,该参数配置下,不会有任何持久化操作,即不会有任何数据写入到磁盘,这种模式不能用于生产环境(因为第二条)

-bootstrap-expect

作用:该命令通知consul server我们现在准备加入的server节点个数,该参数是为了延迟日志复制的启动直到我们指定数量的server节点成功的加入后启动。

-node

作用:指定节点在集群中的名称,该名称在集群中必须是唯一的(默认采用机器的host)
推荐:直接采用机器的IP

-bind

作用:指明节点的IP地址,有时候不指定绑定IP,会报Failed to get advertise address: Multiple private IPs found. Please configure one. 的异常

-server

作用:指定节点为server,每个数据中心(DC)的server数推荐至少为1,至多为5
所有的server都采用raft一致性算法来确保事务的一致性和线性化,事务修改了集群的状态,且集群的状态保存在每一台server上保证可用性

server也是与其他DC交互的门面(gateway)

-client

作用:指定节点为client,指定客户端接口的绑定地址,包括:HTTP、DNS、RPC
默认是127.0.0.1,只允许回环接口访问;若不指定为-server,其实就是-client

-join

作用:将节点加入到集群

-datacenter(老版本叫-dc,-dc已经失效)

作用:指定机器加入到哪一个数据中心中

5.4 服务注册

服务注册可以通过提供服务定义配置或通过HTTP API调用来注册。

官网推荐用配置的方式注册。操作步骤如下:

1.为Consul配置创建一个目录。#mkdir /etc/consul.d/

2.在该目录下创建配置文件, web.json

服务注册

配置说明:

  • name:服务名称,唯一
  • tags: 一般标识服务的类型,如api, db, global等
  • address: ip地址
  • port: 端口号
  • check: 标识健康检查的api

3.启动服务的时候要使用-config-dir,即可完成服务注册。

Consul agent -config-dir ./consul.d -data-dir /tmp/node0 -node=node0 -datacenter=dc1 -ui

5.4完整示例

示例有一个集群,包括一个consul server端,一个consul client端;其中consul client端添加服务注册,健康检查等。

  1. 准备两台服务器,一台作为consul server 端,一台作为consul client端
主机名称 IP作用
node0 10.9.8.102
nodebob 10.9.8.103
  1. 在第一台服务器上启动node0,作为 consul服务端
    consul agent -data-dir /tmp/node0 -node=node0 -datacenter=dc1 -ui -server

  2. 在第二台服务器上,添加服务配置
    创建配置目录 consul.d, 添加配置 web.json
    服务配置

  3. 在第二台服务器上,启动 nodebob,作为consul 客户端,并且加入到集群
    consul agent -data-dir /tmp/nodebob -node=nodebob --config-dir ./consul.d -datacenter=dc1 -ui -join 10.9.8.102

通过访问http://localhost:8500/ui/dc1/nodes,我们可以看到两个节点:
节点信息

  1. 查看健康检查信息
    访问: http://localhost:8500/ui/dc1/nodes/nodebob
    健康信息

  2. 若应用客户端需要调用第二台服务器上的刚注册的服务,不需要前端应用管理ip,端口配置信息,只需要根据服务名(唯一)访问consul服务中心,即可获取ip,端口号。

本地调用: http://localhost:8500/v1/catalog/service/web
调用服务

  1. 参考示例疑问思考
    若完成上面6步骤,那么已经成功完成了一个简单consul应用demo。但是这个demo还是太简单了,还有一些地方有些疑问,欢迎一起交流:

1.Consul client 和 consul server在实际项目中,如何分配?什么样的服务使用 consul client,什么样的服务用consul server?

2.如果有多个consul server, 怎么确定服务注册中心?前端应用如何确定服务注册中心?

3.Consul如何实现负载均衡?

4.按照一体化应用,前端直接访问后台服务;若使用微服务,前端需要先访问服务注册中心,拿到ip,端口号后再访问后台服务;是不是增加访问成本,性能变差?

5.若前端应用获取ip,端口都是通过服务注册中心, 那么实际项目中,这个服务注册中心是不是压力很大?

6. 微服务架构的取舍

1.在合适的项目,合适的团队,采用微服务架构收益会大于成本。

2.微服务架构有很多吸引人的地方,但在拥抱微服务之前,也需要认清它所带来的挑战。

3.需要避免为了“微服务”而“微服务”。

4.微服务架构引入策略 – 对传统企业而言,开始时可以考虑引入部分合适的微服务架构原则对已有系统进行改造或新建微服务应用,逐步探索及积累微服务架构经验,而非全盘实施微服务架构。

7. 参考文献

发布了30 篇原创文章 · 获赞 49 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/bob_baobao/article/details/83825958