基于 Spring Cloud 的微服務(wù)落地

微服務(wù)架構(gòu)模式的核心在于如何識別服務(wù)的邊界色解,設(shè)計出合理的微服務(wù)痘昌。但如果要將微服務(wù)架構(gòu)運用到生產(chǎn)項目上钥勋,并且能夠發(fā)揮該架構(gòu)模式的重要作用,則需要微服務(wù)框架的支持辆苔。

在Java生態(tài)圈笔诵,目前使用較多的微服務(wù)框架就是集成了包括Netfilix OSS以及Spring的Spring Cloud。它包括:

Spring Cloud Config:配置管理工具姑子,支持使用Git存儲配置內(nèi)容,可以實現(xiàn)應(yīng)用配置的外部化存儲测僵,支持客戶端配置信息刷新街佑、加密/解密配置內(nèi)容等谢翎。

Spring Cloud Netflix:對Netflix OSS進行了整合。其中又包括:

Eureka:服務(wù)治理組件沐旨,包含服務(wù)注冊中心森逮、服務(wù)注冊與發(fā)現(xiàn)。

Hystrix:容器管理組件磁携,實現(xiàn)斷路器模式褒侧,倘若依賴的服務(wù)出現(xiàn)延遲或故障,則提供強大的容錯功能谊迄。

Ribbon:客戶端負載均衡的服務(wù)調(diào)用組件闷供。

Feign:基于Ribbon和Hystrix的聲明式服務(wù)調(diào)用組件。

Zuul:網(wǎng)關(guān)組件统诺,提供智能路由歪脏、訪問過濾等功能。

Archaius:外部化配置組件粮呢。

Spring Cloud Bus:事件婿失、消息總線。

Spring Cloud Cluster:針對ZooKeeper啄寡、Redis豪硅、Hazelcast、Consul的選舉算法和通用狀態(tài)模式的實現(xiàn)挺物。

Spring Cloud Cloudfoundry:與Pivotal Cloudfoundry的整合支持懒浮。

Spring Cloud Consul:服務(wù)發(fā)現(xiàn)與配置管理工具。

Spring Cloud Stream:通過Redis姻乓、Rabbit或者Kafka實現(xiàn)的消息驅(qū)動的微服務(wù)嵌溢。

Spirng Cloud AWS:簡化和整合Amazon Web Service。

Spring Cloud Security:安全工具包蹋岩,提供Zuul代理中對OAuth2客戶端請求的中繼器赖草。

Spring Cloud Sleuth:Spring Cloud應(yīng)用的分布式跟蹤實現(xiàn),可以整合Zipkin剪个。

Spring Cloud ZooKeeper:基于ZooKeeper的服務(wù)發(fā)現(xiàn)與配置管理組件秧骑。

Spring Cloud Starters:Spring Cloud的基礎(chǔ)組件,是基于Spring Boot風(fēng)格項目的基礎(chǔ)依賴模塊扣囊。

Spring Cloud CLI:用于在Groovy中快速創(chuàng)建Spring Cloud應(yīng)用的Spring Boot CLI插件乎折。

服務(wù)治理

當(dāng)一個系統(tǒng)的微服務(wù)數(shù)量越來越多的時候,我們就需要對服務(wù)進行治理侵歇,提供統(tǒng)一的服務(wù)注冊中心骂澄,然后在其框架下提供發(fā)現(xiàn)服務(wù)的功能。這樣就避免了對多個微服務(wù)的配置惕虑,以及微服務(wù)之間以及與客戶端之間的耦合坟冲。

Spring Cloud Eureka是對Netflix Eureka的包裝磨镶,用以實現(xiàn)服務(wù)注冊與發(fā)現(xiàn)。Eureka服務(wù)端即服務(wù)注冊中心健提,支持高可用配置琳猫。它依托于強一致性提供良好的服務(wù)實例可用性,并支持集群模式部署私痹。Eureka客戶端則負責(zé)處理服務(wù)的注冊與發(fā)現(xiàn)脐嫂。客戶端服務(wù)通過annotation與參數(shù)配置的方式紊遵,嵌入在客戶端應(yīng)用程序代碼中账千。在運行應(yīng)用程序時,Eureka客戶端向注冊中心注冊自身提供的服務(wù)癞蚕,并周期性地發(fā)送心跳更新它的服務(wù)租約蕊爵。

搭建服務(wù)注冊中心

