Netflix是一家在线影片租赁提供商。java
Netflix 开源软件git
NetflixOSS github
Spring Cloud Netflix 经过自动配置以及绑定Spring环境中的其余模块的方式将Netflix OSS与Spring Boot 应用进行整合。web
经过简单的注解就能够快速在应用中开启一个标准配置的大型分布式及高可用的Netflix组件。spring
标准配置 包括:服务发现(
Eureka
);断路器(Hystrix
);智能路由(Zuul
);客户端负载均衡(Ribbon
)bootstrap
服务发现是微服务架构中重要的一个概念。通常来讲,在每一个客户端进行配置或者某种形式的约定来进行服务调用是很麻烦的,并且须要频繁修改。
Eureka
是Netflix服务发现服务以及客户端的实现。服务可以以一种高可用的方式进行配置和部署,对于每一个注册的服务彼此间都会进行状态复制。缓存
当一个注册器客户端经过Eureka进行注册时,它会带上一些描述本身状况的元数据,如:地址、端口、健康指示器地址、主页等等。Eureka会接收每个服务实例发送的心跳包。若是心跳包超过配置的间隔时间,那这个服务实例就会被移除。安全
Eureka客户端代码示例:网络
@Configuration @ComponentScan @EnableAutoConfiguration @EnableEurekaClient @RestController public class Application { @RequestMapping("/") public String home() { return "Hello world"; } public static void main(String[] args) { new SpringApplicationBuilder(Application.class).web(true).run(args); } }
可见,这就是一个普通的Spring Boot 应用。例子中使用了
@EnableEurekaClient
,当Eureka可用时,也可使用@EnableDiscoveryClient
。此外还须要在本地配置一个Eureka服务。例如:架构
application.yml
eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/
这里的
defaultZone
,表示任何处理任何没有匹配上的url请求。(默认请求处理地址)
默认应用名(服务ID)、虚拟地址和端口,会从
Environment
中获取:${spring.application.name}
、${spring.application.name}
、${server.port}
。
@EnableEurekaClient
会让应用既作为一个Eurake实例,同时也做为一个Eurake的客户端(可以经过这个客户端,查询到注册的本地其余服务)。Eurake实例能够经过eureka.instance.*
相关配置项进行配置。默认状况下使用spring.application.name
做为注册服务的service ID 和 虚拟IP
具体配置相能够参见 EurekaInstanceConfigBean 和 EurekaClientConfigBean
若是
eureka.client.serviceUrl.defaultZone
的URL中嵌入了帐号信息则Eurake客户端会自动使用HTTP basic 认证。(如:http://user:password@localhost:8761/eureka
)
若是须要更为复杂的认证方式,能够本身实现一个
DiscoveryClientOptionalArgs
而后注入一个ClientFilter
实例,这样客户端与服务端的调用都会通过这个Filter。
注意: 因为Eurake的限制,不可能为每个服务配置单独的认证,所以第一个被发现的认证方式会被使用。
一个Eurake实例的状态页和健康指示器默认为:
/info
和/health
,这两个是由Spring Boot Actuator应用提供的访问端点。能够经过如下方式进行修改:
application.yml
eureka: instance: statusPageUrlPath: ${management.context-path}/info healthCheckUrlPath: ${management.context-path}/health
这些地址将会被用于客户端元数据的获取,以及必要的检测时使用。所以,这些端点是颇有用的。
若是你想让应用之间经过HTTPS通信,那能够在
EurekaInstanceConfig
中配置两个开关:eureka.instance.[nonSecurePortEnabled,securePortEnabled]=[false,true]
。 这样Eureka
就会经过安全方式发布实例信息。 这样的话,Spring Cloud 的DiscoveryClient
将会为已注册的服务返回一个https://…
URI, 同时Eureka
实例信息将会提供一个安全的健康检查URL。
因为
Eureka
的内部机制,使得还会为状态和主页提供一个非安全的URL,固然,这也是能够经过额外的配置关闭掉。
application.yml
eureka: instance: statusPageUrl: https://${eureka.hostname}/info healthCheckUrl: https://${eureka.hostname}/health homePageUrl: https://${eureka.hostname}/
注意:
${eureka.hostname}
是一个Eureka
的原生占位符,之后的版本才可用。因此,可使用spring的占位符来替代,如:${eureka.instance.hostName}
注意: 若是你运行在代理的网络状况,那SSL可能被代理清理掉。并且,代理可能致使你得到的来源端口、地址不正确
默认状况下,Eureka经过客户端心跳包来检测客户端状态。没有额外配置的状况下
Discovery
客户端不会为每个Spring Boot 应用发起额外的健康检查。这样,也就意味着,一旦服务注册成功后,Eureka
总会认为应用是在线状态。 固然,也能够开启Eureka的健康检查,这样应用状态就能够转播给Eureka了。
application.yml
eureka: client: healthcheck: enabled: true
警告:
eureka.client.healthcheck.enabled=true
只能在application.yml
中设置,若是在bootstrap.yml
中设置,会致使Eureka在注册时获得一个UNKNOWN
的状态
若是须要更多的健康检查控制,能够本身实现一个
com.netflix.appinfo.HealthCheckHandler
.
花些时间去了解Eureka的元数据是值得的,你能够在这个过程当中对本身平台有更清楚的认识。标准的元数据例如:主机名,IP地址,端口号,状态页,健康检查。这些会在服务注册以及客户端直连服务端时被发布出来。对于实例注册时,能够经过
eureka.instance.metadataMap
配置额外的元数据信息,这样不会对客户端有啥影响,除非客户端能本身处理某些特殊元数据。后面还会继续说明元数据在Spring Cloud 中的意义。
Cloudfoundry提供了针对全部实例中相同主机名相同应用的全局路由功能。相似一个小型PaaS平台。这个不是Eureka必要的功能,但仍是建议开启此功能。开启时,须要明确指定主机名和端口号。能够经过设置实例的元数据来让客户端区分不一样的实例,默认经过
eureka.instance.instanceId
和vcap.application.instance_id
来区分。例如:
application.yml
eureka: instance: hostname: ${vcap.application.uris[0]} nonSecurePort: 80
经过这种方式来设置Cloudfoundry实例的安全规则,你能够注册并使用虚拟主机的IP地址进行服务之间的调用。这个特性还不能在PWS(Pivotal Web Services)环境下使用。
若是须要在AWS中部署Eureka,能够定制一个
EurekaInstanceConfigBean
:
@Bean @Profile("!default") public EurekaInstanceConfigBean eurekaInstanceConfig() { EurekaInstanceConfigBean b = new EurekaInstanceConfigBean(); AmazonInfo info = AmazonInfo.Builder.newBuilder().autoBuild("eureka"); b.setDataCenterInfo(info); return b; }
普通的Netflix Eureka实例注册时使用主机名做为实例ID。Spring Cloud Eureka提供了一个更为合理的ID策略:
${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}}
例如:myhost:myappname:8080
使用Spring Cloud时,能够覆盖这个值,经过
eureka.instance.instanceId
这个配置。例如:
application.yml
eureka: instance: instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
若是多个服务实例部署在同一个主机上,那这个元数据会加上一个随机数,保证明例惟一性。 在一个Spring Boot 应用中,Cloudfoundry的
vcap.application.instance_id
会被自动赋值,不须要随机数。
一旦在应用中使用了
@EnableDiscoveryClient
或者@EnableEurekaClient
,那你就能够从Eureka Server中使用服务发现功能。 还有一种方法就是直接使用原生的com.netflix.discovery.EurekaClient
(对应Spring Cloud的DiscoveryClient
)。例如:
@Autowired private EurekaClient discoveryClient; public String serviceUrl() { InstanceInfo instance = discoveryClient.getNextServerFromEureka("STORES", false); return instance.getHomePageUrl(); }
提示:不要在@PostConstruct
方法以及@Scheduled
中(或者任何ApplicationContext
还没初始完成的地方)使用EurekaClient
。其须要等待SmartLifecycle
(phase=0
)初始化完成才能够
一般来讲,不须要直接使用原始的Netflix 的
EurekaClient
,由于,提供了不少更方便使用的包装器。 Spring Cloud支持Feign(一个REST客户端)以及Spring本身的RestTemplate
来使用Eureka服务的逻辑标识符,而不是经过物理URL。 能够为物理服务简单的配置一个固定列表集合:<client>.ribbon.listOfServers
用逗号分割物理地址或者主机名,<client>指的是客户端ID。
你也可使用
org.springframework.cloud.client.discovery.DiscoveryClient
,这个客户端提供了一套简单的API来操做客户端,不须要专门去使用Netflix。例如:
@Autowired private DiscoveryClient discoveryClient; public String serviceUrl() { List<ServiceInstance> list = discoveryClient.getInstances("STORES"); if (list != null && list.size() > 0 ) { return list.get(0).getUri(); } return null; }
做为一个实例涉及到一个心跳机制去注册(经过
serviceUrl
),默认持续30秒。直到实例自身,服务端,客户端各自元数据本地缓存同步完成后,服务才可用(至少须要3次心跳周期)。 能够经过eureka.instance.leaseRenewalIntervalInSeconds
修改这个周期,改善客户端连接到服务的速度。不过,考虑到短时间的波动以及服务续期等状况,在生产环境最好仍是用默认设定。