爲了鞏固自身學習,從今天(2019.01.08),天天晚上開始總結SpringCloud的相關學習,用於自我勉勵,自我積累與人生總結。html
總結2018年的我,心態較之從前浮躁,雜念多了,沒有用心,更沒能好好的反思本身;按照本身單身的狀況,平時我本應該有更多的時間去學習,去提升,去真正的充實本身。java
學習自己就並不是易事,不管是爲了生活仍是理想,仍是一種生活狀態,最重要的是要用心,要真正的去理解,更要沉得住氣,靜得下心。git
選擇了IT這一行,應該有苦修的覺悟,任何技術只停留在簡單會用的階段(目前我深陷其中),實際上是遠遠不夠的。就跟我最先學了spring-cloud-ribbon只知道一個@LoadBalanced同樣,感受很空洞,遇到問題可能就會一籌莫展,由於本身根本沒有真正的學會一件事,沒有真正悟到它的原理,認清它的本質。github
2019年,我但願我能戒掉週末還有時間打遊戲的生活狀態,能充實本身,克服焦慮;web
2019年,我但願我能堅持,能勤奮;spring
2019年,我但願我能多讀書,能成長;bootstrap
2019年,我但願我能坦然面對生活中的任何壓力,能有內驅動力,能找到女友,找到外驅動力。api
但願我每次看到這段給本身的話,都不要忘了初心。緩存
好了,閒言碎語,皆盡於此。安全
它主要記錄各個微服務和微服務地址的映射關係,各個微服務都將本身註冊到這個註冊中心上面,當微服務之間須要互相調用時,就能夠從註冊中心上面去發現微服務和進行調用。
Spring Cloud是一個開箱即用的微服務框架,秉承了微服務的真正理念而設計。
注 : 本文只講Eureka,不關注Consul與Zookeeper等替代方案
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-eureka-server</artifactId> </dependency>
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; /** * Created by EalenXie on 2018/12/28 14:13. */ @EnableEurekaServer @SpringBootApplication public class SpringCloudEurekaServerApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudEurekaServerApplication.class, args); } }
server: port: 8761 eureka: instance: hostname: localhost # 服務註冊中心實例的主機名 lease-renewal-interval-in-seconds: 30 # 客戶端向Eureka發送心跳週期(s) lease-expiration-duration-in-seconds: 90 # Eureka Server接收實例的最後一次發出的心跳後,刪除須要等待時間(s) server: enable-self-preservation: true # Eureka自我保護模式 client: register-with-eureka: false # 是否向服務註冊中心註冊本身 fetch-registry: false # 是否檢索發現服務 service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # 指定服務註冊中心的位置
Eureka Server 實例1 配置
server: port: 8761 eureka: instance: hostname: localhost # 服務註冊中心實例的主機名 server: enable-self-preservation: true # Eureka自我保護模式 client: register-with-eureka: true # 是否註冊到Eureka Server fetch-registry: true # 是否檢索發現服務 service-url: defaultZone: http://${eureka.instance.hostname}:8762/eureka/,http://${eureka.instance.hostname}:8763/eureka/ #指定多個服務註冊中心的位置,並向服務註冊中心註冊本身
Eureka Server 實例2 配置
server: port: 8762 eureka: instance: hostname: localhost # 服務註冊中心實例的主機名 server: enable-self-preservation: true # Eureka自我保護模式 client: register-with-eureka: true # 是否註冊到Eureka Server fetch-registry: true # 是否檢索發現服務 service-url: defaultZone: http://${eureka.instance.hostname}:8761/eureka/,http://${eureka.instance.hostname}:8763/eureka/ #指定多個服務註冊中心的位置,並向服務註冊中心註冊本身
...
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * Created by EalenXie on 2018/12/28 14:45. */ @SpringBootApplication @EnableDiscoveryClient public class SpringCloudEurekaClientApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudEurekaClientApplication.class, args); } }
server: port: 8090 spring: application: name: spring-cloud-eureka-client-application eureka: client: service-url: defaultZone: http://localhost:8761/eureka/
package com.netflix.discovery.shared; import java.util.List; import com.netflix.appinfo.InstanceInfo; public interface LookupService<T> { Application getApplication(String appName); Applications getApplications(); List<InstanceInfo> getInstancesById(String id); InstanceInfo getNextServerFromEureka(String virtualHostname, boolean secure); }
默認狀況下,若是Eureka Server在必定時間內沒有接收到某個微服務實例的心跳,Eureka Server將會註銷該實例(默認90秒)。 可是當網絡分區故障發生時,會統計心跳失敗的比例,閾值因子默認是0.85,若是閾值比最小值大則代表微服務與Eureka Server之間沒法正常通訊,這就可能變得很是危險了--由於微服務自己是健康的,此時本不該該註銷這個微服務。 Eureka Server經過'自我保護模式'來解決這個問題,當Eureka Server節點在短期內丟失過多客戶端時(可能發生了網絡分區故障),那麼這個節點就會進入自我保護模式。 一旦進入該模式,Eureka Server就會保護服務註冊表中的信息,再也不刪除服務註冊表中的數據(也就是不會註銷任何微服務)。當網絡故障恢復後,該Eureka Server節點會自動退出自我保護模式。 自我保護模式是一種對網絡異常的安全保護措施。使用自我保護模式,而已讓Eureka集羣更加的健壯、穩定。
POST /eureka/apps/{appId} 註冊新的實例 DELETE /eureka/apps/{appId}/{instanceId} 註銷應用實例 PUT /eureka/apps/{appId}/{instanceId} 應用實例發送心跳 GET /eureka/apps 查詢全部的實例 GET /eureka/apps/{appId} 查詢指定appId的實例 GET /eureka/apps/{appId}/{instanceId} 查詢指定appId和instanceId的實例 GET /eureka/instances/{instanceId} 查詢指定的instanceId的實例 PUT /eureka/apps/{appId}/{instanceId}/status?value=OUT_OF_SERVICE 暫停應用實例 PUT /eureka/apps/{appId}/{instanceId}/status?value=UP 恢復應用實例 PUT /eureka/apps/{appId}/{instanceId}/metadata?key=value 更新元數據信息 GET /eureka/vips/{vipAddress} 根據vip地址查詢 GET /eureka/svips/{svipAddress} 根據svip地址查詢
InstanceInfo : 註冊的服務實例,裏面包含服務實例的各項屬性 LeaseInfo : Eureka用這個類來標識應用實例的租約信息 ServiceInstance : 發現的實例信息的抽象接口,約定了服務發現的實例應用有哪些通用信息 InstanceStatus : 用於標識服務實例的狀態,是一個枚舉類,主要有狀態UP,DOWN,STARTING,OUT_OF_SERVICE,UNKNOWN EurekaServerConfigBean : Eureka Server的核心配置類,裏面包含了Eureka Server的各項核心屬性信息
package com.netflix.eureka.lease; import com.netflix.eureka.registry.AbstractInstanceRegistry; public interface LeaseManager<T> { void register(T r, int leaseDuration, boolean isReplication); boolean cancel(String appName, String id, boolean isReplication); boolean renew(String appName, String id, boolean isReplication); void evict(); }
服務註冊(register) : 其餘客戶端將本身註冊到Eureka上面 服務下線(cancel) : Eureka 刪除服務信息 服務租約(renew) : 客戶端定時向Eureka發送心跳證實本身存活,Eureka接收到心跳爲其維持租約 服務剔除(evict) : Eureka Server的方法,剔除心跳檢測過時的服務實例
package name.ealen.listener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean; import org.springframework.cloud.netflix.eureka.server.event.*; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; /** * Created by EalenXie on 2018/9/20 14:46. * EurekaServerEventListener 監聽Eureka的事件行爲 * 注 : EurekaInstanceRegisteredEvent,EurekaInstanceCanceledEvent,EurekaInstanceRenewedEvent */ @Component public class EurekaServerEventListener { private static final Logger log = LoggerFactory.getLogger(EurekaServerEventListener.class); /** * Eureka Server 註冊事件 */ @EventListener public void eurekaRegister(EurekaRegistryAvailableEvent event) { //write your logic.......... log.info("Eureka Server Register at timestamp : {}", event.getTimestamp()); } /** * Eureka Server 啓動事件 */ @EventListener public void serverStart(EurekaServerStartedEvent event) { //write your logic.......... Object source = event.getSource(); if (source instanceof EurekaServerConfigBean) { EurekaServerConfigBean eureka = (EurekaServerConfigBean) source; log.info("Eureka ServerConfigBean : {}",eureka); } } /** * 服務註冊事件 */ @EventListener(condition = "#event.replication==false") public void instanceRegister(EurekaInstanceRegisteredEvent event) { //write your logic.......... log.info("Register InstanceInfo : {}",event.getInstanceInfo()); } /** * 服務下線事件 */ @EventListener(condition = "#event.replication==false") public void instanceCancel(EurekaInstanceCanceledEvent event) { //write your logic.......... log.info("instanceCancel serviceId : {}",event.getServerId()); } /** * 服務續約事件 */ @EventListener(condition = "#event.replication==false") public void instanceRenewed(EurekaInstanceRenewedEvent event) { //write your logic.......... } }
Eureka會爲每一個核心動做發佈一個相關的事件,咱們能夠經過監聽這些事件來作一些針對性的自定義處理邏輯。 Eureka Server自身註冊事件 : EurekaRegistryAvailableEvent Eureka Server自身啓動事件 : EurekaServerStartedEvent 服務註冊事件(register) : EurekaInstanceRegisteredEvent 服務下線事件(cancel) : EurekaInstanceCanceledEvent 服務租約事件(renew,續約,發送心跳) : EurekaInstanceRenewedEvent
Spring Boot Actuator 提供了/health 端點
只須要啓用Eureka的健康檢查,就能夠將端點中的健康狀態傳遞到Eureka Server
eureka.client.healthcheck.enable: true
注意 : 這個只能在application.yml中配置,若是在bootstrap.yml中配置,可能會致使一些不良後果。
這一點官方有明確說明 : https://cloud.spring.io/spring-cloud-static/Edgware.SR5/single/spring-cloud.html#_eureka_s_health_checks
eureka.client.register-with-eureka: true 是否註冊本身到Eureka Server上面 eureka.client.fetch-registry: true 是否從Eureka Server上面拉取服務信息 eureka.client.enable: true 是否啓用Eureka客戶端,不啓用則不註冊到Eureka Server eureka.client.healthcheck.enable: true 是否啓用Eureka健康檢查 eureka.client.availability-zones: new HashMap<>() 告訴client有哪些可用的region和zone eureka.client.filter-only-up-instances: true 是否過濾出InstanceStatus爲UP的實例 eureka.client.region: us-east-1 指定該應用實例所在的region,AWS datacenters適用 eureka.client.prefer-same-zone-eureka: true 是否優先使用與該應用相同Zone的Eureka Server eureka.client.cache-refresh-executor-thread-pool-size: 2 緩存刷新線程池CacheRefreshThread的初始化線程數 eureka.client.registry-fetch-interval-seconds: 30 Eureka client拉取服務註冊信息間隔時間(s) eureka.client.instance-info-replication-interval-seconds: 30 複製實例變化信息到Eureka服務器所須要的時間間隔(s) eureka.client.eureka-service-url-poll-interval-seconds: 300 輪詢Eureka服務端地址更改的間隔時間(s) eureka.client.eureka-server-read-timeout-seconds: 8 讀取Eureka Server信息的超時時間(s) eureka.client.eureka-server-connect-timeout-seconds: 5 鏈接Eureka Server的超時時間(s) eureka.client.eureka-server-total-connections: 200 從Eureka客戶端到全部Eureka服務端的鏈接總數 eureka.client.eureka-server-total-connections-per-host: 50 從Eureka客戶端到每一個Eureka服務端主機的鏈接總數 eureka.client.eureka-connection-idle-timeout-seconds: 30 Eureka服務端鏈接的空閒關閉時間(s) eureka.instance.metadata-map: new HashMap<>() 指定應用實例的元數據信息 eureka.instance.prefer-ip-address: false 是否優先使用ip地址來替代hostname做爲實例hostname字段值 eureka.instance.lease-expiration-duration-in-seconds: 90 Eureka clent最後一次心跳後,Eureka Server剔除須要等待時間(s) eureka.instance.lease-renewal-interval-in-seconds: 30 客戶端向Eureka Server發送心跳週期(s)
eureka.server.enable-self-preservation: true Eureka Server是否開啓自我保護模式 eureka.server.renewal-percent-threshold: 0.85 指定每分鐘須要收到的續約次數的闕值,若是閾值比最小值大,則自我保護模式開啓 eureka.server.eviction-interval-timer-in-ms: 60*1000 指定EvictionTask定時任務的調度頻率,用於剔除過時的實例 eureka.server.wait-time-in-ms-when-sync-empty: 1000*60*5 在Eureka服務器獲取不到集羣裏對等服務器上的實例時,須要等待的時間
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
security: basic: enabled: true # 開啓基於HTTP Basic的認證 user: name: ealenxie # 登錄帳號名 password: zaxscdvfrewq # 登錄密碼 server: port: 8761 eureka: instance: hostname: localhost # 服務註冊中心實例的主機名 client: register-with-eureka: false # 是否向服務註冊中心註冊本身 fetch-registry: false # 是否檢索發現服務 service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # 指定服務註冊中心的位置
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @EnableWebSecurity public class EurekaServerSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { super.configure(http); http.csrf().disable(); } }
security: basic: enabled: true # 開啓基於HTTP Basic的認證 user: name: ealenxie # 登錄帳號名 password: zaxscdvfrewq # 登錄密碼 server: port: 8090 spring: application: name: spring-cloud-eureka-client-application eureka: client: service-url: defaultZone: http://${security.user}:${security.password}@localhost:8761/eureka/ #包含帳號信息的Eureka Server地址
其實現方式能夠參考博客(篇幅緣由) : https://www.v2ex.com/t/516287
或者參考《從新定義Spring Cloud實戰》一書 , 61頁章節,啓用https。
基本效果 :
<dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-server</artifactId> <version>1.5.6</version> </dependency> <dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-server-ui</artifactId> <version>1.5.6</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- 在管理界面中與 JMX-beans 進行交互所須要被依賴的 JAR --> <dependency> <groupId>org.jolokia</groupId> <artifactId>jolokia-core</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
package name.ealen; import de.codecentric.boot.admin.config.EnableAdminServer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * Created by EalenXie on 2018/11/6 9:23. */ @SpringBootApplication @EnableDiscoveryClient @EnableAdminServer public class SpringBootAdminApplication { public static void main(String[] args) { SpringApplication.run(SpringBootAdminApplication.class,args); } }
server: port: 8889 spring: application: name: spring-cloud-boot-admin eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ management: security: enabled: false
點開 Details按鈕,能夠看到Admin裏面的各類詳細配置信息,內存信息,接口調用次數,甚至是線程數量,均可以一目瞭然,十分方便。
大量參考了《從新定義Spring Cloud實戰》一書的內容 , 我的十分推崇。
參考了周立老師的《Spring Cloud與Docker》一書。
參考了翟永超大神的《Spring Cloud 微服務實戰》一書。
本文是總結根據自身從各路大神所學習到的內容與理解。
我的才疏學淺,如博文有不當之處,望各路大神見諒和幫忙指正。
原創不易,十分感謝各位提出意見和支持。