服務(wù)注冊中心是一個獨立部署的服務(wù)(你可以認為它也是一個微服務(wù)),所以需要單獨為它創(chuàng)建一個項目桦山,并在pom.xml中添加Eureka的依賴:

org.springframework.cloud

spring-cloud-starter-eureka-server

創(chuàng)建Spring Boot Application:

@EnableEurekaServer

@SpringBootApplication

publicclassApplication{

publicstaticvoidmain(String[] args){

newSpringApplicationBuilder(Application.class).web(true).run(args);

? ?}

}

注冊服務(wù)提供者

要讓自己編寫的微服務(wù)能夠注冊到Eureka服務(wù)器中攒射,需要在服務(wù)的Spring Boot Application中添加@EnableDiscoveryClient注解,如此才能讓Eureka服務(wù)器發(fā)現(xiàn)該服務(wù)恒水。當(dāng)然会放,pom.xml文件中也需要添加相關(guān)依賴:

org.springframework.cloud

spring-cloud-starter-eureka

同時,我們還需要為服務(wù)命名钉凌,并指定地址咧最。這些信息都可以在application.properties配置文件中配置:

spring.application.name=demo-service

eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

說明:Spring更推薦使用yml文件來維護系統(tǒng)的配置,yml文件可以體現(xiàn)出配置節(jié)的層次關(guān)系御雕,表現(xiàn)力比單純的key-value形式更好矢沿。如果結(jié)合使用后面講到的Spring Cloud Config,則客戶端的配置文件必須命名為bootstrap.properties或者bootstrap.yml酸纲。與上述配置相同的yml文件配置為:

spring:

?application:

? ?name:demo-service

eureka:

?client:

? ?serviceUrl:

? ? ?defaultZone:http://localhost:1111/eureka/

服務(wù)發(fā)現(xiàn)與消費

在微服務(wù)架構(gòu)下捣鲸,許多微服務(wù)可能會扮演雙重身份。一方面它是服務(wù)的提供者闽坡,另一方面它又可能是服務(wù)的消費者栽惶。注冊在Eureka Server中的微服務(wù)可能會被別的服務(wù)消費。此時疾嗅,就相當(dāng)于在服務(wù)中創(chuàng)建另一個服務(wù)的客戶端外厂,并通過RestTemplate發(fā)起對服務(wù)的調(diào)用。為了更好地提高性能代承,可以在服務(wù)的客戶端引入Ribbon汁蝶,作為客戶端負載均衡。

現(xiàn)在假定我們要為demo-service創(chuàng)建一個服務(wù)消費者demo-consumer论悴。該消費者自身也是一個Spring Boot微服務(wù)穿仪,同時也能夠被Eureka服務(wù)器注冊席爽。這時,就需要在該服務(wù)的pom.xml中添加eureka與ribbon的依賴:

org.springframework.cloud

spring-cloud-starter-eureka

org.springframework.cloud

spring-cloud-starter-ribbon

然后在主應(yīng)用類ConosumerApplication中注入RestTemplate啊片,并引入@LoadBalanced注解開啟客戶端負載均衡:

@EnableDiscoveryClient

@SpringBootApplication

publicclassConsumerApplication{

@Bean

@LoadBalanced

RestTemplaterestTemplate(){

returnnewRestTemplate();

? ?}

publicstaticvoidmain(String[] args){

? ? ? ?SpringApplication.run(ConsumerApplication.class, args)

? ?}

}

假設(shè)消費demo-service的客戶端代碼寫在demo-consumer服務(wù)的其中一個Controller中:

@RestController

publicclassConsumerController{

@Autowired

? ?RestTemplate restTemplate;

@RequestMapping(value ="/demo-consumer", method = RequestMethod.Get)

publicStringhelloConsumer(){

returnrestTemplate.getForEntity("http://demo-service/demo", String.class).getBody();

? ?}

}

通過RestTemplate就可以發(fā)起對demo-service的消費調(diào)用。

聲明式服務(wù)調(diào)用

通過Ribbon和Hystrix可以實現(xiàn)對微服務(wù)的調(diào)用以及容錯保護玖像,但Spring Cloud還提供了另一種更簡單的聲明式服務(wù)調(diào)用方式紫谷,即Spring Cloud Feign。Feign實際上就是對Ribbon與Hystrix的進一步封裝捐寥。通過Feign笤昨,我們只需創(chuàng)建一個接口并用annotation的方式配置,就可以完成對服務(wù)供應(yīng)方的接口(REST API)綁定握恳。

