1.爲什麼用微服務
首先單個系統雖然在初期可以很方面快捷的進行開發、使用,但是隨着系統越來越龐大,開發維護的人員交換,開發與維護的成本越來越大,且難以控制,在這種情況下微服務誕生了,他們將系統中不同模塊拆分成多個不同的服務,這些服務都是能夠獨立部署、擴展和開發的,不同的服務運行不會影響到其他服務,節約成本的同時提高了系統的瓶頂。
2.微服務九大特徵
服務組件化、按業務組織團隊、做“產品”的態度、智能端點與啞管道、去中心化治理、去中心化管理數據、基礎設施自動化、容錯設計、
3.爲什麼選擇SpringCloud
國內目前已經有很多微服務架構了,如:阿里的Dubbo,淘寶的Diamond,京東的Hydra,但是當開始瞭解的時候(比如我接觸過的Dubbo)發現他們對各個組件的選擇自由度很高,但是如果某一組件出了問題項目就會出現問題(當然高手除外,否則投入的精力成本太高),而SpringCloud在Spring社區下,做了大量的兼容測試,保證了其擁有更好的穩定性,不論其項目的發展目標,還是Spring強大背景,亦或是及其極高的社會活躍度,都是未來企業架構師必須瞭解和接觸到的。
4.SpringCloud簡介
SpringCloud是基於SpringBoot實現的微服務架構開發工具。
SpringCloud還包含了很多子項目,如下所述:
·Spring Cloud Config:配置管理工具,支持使用Git存儲配置內容,可以使用它實現應用配置的外部化存儲,並支持客戶端配置信息刷新、加密/解密配置內容等。 ·Spring Cloud Netflix:核心組件,對多個Netflix OSS升源套件進行整合。 _Eureka:服務治理組件,包含服務註冊中心、服務註冊與發現機制的實現。 -Hystrix:容錯管理組件,實現斷路器模式,幫助服務依賴中出現的延遲和爲故障提供強大的容錯能力。 _Ribbon:客戶端負載均衡的服務調用組件。 -Feign:基於Ribbon和Hystrix的聲明式服務調用組件。 -Zuul:網關組件,提供智能路由、訪問過濾等功能。 -Archaius:外部化配置組件。 ·Spring Cloud Bus:事件、消息總線,用於傳播集羣中的狀態變化或事件,以觸發後 續的處理,比如用來動態刷新配置等。 ·Spring Cloud Cluster:針對ZooKeeper、Redis、Hazelcast、Consul的選舉算法和通用 狀態模式的實現。 ·Spring Cloud Cloudfoundry:與Pivotal Cloudfoundry的整合支持。 ·Spring Cloud Consul:服務發現與配置管理工具。 ·Spring Cloud Stream:通過Redis、Rabbit或者Kafka實現的消費微服務,可以通過 簡單的聲明式模型來發送和接收消息。 ·Spring Cloud AWS:用於簡化整合Amazon Web Service的組件。 ·Spring Cloud Security:安全工具包,提供在Zuul代理中對OAuth2客戶端請求的中 繼器。 ·Spring Cloud Sleuth: Spring Cloud皮用的分佈式跟蹤實現,可以完美整合Zipkin。 ·Spring Cloud ZooKeeper:基於ZooKeeper的服務發現與配置管理組件。 ·Spring Cloud Starters: Spring Cloud的基礎組件,它是基於Spring Boot風格項目的 基礎依賴模塊。 ·Spring Cloud CLI:用於在Groovy中快速創建Spring Cloud應用的Spring Boot CLI 插件。
|
5.微服務構建
構建maven項目
構建步驟
1.通過官方的SpringInitializr工具來產生基礎項目
2.訪問http://start.spring.io
3.選擇構建工具Maven Project、Spring Boot版本選擇1.5.9,填寫Group和
Artifact佶息,在Search for dependencies中可以搜索需要的其他依賴包,
這裏我們要實現RESTfulAPI,所以可以添加Web依賴。
4.單擊Generate Project按鈕下載項目壓縮包。
5.把壓縮包解壓後,用Eclipse導入該maven項目。import->Existing Maven Projects
6.項目構建完成
Maven配置解析
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>cn.dyc.springcloud</groupId> <artifactId>hello</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging>
<name>hello</name> <description>Demo project for Spring Boot</description>
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> |
在基礎信息部分,groupld和artifactld對應生成項目時頁面上輸入的內容。另外,我們還可以注意到,打包形式爲jar: <packaging>jar</packaging>, Spring Boot默認將該Web應用打包爲jar的形式,而非war的形式,因爲默認的Web模塊依賴會包含嵌入式的Tomcat.這樣使得我們的應用jar自身就具備了提供Web服務的能力,後續我們會演示如何啓動它。父項目parent配置指定爲spring-boot-starter-parent的1.5.9版本,該父項目中定義了Spring Boot版本的基礎依賴以及一些默認配置內容,比如,配置文件
application.properties的位置等。
在項目依賴dependencies配置中,包含了下面兩項。
.spring-boot-starter-web:全棧Web開發模塊,包含嵌入式Tomcat、Spring MVC。
.spring-boot-starter-test:通用測試模塊,包含JUnit、Hamcrest、Mockito。
這裏所引用的web和test模塊,在SpringBoot生態中被稱爲Starter POMs。StarterPOMs是一系列輕便的依賴包,是一套一站式的Spring相關技術的解決方案。開發者在使用和整合模塊時,不必再去搜尋樣例代碼中的依賴配置來複制使用,只需要引入對應的模塊包即可。比如,開發Web應用的時候,就引入spring-boot-starter-web,希望應用具備訪問數據庫能爲的時候,那就再引入spring-boot-starter-j dbc或是更好用的spring-boot-starter-data-jpa。在使用Spring Boot構建應用的時候,各項功能模塊的整合不再像傳統Spring應用的開發方式那樣,需要在pom. xml中做大量的依賴配置
而是通過使用Starter POMs定義的依賴包,使得功能模塊整合變得非常輕巧,易於理解與使用。
Spring Boot的Starter POMs採用spring-boot-starter-★的命名方式,★代表一個特別的應用功能模塊,比如這裏的web、test。Spring Boot工程本身的結構非常簡單,大量的學習要點還是將來在對這些Starter POMs的使用之上。項目構建的build部分,引入了Spring Boot的Maven插件,該插件非常實用,可以幫助我們方便地啓停應用,這樣在開發時就不用每次去找主類或是打包成jar來運行微
服務,只需要通過mvn spring-boot:run命令就可以快速啓動Spring Boot應用。
實現RESTfuIAPI
在Spring Boot中創建一個RESTful API的實現代碼同Spring MVC應用一樣,只是不
需要像Spring MVC那樣先做很多配置,而是像下面這樣直接開始編寫Controller內容:
·新建package,命名爲cn.dyc.springcloud.web,可根據實際的構建情況修改成自
己的路徑。
·新建HelloController類,內容如下所示。
@RestController public class HelloController { @RequestMapping ( "/hello") public String index() { return "Hello World"; } } 注意事項:要將Application(main類)放在最外層,也就是要包含所有子包。比如你的groupId是cn.dyc.springcloud,子包就是所謂的com.google.xxx,所以要將Application放在cn.dyc.springcloud包下。 請參考以下結論:spring-boot會自動加載啓動類所在包下及其子包下的所有組件。 |
單元測試
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = HelloApplication.class) @WebAppConfiguration public class HelloApplicationTests { private MockMvc mvc;
@Before public void setUp(){ mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build(); }
@Test public void hello() throws Exception { mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("hello world"))); } }
解析: (1) @RunWith( SpringjUnit4ClassRunner.class):引入Spring對Junit4的支持。 (2) @SpringBootTest(classes = HelloApplication.class):指定Spring Boot的啓動類。 (3) @WebAppConfiguration:開啓Web應用的配置,用於模擬ServletContext。 (4) MockMvc對象:用於模擬調用Controller的接口發起請求,在@Test定義的hello測試用例中,perform函數執行一次請求調用,accept用於執行接收的數據類型, (5) andExpect用於判斷接口返回的期望值。 (6) @Before: JUnit中定義在測試用例@Test內容執行前預加載的內容,這裏用來初始化對HelloController的模擬。 (7) 注意引入下面的靜態引用,讓status. content\ equalTo困數可用: import static org.hamcrest.Matchers.equalTo; import static org. springf ramework. test. web. se rvlet. result. Moc kMvcResultMatchers.content; import static org. springframework. test .web. servlet. result .MockMvcResultMatchers.status; |
多壞境配置
經使得應用的屬性在啓動前是可變的,所以其中的端口號也好、數據庫連接也好,都是可以在應用啓動時發生改變的,而不同於以往的Spring應用通過Maven的Profile在編譯器中進行不同環境的構建。Spring Boot的這種方式,可以讓應用程序的打包內容貫穿開發、測試以及線上部署,而Maven不同Profile的方案爲每個環境所構建的包,其內容本質上是不同的。但是,如果每個參數都需要通過命令行來指定,這顯然也不是一個好的方案,所以下面我們看看如何在Spring Boot中實現多環境的配置。多環境配置我們在開發應用的時候,通常同一套程序會被應用和安裝到幾個不同的環境中,比如開發、測試、生產等。其中每個環境的數據庫地址、服務器端口等配置都不同,如果在爲
不同環境打包時都要頻繁修改配置文件的話,那必將是個非常煩瑣且容易發生錯誤的事。對於多環境的配置,各種項目構建工具或是框架的基本思路是一致的,通過配置多份不同環境的配置文件,再通過打包命令指定需要打包的內容之後進行區分打包,Spring Boot
也不例外,或者說實現起來更加簡單。
在Spring Boot中,多環境配置的丈件名需要滿足application-{profile}.
properties的格式,其中{profile}對應你的環境標識,如下所示。
.application-dev.properties:開發環境。
.application-test.properties:測試環境。
.application-prod.properties:生產環境。
至於具體哪個配置文件會被加載,需要在application .properties文件中通過spring.profiles.active屬性來設置,其值對應配置文件中的{profile)值。如spring.profiles .active-test就會加載application-test.properties配置文件內容。
下面,以不同環境配置不同的服務端口爲例,進行樣例實驗。
·針對各環境新建不同的配置文件application-dev.properties、
application-test .properties. application-prod.propertieS
在這三個文件中均設置不同的server.port屬性,例如,dev環境設置爲Illl,
test壞境設置爲2222,prod環境設置爲3333。
.application.properties中j發置spring.profiles .active=dev,意爲默認以dev環境設置。
·測試不同配置的加載。
加載順序
Spring Cloud Config是SpringCloud非常重要的一個內容,爲了後續能更好地理解Spring CloudConfig的加載機制,我們需要對Spring Boot對數據文件的加載機制有一定的瞭解。
爲了能夠更合理地重寫各屬性的值,Spring Boot使用了下面這種較爲特別的屬性加載
順序:
1.在命令行中傳入的參數。
2.SPRING APPLICATIONJSON中的屬性。SPRING APPLICATION JSON是以JSON格式配置在系統環境變量中的內容。
3.java:comp/env中的JNDI屬性。
4.Java的系統屬性,可以通過System.getProperties()獲得的內容。
5.操作系統的環境變量。
6。通過random.★配置的隨機屬性。
7.位於當前應用jar包之外,針對不同{profile)環境的配置文件內容,例如application-{ profile).properties或是YAML定義的配置文件。
8.位於當前應用jar包之內,針對不同{profile)環境的配置文件內容,例如application-{ profile).properties或是YAML定義的配置文件。
9.位於當前應用jar包之外的application.properties和YAML配置內容。
10.位於當前應用jar包之內的application.properties和YAML配置內容。
Il.在@Configuration註解修改的類中,通過@PropertySource註解定義的屬性。
12.應用默認屬性,使用SpringApplication.setDefaultProperties定義的內容。
優先級按上面的順序由高到低,數字越小優先級越高。
監控與管理
pom文件中增加:
<!-- SpringBoot監控和管理的包(對中小型團隊來說比較重要) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> |
項目啓動後,控制檯會發現多了很多數據。如:
瀏覽器訪問:/health
最後項目奉上、 ^ _ ^