本文主要討論微服務的基本概念,SpringCloud的核心組成和SpringCloud的使用示例。
什麼是微服務
-
單體架構的困境
單體架構我們可以理解爲我們將所有的功能打成一個Jar包或者war包,放在一臺服務器的tomcat裏運行,在應用比較小時,還很合適,但是當業務擴張,很多問題就顯露出來,比如應用職責過多,導致耦合度加劇,緊接着就會引發運維,部署等各種問題。
-
微服務架構
微服務的核心思想就是“分治”。這種思想其實之前就有,比如SOA(面向服務編程)等。只是微服務的劃分粒度更細。
微服務的好處顯而易見,可以將各個服務解耦,獨立管理,獨立開發。帶來極大的靈活性和擴展性。
但是當服務進行細粒度的拆分,雖然每個單獨服務進行自治時運維部署等都很方便,但整個應用的部署複雜度增加了,當一個業務涉及多個服務時,會有各種問題,比如服務可用性如何保證?如何進行調試?
這些正是我們需要一些微服務框架來更好的處理這些問題。這些服務框架包括但不限於:服務發現、負載均衡、健康檢查、鏈路追蹤、安全等等。
SpringCloud是什麼
SpringCloud並沒有重複造輪子,也沒有從零開始構建,它是在Netflix OSSden多家開源的基礎上使用SpringBoot風格將這些比較成熟的微服務框架組合起來,屏蔽掉了負責的配置和實現原理,爲快速構建微服務架構的應用提供了一套基礎設施工具和開發支持。所提供的基礎設施,如服務發現、客戶端負載均衡、API網關、微服務容錯、統一配置中心、消息總線及微服務調用監控等,都可以做到一鍵啓動和部署。
SpringCloud的核心關鍵點
SpringCloud使用示例
注意:springcloud和對應springboot版本要適配
Release Train | Boot Version |
---|---|
Hoxton | 2.2.x |
Greenwich | 2.1.x |
Finchley | 2.0.x |
Edgware | 1.5.x |
Dalston | 1.5.x |
下面詳細配置見github
該示例包含下面三個微服務應用:
-
discover-service
這是一個服務治理服務
-
provide_service
作爲服務提供者,爲消費服務者提供服務
-
consumer_service
作爲服務消費者,承擔用戶的請求
服務治理服務需要在啓動時做如下聲明:
@EnableEurekaServer
@SpringBootApplication
public class DiscoverApplication {
public static void main(String[] args) {
SpringApplication.run(DiscoverApplication.class, args);
}
}
這樣,就可以管理註冊到上面的服務。
服務提供者和服務消費者都需要註冊到治理服務上。註冊過程就是聲明@EnableEurekaServer
,並做相關配置。
服務提供者代碼非常簡單,就是一個普通的Controller,提供一個http接口服務。
/**
* Hello Endpoint
*/
@RestController
@RequestMapping("/hello")
public class HelloProviderEndpoint {
@Value("${server.port}")
String port;
/**
* Hello
* @return
*/
@RequestMapping(value = "/{name}", method = RequestMethod.GET)
public String hello(@PathVariable String name){
return "Hello, " + name + "!"+port;
}
}
服務消費者調用關鍵代碼
@RestController
@RequestMapping("/hello")
public class HelloConsumerEndpoint {
@Autowired
private HelloService helloService;
@Autowired
RestTemplate restTemplate;
/**
* Hello 使用feign
* @return
*/
@RequestMapping(value = "/{name}", method = RequestMethod.GET)
public String hello(@PathVariable String name){
return this.helloService.hello(name);
}
}
這裏關鍵在helloService裏
@FeignClient(value = "provide-service", fallback = HelloServiceFallback.class)
public interface HelloService {
@RequestMapping(value = "/hello/{name}", method = RequestMethod.GET)
String hello(@PathVariable("name") String name);
}
這裏聲明爲一個feign客戶端,只需要利用服務名稱provide-service
就可以調用服務,而且可以設置一個服務調用失敗的降級回調處理。
feign裏面集成了ribbon,可以自動進行負載均衡處理。並且調用方式更加簡單,如果只使用ribbon,需要藉助RestTemplate(祥見代碼)。
運行注意:
運行時,先啓動治理服務discover,然後再依次啓動服務提供者provide和consumer。否則可能調用失敗。
可以通過http://localhost:8260/訪問Euraka管理界面
可以看到上面已經註冊了兩個服務實例。
最後通過Intellj自帶的工具調用服務消費者提供的接口:
目前測試只有一個服務提供者,所以爲了測試多個服務提供者負載均衡的場景有一個技巧就是通過不同的端口,啓動多個provide-service,如下圖,複製一個後,指定新的端口,再次請求,可以看到端口有時是2100有時是2101。
如果此時關閉provide-service,再次訪問,就會走到服務降級邏輯裏。