假設(shè)我們有三個服務(wù):

Notification Service

Account Service

Statistics Service

服務(wù)之間的依賴關(guān)系如下圖所示:

要使用Feign來完成聲明式的服務(wù)調(diào)用瞒窒,需要在作為調(diào)用者的服務(wù)中創(chuàng)建Client。Client通過Eureka Server調(diào)用注冊的對應(yīng)服務(wù)乡洼,這樣可以解除服務(wù)之間的耦合崇裁。結(jié)構(gòu)如下圖所示:

為了使用Feign,需要對應(yīng)微服務(wù)的pom.xml文件中添加如下依賴:

org.springframework.cloud

spring-cloud-starter-feign

同時束昵,還需要在被消費的微服務(wù)Application中添加@EnableFeignClients注解拔稳。例如在Statistics服務(wù)的應(yīng)用程序類中:

@SpringBootApplication

@EnableDiscoveryClient

@EnableFeignClients

publicclassStatisticsApplication{

publicstaticvoidmain(String[] args){

? ? ? ?SpringApplication.run(StatisticsApplication.class, args);

? ?}

}

由于Account服務(wù)需要調(diào)用Statistics服務(wù),因此需要在Account服務(wù)項目中增加對應(yīng)的client接口:

@FeignClient(name ="statistics-service")

