1.配置,服务发现和负载平衡–简介
我们正在缓慢但稳定地朝着准备好将微服务部署到生产中的方向发展。 在本教程的这一部分中,我们将讨论三个主要主题:配置,服务发现和负载平衡。
我们的目标是了解基本的基本概念,而不是覆盖所有可用选项。 正如我们将在本教程的后面看到的那样,配置管理,服务发现和负载平衡将一遍又一遍地弹出,尽管它们的上下文和形状不同。
目录
2.配置
每个微服务的配置很可能会因环境而异。 很好,但是提出了一个问题:如何告诉所涉及的微服务使用什么配置?
许多框架为配置管理提供了不同的机制(例如,配置文件,配置文件,命令行选项等),但是我们在这里提倡的方法是遵循“十二因子应用程序”方法(我们已经介绍过 )。
十二要素应用程序将配置存储在 环境变量中(通常缩写为env vars或env )。 Env var易于在部署之间进行更改,而无需更改任何代码。 与配置文件不同,它们很少有可能被意外检入代码存储库; 与自定义配置文件或其他配置机制(例如Java系统属性)不同,它们是与语言和操作系统无关的标准。 – https://12factor.net/config
环境变量仅表现出一个主要限制:它们本质上是静态的。 它们的值的任何更改都可能需要重新启动完整的微服务 。 对于许多人来说,这可能不是问题,但通常需要在运行时具有某种灵活性来修改服务配置。
动态配置
无需重新启动服务即可更新配置的功能非常吸引人。 但是要付出的代价也很高,因为它需要大量的仪器,而且没有太多的框架或库提供这种透明的支持。
例如,让我们考虑动态更改数据库JDBC URL连接字符串。 不仅必须透明地重新创建基础数据源,而且还必须清空并重新初始化JDBC连接池。
动态配置背后的机制实际上取决于您使用哪种配置管理方法( Consul , Zookeeper , Spring Cloud Config …),但是某些框架(例如Spring Cloud)减轻了很多负担。开发人员。
功能标志
功能标记 (或功能切换 )没有完全落入配置桶中,但是它是动态更改服务或应用程序特征的非常强大的技术。 它们在A / B测试中非常有用并被广泛采用,新功能推出,引入实验功能,仅举几个例子。
在Java生态系统中, FF4J可能是功能标记模式的最流行实现。 另一个库是Togglz,但是最近 没有积极维护 。 如果我们不仅限于Java,那么值得一看的是Unleash ,这是一种企业级功能切换服务。 它具有令人印象深刻的SDK列表,可用于许多编程语言, 包括Java 。
Spring Cloud Config
如果您的微服务建立在Spring Platform之上,那么Spring Cloud Config是最容易使用的配置管理选项之一。 它同时提供服务器端和客户端支持(通信基于HTTP协议),非常易于与现有服务集成,甚至可以嵌入到现有服务中。
由于JCG租车平台需要配置管理服务,因此让我们看看使用Git支持的Spring Cloud Config进行配置是多么简单。
server:
port: 20100
spring:
cloud:
config:
server:
git:
uri: file://${rentals.home}/rentals-config
application:
name: config-server
要运行嵌入式配置服务器实例,惯用的Spring Boot注释驱动方法是必经之路。
@SpringBootApplication
@EnableConfigServer
public class ConfigServerRunner {
public static void main(String[] args) {
SpringApplication.run(ConfigServerRunner.class, args);
}
}
尽管Spring Cloud Config具有开箱即用的加密和解密支持,但您也可以将其与HashiCorp Vault 结合使用以管理敏感的配置属性和机密信息 。
古a
在用于配置管理的通用库的范围内 , Netflix的 Archaius可能是最著名的库(在JVM平台的情况下)。 它确实支持动态配置属性,复杂的复合配置层次结构,具有本机Scala支持,并且可以与Zookeeper后端一起使用。
3.服务发现
使用至少某种形式的直接通信的 微服务附带的最具挑战性的问题之一是对等方如何发现彼此。 例如,在JCG租车平台中, 预订服务应该知道库存服务在哪里。 如何解决这一特殊挑战?
可能有人争辩说,使用环境变量将所有正在运行的Inventory Service实例的主机/端口对的列表传递给Reservation Service是可行的,但这并不是真正可持续的。 如果库存服务按比例放大或缩小怎么办? 或者如果某些Inventory Service实例由于网络故障或崩溃而无法访问怎么办? 这确实是一个动态的,可操作的数据,应如此对待。
公平地说,服务发现通常与集群管理和协调并驾齐驱。 这是一个非常有趣但广泛的主题,因此我们的重点将放在服务发现方面。 有很多可用的开源选项,从相当底层的功能到成熟的分布式协调器,我们将浏览使用最广泛的选项。
JGroups
JGroups是同类中最古老的一种,它是用于可靠消息传递的工具包,它具有许多其他功能,可充当集群管理和成员资格检测的骨干。 它本身并不是专用的服务发现解决方案,但可以在最低级别用于实施一个解决方案。
Atomix
同样, Atomix框架提供了以下功能:集群管理,跨节点通信,异步消息传递,组成员资格,组长选举,分布式并发控制,分区,复制和状态更改在分布式系统中的协调。 公平地讲,它也不是直接的服务发现解决方案,而是使自己拥有自己的使能器,因为该框架已将所有必要的部分准备就绪。
尤里卡
由Netflix开发的Eureka是一项基于REST的服务,专用于主要用于服务发现目的(重点是AWS支持)。 它完全用Java编写,包括服务器和客户端组件。
它实际上独立于任何类型的框架。 但是, Spring Cloud Netflix提供了Spring Boot应用程序和服务与许多Netflix组件的出色集成,包括基于Eureka服务器和客户端的抽象。 让我们看看JCG租车平台如何从Eureka中受益。
server:
port: 20200
eureka:
client:
registerWithEureka: false
fetchRegistry: false
healthcheck:
enabled: true
serviceUrl:
defaultZone: http://localhost:20201/eureka/
server:
enable-self-preservation: false
wait-time-in-ms-when-sync-empty: 0
instance:
appname: eureka-server
preferIpAddress: true
我们还可以从与Spring Cloud Config的无缝集成中受益,而不是对配置属性进行硬编码。
spring:
application:
name: eureka-server
cloud:
config:
uri:
- http://localhost:20100
与Spring Cloud Config示例类似,运行嵌入式Eureka服务器实例仅需要一个带注释的类。
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerRunner {
public static void main(String[] args) {
SpringApplication.run(EurekaServerRunner.class, args);
}
}
在服务方面,应该插入Eureka客户端并将其配置为与我们刚刚实现的Eureka服务器通信。 由于Reservation Service是在Spring Boot的基础上构建的,因此,借助Spring Cloud Netflix ,集成非常简单明了。
eureka:
instance:
appname: reservation-service
preferIpAddress: true
client:
register-with-eureka: true
fetch-registry: true
healthcheck:
enabled: true
service-url:
defaultZone: http://localhost:20200/eureka/
当然,最好从Spring Cloud Config或类似的配置管理解决方案中选择这些属性。 当我们运行Reservation Service的多个实例时,每个实例都会向Eureka服务发现进行注册,例如:
![Eureka服务器控制台](https://i-blog.csdnimg.cn/blog_migrate/e60af348958bdc38c4cf7baa7e97c2b0.png)
如果您正在寻找自助服务发现, Eureka可能是一个很好的选择。 我们还没有做任何复杂的事情,但是Eureka有很多功能和配置参数需要调整。
动物园管理员
Apache ZooKeeper是用于管理配置和分布式协调的集中式高可用性服务。 它是开放源代码分布式协调器的先驱之一,经过多年的考验,是许多其他项目的可靠骨干。
对于基于JVM的应用程序,可以与Apache ZooKeeper一起使用的客户端库的生态系统非常丰富。 Apache Curator最初是从Netflix开始的,它提供了高级抽象,使使用Apache ZooKeeper更加容易和可靠。 重要的是, Apache Curator还包括一组针对常见用例和扩展(例如服务发现)的配方。
对于基于Spring的应用程序来说,还有更多的好消息,因为Spring Cloud Zookeeper专门致力于为Spring Boot应用程序和服务提供Apache Zookeeper集成。 与Apache Curator相似,它带有常用的模式,包括服务发现和配置。
等
本质上, etcd是分布式,一致且高度可用的键值存储。 但是,不要让这个简单的定义误导您,因为etcd通常被用作服务发现和配置管理的后端。
领事
领事通过HashiCorp已经开始作为一个分布式,高可用性和数据中心服务发现和配置感知解决方案。 它是增强服务发现能力的第一批产品之一,成为一流的公民,而不是配方或模式。
Consul的API完全基于HTTP,因此不需要特殊的客户端即可开始使用它。 但是,有一些专用的JVM库使与Consul的集成更加容易,包括用于Spring Boot应用程序和服务的Spring Cloud Consul项目。
毫无疑问, Consul的发展非常Swift,已经不仅限于服务发现和键/值存储。 在本教程的后续部分中,我们将以不同的方式再次遇到它。
4.负载平衡
服务发现是构建可扩展且具有弹性的微服务体系结构的基础 。 有关有多少个服务实例及其位置的知识对于用户完成工作至关重要,但也出乎意料地揭示了另一个问题:在许多服务实例中,应该为下一个请求选择哪个服务实例? 这称为负载平衡 ,旨在优化资源效率,总体系统可靠性和可用性。
总的来说, 负载平衡有两种类型,客户端和服务器端(包括DNS )。 在客户端负载平衡的情况下,每个客户端都通过服务发现来获取可用对等方的列表,并自行决定要调用哪个对等方。 相反,在服务器端负载平衡的情况下,客户端有一个与之通信的单个入口点( 负载平衡器 ),它将请求转发到各个服务实例。
如您所料, 负载均衡器可能位于不同的OSI级别,并且希望支持不同的通信协议(例如TCP , UDP , HTTP , HTTP / 2 , gRPC等等)。 从微服务实现的角度来看,运行状况检查的存在是必需的操作要求,以便负载平衡器能够维护最新的活动实例集。 令人振奋的是,人们对健康检查的形式化进行了重新努力,即HTTP API的健康检查响应格式和GRPC健康检查协议 。
在本节的其余部分,我们将讨论典型的开源解决方案,您可能会发现它们对负载平衡 (和反向代理 )很有用。
Nginx的
nginx是一个开放源代码软件,用于Web服务, 反向代理 ,缓存, TCP / HTTP / UDP流量(也包括HTTP / 2和gRPC )的负载平衡 ,媒体流等等。 Nginx之所以成为最受欢迎的选择,是因为它的功能远远超出了负载平衡 ,而且运行非常非常好。
HAProxy
HAProxy是免费的,非常快速,可靠的高性能TCP / HTTP (包括HTTP / 2和gRPC ) 负载平衡器 。 与nginx一起 ,它已成为事实上的标准开源负载平衡器 ,适用于大多数部署环境和工作负载。
突触
Synapse是由Airbnb开发和开源的服务发现系统。 它是SmartStack框架的一部分,并建立在经过战斗测试的Zookeeper , HAProxy (或nginx )之上。
特拉菲克
Traefik是一个非常流行的开源反向代理和负载平衡器 。 它与现有的基础架构组件集成得非常好,并支持HTTP , Websocket和HTTP / 2和gRPC 。 Traefik最强大的方面之一就是操作友好性,因为它公开了指标,访问日志,捆绑了Web UI和REST(ful) Web API(除了集群,重试和断路之外)。
使者
Envoy是新一代边缘和服务代理的代表。 它支持高级负载平衡功能(包括重试,断路,速率限制,请求屏蔽,区域本地负载平衡等),并且对HTTP / 2和gRPC具有一流的支持。 另外, Envoy提供的独特功能之一是对HTTP / 2代理透明的HTTP / 1.1 。
Envoy假定采用旁架部署模型,这基本上意味着使其与应用程序或服务一起运行。 它已成为现代基础结构的关键部分,我们将在本教程的下一部分中很快与Envoy见面。
带
到目前为止,我们仅看到服务器端负载均衡器或侧面汽车,但是现在该介绍由Netflix开源的Ribbon (具有内置软件负载均衡的客户端IPC库)了。 它支持TCP , UDP和HTTP协议,并与Eureka很好地集成。
Ribbon还受Spring Cloud Netflix的支持,因此将其集成到Spring Boot应用程序和服务中确实很容易。
5.云
每个单一的云提供商都在配置管理,服务发现和负载平衡方面提供自己的服务。 其中有些是内置的,有些可能在某些情况下可用,但是总的来说,利用此类产品可以为您节省大量时间和金钱。
转向无服务器执行模型对发现和扩展需求提出了不同的要求,以响应不断变化的需求。 它确实成为平台的一部分,到目前为止,我们所讨论的解决方案在那儿并不鲜见。
6。结论
在本部分教程中,我们讨论了诸如配置管理,服务发现和负载平衡之类的重要主题。 它不是详尽的概述,而是集中在对基本概念的理解上。 正如我们稍后将要看到的那样,新一代基础架构工具通过解决微服务体系结构带来的许多问题而走得更远。
7.接下来
在本教程的下一部分中,我们将讨论API网关和聚合器,以及微服务部署的其他关键部分。