如何搭建一個簡單的微服務?


  我們本文,只介紹如何搭建一個微服務架構,其中微服務的理論知識見另一篇文章:

  1、創建父工程(之后所有的服務,均在父工程下創建),引入在pom文件引入依賴

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6 
 7     <groupId>com.mk</groupId>
 8     <artifactId>spring_cloud</artifactId>
 9     <version>1.0-SNAPSHOT</version>
10 
11     <modules>
12         <module>User-Service</module>
13         <module>consumer-user</module>
14         <module>Euraka-service</module>
15         <module>getAwayService</module>
16         <module>myConfig</module>
17     </modules>
18     <packaging>pom</packaging>
19 
20     <properties>
21         <java.version>1.8</java.version>
22         <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
23         <mapper.starter.version>2.1.5</mapper.starter.version>
24         <mysql.version>5.1.46</mysql.version>
25     </properties>
26 
27 
28     <parent>
29         <groupId>org.springframework.boot</groupId>
30         <artifactId>spring-boot-starter-parent</artifactId>
31         <version>2.1.2.RELEASE</version>
32         <relativePath/>
33 
34     </parent>
35 
36     <dependencyManagement>
37     <dependencies>
38         <!-- springCloud -->
39         <dependency>
40             <groupId>org.springframework.cloud</groupId>
41             <artifactId>spring-cloud-dependencies</artifactId>
42             <version>${spring-cloud.version}</version>
43             <type>pom</type>
44             <scope>import</scope>
45         </dependency>
46         <!-- 通用Mapper啟動器 -->
47         <dependency>
48             <groupId>tk.mybatis</groupId>
49             <artifactId>mapper-spring-boot-starter</artifactId>
50             <version>${mapper.starter.version}</version>
51         </dependency>
52         <!-- mysql驅動 -->
53         <dependency>
54             <groupId>mysql</groupId>
55             <artifactId>mysql-connector-java</artifactId>
56             <version>${mysql.version}</version>
57         </dependency>
58 
59 
60     </dependencies>
61 </dependencyManagement>
62 <dependencies>
63 <dependency>
64     <groupId>org.projectlombok</groupId>
65     <artifactId>lombok</artifactId>
66 </dependency>
67 </dependencies>
68 <build>
69 <plugins>
70     <plugin>
71         <groupId>org.springframework.boot</groupId>
72         <artifactId>spring-boot-maven-plugin</artifactId>
73     </plugin>
74 </plugins>
75 </build>
76 </project>
View Code

  


 

 

  2、服務提供者:我們的服務是,根據id查詢一個user,所以就會引入一些數據庫相關的依賴

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <parent>
 6         <artifactId>spring_cloud</artifactId>
 7         <groupId>com.mk</groupId>
 8         <version>1.0-SNAPSHOT</version>
 9     </parent>
10 
11 
12     <modelVersion>4.0.0</modelVersion>
13 
14     <artifactId>User-Service</artifactId>
15 
16     <properties>
17         <maven.compiler.source>8</maven.compiler.source>
18         <maven.compiler.target>8</maven.compiler.target>
19     </properties>
20 
21     <dependencies>
22         <dependency>
23             <groupId>org.springframework.boot</groupId>
24             <artifactId>spring-boot-starter-web</artifactId>
25         </dependency>
26 
27         <dependency>
28             <groupId>org.springframework.boot</groupId>
29             <artifactId>spring-boot-starter-test</artifactId>
30         </dependency>
31 
32 
33         <!-- 通用Mapper啟動器 -->
34         <dependency>
35             <groupId>tk.mybatis</groupId>
36             <artifactId>mapper-spring-boot-starter</artifactId>
37         </dependency>
38 
39 
40         <!-- mysql驅動 -->
41         <dependency>
42             <groupId>mysql</groupId>
43             <artifactId>mysql-connector-java</artifactId>
44         </dependency>
45 
46         <dependency>
47             <groupId>org.springframework.cloud</groupId>
48             <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
49         </dependency>
50 
51         <dependency>
52             <groupId>org.springframework.cloud</groupId>
53             <artifactId>spring-cloud-starter-config</artifactId>
54         </dependency>
55     </dependencies>
56 
57 
58 </project>
View Code

  2.1:實體類:其中Data注解,減少代碼量

 

 

   2.2:dao層:使用tkMybatis,所以就不需要我們自己寫單表的一些語句

 

   2.3:service層:

2.4:controller層:

 

 

2.5:啟動類:

 

 

2.6:yml配置文件(配有注釋)

 

 

 

  3.1:服務消費者因為客戶端,不需要操作數據庫,所以只需要實體類和控制層就行。

  3.2:pom依賴文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <parent>
 6         <artifactId>spring_cloud</artifactId>
 7         <groupId>com.mk</groupId>
 8         <version>1.0-SNAPSHOT</version>
 9     </parent>
10     <modelVersion>4.0.0</modelVersion>
11 
12     <artifactId>consumer-user</artifactId>
13 
14     <properties>
15         <maven.compiler.source>8</maven.compiler.source>
16         <maven.compiler.target>8</maven.compiler.target>
17     </properties>
18 
19 
20     <dependencies>
21         <dependency>
22             <groupId>org.springframework.boot</groupId>
23             <artifactId>spring-boot-starter-web</artifactId>
24         </dependency>
25 
26 
27         <!--euraka客戶端-->
28         <dependency>
29             <groupId>org.springframework.cloud</groupId>
30             <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
31         </dependency>
32 
33         <!--熔斷器-->
34         <dependency>
35             <groupId>org.springframework.cloud</groupId>
36             <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
37         </dependency>
38 
39         <!--feign代理-->
40         <dependency>
41             <groupId>org.springframework.cloud</groupId>
42             <artifactId>spring-cloud-starter-openfeign</artifactId>
43         </dependency>
44     </dependencies>
45 
46 </project>
View Code

  3.3:實體類:因為是客戶端,所以就不需要那些jpa注解

 1 package com.mk.consumer.pojo;
 2 
 3 import lombok.Data;
 4 
 5 @Data
 6 public class User {
 7   private Long id;
 8   private String userName;
 9   private String password;
10   private String name;
11   private long age;
12   private long sex;
13   private java.sql.Date birthday;
14   private java.sql.Date created;
15   private java.sql.Date updated;
16   private String note;
17 
18 }
View Code

  3.4:controller層:(這里我們采用截圖,因為后面會對這里進行改造)

 

   3.5:配置文件:

 

 

  3.6:啟動類:

 1 package com.mk.consumer;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
 6 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 7 import org.springframework.cloud.client.loadbalancer.LoadBalanced;
 8 import org.springframework.cloud.openfeign.EnableFeignClients;
 9 import org.springframework.context.annotation.Bean;
10 import org.springframework.web.client.RestTemplate;
11 
12 @SpringBootApplication
13 @EnableDiscoveryClient
14 @EnableCircuitBreaker   //開啟熔斷器
15 @EnableFeignClients //開啟feign組件功能
16 public class Application {
17     public static void main(String[] args) {
18         SpringApplication.run(Application.class, args);
19     }
20 
21 
22     /*spring提供的模板,對http進行封裝*/
23     @Bean
24     @LoadBalanced       //負載均衡
25     public RestTemplate restTemplate(){
26         return new RestTemplate();
27     }
28 }
View Code

  

 


 

 

  4.1Eureka注冊中心;既然后我們客戶端和服務端都有了,那么我們還需要搭建自己的Eureka注冊中心,來發現服務,引入依賴

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <parent>
 6         <artifactId>spring_cloud</artifactId>
 7         <groupId>com.mk</groupId>
 8         <version>1.0-SNAPSHOT</version>
 9     </parent>