publicinterfaceStatisticsServiceClient{

@RequestMapping(method = RequestMethod.PUT, value ="/statistics/{accountName}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)

voidupdateStatistics(@PathVariable("accountName")String accountName, Account account);

}

StatisticsServiceClient接口的updateStatistics()方法會調(diào)用URI為/statistics/{accountName}的REST服務(wù)锹雏,且HTTP動詞為put巴比。這個服務(wù)其實對應(yīng)就是Statistics Service中StatisticsController類中的saveStatistics()方法:

@RestController

publicclassStatisticsController{

@Autowired

privateStatisticsService statisticsService;

@RequestMapping(value ="/{accountName}", method = RequestMethod.PUT)

publicvoidsaveStatistics(@PathVariable String accountName, @Valid @RequestBody Account account){

? ? ? ?statisticsService.save(accountName, account);

? ?}

}

在Account服務(wù)中,如果要調(diào)用Statistics服務(wù)礁遵,都應(yīng)該通過StatisticsServiceClient接口進行調(diào)用轻绞。例如,Account服務(wù)中的AccountServiceImpl要調(diào)用updateStatistics()方法佣耐,就可以在該類的實現(xiàn)中通過@autowired注入StatisticsServiceClient接口:

@Service

publicclassAccountServiceImplimplementsAccountService{

@Autowired

privateStatisticsServiceClient statisticsClient;

@Autowired

privateAccountRepository repository;

@Override

publicvoidsaveChanges(String name, Account update){

//...

? ? ? ?statisticsClient.updateStatistics(name, account);

? ?}

}

Notification服務(wù)對Account服務(wù)的調(diào)用如法炮制政勃。

服務(wù)容錯保護

在微服務(wù)架構(gòu)中,微服務(wù)之間可能存在依賴關(guān)系晰赞,例如Notification Service會調(diào)用Account Service稼病,Account Service調(diào)用Statistics Service。真實產(chǎn)品中掖鱼,微服務(wù)之間的調(diào)用會更加尋常然走。倘若上游服務(wù)出現(xiàn)了故障,就可能會因為依賴關(guān)系而導(dǎo)致故障的蔓延戏挡,最終導(dǎo)致整個系統(tǒng)的癱瘓芍瑞。

Spring Cloud Hystrix通過實現(xiàn)斷路器(Circuit Breaker)模式以及線程隔離等功能,實現(xiàn)服務(wù)的容錯保護褐墅。

仍然參考前面的例子〔鹈剩現(xiàn)在系統(tǒng)的微服務(wù)包括:

上游服務(wù):demo-service

下游服務(wù):demo-consumer

Eureka服務(wù)器:eureka-server

假設(shè)上游服務(wù)可能會出現(xiàn)故障洪己,為保證系統(tǒng)的健壯性,需要在下游服務(wù)中加入容錯包含功能竟贯。首先需要在demo-consumer服務(wù)中添加對hystrix的依賴:

org.springframework.cloud

spring-cloud-starter-hystrix

然后在demo-consumer的應(yīng)用程序類中加入@EnableCircuitBreaker開啟斷路器功能:

@EnableCircuitBreaker

@EnableDiscoveryClient

@SpringBootApplication

publicclassConsumerApplication{

@Bean

@LoadBalanced

RestTemplaterestTemplate(){

returnnewRestTemplate();

? ?}

publicstaticvoidmain(String[] args){

? ? ? ?SpringApplication.run(ConsumerApplication.class, args)

? ?}

}

注意:Spring Cloud提供了@SpringCloudApplication注解簡化如上代碼答捕。該注解事實上已經(jīng)包含了前面所述的三個注解。@SpringCloudApplication注解的定義如下所示:

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

@SpringBootApplication

@EnableDiscoveryClient

@EnableCircuitBreaker

public@interfaceSpringCloudApplication {}

接下來屑那,需要引入一個新的服務(wù)類來封裝hystrix提供的斷路器保護功能拱镐,主要是定義當(dāng)故障發(fā)生時需要執(zhí)行的回調(diào)邏輯,即代碼中指定的fallbackMethod:

@Service

publicclassConsumerService{

@Autowired

? ?RestTemplate restTemplate;

@HystrixCommand(fallbackMethod ="consumerFallback")

publicStringconsume(){

returnrestTemplate.getForEntity("http://demo-service/demo", String.class).getBody();

? ?}

publicStringconsumerFallback(){

return"error";

? ?}

}

@RestController

publicclassConsumerController{

@Autowired

? ?ConsumerService consumerService;

@RequestMapping(value ="/demo-consumer", method = RequestMethod.Get)

publicStringhelloConsumer(){

returnconsumerService.consume();

? ?}

}

服務(wù)監(jiān)控

微服務(wù)架構(gòu)將服務(wù)的粒度分解的足夠細持际,這使得它在保證服務(wù)足夠靈活沃琅、足夠獨立的優(yōu)勢下,也帶來了管理和監(jiān)控上的挑戰(zhàn)蜘欲,服務(wù)與服務(wù)之間的依賴也變得越來越復(fù)雜益眉。因此,對服務(wù)健康度和運行指標的監(jiān)控就變得非常重要姥份。

Hystrix提供了Dashboard用以監(jiān)控Hystrix的各項指標信息郭脂。為了監(jiān)控整個系統(tǒng)的微服務(wù),我們需要為Hystrix Dashboard建立一個Spring Boot微服務(wù)殿衰。在該服務(wù)項目的pom文件中朱庆,添加如下依賴:

org.springframework.cloud

spring-cloud-starter-hystrix

org.springframework.cloud

spring-cloud-starter-hystrix-dashboard

org.springframework.cloud

spring-cloud-starter-actuator

服務(wù)的Application類需要添加@EnableHystrixDashboard,以啟用Hystrix Dashboard功能闷祥。同時娱颊,可能需要根據(jù)實際情況修改application.properties配置文件,例如選擇可用的端口號等凯砍。

如果要實現(xiàn)對集群的監(jiān)控箱硕,則需要加入Turbine。

API網(wǎng)關(guān)

理論上悟衩,客戶端可以直接向每個微服務(wù)直接發(fā)送請求剧罩。但是這種方式是存在挑戰(zhàn)和限制的,調(diào)用者需要知道所有端點的地址座泳,分別對每一段信息執(zhí)行http請求惠昔,然后將結(jié)果合并到客戶端。

一般而言挑势,針對微服務(wù)架構(gòu)模式的系統(tǒng)镇防,采用的都是前后端分離的架構(gòu)。為了明顯地隔離開前端與后端的邊界潮饱,我們通忱囱酰可以專門為前端的消費者定義更加粗粒度的Open Service。這些Open Service是對外的RESTful API服務(wù),可以通過F5啦扬、Nginx等網(wǎng)絡(luò)設(shè)備或工具軟件實現(xiàn)對各個微服務(wù)的路由與負載均衡中狂,并公開給外部的客戶端調(diào)用(注意,內(nèi)部微服務(wù)之間的調(diào)用并不需要通過Open Service)扑毡。這種對外公開的Open Service通常又被稱為邊緣服務(wù)(edge service)胃榕。

如果這些Open Service需要我們自己去開發(fā)實現(xiàn)并進行服務(wù)的運維,在系統(tǒng)規(guī)模不斷增大的情況下僚楞,會變得越來越困難勤晚。例如,當(dāng)增加了新的微服務(wù)又或者IP地址發(fā)生變動時泉褐,都需要運維人員手工維護這些路由規(guī)則與服務(wù)實例列表。又例如針對所有垂直分隔的微服務(wù)鸟蜡,不可避免存在重用的橫切關(guān)注點膜赃,例如用戶身份認證、授權(quán)或簽名校驗等機制揉忘。我們不能在所有微服務(wù)中都去添加這些相同的功能跳座,因為這會造成橫切關(guān)注點的冗余。

解決的辦法是引入API網(wǎng)關(guān)(API Gateway)泣矛。它是系統(tǒng)的單個入口點疲眷,用于通過將請求路由到適當(dāng)?shù)暮蠖朔?wù)或者通過調(diào)用多個后端服務(wù)并聚合結(jié)果來處理請求。此外您朽,它還可以用于認證狂丝、insights、壓力測試哗总、金絲雀測試(canary testing)几颜、服務(wù)遷移、靜態(tài)響應(yīng)處理和主動變換管理讯屈。Spring Cloud為API網(wǎng)關(guān)提供的解決方案就是Spring Cloud Zuul蛋哭,它是對Netflix Zuul的包裝。

