什么是服务注册和发现
假设有2个微服务A和B分别在端点http:// localhost:8181 /和http:// localhost:8282 /上运行,如果想要在A服务中调用B服务,那么我们需要在A服务中键入B服务的url,这个url是负载均衡器分配给我们的,包括负载平衡后的IP地址,那么很显然,B服务与这个URL硬编码耦合在一起了,如果我们使用了服务自动注册机制,就可以使用B服务的逻辑ID,而不是使用特定IP地址和端口号来调用服务。
我们可以使用Netflix Eureka Server创建Service Registry服务器,并将我们的微服务同时作为Eureka客户端,这样一旦我们启动微服务,它将自动使用逻辑服务ID向Eureka Server注册。然后,其他微服务(同样也是Eureka客户端)就可以使用服逻辑务ID来调用REST端点服务了。
Spring Cloud使用Load Balanced RestTemplate创建Service Registry并发现其他服务变得非常容易。
除了使用Netflix Eureka Server作为服务发现,也可以使用Zookeeper,但是根据CAP定理,在需要P网络分区容忍性情况下,强一致性C和高可用性A只能选择一个,Zookeeper是属于CP,而Eureka是属于AP,在服务发现方面,高可用性才是更重要,否则无法完成服务之间调用,而服务信息是否一致则不是最重要,A服务发现B服务时,B服务信息没有及时更新,可能发生调用错误,但是调用错误总比无法连接到服务注册中心要强。否则,服务注册中心就成为整个系统的单点故障,存在极大的单点风险,这是我们为什么需要分布式系统的首要原因。
基于Eureka的注册服务器
让我们使用Netflix Eureka创建一个Service Registry,它只是一个带有Eureka Server启动器的SpringBoot应用程序。
使用Intellij的Idea开发工具是非常容易启动Spring cloud的:
可以从https://start.spring.io/网址,选择相应组件即可。
由于我们需要建立一个注册服务器,因此选择Eureka Server组件即可,通过这些自动工具实际上是能自动生成Maven的配置:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
我们需要给SpringBoot启动类添加@EnableEurekaServer注释,以使我们的SpringBoot应用程序成为基于Eureka Server的Service Registry。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class ServiceRegistryApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceRegistryApplication.class, args);
}
}
默认情况下,每个Eureka服务器也是Eureka客户端,客户端一定会需要一个服务器URL来定位,否则就会不断报错,由于我们只有一个Eureka Server节点(独立模式),我们将通过在application.properties文件中配置以下属性来禁用此客户端行为。
SpringCloud有properties和YAML两种配置方式,这两种配置方式其实只是形式不同,properties配置信息格式是a.b.c,而YAML则是a:b:c:,两者本质是一样的,只需要其中一个即可,这里以properties为案例:
spring.application.name=jdon-eureka-server server.port=1111 eureka.instance.hostname=localhost eureka.client.register-with-eureka=false eureka.