10     <modelVersion>4.0.0</modelVersion>
11 
12     <artifactId>Euraka-service</artifactId>
13 
14     <properties>
15         <maven.compiler.source>8</maven.compiler.source>
16         <maven.compiler.target>8</maven.compiler.target>
17     </properties>
18 
19     <dependencies>
20         <dependency>
21             <groupId>org.springframework.cloud</groupId>
22             <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
23         </dependency>
24     </dependencies>
25 
26 
27 
28 </project>
View Code

  4.2:配置文件:(配有注解)

 1 #端口號
 2 server:
 3   port: 10010
 4 
 5 #服務名,因為Eureka本身也是一個服務
 6 spring:
 7   application:
 8     name: eureka
 9 
10 #服務注冊中心的位置
11 eureka:
12   client:
13     service-url:
14       defaultZone: http://127.0.0.1:10010/eureka
15   instance:
16 
17 #      不注冊自己
18     register-with-eureka: false
19 #    不拉取服務
20     fetch-registry: false
View Code

  4.3:啟動類:

 1 package com.mk.eureka;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
 6 
 7 @SpringBootApplication
 8 @EnableEurekaServer
 9 public class Application {
10     public static void main(String[] args) {
11         SpringApplication.run(Application.class, args);
12     }
13 }
View Code

 

以上我們的客戶端,服務端,注冊中心都配置完畢,那么我們啟動服務看看。

訪問Eureka注冊中心:注意端口號

 

 

訪問我們的服務:(傳入id為2),可以看到,返回一個json數據

 

 

以上就是,我們傳入正確的id,假如,我們傳入的id,在數據庫中,不存在怎么辦呢。經實踐發現,服務就會一直等待,那么我們后續的其他的請求就會阻塞,這樣我們后續用戶的請求也會阻塞。

  5.Spring Cloud為我們提供了Hystrix組件:特地處理我們服務時間超時,然后我們可以回顯給用戶一些有好的提示。

  5.1:添加hystrix依賴

 

 

   5.2:在啟動類上添加開啟@EnableCircuitBreaker的注解

 

 

   5.3.編寫我們的降級邏輯,也就是給用戶的提示

 

 

 

  5.4.測試降級邏輯,為了確保一定能夠滿足服務降級的條件(1.該服務的線程池滿,2.服務超時(Hystrix的默認超時時長為1)),我們就不啟動服務端,那么客戶端的請求一定超時,就會觸發服務降級。下面是測試結果

 

 

 

 

 從上面可以看出,我們的服務,雖然沒有得到應該的結果,但是我們的線程得到釋放,並不會影響其他的服務。這就是我們服務降級的一個流程。

 

  那么上面服務降級的方式,我們每增加一個方法是不是,就需要我們在該方法上進行注入呢,還有另外一種,更加簡便的方式,就注解在類上,就不用每一個方法都去注入了

 

 

 

 

 

 

 以上我們就搭建了一個簡易的微服務,但是還存在一些問題。比如我的3.4步驟中,可以看到我們的url被寫死,那么我們后期的需求改變或者說是拓展其他的功能,那么顯然是不方便的。

 


 

 

  我們SpringCloud給我們提供了一個叫做feign的組件,是一種聲明式、模板化的HTTP客戶端。在Spring Cloud中使用Feign, 我們可以做到使用HTTP請求遠程服務時能與調用本地方法一樣的編碼體驗,開發者完全感知不到這是遠程方法,更感知不到這是個HTTP請求。下面,我們就對客戶端進行優化。

 

  6.Feign聲明式服務,

  6.1.pom文件依賴,添加如下

 

 

 

  6.2我們添加日志配置類,方便我們對請求的參數,請求體進行查看。

package com.mk.consumer.logger;


import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignLogger {
    
    @Bean
    public Logger.Level feignLoggerLevel(){
        //日志級別是記錄所有(包括請求的行,請求體,)
        return Logger.Level.FULL;
    }
}
View Code

 

  6.3.下面我們添加我們的客戶端控制層的接口,

 

   6.4.我們改造后的控制層,就變得優雅了許多,仿佛就是在調用我們的本地方法。

 

 

  6.5.測試結果

 