路由規(guī)則與服務(wù)實例維護

Zuul解決路由規(guī)則與服務(wù)實例維護的方法是通過Spring Cloud Eureka涮母。API Gateway自身就是一個Spring Boot服務(wù)谆趾,該服務(wù)自身被注冊為Eureka服務(wù)治理下的應(yīng)用,同時它會從Eureka中獲得所有其他微服務(wù)的實例信息叛本。這樣的設(shè)計符合DRY原則首尼,因為Eureka已經(jīng)維護了一套服務(wù)實例信息,Zuul直接重用了這些信息验烧,無需人工介入向叉。

對于路由規(guī)則,Zuul默認會將服務(wù)名作為ContextPath創(chuàng)建路由映射,基本上這種路由映射機制就可以滿足微服務(wù)架構(gòu)的路由需求性芬。倘若需要一些特殊的配置峡眶,Zuul也允許我們自定義路由規(guī)則,可以通過在API網(wǎng)關(guān)的Application類中創(chuàng)建PatternServiceRouteMapper來定義自己的規(guī)則植锉。

橫切關(guān)注點

諸如授權(quán)認證辫樱、簽名校驗等業(yè)務(wù)邏輯本身與微服務(wù)應(yīng)用所要處理的業(yè)務(wù)邏輯沒有直接關(guān)系,我們將這些可能橫跨多個微服務(wù)的功能稱為“橫切關(guān)注點”俊庇。這些橫切關(guān)注點往往會作為“裝飾”功能在服務(wù)方法的前后被調(diào)用狮暑。Spring Cloud Zuul提供了一套過濾器機制,允許開發(fā)者創(chuàng)建各種過濾器辉饱,并指定哪些規(guī)則的請求需要執(zhí)行哪個過濾器搬男。

自定義的過濾器繼承自ZuulFilter類。例如我們要求客戶端發(fā)過來的請求在路由之前需要先驗證請求中是否包含accessToken參數(shù)彭沼,如果有就進行路由缔逛,否則就拒絕,并返回401 Unauthorized錯誤姓惑,則可以定義AccessFilter類:

publicclassAccessFilterextendsZuulFilter{

privatestaticLogger log = LoggerFactory.getLogger(AccessFilter.class);

@Override

publicStringfilterType(){

return"pre"

? ?}

@Override

publicintfilterOrder(){

return0;

? ?}

@Override

publicbooleanshouldFilter(){

returntrue;

? ?}


@Override

publicObjectrun(){

? ? ? ?RequestContext ctx = RequestContext.getCurrentContext();

? ? ? ?HttpServletRequest request = ctx.getRequest();


log.info("send {} request to {}", request.getMethod(), request.getRequestURL().toString());

Object accessToken = request.getParameter("accessToken");

if(accessToken ==null) {

log.warn("access token is empty");

ctx.setSendZuulResponse(false);

ctx.setResponseStatusCode(401);

returnnull;

? ? ? ?}

log.info("access token ok");

returnnull;

? ?}

}

