Netflix:提供了很多組件來構建大型分佈式系統,包括服務發現(Eureka)、斷路器(Hystrix)、智能路由(Zuul)和客戶端負載平衡(Ribbon)。
5.1. Service Discovery: Eureka Clients
5.1.1. How to Include Eureka Client
引用依賴:
group ID:org.springframework.cloud
artifact ID: spring-cloud-starter-netflix-eureka-client
5.1.2. Registering with Eureka
客戶端向Eureka註冊時,提供了自身的元數據(host、port、健康指示的url、主頁和其他詳細信息),Eureka會通過心跳機制檢測各實例的狀態,如果超過配置時間沒得到心跳,Eureka會認爲實例掛掉了,會從註冊表中刪除實例。
下面的例子展示了一個最小的Eureka客戶端應用程序:
@SpringBootApplication
@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);
}
}
application.yml
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
設置eureka.client.enabled
爲false禁止Eureka來發現服務。當spring.cloud.discovery.enabled
設置爲false的時候,Eureka也不會去發現客戶端。
5.1.3. Authenticating with the Eureka Server
user:password@localhost:8761/eureka
格式配置eureka.client.serviceUrl.defaultZone,HTTP基本身份驗證將自動添加到您的eureka客戶機中。 或者可以創建一個DiscoveryClientOptionalArgs bean,並注入ClientFilter實例。
5.1.4. Status Page and Health Indicator
application.yml
eureka:
instance:
statusPageUrlPath: ${server.servletPath}/info #狀態監測
healthCheckUrlPath: ${server.servletPath}/health #健康監測
5.1.5. Registering a Secure Application
下面兩個配置讓Eureka發佈的時候以HTTPS的方式發佈:
eureka.instance.[nonSecurePortEnabled]=[false]
eureka.instance.[securePortEnabled]=[true]
由於Eureka的內部工作方式,它仍然爲狀態和主頁發佈不安全的URL,除非您也顯式地覆蓋它們。您可以使用佔位符來配置eureka實例url,如下例所示:
application.yml
eureka:
instance:
statusPageUrl: https://${eureka.hostname}/info
healthCheckUrl: https://${eureka.hostname}/health
homePageUrl: https://${eureka.hostname}/
5.1.6. Eureka’s Health Checks
默認情況下,Eureka使用客戶端心跳來確定客戶端是否啓動。除非另有說明,否則發現客戶端不會根據SpringBootActuator傳播應用程序的當前健康檢查狀態。因此,在成功註冊之後,尤里卡總是會宣佈應用程序處於“UP”狀態。可以通過啓用Eureka健康檢查來更改此行爲,這將導致將應用程序狀態傳播到Eureka。因此,所有其他應用程序都不會將流量發送到除“UP”以外的其他狀態的應用程序。下面的示例展示瞭如何使用:
application.yml
eureka:
client:
healthcheck:
enabled: true
注意該配置智能配置在application.yml中,配置在bootstrap.yml中會導致註冊到Eureka後狀態是UNKNOWN 。
如果您需要對健康檢查進行更多的控制,請考慮實現您自己的com.netflix.appinfo.HealthCheckHandler。
5.1.7. Eureka Metadata for Instances and Clients
Using Eureka on Cloud Foundry
Using Eureka on AWS
Changing the Eureka Instance 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來覆蓋默認值:
application.yml
eureka:
instance:
instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
5.1.8. Using the EurekaClient
一旦您有了一個發現客戶機應用程序,就可以使用它從Eureka服務器發現服務實例。一種方法是使用本地的com.netflix.discovery.EurekaClient(與Spring Cloud DiscoveryClient相反),如下面的示例所示:
@Autowired
private EurekaClient discoveryClient;
public String serviceUrl() {
InstanceInfo instance = discoveryClient.getNextServerFromEureka("STORES", false);
return instance.getHomePageUrl();
}
EurekaClient without Jersey
默認情況下,EurekaClient使用Jersey進行HTTP通信。如果希望避免Jersey的依賴項,可以將其排除在依賴項之外。Spring Cloud基於Spring RestTemplate自動配置傳輸客戶機。看下面:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</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>
5.1.9. Alternatives to the Native Netflix EurekaClient
5.1.10. Why Is It so Slow to Register a Service?
作爲一個實例還涉及到到註冊中心的一個週期心跳(通過客戶機的serviceUrl),默認持續時間爲30秒。只有當實例、服務器和客戶端在其本地緩存中都具有相同的元數據時,客戶端才能發現服務(因此可能需要3次心跳)。
5.1.11. Zones
5.1.12. Refreshing Eureka Clients
eureka.client.refresh.enable=false #禁止eureka客戶端刷新
5.1.13. Using Eureka with Spring Cloud LoadBalancer
5.2. Service Discovery: Eureka Server
5.2.1. How to Include Eureka Server
group ID: org.springframework.cloud
artifact ID:spring-cloud-starter-netflix-eureka-server
5.2.2. How to Run a Eureka Server
@SpringBootApplication
@EnableEurekaServer
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
服務器有一個主頁,在/ Eureka /*下有用於正常Eureka功能的UI和HTTP API端點。
5.2.3. High Availability, Zones and Regions
Eureka服務器沒有後端存儲,但是註冊表中的服務實例都必須發送心跳來保持它們的註冊是最新的(所以這可以在內存中完成)。客戶端也有一個Eureka註冊的內存緩存(這樣他們就不必爲每個服務請求都去註冊)。
默認情況下,每個Eureka服務器也是一個Eureka客戶端,需要(至少一個)服務URL來定位一個對等點。如果您不提供它,服務就會運行並正常工作,但是它會使您的日誌充滿許多關於不能向對等方註冊的噪音。
5.2.4. Standalone Mode
這兩個緩存(客戶端和服務器)和心跳的組合使一個獨立的Eureka服務器具有相當強的故障恢復能力,只要有某種監視器或彈性運行時(如Cloud Foundry)使它保持活動狀態。在獨立模式下,您可能更希望關閉客戶端行爲,這樣它就不會一直嘗試,也不會失敗。下面的例子演示瞭如何關閉客戶端行爲:
application.yml (Standalone Eureka Server)
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
注意,serviceUrl指向與本地實例相同的主機。
5.2.5. Peer Awareness
通過運行多個實例並讓它們彼此註冊,Eureka可以變得更有彈性和可用性。實際上,這是默認的行爲,所以您需要做的只是向對等節點添加一個有效的serviceUrl,如下面的示例所示:
application.yml (Two Peer Aware Eureka Servers)
---
spring:
profiles: peer1
eureka:
instance:
hostname: peer1
client:
serviceUrl:
defaultZone: https://peer2/eureka/
---
spring:
profiles: peer2
eureka:
instance:
hostname: peer2
client:
serviceUrl:
defaultZone: https://peer1/eureka/
在前面的示例中,我們有一個YAML文件,可以通過在不同的Spring配置文件中運行它來在兩個主機(peer1和peer2)上運行相同的服務器。您可以通過操作/etc/hosts來解析主機名,從而使用此配置測試單個主機上的對等點感知(在生產環境中這樣做沒有多大價值)。實際上,如果您運行的機器知道自己的主機名(默認情況下,使用java.net.InetAddress
查找),則不需要eureka.instance.hostname
。
您可以將多個對等點添加到一個系統中,並且只要它們都通過至少一條邊彼此連接,它們就會在彼此之間同步註冊。如果對等點在物理上是分開的(在一個數據中心內或在多個數據中心之間),那麼在原則上,系統可以在“split-brain”類型的故障中倖存下來。您可以向系統中添加多個對等點,只要它們彼此都直接連接,它們就會在彼此之間同步註冊。
application.yml (Three Peer Aware Eureka Servers)
eureka:
client:
serviceUrl:
defaultZone: https://peer1/eureka/,http://peer2/eureka/,http://peer3/eureka/
---
spring:
profiles: peer1
eureka:
instance:
hostname: peer1
---
spring:
profiles: peer2
eureka:
instance:
hostname: peer2
---
spring:
profiles: peer3
eureka:
instance:
hostname: peer3
5.2.6. When to Prefer IP Address
eureka.instance.preferIpAddress = true #以ip的形式發佈,而不是主機名
5.2.7. Securing The Eureka Server
只需通過Spring -boot-starter- Security
將Spring Security添加到服務器的類路徑中,就可以保護Eureka服務器。默認情況下,當Spring Security在類路徑上時,它將要求在嚮應用程序發送每個請求時發送一個有效的CSRF令牌。Eureka客戶端通常不會擁有有效的跨站請求僞造(CSRF)令牌,您需要禁用/ Eureka /**端點的這個要求。例如:
@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().ignoringAntMatchers("/eureka/**");
super.configure(http);
}
}
For more information on CSRF see the Spring Security documentation.
A demo Eureka Server can be found in the Spring Cloud Samples repo.
5.2.8. Disabling Ribbon with Eureka Server and Client starters
spring-cloud-starter-netflix-eureka-server
和spring-cloud-starter-netflix-eureka-client
附帶了一個spring-cloud-starter-netflix-ribbon
。由於Ribbon負載均衡器現在處於維護模式,我們建議改用Spring Cloud LoadBalancer,它也包含在Eureka啓動器中。
pring.cloud.loadbalancer.ribbon.enabled = false #禁用ribbon負載均衡
也可以從maven依賴中去除ribbon依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</exclusion>
<exclusion>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-eureka</artifactId>
</exclusion>
</exclusions>
</dependency>
5.2.9. JDK 11 Support
Eureka服務器所依賴的JAXB模塊在JDK 11中被刪除。如果您打算在運行Eureka服務器時使用JDK 11,則必須在POM或Gradle文件中包含這些依賴項。
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>