SpringBoot + Spring Cloud Eureka 服務註冊與發現
什麼是Spring Cloud Eureka
Eureka是Netflix公司開發的開源服務註冊發現組件,服務發現可以說是微服務開發的核心功能了,微服務部署後一定要有服務註冊和發現的能力,Eureka就是擔任這個角色。如果你用過Dubbo的話,Dubbo裏服務註冊和發現就是通過Zookeeper框架完成的。
Eureka 目前是2.2.x版本,目前官方已經宣佈不再維護和更新了,不過Eureka 做註冊中心已經在生產環境中大規模使用了,可以說很穩定了。從我個人的角度看,目前大家使用的更多的是阿里的 Nacos 和 Consul 這兩個組件實現了不止服務發現和註冊,微服務開發不用再去依賴更多的組件和框架。這篇文章模擬一下Eureka Server集羣和服務提供者集羣和服務消費。
版本說明
SpringCloud + SpringBoot開發微服務並不是版本越新越好,Spring Cloud官方提供了一個版本對應關係。目前最新的就是Hoxton, 對應SpringBoot 2.2.x版本。
準備工作
- 新建父工程, 主要約定SpringCloud, SpringBoot版本號,我使用的是Hoxton.SR1, SpringBoot2.2。
- 新建5個子Module,這裏兩個Eureka Server,兩個Service,一個consumer, 兩個Eureka Servr我用7001和7002端口來模擬和區分Eureka集羣,兩個Service 用8001和8002來模擬,主要是想在服務消費時反應客戶端負載均衡。
項目結構如下圖
父工程pom.xml
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.2.2.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
服務註冊中心
服務提供者我用了7001和7002模擬集羣,兩個程序代碼都是相同。
新建Module,添加spring-cloud-starter-netflix-eureka-server。
pom.xml
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>
application.yml
server: port: 7001 eureka: client: service-url: defaultZone: http://eureka7002.com:7002/eureka # 集羣就是指向其他配置中心 register-with-eureka: false fetch-registry: false instance: hostname: eureka7001.com #eureka服務端實例名稱 server: enable-self-preservation: false
修改啓動類
@SpringBootApplication @EnableEurekaServer public class MyEurekaServer7001 { public static void main(String[] args) { SpringApplication.run(MyEurekaServer7001.class,args); } }
我這裏貼出了7001的代碼,7002唯一不同的地方在application.yml配置裏,如果是集羣的話eureka.client.service-url.defaultZone需要配置集羣裏其他server節點。這裏instance.hostname配置爲eureka7001.com, 對應配置需要修改下本機hosts
127.0.0.1 eureka7001.com 127.0.0.1 eureka7002.com
啓動兩個註冊中心服務
eureka7001
eureka7002
服務啓動後,注意到DS Replicas中包含集羣中另一臺機器,說明集羣已生效。
服務提供者
服務提供者我這裏用了8001和8002兩個來模擬集羣。
pom.xml
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
application.yml
server: port: 8001 spring: application: name: CLOUD-STUDENT-SERVICE eureka: client: register-with-eureka: true #集羣節點下需要設置爲true,才能配合客戶端使用Ribbon 負載均衡 fetch-registry: true service-url: defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka #集羣需要配置所有註冊中心 instance: instance-id: student-service8001 prefer-ip-address: true # 訪問路徑可以顯示ip地址
添加一個服務接口
@RestController @RequestMapping("/student") public class StudentController { @GetMapping("/list") public List<String> list(){ return Arrays.asList("Kobe","Lin","Tim","James"); } @GetMapping("/version") public String version(){ return "8001,202007162310"; } }
修改啓動類
@SpringBootApplication @EnableEurekaClient public class MyStudentService8001 { public static void main(String[] args) { SpringApplication.run(MyStudentService8001.class,args); } }
依次啓動兩個服務提供者8001和8002。服務啓動後無錯誤的情況下刷新Eureka Server界面。
eureka7001
eureka7002
在Application裏已經看到CLOUD-STUDENT-SERVICE的狀態中已經有兩個服務註冊進來了。
服務消費者
服務消費者我就寫了一個Module,端口8087
pom.xml
<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> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
application.yml
這裏客戶端消費服務時需要配置集羣中的兩個註冊中心地址。
server: port: 8087 spring: application: name: student-consumer eureka: client: fetch-registry: true register-with-eureka: false service-url: defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
服務消費接口
服務消費我們仍然用的RestTemplate,客戶端負載均衡用的實際上是Ribbon組件,默認使用輪訓算法。
@RestController @RequestMapping("/student") public class StudentController { @Autowired RestTemplate restTemplate; @GetMapping("/version") public String index(){ return restTemplate.getForObject("http://CLOUD-STUDENT-SERVICE/student/version",String.class); } }
修改啓動類
我在啓動類還配置了RestTemplate,啓動類兩個關鍵註解SpringBootApplication和EnableEurekaClient。
@SpringBootApplication @EnableEurekaClient public class StudentConsumer8087 { @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(StudentConsumer8087.class,args); } }
啓動並訪問服務消費者接口 http://localhost:8087/student/version , 從輸出結果能看到會輪訓調用8001和8002的接口8002,202007162310,8001,202007162310。