要讓該自定義過濾器生效褐奴,還需要在Zuul服務(wù)的Application中創(chuàng)建具體的Bean:

@EnableZuulProxy

@SpringCloudApplication

publicclassZuulApplication{

publicstaticvoidmain(String[] args){

newSpringApplicatonBuilder(ZuulApplication.class).web(true).run(args);

? ?}

@Bean

publicAccessFilteraccessFilter(){

returnnewAccessFilter();

? ?}

}

Zuul一共提供了四種過濾器:

pre filter

routing filter

post filter

error filter

下圖來自官網(wǎng),它展現(xiàn)了客戶端請求到達Zuul API網(wǎng)關(guān)的生命周期與過濾過程:

通過starter添加Zuul的依賴時于毙,自身包含了spring-cloud-starter-hystrix與spring-cloud-starter-ribbon模塊的依賴敦冬,因此Zuul自身就擁有線程隔離與斷路器的服務(wù)容錯功能,以及客戶端負載均衡唯沮。但是脖旱,倘若我們使用path與url的映射關(guān)系來配置路由規(guī)則,則路由轉(zhuǎn)發(fā)的請求并不會采用HystrixCommand來包裝烂翰,因而這類路由是沒有服務(wù)容錯與客戶端負載均衡作用的夯缺。所以在使用Zuul時,應(yīng)盡量使用path和serviceId的組合對路由進行配置甘耿。

分布式配置中心

為什么要引入一個分布式配置中心踊兜?一個微服務(wù)就需要至少一個配置文件,怎么管理分散在各個微服務(wù)中的配置文件呢佳恬?如果微服務(wù)采用的是不同的技術(shù)棧捏境,如何來統(tǒng)一微服務(wù)的配置呢?微服務(wù)是部署在不同的節(jié)點中毁葱,顯然我們無法在單機中實現(xiàn)對分布式節(jié)點的配置管理垫言。這就是引入Spring Cloud Config的目的。

Spring Cloud Config提供了服務(wù)端和客戶端支持倾剿。服務(wù)端是一個獨立的微服務(wù)筷频,同樣可以注冊到Eureka服務(wù)器中蚌成。每個需要使用分布式配置中心的微服務(wù)都是Spring Cloud Config的客戶端。Spring Cloud Config默認實現(xiàn)基于Git倉庫凛捏,既可以進行版本管理担忧,還可以通過本地Git庫起到緩存作用。Spring Cloud Config不限于基于Spring Cloud開發(fā)的系統(tǒng)坯癣,而是可以用于任何語言開發(fā)的程序瓶盛,并支持自定義實現(xiàn)。

配置中心服務(wù)端

Spring Cloud Config Server作為配置中心服務(wù)端示罗,提供如下功能:

拉取配置時更新git倉庫副本惩猫,保證是最新結(jié)果

支持數(shù)據(jù)結(jié)構(gòu)豐富,yml, json, properties等

配合Eureke可實現(xiàn)服務(wù)發(fā)現(xiàn)蚜点,配合cloud bus可實現(xiàn)配置推送更新

配置存儲基于git倉庫轧房,可進行版本管理

簡單可靠,有豐富的配套方案

建立一個Config服務(wù)绍绘,需要添加如下依賴:

org.springframework.cloud

spring-cloud-config-server

服務(wù)的Application類需要添加@EnableConfigServer注解:

@SpringBootApplication

@EnableConfigServer

publicclassConfigApplication{

publicstaticvoidmain(String[] args){

? ? ? ?SpringApplication.run(ConfigApplication.class, args);

? ?}

}

配置服務(wù)的基本信息和Git倉庫的信息放在application.yml文件中:

spring:

?cloud:

? ?config:

? ? ?server:

? ? ? ?git:

? ? ? ? ? ?uri:http://localhost/workspace/springcloud-demo

? ? ? ? ? ?username:user

? ? ? ? ? ?password:password

server:

?port:8888

security:

?user:

? ?password:${CONFIG_SERVICE_PASSWORD}

Git庫與配置服務(wù)

在Config服務(wù)中配置了Git服務(wù)器以及Git庫的信息后锯厢,我們就可以在git庫中提交配置文件。存儲在git庫中配置文件的名字以及分支名(默認為master分支)會組成訪問Config服務(wù)的URI脯倒。假設(shè)有一個服務(wù)為Notification服務(wù),則它在配置中心服務(wù)端的配置文件為notification-dev.yml捺氢,內(nèi)容如下:

