SpringCloud微服務(wù)
架構(gòu)演進(jìn)
- 單體架構(gòu)
- 垂直拆分
- 分布式SOA面向服務(wù)架構(gòu)
- 微服務(wù)架構(gòu)
服務(wù)調(diào)用方式:
- RPC,早期的webservice,現(xiàn)在熱門的dubbo,都是RPC的典型代表
- HTTP,HttpClient,OKHttp,URLConnection,RestTemplate
Euraka服務(wù)注冊中心
注冊中心
org.springframework.cloudspring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-netflix-eureka-server
@SpringBootApplication@EnableEurekaServerpublic class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); }}
server: port: 8761eureka: instance: hostname: localhost client: registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #是否將自己注冊到Eureka服務(wù)中,默認(rèn)為true(由于當(dāng)前就是eureka服務(wù),固設(shè)置為false) registerWithEureka: false #設(shè)置是否從eureka服務(wù)上獲取注冊信息,默認(rèn)為true(由于當(dāng)前就是eureka服務(wù),固設(shè)置為false) fetchRegistry: false server: # 是否開啟自我保護模式(自我保護模式,當(dāng)eureka在一定時間內(nèi)沒有接受到某個微服務(wù)實例的心跳包,默認(rèn)90S會注銷該實例), # 一旦進(jìn)入自我保護模式,若短時間內(nèi)丟失大量客戶端,eureka也會保護注冊表的信息,不再注銷 enable-self-preservation: false # 清理間隔。默認(rèn)為60000ms eviction-interval-timer-in-ms: 5000
服務(wù)提供者(服務(wù)注冊)
org.springframework.cloud spring-cloud-starter-netflix-eureka-client </dependency
2.添加 @EnableDiscoveryClient 來開啟Eureka客戶端功能
@SpringBootApplication@EnableDiscoveryClientpublic class SpringDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringDemoApplication.class, args); }}
3.編寫配置文件
eureka: instance: #在調(diào)用服務(wù)的時候就已經(jīng)變成ip地址;需要注意的是:不是在eureka中的控制臺服務(wù)實例狀態(tài)顯示。 ip-address: 127.0.0.1 prefer-ip-address: true #使用ip注冊 client: # 是否開啟健康檢查 healthcheck: enabled: true # 集群url service-url: defaultZone: http://127.0.0.1:8761/eureka
服務(wù)消費者(服務(wù)發(fā)現(xiàn))
消費應(yīng)用從注冊中心獲取服務(wù)列表,從而得知每個服務(wù)方的信息,知道去哪里調(diào)用服務(wù)方
服務(wù)續(xù)約
在注冊服務(wù)完成以后,服務(wù)提供者會維持一個心跳(定時向EurekaServer發(fā)起Rest請求),有兩個重要參數(shù)可以修改服務(wù)續(xù)約的行為
eureka: instance: #服務(wù)失效時間,默認(rèn)值90秒lease-expiration-duration-in-seconds: 90 #服務(wù)續(xù)約(renew)的間隔,默認(rèn)為30秒lease-renewal-interval-in-seconds: 30
也就是說,默認(rèn)情況下每隔30秒服務(wù)會向注冊中心發(fā)送一次心跳,證明自己還活著。如果超過90秒沒有發(fā)送心跳,EurekaServer就會認(rèn)為該服務(wù)宕機,會定時(eureka.server.eviction-interval-timer-in-ms設(shè)定的時間)從服務(wù)列表中剔除
失效剔除和自我保護
服務(wù)注冊中心在啟動時會創(chuàng)建一個定時任務(wù),默認(rèn)每隔一段時間(默認(rèn)為60秒)將當(dāng)前清單中超時(默認(rèn)為90秒)沒有續(xù)約的服務(wù)剔除。
Eureka Server在運行期間,會統(tǒng)計心跳失敗的比例在15分鐘之內(nèi)是否低于85%,如果出現(xiàn)低于的情況,Eureka Server會將當(dāng)前的實例注冊信息保護起來,不再刪除服務(wù)注冊表中的數(shù)據(jù)(也就是不會注銷任何微服務(wù))
Consul
特性
- 高效的Raft一致性算法
- 支持多數(shù)據(jù)中心
- 支持健康檢查
- HTTP和DNS支持
Consul和Eureka的區(qū)別:
- Consul強一致性(CP),Eureka保證高可用和最終一致性(AP)
- Consul使用Go語言,Eureka使用Java語言
- Consul 不同于 Eureka 需要單獨安裝,官網(wǎng):https://www.consul.io/downloads
Consul架構(gòu)圖
Consul基本使用
服務(wù)提供者
org.springframework.cloudspring-cloud-starter-consul-discovery org.springframework.bootspring-boot-starter-actuator
spring: application: name: consul-provider ####consul注冊中心地址 cloud: consul: host: localhost port: 8500 discovery: service-name: ${spring.application.name} #注冊中心名字與spring的應(yīng)用名稱一致 #—————————–相關(guān)配置—————————-| #是否注冊 register: true #實例ID instance-id: ${spring.application.name}-1 #服務(wù)實例名稱 service-name: ${spring.application.name} #服務(wù)實例端口 port: ${server.port} #健康檢查路徑 healthCheckPath: /actuator/health #健康檢查時間間隔 healthCheckInterval: 15s #開啟ip地址注冊 prefer-ip-address: true #實例的請求ip ip-address: ${spring.cloud.client.ip-address}
服務(wù)消費者
org.springframework.cloudspring-cloud-starter-consul-discovery
spring: application: name: consul-provider ####consul注冊中心地址 cloud: consul: host: localhost port: 8500 discovery: #設(shè)置不需要注冊到Consul中 register: false
負(fù)載均衡Ribbon
Ribbon是 Netflix 發(fā)布的一個負(fù)載均衡器,有助于控制 HTTP 和 TCP客戶端行為。Ribbon自動的從注冊中心中獲取服務(wù)提供者的
列表信息,并基于內(nèi)置的負(fù)載均衡算法,請求服務(wù)。
搭建過程
先編寫請求的接口
@Value(“${spring.cloud.client.ip-address}”)private String ip;@Value(“${server.port}”)private String port;@ResponseBody@RequestMapping(value = “backInfo”, method = RequestMethod.GET)public String backInfo() {return “調(diào)用的是” + ip + “端口是:” + port;}
我們假設(shè)搭建兩臺服務(wù)提供者,端口分別為:8090和8091,將已有服務(wù)的配置更改為
server: #的${}表示在jvm啟動時候若能找到對應(yīng)port則使用,若無則使用后面的默認(rèn)值port: ${port:8090}
另外一臺在啟動的時候可以指定端口port,在如下界面中的 VM options 中設(shè)置 -Dport=10087
因為Eureka中已經(jīng)集成了Ribbon,所以我們無需引入新的依賴。直接修改消費者的啟動類
@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
@Autowiredprivate RestTemplate restTemplate;@ResponseBody@RequestMapping(value = “getIpAndPort”, method = RequestMethod.GET)public String printInfo() {String url = “http://springbootdemo/backInfo”;return restTemplate.getForObject(url, String.class);}
負(fù)載均衡策略
Ribbon默認(rèn)的負(fù)載均衡策略是輪詢,Ribbon內(nèi)置了多種負(fù)載均衡策略
修改負(fù)載均衡規(guī)則的配置:
springbootdemo: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #格式是: {服務(wù)名稱}.ribbon.NFLoadBalancerRuleClassName
- com.netflix.loadbalancer.RoundRobinRule :以輪詢的方式進(jìn)行負(fù)載均衡。
- com.netflix.loadbalancer.RandomRule :隨機策略
- com.netflix.loadbalancer.RetryRule :重試策略
- com.netflix.loadbalancer.WeightedResponseTimeRule :權(quán)重策略
- com.netflix.loadbalancer.BestAvailableRule :最佳策略
- com.netflix.loadbalancer.AvailabilityFilteringRule :可用過濾策略
策略選擇:
源碼跟蹤
RibbonAutoConfifiguration->LoadBalancerAutoConfiguration->LoadBalancerInterceptor
服務(wù)調(diào)用Feign
Feign是一種聲明式、模板化的HTTP客戶端。
基于Feign的服務(wù)調(diào)用
1.在消費者引入依賴
org.springframework.cloud spring-cloud-starter-openfeign
2.啟動類開啟feign支持
@SpringBootApplication@EnableDiscoveryClient@ComponentScan(basePackages = “com.jyd0124.consume_server.*”)@EnableFeignClientspublic class ConsumeServerApplication { public static void main(String[] args) { SpringApplication.run(ConsumeServerApplication.class, args); } @Bean @LoadBalanced public RestTemplate returnBean() { return new RestTemplate(); }}
3.創(chuàng)建接口和定義需要遠(yuǎn)程調(diào)用的方法
@FeignClient(“springbootdemo”)public interface SpringBootFeign { @RequestMapping(value = “/person”, method = RequestMethod.GET) public Map getPerson(@RequestParam(value = “id”) int id);}
4.調(diào)用服務(wù)。
@Autowiredprivate SpringBootFeign springBootFeign; @ResponseBody@RequestMapping(value = “/person/{id}”, method = RequestMethod.GET)public Map printInfo(@PathVariable(“id”) int id) {return springBootFeign.getPerson(id);}
5.訪問,測試結(jié)果
負(fù)載均衡
Feign中本身已經(jīng)集成了Ribbon依賴和自動配置,因此我們不需要額外引入依賴,也不需要再注冊RestTemplate 對象,可以通過 ribbon.xx 來進(jìn)行全局配置。也可以通過 服務(wù)名.ribbon.xx 來對指定服務(wù)配置。
Feign的配置
feign: client: config: feignName: ##定義FeginClient的名稱 connectTimeout: 5000 # 建立鏈接的超時時長 readTimeout: 5000 # 讀取超時時長 # 配置Feign的日志級別,相當(dāng)于代碼配置方式中的Logger loggerLevel: full # Feign的錯誤解碼器,相當(dāng)于代碼配置方式中的ErrorDecoder errorDecoder: com.example.SimpleErrorDecoder # 配置重試,相當(dāng)于代碼配置方式中的Retryer retryer: com.example.SimpleRetryer # 配置攔截器,相當(dāng)于代碼配置方式中的 RequestInterceptor requestInterceptors: – com.example.FooRequestInterceptor – com.example.BarRequestInterceptor #配置熔斷不處理404異常 decode404: false
請求壓縮: 支持對請求和響應(yīng)進(jìn)行GZIP壓縮,以減少通信過程中的性能損耗
#請求壓縮feign: compression: request: enabled: true # 開啟請求壓縮 response: enabled: true # 開啟響應(yīng)壓縮
Hystrix支持
Feign默認(rèn)也有對Hystrix的集成
feign: hystrix: enabled: true # 開啟Feign的熔斷功能
日志級別
默認(rèn)情況下Feign的日志是沒有開啟的。
feign: client: config: feignName: loggerLevel: full #NONE【性能最佳,適用于生產(chǎn)】:不記錄任何日志(默認(rèn)值) #BASIC【適用于生產(chǎn)環(huán)境追蹤問題】:僅記錄請求方法、URL、響應(yīng)狀態(tài)代碼以及執(zhí)行時間 #HEADERS:記錄BASIC級別的基礎(chǔ)上,記錄請求和響應(yīng)的header。 #FULL【比較適用于開發(fā)及測試環(huán)境定位問題】:記錄請求和響應(yīng)的header、body和元數(shù)據(jù)
熔斷器Hystrix
雪崩效應(yīng)
在微服務(wù)架構(gòu)中,根據(jù)業(yè)務(wù)來拆分成一個個的服務(wù),服務(wù)與服務(wù)之間可以相互調(diào)用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign來調(diào)用。為了保證其高可用,單個服務(wù)通常會集群部署。由于網(wǎng)絡(luò)原因或者自身的原因,服務(wù)并不能保證100%可用,如果單個服務(wù)出現(xiàn)問題,調(diào)用這個服務(wù)就會出現(xiàn)線程阻塞,此時若有大量的請求涌入,Servlet容器的線程資源會被消耗完畢,導(dǎo)致服務(wù)癱瘓。服務(wù)與服務(wù)之間的依賴性,故障會傳播,會對整個微服務(wù)系統(tǒng)造成災(zāi)難性的嚴(yán)重后果,這就是服務(wù)故障的“雪崩”效應(yīng)。
Hystrix的特性
- 服務(wù)熔斷
Hystrix的熔斷狀態(tài)機模型:
hystrix: command: default: execution.isolation.thread.timeoutInMilliseconds: 2000 circuitBreaker: errorThresholdPercentage: 50 # 觸發(fā)熔斷錯誤比例閾值,默認(rèn)值50% sleepWindowInMilliseconds: 10000 # 熔斷后休眠時長,默認(rèn)值5秒 requestVolumeThreshold: 10 # 觸發(fā)熔斷的最小請求次數(shù),默認(rèn)20 #配置項可以參考 HystrixCommandProperties 類
- 服務(wù)降級
- 通過HystrixdeCommand的fallback實現(xiàn)服務(wù)降級。
- 服務(wù)隔離
-線程池隔離策略
– 信號量隔離策略
Ribbon中使用斷路器
org.springframework.cloud spring-cloud-starter-hystrix
@SpringBootApplication@EnableDiscoveryClient@EnableHystrixpublic class ConsumeServerApplication { public static void main(String[] args) { SpringApplication.run(ConsumeServerApplication.class, args); } @Bean @LoadBalanced public RestTemplate returnBean() { return new RestTemplate(); }}
@ResponseBody@RequestMapping(value = “/info”, method = RequestMethod.GET)@HystrixCommand(fallbackMethod = “backErrorInfo”)public String printInfo() { String url = “http://springbootdemo/backInfo”; return restTemplate.getForObject(url, String.class);}public String backErrorInfo(){ return “sorry,error”;}
Feign中使用斷路器
SpringCloud Fegin默認(rèn)已為Feign整合了hystrix
feign: hystrix: enabled: true # 開啟Feign的熔斷功能
@Componentpublic class HystrixMethod implements SpringBootFeign { @Override public Map getPerson(int id) { Map map = new HashMap(); map.put(“code”, 500); map.put(“msg”, “sorry,error”); return map; }}
@FeignClient(name = “springbootdemo”, fallback = HystrixMethod.class)public interface SpringBootFeign { @RequestMapping(value = “/person”, method = RequestMethod.GET) public Map getPerson(@RequestParam(value = “id”) int id);}
Hystrix Dashboard
org.springframework.bootspring-boot-starter-actuatororg.springframework.cloudspring-cloud-starter-hystrix-dashboard
@SpringBootApplication@EnableDiscoveryClient@EnableHystrix@EnableHystrixDashboardpublic class ConsumeServerApplication { public static void main(String[] args) { SpringApplication.run(ConsumeServerApplication.class, args); } @Bean @LoadBalanced public RestTemplate returnBean() { return new RestTemplate(); }}
遇到問題:https://blog.csdn.net/ghyghost/article/details/108053206
斷路器聚合監(jiān)控Turbine,Turbine是一個聚合Hystrix 監(jiān)控數(shù)據(jù)的工具。
網(wǎng)關(guān)Gateway
介紹
Spring Cloud Gateway 是 Spring 官方基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技術(shù)開發(fā)的網(wǎng)關(guān),旨在為微服務(wù)架構(gòu)提供一種簡單而有效的統(tǒng)一的 API 路由管理方式。Spring Cloud Gateway 作為 Spring Cloud 生態(tài)系中的網(wǎng)關(guān),目標(biāo)是替代 Netflflix ZUUL,其不僅提供統(tǒng)一的路由方式,并且基于 Filter 鏈的方式提供了網(wǎng)關(guān)基本的功能,例如:安全,監(jiān)控/埋點,和限流等。
快速入門
org.springframework.cloudspring-cloud-starter-gatewayorg.springframework.cloudspring-cloud-starter-netflix-eureka-client
@SpringBootApplication@EnableDiscoveryClientpublic class GatewayServerApplication { public static void main(String[] args) { SpringApplication.run(GatewayServerApplication.class, args); }}
server: port: 8765spring: application: # 注冊到eureka上的應(yīng)用名稱 name: gateway_server cloud: gateway: #由一個ID、一個目的URL、一組斷言工廠、一組Filter組成 routes: # 路由id,可以隨意寫 – id: consume-server-route # 代理的服務(wù)地址 uri: http://127.0.0.1:8081 # 路由斷言,可以配置映射路徑 predicates: – Path=/person/**eureka: client: # 集群url service-url: defaultZone: http://127.0.0.1:8761/eureka instance: prefer-ip-address: true #使用ip注冊 ip-address: 127.0.0.1 instance-id: ${spring.cloud.client.ip-address}:${server.port}
路由
spring: application: # 注冊到eureka上的應(yīng)用名稱 name: gateway_server cloud: gateway: #由一個ID、一個目的URL、一組斷言工廠、一組Filter組成 routes: # 路由id,可以隨意寫 – id: consume-server-route # 代理的服務(wù)地址 uri: http://127.0.0.1:8081 # 路由斷言,可以配置映射路徑 predicates: – Path=/** filters: # 添加請求路徑的前綴 – PrefixPath=/person
相當(dāng)于PrefixPath=/personhttp://localhost:8765/180868 –》http://localhost:8765/person/180868 –》http://localhost:8081/person/180868
spring: application: # 注冊到eureka上的應(yīng)用名稱 name: gateway_server cloud: gateway: #由一個ID、一個目的URL、一組斷言工廠、一組Filter組成 routes: # 路由id,可以隨意寫 – id: consume-server-route # 代理的服務(wù)地址 uri: http://127.0.0.1:8081 # 路由斷言,可以配置映射路徑 predicates: – Path=/api/person/** filters: # 表示過濾1個路徑,2表示兩個路徑,以此類推 – StripPrefix=1
StripPrefix=1 http://localhost:8765/api/person/180868–》http://localhost:8765/person/180868–》http://localhost:8081/person/180868
uri以 lb: //開頭(lb代表從注冊中心獲取服務(wù)),后面接的就是你需要轉(zhuǎn)發(fā)到的服務(wù)名稱
spring: application: # 注冊到eureka上的應(yīng)用名稱 name: gateway_server cloud: gateway: routes: # 路由id,可以隨意寫 – id: consume-server-route # 代理的服務(wù)地址 uri: lb://springbootdemo # 路由斷言,可以配置映射路徑 predicates: – Path=/person/**
路由轉(zhuǎn)發(fā)是直接將匹配的路由path直接拼接到映射路徑(URI)之后,那么往往沒有那么便利。修改application.yaml
spring: application: # 注冊到eureka上的應(yīng)用名稱 name: gateway_server cloud: gateway: routes: # 路由id,可以隨意寫 – id: consume-server-route # 代理的服務(wù)地址 uri: lb://springbootdemo # 路由斷言,可以配置映射路徑 predicates: – Path=/springbootdemo/** filters: – RewritePath=/springbootdemo/(?.*), /${segment}
請求http://localhost:8765/springbootdemo/person/180868 –》http://localhost:8765/person/180868–》http://localhost:8081/person/180868( 值得注意的是在yml文檔中 $ 要寫成 $ )
spring: application: # 注冊到eureka上的應(yīng)用名稱 name: gateway_server cloud: gateway: discovery: locator: #設(shè)置路由訪問方式:http://Gateway_HOST:Gateway_PORT/大寫的serviceId/**,其中微服務(wù)應(yīng)用名默認(rèn)大寫訪問。 enabled: true # 該設(shè)置可以將服務(wù)名改成小寫(默認(rèn)為大寫) lower-case-service-id: true
這樣,就可以通過http://localhost:8765/springbootdemo/person?id=180868訪問
過濾器
- pre:: 這種過濾器在請求被路由之前調(diào)用。
- post : 這種過濾器在路由到微服務(wù)以后執(zhí)行。
- 局部過濾器(GatewayFilter),應(yīng)用到單個路由或者一個分組的路由上,通過 spring.cloud.gateway.routes.filters 配置在具體路由下,只作用在當(dāng)前路由上;
- 全部過濾器(GlobalFilter),應(yīng)用到所有的路由上,實現(xiàn) GlobalFilter 接口即可
過濾器名稱 | 說明 |
AddRequestHeader | 對匹配上的請求加上Header |
AddRequestParameters | 對匹配上的請求路由添加參數(shù) |
AddResponseHeader | 對從網(wǎng)關(guān)返回的響應(yīng)添加Header |
StripPrefifix | 對匹配上的請求路徑去除前綴 |
配置全局默認(rèn)過濾器
spring: cloud: gateway: default-filters: – AddResponseHeader=X-Response-Default-MyName, jyd0124
其他過濾器具體可參考GatewayFilterFactory類
@Componentpublic class TokenFilter implements GlobalFilter, Ordered { private final Logger logger = LoggerFactory.getLogger(TokenFilter.class); @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { //request,response都可以通過 ServerWebExchange 獲取 String token = exchange.getRequest().getQueryParams().getFirst(“token”); if (StringUtils.isBlank(token)) { logger.info(“token is empty …”); exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } //chain.filter 繼續(xù)向下游執(zhí)行 return chain.filter(exchange); } @Override public int getOrder() { //過濾器的優(yōu)先級,返回值越大級別越低 return 0; }}
跨域問題
@Configurationpublic class GwCorsFilter { /** * 以下CorsWebFilter跨域處理也可以通過配置文件進(jìn)行處理 * spring: * cloud: * gateway: * globalcors: * cors-configurations: */ @Bean public CorsWebFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); // 允許cookies跨域 config.addAllowedOrigin(“*”);// #允許向該服務(wù)器提交請求的URI,*表示全部允許,在SpringMVC中,如果設(shè)成*,會自動轉(zhuǎn)成當(dāng)前請求頭中的Origin config.addAllowedHeader(“*”);// #允許訪問的頭信息,*表示全部 config.setMaxAge(18000L);// 預(yù)檢請求的緩存時間(秒),即在這個時間段里,對于相同的跨域請求不會再預(yù)檢了 config.addAllowedMethod(“OPTIONS”);// 允許提交請求的方法類型,*表示全部允許 config.addAllowedMethod(“HEAD”); config.addAllowedMethod(“GET”); config.addAllowedMethod(“PUT”); config.addAllowedMethod(“POST”); config.addAllowedMethod(“DELETE”); config.addAllowedMethod(“PATCH”); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser()); source.registerCorsConfiguration(“/**”, config); return new CorsWebFilter(source); } /** * *如果使用了注冊中心(如:Eureka),進(jìn)行控制則需要增加如下配置 */ @Bean public RouteDefinitionLocator discoveryClientRouteDefinitionLocator(DiscoveryClient discoveryClient) { return new DiscoveryClientRouteDefinitionLocator(discoveryClient,new DiscoveryLocatorProperties()); } /** * 以下是springboot2.0.5出現(xiàn)only one connection 的解決辦法 * @return */ @Bean public HiddenHttpMethodFilter hiddenHttpMethodFilter() { return new HiddenHttpMethodFilter() { @Override public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { return chain.filter(exchange); } }; }}
負(fù)載均衡和熔斷
Gateway中默認(rèn)已經(jīng)集成了Ribbon負(fù)載均衡和Hystrix熔斷機制。但是所有的策略都是走的默認(rèn)值,建議根據(jù)Ribbon和Hystrix手動進(jìn)行配置。
網(wǎng)關(guān)限流
- 計數(shù)器限流算法
- 漏桶算法
- 令牌桶算法
- 基于Filter的限流
- 基于Sentinel的限流
SpringCloud Config配置中心
在gitee上創(chuàng)建遠(yuǎn)程配置文件
構(gòu)建config配置中心服務(wù)
org.springframework.cloudspring-cloud-config-serverorg.springframework.cloudspring-cloud-starter-netflix-eureka-client
@SpringBootApplication@EnableDiscoveryClient@EnableConfigServerpublic class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); }}
server: port: 8888spring: application: name: config_server cloud: config: server: git: #配置文件所在的git倉庫 uri: https://gitee.com/jyd0124/springcloudconfig.git #配置文件分支 default-label: master #配置文件所在根目錄 search-paths: config #如果Git倉庫為公開倉庫,可以不填寫用戶名和密碼,如果是私有倉庫需要填寫 username: xxx password: xxxeureka: client: service-url: defaultZone: http://127.0.0.1:8761/eureka #服務(wù)注冊地址
獲取配置中心配置
org.springframework.cloudspring-cloud-starter-configorg.springframework.cloudspring-cloud-starter-netflix-eureka-client
刪除consume_server的application.yml 文件(因為該文件從配置中心獲取)
創(chuàng)建consume_server 的bootstrap.yml 配置文件,其內(nèi)容如下
spring: cloud: config: name: consume-server # 遠(yuǎn)程倉庫中的版本保持一致 label: master #profile: dev #通過ip直接訪問配置中心 #uri: http://localhost:8888/ #通過eurka訪問配置中心 discovery: #配置中心服務(wù) service-id: config-server enabled: trueeureka: client: service-url: defaultZone: http://127.0.0.1:8761/eureka #服務(wù)注冊地址
3.啟動consume_server項目發(fā)現(xiàn)獲取到配置文件將服務(wù)暴露在8081端口,測試接口可成功返回數(shù)據(jù)
補充:bootstrap.yml文件也是Spring Boot的默認(rèn)配置文件,而且其加載的時間相比于application.yml更早。bootstrap.yml文件相當(dāng)于項目啟動時的引導(dǎo)文件,內(nèi)容相對固定。application.yml文件是微服務(wù)的一些常規(guī)配置參數(shù),變化比較頻繁。
Spring Cloud Bus服務(wù)總線
問題:
前面已經(jīng)完成了將微服務(wù)中的配置文件集中存儲在遠(yuǎn)程Git倉庫,如果我們更新Git倉庫中的配置文件,那用戶微服務(wù)是否可以及時接收到新的配置信息并更新呢?經(jīng)過測試,對于Git倉庫中配置文件的修改并沒有及時更新到用戶微服務(wù),只有重啟用戶微服務(wù)才能生效。如果想在不重啟微服務(wù)的情況下更新配置該如何實現(xiàn)呢? 可以使用Spring Cloud Bus來實現(xiàn)配置的自動更新。
介紹
Spring Cloud Bus是用輕量的消息代理將分布式的節(jié)點連接起來,可以用于廣播配置文件的更改或者服務(wù)的監(jiān)控管理。也就是消息總線可以為微服務(wù)做監(jiān)控,也可以實現(xiàn)應(yīng)用程序之間相互通信。 Spring Cloud Bus可選的消息代理有兩種:RabbitMQ和Kafka。
具體實現(xiàn)可參考:https://www.fangzhipeng.com/springcloud/2018/08/08/sc-f8-bus.html https://www.cnblogs.com/babycomeon/p/11141160.html
Spring Cloud體系技術(shù)綜合應(yīng)用概覽
來源:https://www.cnblogs.com/jyd0124/p/springcloud.html