在开发Spring Boot + Spring Cloud微服务时,开发人员通常在本地运行,同时还会运行Spring Cloud Config Server和Spring Cloud Netflix Eureka的本地实例,为开发中的微服务提供必要的框架,并更精确地复制测试和生产环境。很多时候,只需要运行开发中的微服务的单个实例。这对我们来说几乎不费吹灰之力,只要通过内部属性(通常位于项目的application.properties/.yml配置文件中)或通过将应用指向我们的本地Spring Cloud Config Server,为服务提供所需的端口号即可。
但是,如果您想运行上述微服务的多个实例并在Eureka中为它们注册,让使用中的微服务可以访问它们,那么会发生什么情况?
我们先来了解一点Spring Cloud Netflix Eureka的背景知识。Eureka是一种服务注册表,为全球许多关键的分布式系统提供服务注册和发现功能。服务注册表为微服务提供了一种发现和被发现的途径,让使用中的微服务可以轻松找到“backing services”,提供使用中服务所用功能的其他微服务。在临时环境(比如云环境)中,当一个微服务发生故障/离线/无法访问时,另一个微服务将迅速启动,在另一位置替换它。服务注册表使微服务实例可以随时随地轻松找到彼此。
再深入了解一下。在本地运行开发计算机时,如果微服务实例联系Eureka请求进行注册,Eureka会将应用的IP地址与在其上侦听的端口号相结合,为该微服务实例创建唯一的标识符/定位符。若要手动更改运行我们的微服务实例的指定端口,将会非常繁琐。相反,我们只要在微服务的属性中设置server.port=0即可将0指定为其目标端口;这样,Spring Boot会为我们运行的每个实例随机分配一个可用的端口号。
但这种做法有个问题。我们的微服务实例会在此端口分配操作之前尝试注册Eureka,而这将导致注册时使用的是本地IP地址和端口号零(0),而且该微服务的每个后续实例都会如此。这限制了我们只能用本地Eureka实例注册,而且只能运行一个实例。幸运的是,有一个简单的解决方法:为每个实例动态分配唯一的实例ID以供Eureka使用。
这里有个项目,我在其中演示了如何使用一个Coffee Service(也可以是其他服务)和Spring Cloud的最新快照(目前是Finchley.BUILD-SNAPSHOT)来完成这项任务。我已经将下列值添加到属性文件中,该文件由Config Server提供给coffee-service的每个实例:
注:我通常喜欢使用YAML文件来保存属性,但它们也可以表示为.properties文件中的直接属性分配,如下所示:
第一行将变量PORT的值(如果存在)分配给server.port,如果该值不存在,则分配0。这会提示Spring Boot随机分配一个未使用的端口。
第二行将当前的spring.application.instance_id(如果存在)附加到spring.application.name后面,并用冒号(:)隔开。如果spring.application.instance_id不存在,则会附加一个随机值来为此实例创建唯一的Eureka实例标识符。
要从IntelliJ IDEA启动coffee-service的两个实例,我们必须从编辑窗口右上角的下拉菜单中选择“Edit configurations...”:
在“Run/Debug Configurations”窗口中,我们必须取消选中“Single instance only”复选框,如下图所示。这样,我们每次运行应用时都会创建一个新的微服务实例,而不是停止现有实例再重新启动它。
当我们运行coffee-service的多个实例时,会看到Eureka服务日志中显示类似下面这样的条目:
以下是它们在Eureka仪表板中的显示方式:
总结
要在本地运行某个微服务的多个实例并在Eureka中为它们注册以获得可发现性,只需完成几项小的配置设置即可,非常简单。如果使用当前的Spring Cloud快照构建(如这些示例中的Finchley.BUILD-SNAPSHOT)并将server.port设置为0,将微服务的eureka.instance.instance-id设置为唯一的值生成字符串,那么系统会在实例初始化后为这两项动态分配唯一值。其余操作则由Spring Cloud Netflix Eureka处理。
| 留言与评论(共有 0 条评论) |