devMode:true

spring:

? ?application:

? ? ? ?name:notification

? ?jdbc:

? ? ? ?host:localhost

? ? ? ?port:3306

? ? ? ?user:root

? ? ? ?password:123456

logging:

? ?file:demo

配置中心客戶端

需要讀取配置中心服務(wù)端信息的微服務(wù)都是配置中心的客戶端藻丢,為了能夠讀取配置服務(wù)端的信息,這些微服務(wù)需要:

在pom中添加對spring-cloud-starter-config的依賴

在bootstrap.properties或者bootstrap.yml中配置獲取配置的config-server位置

例如摄乒,Account服務(wù)的配置是由Spring Cloud Config進行管理的悠反。在它的資源目錄下,提供了bootstrap.yml配置文件馍佑,內(nèi)容如下所示:

spring:

?application:

? ?name:account-service

?cloud:

? ?config:

? ? ?uri:http://config:8888

? ? ?fail-fast:true

? ? ?password:${CONFIG_SERVICE_PASSWORD}

? ? ?username:user

注意斋否,該配置文件除了配置了該Account服務(wù)應(yīng)用的name之外,主要是支持該應(yīng)用獲得配置服務(wù)端的信息拭荤。微服務(wù)自身的配置信息則統(tǒng)一放到配置中心服務(wù)端的文件中茵臭,并由Git庫進行管理。例如舅世,Account服務(wù)的詳細配置在配置中心服務(wù)端的account-dev.yml文件中:

security:

?oauth2:

? ?client:

? ? ?clientId:account-service

? ? ?clientSecret:${ACCOUNT_SERVICE_PASSWORD}

? ? ?accessTokenUri:http://auth-service:5000/uaa/oauth/token

? ? ?grant-type:client_credentials

? ? ?scope:server

spring:

?data:

? ?mongodb:

? ? ?host:account-mongodb

? ? ?username:user

? ? ?password:${MONGODB_PASSWORD}

? ? ?database:piggymetrics

? ? ?port:27017

server:

?context-path:/accounts

?port:6000

Spring Cloud Config通過Git實現(xiàn)分布式的配置管理旦委。當(dāng)配置中心服務(wù)端的配置信息發(fā)生變更時,各個作為配置客戶端的微服務(wù)會向Git庫提交pull更新雏亚,獲得最新的配置信息缨硝。

當(dāng)然,Spring Cloud Config還可以使用SVN庫進行配置管理罢低,也支持簡單的本地文件系統(tǒng)的存儲方式查辩。此時需要將spring.profiles.active設(shè)置為native,并設(shè)置搜索配置文件的路徑。如果不配置路徑宜岛,默認在src/main/resources目錄下搜索长踊。如下配置文件:

spring:

?cloud:

? ?config:

? ? ?server:

? ? ? ?native:

? ? ? ? ?search-locations:classpath:/shared

?profiles:

? ?active:native

搜索路徑放在classpath下的shared目錄下,那么在代碼中谬返,目錄就是resources/shared之斯。如果使用本地文件系統(tǒng)管理配置文件,則無法支持分布式配置管理以及版本管理遣铝,因此在生產(chǎn)系統(tǒng)下佑刷,還是推薦使用Git庫的方式。

總結(jié)

在實施微服務(wù)時酿炸,我們可以將微服務(wù)視為兩個不同的邊界瘫絮。一個是與前端UI的通信,稱為Open Service(Edge Service)填硕,通過引入API Gateway來實現(xiàn)與前端UI的通信麦萤。另一個是在邊界內(nèi)業(yè)務(wù)微服務(wù)之間的通信,通過Feign實現(xiàn)微服務(wù)之間的協(xié)作扁眯。所有的微服務(wù)都會通過Eureka來完成微服務(wù)的注冊與發(fā)現(xiàn)壮莹。一個典型的基于Spring Cloud的微服務(wù)架構(gòu)如下所示:

微服務(wù)的集成可以通過Feign+Ribbon以RESTful方式實現(xiàn)通信,也可以基于RPC方式(可以結(jié)合Protocol Buffer)完成服務(wù)之間的通信姻檀,甚至可以通過發(fā)布事件與訂閱事件的機制命满。事件機制可以使微服務(wù)之間更加松散耦合。這時绣版,我們可以引入RabbitMQ或Kafka來做到服務(wù)與服務(wù)之間的解耦胶台。事件機制是異步和非阻塞的,在某些業(yè)務(wù)場景下杂抽,它的性能會更加的好诈唬。Spring Cloud也提供了相關(guān)的組件Spring Cloud Stream來支持這種事件機制。

