服务发现:微服务架构关键原则之一。尝试配置每个客户端或某种形式的约定可能非常困难,可以非常脆弱。Netflix服务发现服务器和客户端是Eureka。将服务器配置和部署为高可用,每个服务器将注册服务的状态复制到其他服务器。
一、如何包含Eureka客户端
用组org.springframework.cloud和工件ID spring-cloud-starter-eureka启动器。
二、注册Eureka
客户端注册Eureka时,提供自身元数据,如主机和端口,健康指示符URL,主页等。Eureka从服务每个实例接收心跳。心跳失败超过可配置时间表,将该实例从注册表中删除。
例子中明确使用@EnableEurekaClient,只有Eureka可用,也可用@EnableDiscoveryClient。需配置才能找到Eureka服务器
“defaultZone”有用的默认值
Environment获取默认应用程序名称(服务ID),虚拟主机和非安全端口分别为${spring.application.name},${spring.application.name}和${server.port}。
@EnableEurekaClient将应用程序同时进入eureka“实例”(注册自己)和一个“客户端”(查询注册表以查找其他服务)。由eureka.instance.*配置键驱动,确保应用程序有spring.application.name(Eureka服务ID或VIP默认值),默认值将正常的。
配置选项的参阅EurekaInstanceConfigBean和EurekaClientConfigBean。
三、Eureka服务器进行身份验证
如eureka.client.serviceUrl.defaultZone网址中包凭据(如http://user:password@localhost:8761/eureka)),HTTP基本身份验证将自动添加到您的eureka客户端。对复的需求,创建DiscoveryClientOptionalArgs类型@Bean,并将ClientFilter实例注入,应用于从客户端到服务器调用。
Eureka中限制,不支持每个服务器的基本身份验证凭据,只能使用第一个找到集合。
四、状态页和健康指标
Eureka实例状态页面和运行状况指示器分别默认为“/ info”和“/ health”,是Spring Boot执行器应用程序中有用端点默认位置。如用非默认上下文路径或servlet路径(例server.servletPath=/foo)或管理端点路径(例management.contextPath=/admin),则要更改,即使是执行器。例:
application.yml
eureka:
instance:
statusPageUrlPath: ${management.context-path}/info
healthCheckUrlPath: ${management.context-path}/health
链接显示客户端元数据中,某些情况下决定是否将请求发送到应用程序,如准确有帮助。
五、注册安全应用程序
应用程序通过HTTPS联系,EurekaInstanceConfig,即 eureka.instance.[nonSecurePortEnabled,securePortEnabled]=[false,true] 设置。发布实例信息显示安全通信的明确偏好。Spring Cloud DiscoveryClient以这种方式配置服务返回https://…; URI,Eureka(本机有安全健康检查URL。
Eureka内部工作方式,会发布状态和主页非安全网址,除非明确地覆盖,用占位符来配置eureka实例URL如
(${eureka.hostname}本地占位符,Spring占位符同样功能${eureka.instance.hostName}。
如应用程序在代理服务器后面运行,且SSL终止服务在代理中(如运行在Cloud Foundry或其他平台为服务),需确保代理“转发”头部被截取并处理应用程序。Spring Boot应用程序中的嵌入式Tomcat容器会自动执行“X-Forwarded - \ *”标头的显式配置。错误迹象:应用程序本身所呈现的链接是错(错误的主机,端口或协议)。
六、Eureka的健康检查
Eureka客户端心跳确定客户端启动(默认)。注册后Eureka永远“UP”。启用Eureka运行状况检查改变,将应用程序状态传播到Eureka。每个其他应用程序将不会在“UP”之外的状态下将流量发送到应用程序。
eureka.client.healthcheck.enabled=true只能在application.yml设置。设置bootstrap.yml中的值副作用,如UNKNOWN状态eureka中注册。
更多控制健康检查,实施自己com.netflix.appinfo.HealthCheckHandler。
七、Eureka实例和客户端的元数据
Eureka元数据工作原理,平台上使用它。有主机名,IP地址,端口号,状态页和运行状况检查等标准元数据。发布在服务注册表中,客户使用,直接方式联系服务。额外的元数据可以添加到eureka.instance.metadataMap中实例注册中,远程客户端可访问,不更改客户端行为,除非意识到元数据含义。特殊情况:Spring Cloud为元数据映射指定含义
(1)在Cloudfoundry上使用Eureka
Cloudfoundry有全局路由器,同一应用程序所有实例都有相同主机名(相似架构的其他PaaS解决方案中也如此)。不一定是用Eureka障碍,如用路由器,需明确设置主机名和端口号。用实例元数据,区分客户端上实例(自定义负载平衡器中)。默认eureka.instance.instanceId为vcap.application.instance_id。例如:
根据Cloudfoundry实例中安全规则设置方式,注册并使用主机VM的IP地址进行直接服务到服务调用。此功能尚未在Pivotal Web Services(PWS)上提供。
(2)在AWS上使用Eureka
如应用程序计划将部署AWS云,Eureka实例被配置为AWS意识到,这可以通过定制来完成EurekaInstanceConfigBean方式如下:
(3)更改Eureka实例ID
香草Netflix Eureka实例注册了与其主机名相同的ID(即每个主机只有一个服务)。Spring Cloud Eureka提供明智默认:${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}}。例如myhost:myappname:8080。
用Spring Cloud,可通过eureka.instance.instanceId中提供唯一标识符来覆盖此。如:
用元数据和在localhost上部署多个服务实例,随机值进行,实例唯一。Cloudfoundry中,vcap.application.instance_id将在Spring Boot中自动填充,不需随机值。
八、使用EurekaClient
有@EnableDiscoveryClient(或@EnableEurekaClient)应用程序,从Eureka服务器发现服务实例。用本机com.netflix.discovery.EurekaClient(而不是Spring云DiscoveryClient)如
不要用@PostConstruct方法或@Scheduled方法(或ApplicationContext尚未启动的任何地方)EurekaClient。被初始化为SmartLifecycle(带有phase=0),最早可靠它可用的是另一个具有更高阶段SmartLifecycle
九、本机Netflix EurekaClient的替代方案
不必用原始Netflix EurekaClient,包装器后用更方便。Spring Cloud支持Feign(REST客户端构建器),支持Spring RestTemplate使用逻辑Eureka服务标识符(VIP)而不是物理URL。用固定的物理服务器列表配置Ribbon,将
还可用org.springframework.cloud.client.discovery.DiscoveryClient,为Netflix不具体的发现客户端提供简单API,如
十、为什么注册服务这么慢?
实例定期心跳到注册表(通过客户端的serviceUrl),默认30秒。实例,服务器和客户端在其本地缓存中都具有相同元数据(可能需要3个心跳)之前,客户端才能发现服务。您可以使用eureka.instance.leaseRenewalIntervalInSeconds更改期限,加快客户端连接到其他服务的过程。生产中,最好用默认值,服务器内部一些计算可以对租赁更新期进行假设。
十一、区
如将Eureka客户端部署到多区域,可能希望这些客户端用另区域中服务前,用同域内服务。需正确配置Eureka客户端。
(1)确保将Eureka服务器部署到每个区域,彼此对等体。详细信息,请参阅区域和区域部分 。
(2)告知Eureka服务所在区域。可用metadataMap属性执行。如,如果service 1部署到zone 1和zone 2,在service 1中设置以下Eureka属性
1区服务1
eureka.instance.metadataMap.zone = zone1
eureka.client.preferSameZoneEureka = true
第2区的服务1
eureka.instance.metadataMap.zone = zone2
eureka.client.preferSameZoneEureka = true