本次分享的是關於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的資訊,更詳細的配置可以參照官網說明。