從結果可以看出,我們同樣可以得到結果,這就是feign組件的作用,方便我們服務的調用,得到與調用本地方法一致的編碼體驗。

  6.6.feign對hystrix的支持,feign中有對hystrix的支持,我們只需要定義一個類,實現我們6.3中的客戶端接口,然后再客戶端中通過注解,添加即可。下面是降級邏輯

 

 

 

 

 6.7.下面我們看一下測試結果,觸發條件和之前的hystrix一樣

 

 


 

7. 以上就是,feign的使用。其實feign就是簡化我們內部的,服務與服務之間的調用,那么我們服務暴露給對外的api接口,應該怎樣解決呢?同樣Spring Cloud提供了Gateway網關組件。

 

 

我們外部的請求,首先就會通過網關的過濾,鑒權,然后才能請求我們內部的服務。下面我們就來配置我們的網關。

7.1,新建一個model,引入依賴

 

 7.2.編寫啟動類

 7.3,編寫配置文件,Gateway,重點就是配置文件

 

 

 

7.4下面我們,啟動服務,看看效果

 

 

 


 

  8.上面就是Gateway的簡單應用,當然,網關還有一些添加前綴,去除前綴,過濾器的一些使用,大家可以自己去探索。大家肯定會發現,我們整個微服務搭建下來,配置文件超級多,而且以后開發,

所有的配置文件肯定也不是在一台電腦上,所以有的配置文件,就訪問不了,沒事,SpringCloud也為我們提供了SpringCloud config分布式配置中心。

 

 

 

  8.1.既然要有git倉庫,那就自己准備一個,我就不粘貼步驟了,唯一需要注意的是這個配置文件的命名方式,就比如我的配置文件的名字是:“userService-dev.yml”,userService就代表服務名,-這是分隔符,dev就代表是開發環境。

然后就是將我們的userService的配置文案上傳到gitee的新建文件,(只截取了一部分)

 

 

8.2新建一個model,引入依賴

 

 

8.3編寫啟動類

 

 8.4編寫配置文件

 

8.5下面我們就通過本地訪問git上的配置文件

 

 

這就是我們之前准備的在倉庫中的配置文件,這樣我們就可以通過配置中心進行訪問。

 

  8.6.既然可以通過配置中心訪問,下面我們就對我們的服務端的配置文件(就是之前的UserService)進行修改,注意配置文件名改為bootstrap.yml,因為bootstrap.yml文件是Spring Boot的默認配置文件,而且其加載的時間相比於application.yml更早。 application.yml和bootstrap.yml雖然都是Spring Boot的默認配置文件,但是定位卻不相同。bootstrap.yml 可以理解成系統級別的一些參數配置,這些參數一般是不會變動的

 

 

 

  8.7.我們重啟UserService服務。發現UserService仍然存在,說明能夠讀取到配置中心的文件。

 

 

 


   9.既然,我們在git配置了配置文件,那么如果,我們在git上進行了修改,那么本地的配置文件會不會自己刷新呢,顯然是不會的。我們的Spring cloud也為我們提供了叫做:Spring cloud bus服務總線,專門用於同步git上配置文件的改變。下面我們進行測試。

   9.1. 在8.2中增加如下依賴,

 

   9.3:在8.3增加如下配置

 

   9.4.在往服務提供者中增加如下依賴:

 

 

 

  9.5.修改2.4的controller為:

 

 

   9.6.測試,先正常訪問

 

   9.7.控制台輸出的是:

 

 

   9.8.我們修改name為mk

 

 

  

  9.9.利用我們postman工具,發送我們在8.3中暴露的api,(注意我們需要提前安裝\otp_win64_23.0.exe和rabbitmq-server-3.8.5.exe),因為rabbitmq使用otp語言實現

 

 

   9.10.我們再次訪問9.6的url,查看控制台的輸出變為我們剛剛更新的mk

 

 

 

 

就實現了我們配置中心改變,同步到本地的功能。


 

 

下面就是SpringCloud的完整體系架構圖

 

 

整個微服務搭建完畢,各個組件的功能總結見另外一篇文章:https://www.cnblogs.com/kunmin/p/15108090.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM