本次分享的是關于springcloud服務注冊與發現的内容,将通過分别搭建服務中心,服務注冊,服務發現來說明;現在北京這邊很多創業公司都開始往springcloud靠了,可能是由于文檔群組件比較豐富的原因吧,畢竟是一款目前來說比較完善的微服務架構;本次分享希望能給大家帶來好的幫助;
- Eureka服務中心
- Provider注冊服務
- Consumer發現服務
- Eureka服務中心高可用
Eureka服務中心
就我現在了解到并且用的比較多的注冊中心有zookeeper和Eureka,我的上上篇文章分享了dubbo+zookeeper來建構服務,是以本次用的是Eureka,springcloud架構也是推薦它來作為注冊中心,當然可以內建其他的服注冊中心,畢竟springcloud依賴于springboot來建構項目的,是以內建其他元件是很快的;首先建立注冊中心項目eureka_server,通過如下引入依賴:
1 <dependency>
2 <groupId>org.springframework.cloud</groupId>
3 <artifactId>spring-cloud-starter-eureka-server</artifactId>
4 </dependency>
複制
然後在application.yml檔案中增加配置項:
1 server:
2 port: 2001
3 spring:
4 application:
5 name: eureka-server
6 eureka:
7 client:
8 register-with-eureka: false #禁止自己當做服務注冊
9 fetch-registry: false #屏蔽注冊資訊
10 instance:
11 prefer-ip-address: true
12 instance-id: ${spring.application.name}:${server.port}
複制
配置完成後,還需要再啟動類增加注解 @EnableEurekaServer ,設定基本完成即可運作,通路 http://localhost:2001/ 得到如下界面:

Provider注冊服務
有了服務注冊中心,我們還需要提供一些服務并且把這些服務注冊到服務中心去,這裡為了友善先建立一個服務提供者和消費者共同使用的接口子產品項目eureka_api,并建立如下接口和請求傳回參數實體類:
1 public interface UserInterface {
2
3 @PostMapping("/users")
4 MoRp<List<MoUser>> getUsers(MoRq rq);
5
6 @GetMapping("/msg")
7 String getMsg();
8 }
複制
MoUser實體:
1 public class MoUser {
2
3 private long id;
4 private String userName;
5 private String userPwd;
6
7 public long getId() {
8 return id;
9 }
10
11 public void setId(long id) {
12 this.id = id;
13 }
14
15 public String getUserName() {
16 return userName;
17 }
18
19 public void setUserName(String userName) {
20 this.userName = userName;
21 }
22
23 public String getUserPwd() {
24 return userPwd;
25 }
26
27 public void setUserPwd(String userPwd) {
28 this.userPwd = userPwd;
29 }
30 }
複制
然後建立我們的服務提供端的子產品eureka_provider,同樣引入eureka依賴不過和server端有點差別:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
複制
再來建立服務提供端要提供的服務UserController,并且實作我們eureka_api子產品中的UserInterface接口,代碼如下:
1 @RestController
2 public class UserController implements UserInterface {
3
4 @Autowired
5 private HttpServletRequest request;
6
7 @Override
8 public MoRp<List<MoUser>> getUsers(MoRq rq) {
9
10 MoRp<List<MoUser>> rp = new MoRp<>();
11
12 List<MoUser> list = new ArrayList<>();
13 for (int i = 0; i < 5; i++) {
14 MoUser moUser = new MoUser();
15 moUser.setId(i);
16 moUser.setUserName("神牛" + i);
17 list.add(moUser);
18 }
19 rp.setT(list);
20 rp.setStatus(list.size() >= 1 ? 1 : 0);
21 rp.setMessage(list.size() >= 1 ? "" : "暫無資料");
22 return rp;
23 }
24
25 @Override
26 public String getMsg() {
27
28 return "這裡是provider,端口:"+ request.getServerPort();
29 }
30 }
複制
這裡需要注意的是Controller的兩個服務接口中沒有再加PostMapping或GetMapping,因為這個由被實作接口申明了;定義好了users和msg服務後,我們還需要能把他們注入到服務注冊中心去,是以需要如下application.yml的配置:
1 spring:
2 application:
3 name: eureka-provider #服務名稱
4 eureka:
5 client:
6 service-url:
7 defaultZone: http://localhost:2001/eureka/ #服務中心位址
8 instance:
9 prefer-ip-address: true
10 instance-id: ${spring.application.name}:${server.port}
11 server:
12 port: 2004
複制
我們還需要在啟動類增加如下标記 @EnableEurekaClient ,它表示啟動eureka用戶端,因為服務提供者相對服務中心來說是屬于用戶端的存在;當運作eureka_provider項目的時候,我們在注冊中心能看到如下資訊:
為了保證服務提供端接口沒問題,我們可以直接點選eureka-provider:2004,然後增加要方法接口的路徑我這裡是:http://192.168.153.148:2004/msg,即可得到如下正常通路接口傳回的資訊:
Consumer發現服務
有了接口服務,我們還需要消費服務,是以建立module項目eureka_consumer,因為這裡采用fegin僞用戶端的方式來通路我們服務提供端,并且同樣需要引入eureka的依賴:
1 <dependency>
2 <groupId>org.springframework.cloud</groupId>
3 <artifactId>spring-cloud-starter-eureka</artifactId>
4 </dependency>
5 <dependency>
6 <groupId>org.springframework.cloud</groupId>
7 <artifactId>spring-cloud-starter-feign</artifactId>
8 </dependency>
複制
然後在service層定義UserService服務并且實作公共接口子產品eureka_api中的接口,代碼如:
1 @FeignClient(value = "eureka-provider")
2 public interface UserService extends UserInterface {
3
4 }
複制
通過FeignClient來指定調用的服務端應用名稱eureka-provider,這名稱對應注冊在服務中心的Application目錄下 ,在Controller層建立一個響應的輸出UserController并分别提供兩個展示的接口,代碼如:
1 @RestController
2 public class UserController{
3
4 @Autowired
5 private UserService userService;
6
7 @GetMapping("/users")
8 public MoRp<List<MoUser>> getUsers(MoRq rq) {
9 return userService.getUsers(rq);
10 }
11
12 @GetMapping("/msg")
13 public String getMsg() {
14 return userService.getMsg();
15 }
16 }
複制
同樣Consumer端也需要在application.yml中配置一些資訊:
1 spring:
2 application:
3 name: eureka-consumer
4 eureka:
5 client:
6 service-url:
7 defaultZone: http://localhost:2001/eureka/ #注冊中心位址
8 instance:
9 prefer-ip-address: true
10 instance-id: ${spring.application.name}:${server.port}
11 server:
12 port: 2005
複制
配置基本和provider端差不多,最後需要在啟動類申明如下注解:
1 @SpringBootApplication
2 @EnableDiscoveryClient //消費者用戶端
3 @EnableFeignClients //feign用戶端
4 public class EurekaConsumerApplication {
5 public static void main(String[] args) {
6 SpringApplication.run(EurekaConsumerApplication.class, args);
7 }
8 }
複制
啟動eureka_consumer項目後,我們能在注冊中心看到它注冊進來的資訊:
然後通過通路eureka_consumer消費方的接口測試eureka_provider服務提供方的接口資料知否能正常響應,接口位址 http://192.168.153.148:2005/msg :
通過通路consumer得到了provider的結果,這就是服務注冊和發現的基本測試流程;至于消費方怎麼請求到提供方接口的,我們通過如下手工圖可解:
Eureka服務中心高可用
由上面手工圖來看,服務中心承擔着很重要的角色,通常這種服務中心不僅僅隻搭建一個,是以需要搭建一套高可用的服務中心出來;其實很簡單provider和consumer配置都不用動,我們隻需要在第一節點的eureka-server項目的application.yml中配置下并且在多啟動幾個不同端口的服務就行了(同一台伺服器是多個端口,不同伺服器端口可能是一樣的):
1 server:
2 port: 2001
3 spring:
4 application:
5 name: eureka-server
6 eureka:
7 client:
8 register-with-eureka: true #配置高可用的時候需要開放自己注冊自己
9 fetch-registry: true
10 service-url:
11 defaultZone: http://localhost:2002/eureka/ #注冊到端口2002的eureka中
12 # defaultZone: http://localhost:2001/eureka/
13 instance:
14 prefer-ip-address: true
15 instance-id: ${spring.application.name}:${server.port}
16 server:
17 eviction-interval-timer-in-ms: 2000 #剔除失效服務間隔
複制
高可用配置需要注意以下幾點:
- register-with-eureka: true 配置高可用的時候需要開放自己注冊自己,便于多個eureka注冊中心互通
- defaultZone:http://localhost:2002/eureka/ 每個注冊中心都需要吧自己注冊到别的注冊中心去
這裡我建立了兩個注冊中心位址分别為:http://localhost:2001/,http://localhost:2002/;由于之前provider和consumer配置的注冊中心位址都是2001端口的,為了驗證高可用我們需要通路2002端口注冊中心,效果如:
能夠看到2002端口有着2001端口同樣的注冊資訊,當我關閉2001端口的應用時,2002還是能夠查到provider和consumer的資訊,更詳細的配置可以參照官網說明。