對于微服務(wù)之間的協(xié)作缩麸,到底選擇Feign這種REST方式铸磅、事件機制或者RPC方式,取決于業(yè)務(wù)場景是否需要同步方式匙睹,還是異步方式愚屁;是高性能高并發(fā),還是普通方式痕檬;是要求徹底解耦霎槐,還是做到一般的松散耦合。我們需要針對實際情況作出實際的判斷梦谜,作出正確的選擇丘跌。沒有誰壞誰好之分袭景,而是看誰更加的適合。

歡迎工作一到五年的Java工程師朋友們加入Java程序員開發(fā): 854393687

群內(nèi)提供免費的Java架構(gòu)學(xué)習(xí)資料(里面有高可用闭树、高并發(fā)耸棒、高性能及分布式、Jvm性能調(diào)優(yōu)报辱、Spring源碼与殃,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構(gòu)資料)合理利用自己每一分每一秒的時間來學(xué)習(xí)提升自己碍现,不要再用"沒有時間“來掩飾自己思想上的懶惰幅疼!趁年輕,使勁拼昼接,給未來的自己一個交代爽篷!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市慢睡,隨后出現(xiàn)的幾起案子逐工,更是在濱河造成了極大的恐慌,老刑警劉巖漂辐,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泪喊,死亡現(xiàn)場離奇詭異,居然都是意外死亡髓涯,警方通過查閱死者的電腦和手機窘俺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來复凳,“玉大人,你說我怎么就攤上這事灶泵∮耍” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵赦邻,是天一觀的道長髓棋。 經(jīng)常有香客問我,道長惶洲,這世上最難降的妖魔是什么按声? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮恬吕,結(jié)果婚禮上签则,老公的妹妹穿的比我還像新娘。我一直安慰自己铐料,他們只是感情好渐裂,可當(dāng)我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布豺旬。 她就那樣靜靜地躺著,像睡著了一般柒凉。 火紅的嫁衣襯著肌膚如雪族阅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天膝捞,我揣著相機與錄音坦刀,去河邊找鬼。 笑死蔬咬,一個胖子當(dāng)著我的面吹牛鲤遥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播计盒,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼渴频,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了北启?” 一聲冷哼從身側(cè)響起卜朗,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咕村,沒想到半個月后场钉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡懈涛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年逛万,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片批钠。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡宇植,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出埋心,到底是詐尸還是另有隱情指郁,我是刑警寧澤,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布拷呆,位于F島的核電站闲坎,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏茬斧。R本人自食惡果不足惜腰懂,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望项秉。 院中可真熱鬧绣溜,春花似錦、人聲如沸娄蔼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至罢防,卻和暖如春艘虎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背咒吐。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工野建, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恬叹。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓候生,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绽昼。 傳聞我的和親對象是個殘疾皇子唯鸭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)硅确,斷路器目溉,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • 微服務(wù)架構(gòu)模式的核心在于如何識別服務(wù)的邊界,設(shè)計出合理的微服務(wù)菱农。但如果要將微服務(wù)架構(gòu)運用到生產(chǎn)項目上缭付,并且能夠發(fā)揮...
    程序員技術(shù)圈閱讀 2,774評論 10 27
  • 1 為什么需要服務(wù)發(fā)現(xiàn) 簡單來說,服務(wù)化的核心就是將傳統(tǒng)的一站式應(yīng)用根據(jù)業(yè)務(wù)拆分成一個一個的服務(wù)循未,而微服務(wù)在這個基...
    謙小易閱讀 25,076評論 4 93
  • 軟件是有生命的陷猫,你做出來的架構(gòu)決定了這個軟件它這一生是坎坷還是幸福。 本文不是講解如何使用Spring Cloud...
    Bobby0322閱讀 22,609評論 3 166
  • 最后三張是最愛的妖,攝影老師還夸我了呢绣檬,emmmmmm…跟五個傻子舍友們,一起玩的挺開心嫂粟,嘻嘻嘻嘻河咽。 ...
    商風(fēng)聲閱讀 217評論 2 2