1.3.8.RELEASE
该项目为Spring Boot应用程序提供了Netflix OSS集成,通过对Spring Environment和其他Spring programming model idioms进行自动配置和绑定。通过一些简单的注解,您可以快速启用和配置应用程序内的通用模式,并使用经过生产测试的Netflix组件构建大型分布式系统。提供的模式包括服务发现(Eureka),断路器(Hystrix),智能路由(Zuul)和客户端负载平衡(Ribbon)。
11. Service Discovery: Eureka Clients
服务发现是基于微服务架构的关键原则之一。试图手动配置每个客户端或某种形式的约定可能非常困难,并且可能非常脆弱。 Eureka是Netflix Service Discovery Server and Client。服务器可以配置和部署为高可用性,每台服务器将注册服务的状态复制到其他服务器。
11.1 How to Include Eureka Client
要在您的项目中包含Eureka客户端,请使用group为 org.springframework.cloud和artifact id 为spring-cloud-starter-netflix-eureka-client的starter。请参阅 Spring Cloud Project page 页面,以获取有关使用当前Spring Cloud Release Train设置构建系统的详细信息。\
11.2 Registering with Eureka
当客户端向Eureka注册时,它会提供有关其本身的元数据,例如host and port, health indicator URL, home page等。Eureka接收来自属于服务的每个实例的心跳消息。如果心跳在可配置的时间表上失败,则通常从注册中心中删除该实例。
Example eureka client:
@Configuration @ComponentScan @EnableAutoConfiguration @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应用程序)。通过在类路径中使用spring-cloud-starter-netflix-eureka-client,您的应用程序将自动向Eureka服务器注册。找到Eureka服务器需要配置信息。例:
application.yml.
eureka:client:serviceUrl:defaultZone: http://localhost:8761/eureka/
其中“defaultZone”是一个magic string fallback value,它为任何不表示偏好的client提供service URL(它是一个有用的默认值)。
从Environment获取的default application name (service ID), virtual host and non-secure port分别为$ {spring.application.name},$ {spring.application.name}和$ {server.port}。
在类路径上具有spring-cloud-starter-netflix-eureka-client使得该应用既变成了Eureka的“实例”(因为它向Eureka注册自己)也变成了Eureka的“client”(因为它可以查询registry以查找其他服务)。实例行为由eureka.instance.*配置key驱动,但如果确保应用程序具有spring.application.name(这是Eureka Service ID或VIP的默认值),则默认值将会很好。
有关可配置选项的更多详细信息,请参阅 EurekaInstanceConfigBean and EurekaClientConfigBean。
要禁用 Eureka Discovery Client ,您可以将eureka.client.enabled设置为false。
11.3 Authenticating with the Eureka Server
如果其中一个eureka.client.serviceUrl.defaultZoneURL嵌入了credentials (curl style, like http://user:password@localhost:8761/eureka
),则HTTP basic authentication将自动添加到您的Eureka客户端。对于更复杂的需求,您可以创建一个DiscoveryClientOptionalArgs类型的@Bean,并将ClientFilter实例注入到它中,所有这些实例都将应用于从客户端到服务器的调用请求中。
11.4 Status Page and Health Indicator
11.5 Registering a Secure Application
11.6 Eureka’s Health Checks
11.7 Eureka Metadata for Instances and Clients
11.7.1 Using Eureka on Cloudfoundry
11.7.2 Using Eureka on AWS
11.7.3 Changing the Eureka Instance ID
11.8 Using the EurekaClient
一旦你有一个作为 discovery client的应用程序,你就可以使用它来发现来自 Eureka Server的service实例。一种方法是使用本地的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),因此最早可以依赖它的是另一个具有更高 phase的SmartLifecycle。
11.8.1 EurekaClient without Jersey
默认情况下,EurekaClient使用Jersey进行HTTP通信。如果你希望避免来自Jersey的依赖关系,你可以将它从你的依赖关系中排除。 Spring Cloud将自动配置基于Spring RestTemplate的传输客户端。
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><exclusions><exclusion><groupId>com.sun.jersey</groupId><artifactId>jersey-client</artifactId></exclusion><exclusion><groupId>com.sun.jersey</groupId><artifactId>jersey-core</artifactId></exclusion><exclusion><groupId>com.sun.jersey.contribs</groupId><artifactId>jersey-apache-client4</artifactId></exclusion></exclusions> </dependency>
11.9 Alternatives to the native Netflix EurekaClient
11.10 Why is it so Slow to Register a Service?
11.11 Zones
12. Service Discovery: Eureka Server
12.1 How to Include Eureka Server
要在您的项目中包括Eureka服务器,请使用group为org.springframework.cloud和artifact id为 spring-cloud-starter-netflix-eureka-server的引用。请参阅 Spring Cloud Project page页面,以获取有关使用当前Spring Cloud Release Train设置构建系统的详细信息。
12.2 How to Run a Eureka Server
Example eureka server;
@SpringBootApplication @EnableEurekaServer public class Application {public static void main(String[] args) {new SpringApplicationBuilder(Application.class).web(true).run(args);}}
这个Eureka Server具有带UI的主页,每个Eureka功能对应的HTTP API端点都在在/eureka/*下。
12.3 High Availability, Zones and Regions
12.4 Standalone Mode
The combination of the two caches (client and server) and the heartbeats make a standalone Eureka server fairly resilient to failure, as long as there is some sort of monitor or elastic runtime keeping it alive (e.g. Cloud Foundry). In standalone mode, you might prefer to switch off the client side behaviour, so it doesn’t keep trying and failing to reach its peers. Example:
application.yml (Standalone Eureka Server).
server:port: 8761eureka:instance:hostname: localhostclient:registerWithEureka: falsefetchRegistry: falseserviceUrl:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
请注意,serviceUrl指向与本地实例相同的主机。
12.5 Peer Awareness
通过运行多个实例并要求它们相互注册,Eureka可以变得更加灵活和可用。事实上,这是默认的行为,所以你需要做的只是为每个同级的server添加一个有效的serviceUrl。
application.yml (Two Peer Aware Eureka Servers).
--- spring:profiles: peer1 eureka:instance:hostname: peer1client:serviceUrl:defaultZone: http://peer2/eureka/--- spring:profiles: peer2 eureka:instance:hostname: peer2client:serviceUrl:defaultZone: http://peer1/eureka/
在这个例子中,我们有一个YAML文件,它可以用于在两台主机(peer1和peer2)上运行同一台服务器,方法是使用不同的Spring profile中运行它。您可以使用此配置通过操纵/ etc / hosts来解析主机名来测试单个主机上的对等意识(在生产中没有太多价值)。事实上,如果您运行在知道主机名的机器上(默认情况下使用java.net.InetAddress查找),则不需要eureka.instance.hostname。
您可以将多个peers (对等点)添加到系统,只要它们全部通过至少一个方面相互连接,它们将会互相同步注册信息。如果peers在物理上是分开的(在数据中心内部或在多个数据中心之间),那么系统原则上会存在split-brain故障。
12.6 Prefer IP Address
在某些情况下,Eureka最好通知服务的IP地址而不是主机名。将eureka.instance.preferIpAddress设置为true,当应用程序向eureka注册时,它将使用其IP地址而不是其主机名。
如果主机名不能由Java确定,则IP地址被发送给Eureka。唯一显式设置主机名的方式是使用eureka.instance.hostname来设置主机名。您可以使用环境变量在运行时设置主机名,例如eureka.instance.hostname = $ {HOST_NAME}。
13. Circuit Breaker: Hystrix Clients
Netflix创建了一个名为 Hystrix 的库,实现 circuit breaker pattern。在微服务体系结构中,通常有多层服务调用。
较低级别的服务中的服务故障可能导致级联故障直至用户。在由metrics.rollingStats.timeInMilliseconds(默认值:10秒)定义的滚动窗口中,对特定服务的调用大于circuitBreaker.requestVolumeThreshold(默认值:20个请求)且故障百分比大于circuitBreaker.errorThresholdPercentage(默认值:> 50% ),circuit 打开并且不再进行请求。在发生错误和开路的情况下,开发者可以提供fallback。
开路可以防止级联失败,并可以提供出现问题的服务重新恢复的时间。The fallback可以是另一个Hystrix保护的调用,静态数据或合适的空值。fallback可以被级联调用,因此第一次fallback调用可以调用处理其他业务然后可以继续调用到静态数据fallback。
13.1 How to Include Hystrix
要将Hystrix包含在您的项目中,请使用group为org.springframework.cloud和artifact id为 spring-cloud-starter-netflix-hystrix的引用。请参阅 Spring Cloud Project page ,以获取有关使用当前Spring Cloud Release Train设置构建系统的详细信息。
Example boot app:
@SpringBootApplication @EnableCircuitBreaker public class Application {public static void main(String[] args) {new SpringApplicationBuilder(Application.class).web(true).run(args);}}@Component public class StoreIntegration {@HystrixCommand(fallbackMethod = "defaultStores")public Object getStores(Map<String, Object> parameters) {//do stuff that might fail}public Object defaultStores(Map<String, Object> parameters) {return /* something useful */;} }
@HystrixCommand由一个名为“javanica”的Netflix contrib库提供。 Spring Cloud会自动将带有该注释的Spring bean包装在连接到Hystrix断路器的代理中。断路器计算何时打开和关闭电路,以及在发生故障时应采取的措施。
要配置@HystrixCommand,您可以使用带有@HystrixProperty注解列表的commandProperties
属性。详情请看 here 。有关可用属性的详细信息,请参阅Hystrix wiki。
13.2 Propagating the Security Context or using Spring Scopes
13.3 Health Indicator
连接断路器的状态也暴露在被调用的应用程序的/ health端点中。
{ "hystrix": { "openCircuitBreakers": ["StoreIntegration::getStoresByLocationLink"],"status": "CIRCUIT_OPEN"},"status": "UP" }
13.4 Hystrix Metrics Stream
启用Hystrix metrics stream包括spring-boot-starter-actuator的依赖。这会将 /hystrix.stream 暴露
为管理端点。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
14. Circuit Breaker: Hystrix Dashboard
Hystrix的主要优势之一是它收集的每个HystrixCommand的metrics 集合。 Hystrix Dashboard(仪表盘)以高效的方式显示每个circuit breaker(断路器)的运行状况。
15. Hystrix Timeouts And Ribbon Clients
使用包装Ribbon clients的Hystrix commands时,要确保将Hystrix timeout配置比配置的Ribbon timeout更长,包括可能进行的任何潜在重试。例如,如果您的Ribbon连接超时时间为一秒,并且Ribbon Clients可能会重试该请求三次,那么您的Hystrix超时应略超过三秒。
15.1 How to Include Hystrix Dashboard
要在项目中包含Hystrix Dashboard,请使用group为org.springframework.cloud和artifact ID 为spring-cloud-starter-hystrix-netflix-dashboard的引用。请参阅 Spring Cloud Project page页面,以获取有关使用当前Spring Cloud Release Train设置构建系统的详细信息。
运行Hystrix Dashboard使用@EnableHystrixDashboard注解Spring Boot主类。然后访问/ hystrix并将仪表板指向Hystrix客户端应用程序中的单个实例/hystrix.stream端点。
连接到使用HTTPS的/hystrix.stream端点时,服务器使用的证书必须由JVM信任。如果证书不可信,您必须将证书导入到JVM中,以便Hystrix仪表板成功连接到stream 终端。
15.2 Turbine
从整个系统的健康状况来看,查看 individual instances Hystrix数据并不是很有用。 Turbine是一个应用程序,它将所有相关的/hystrix.stream端点汇总到一个组合的/turbine.stream中,供Hystrix仪表板使用。Individual instances通过Eureka找到。 运行Turbine只要使用@EnableTurbine注解(例如,使用spring-cloud-starter-netflix-turbine来设置类路径)注释main类就好了。所有来自 the Turbine 1 wiki的配置属性都被应用。唯一的区别是turbine.instanceUrlSuffix不需要预先添加端口,因为除非turbine.instanceInsertPort = false,否则它会自动处理。
默认情况下,Turbine通过在Eureka中查找注册实例的hostname和port entrys去查找这个注册实例的/hystrix.stream端点,然后将/hystrix.stream端点附加到注册实例上。如果实例的元数据包含management.port,则将使用它而不是/hystrix.stream端点的端口值。默认情况下,元数据条目management.port等于management.port配置属性,但可以使用以下配置覆盖它:
eureka:instance:metadata-map:management.port: ${management.port:8081}
配置key turbine.appConfig是trubin将用于查找实例的eureka serviceIds列表。然后turbine stream被用于Hystrix仪表板中,使用如下形式的URL:http://my.turbine.sever:8080/turbine.stream?cluster=CLUSTERNAME(如果名称为“default”,则可以省略cluster参数)。cluster参数必须与turbine.aggregator.clusterConfig entry匹配。从Eureka返回的值是大写,因此,如果有一个名为“customers”的应用程序注册到Eureka,我们预计此示例可以工作:
turbine:aggregator:clusterConfig: CUSTOMERSappConfig: customers
如果您需要定制Turbine应使用什么cluster names(您不想在turb.aggregator.clusterConfig配置中存储cluster names),请提供TurbineClustersProvider类型的bean。
clusterName可以通过turbine.clusterNameExpression中的SPEL表达式进行自定义,用root作为InstanceInfo的一个实例。缺省值是appName,这意味着Eureka serviceId最终作为cluster key(例如,customers的InstanceInfo具有“CUSTOMERS”的appName)。另一个示例是turb.clusterNameExpression = aSGName,它将从AWS ASG名称中获取集群名称。另一个例子:
turbine:aggregator:clusterConfig: SYSTEM,USERappConfig: customers,stores,ui,adminclusterNameExpression: metadata['cluster']
在这种情况下,来自4个服务的 cluster name 将从其元数据map中提取出来,并且预计包含“SYSTEM”和“USER”的值。
要为所有应用程序使用“default” cluster,您需要一个字符串文字表达式(使用单引号,如果使用YAML,也使用双引号进行转义):
turbine:appConfig: customers,storesclusterNameExpression: "'default'"
Spring Cloud提供了一个spring-cloud-starter-netflix-turbine,它拥有运行Turbine服务器所需的所有依赖。只需创建一个Spring Boot应用程序并使用@EnableTurbine对其进行注释。
默认情况下,Spring Cloud允许Turbine使用主机和端口为每个主机,每个群集允许多个进程。如果您希望Turbine中内置的本机Netflix行为不允许每个主机,每个集群(实例id的key是主机名)都有多个进程,那么请设置属性turbine.combineHostPort = false。
15.3 Turbine Stream
16. Client Side Load Balancer: Ribbon
Ribbon是一个客户端负载均衡器,它可以让您对HTTP和TCP客户端的行为有很多控制权。 Feign已经使用Ribbon,所以如果您使用的是@FeignClient,那么本节也适用您。
Ribbon中的一个核心概念是named client的概念。每个负载均衡器都是组件的集合的一部分,这些组件一起工作以根据需要连接远程服务器,并且该集合具有作为应用程序开发人员提供的名称(例如,使用@FeignClient注释)。 Spring Cloud使用RibbonClientConfiguration根据需要为每个named client创建一个新的ensemble 作为ApplicationContext。这包含(除其他外)an ILoadBalancer
, a RestClient
, and a ServerListFilter
.。
未完待续