2.Eureka服務注冊和發現
Eureka是Netflix的一個子子產品,也是核心子產品之一,Eureka是一個基于REST的服務,用于定位服務,以實作雲端中間層服務發現和故障轉移,服務注冊與發現對于微服務架構來說是非常重要的,有了服務發現與注冊,隻需要使用服務的辨別符,就可以通路到服務,而不需要修改服務調用的配置檔案了,功能類似于dubbo的注冊中心,比如Zookeeper;
Eureka采用了C-S的設計架構,Eureka Server 作為服務注冊功能的伺服器,他是服務注冊中心;
而系統中的其他微服務,使用Eureka的用戶端連接配接到Eureka Server并維持心跳連接配接,這樣系統的維護人員可以通過Eureka Server來監控系統中各個微服務是否正常運作,SpringCloud的一些其他子產品(比如Zuul)就可以通過Eureka Server 來發現系統中的其他微服務,并執行相關的邏輯;
Eureka包含兩個元件:Eureka Server和Eureka Client;
Eureka Server提供服務注冊服務
各個節點啟動後,會在Eureka Server中進行注冊,這樣Eureka Server中的服務注冊中将會存儲所有可用服務節點的資訊,服務節點的資訊可以在界面中直覺的看到;
Eureka Client是一個Java用戶端,用于簡化Eureka Server的互動,用戶端同時也具備一個内置的,使用輪詢(round-robin)負載算啊的負載均衡器,在應用啟動後,将會向Eureka Server發送心跳(預設周期為30秒).如果Eureka Server在多個心跳周期内沒有接收到某個節點的心态,Eureka Server将會從服務系統資料庫中把這個服務節點移除(預設90秒);
Eureka的三大角色:
1. Eureka Server提供服務注冊和發現;
2. Service Provider 服務提供方将自身服務注冊到Eureka,進而使服務消費方能夠找到;
3. Service Consumer服務消費方從Eureka擷取注冊服務清單,進而能夠消費服務;
2.1建立一個microservicecloud-provider-dept-7001(Eureka服務注冊中心Module)
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL90zdY5WNXFGM1cVWxw2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL1ITOwATNxETM3AzMwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
邊寫pom.xml檔案
<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>
<parent>
<groupId>com.yt.springcloud</groupId>
<artifactId>microservicecloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>microservicecloud-provider-dept-7001</artifactId>
<dependencies>
<dependency><!-- eureka-server服務端 -->
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!-- 修改後立即生效,熱部署 (一修改,自動釋出,自動建構)-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
編寫application.yml
server:
port: 7001
eureka:
instance:
hostname: localhost #eureka服務端的執行個體名稱
client:
register-with-eureka: false #false表示不想注冊中心注冊自己
fetch-registry: false #false表示自己端就是注冊中心,我的職責就是維護服務執行個體,并不需要去檢索服務
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # 設定與Eureka server互動的位址查詢服務和注冊服務
新增加一個新元件的步驟(這裡不屬于操作,屬于一點小筆記而已)
建立EurekaServer7001_App.java啟動類
package com.yt.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableAutoConfiguration
@SpringBootConfiguration
@EnableEurekaServer //EurekaServer伺服器端啟動類,接受其他微服務注冊進來
public class EurekaServer7001_App {
public static void main(String[] args) {
SpringApplication.run(EurekaServer7001_App.class, args);
}
}
啟動EurekaServer7001_App 通路路徑:http://localhost:7001/
将microservicecloud-provider-dept-8001項目注冊到Eureka
修改microservicecloud-provider-dept-8001項目的pom.xml檔案(在之前的pom.xml基礎之上添加了兩個依賴)
<!-- 将微服務provider側注冊進入eureka(引入eureka的client端) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
修改microservicecloud-provider-dept-8001項目的application.yml檔案(在之前的application.yml基礎之上添加了eureka)
server:
port: 8001 # 目前微服務的端口
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置檔案所在路徑
type-aliases-package: com.yt.springcloud.entity # 所有餓entity實體類所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射檔案
spring:
application:
name: microservicecloud-dept # 對外暴露的微服務的名字(很重要)
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 目前資料源操作類型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驅動包
url: jdbc:mysql://localhost:3306/cloudDB01 # 資料庫名稱
username: root
password: hannong
dbcp2:
min-idle: 5 # 資料庫連接配接池的最小維持連接配接數
initial-size: 5 # 初始化連接配接數
max-total: 5 # 最大連接配接數
max-wait-millis: 200 # 等待連接配接擷取的最大逾時時間
eureka:
client: #用戶端注冊進eureka服務清單内
service-url:
defaultZone: http://localhost:7001/eureka #去注冊中心的位址
修改microservicecloud-provider-dept-8001項目的DeptProvider8001_App啟動類(添加一個注解@EnableEurekaClient)
package com.yt.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient//本服務啟動後會自動注冊進eureka服務中
public class DeptProvider8001_App {
public static void main(String[] args) {
SpringApplication.run(DeptProvider8001_App.class, args);
}
}
先啟動microservicecloud-provider-dept-7001的啟動類,再啟動microservicecloud-provider-dept-8001的啟動類
通路路徑:http://localhost:7001/
主機名稱:服務名稱修改
修改microservicecloud-provider-dept-8001項目工程的application.yml
server:
port: 8001 # 目前微服務的端口
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置檔案所在路徑
type-aliases-package: com.yt.springcloud.entity # 所有餓entity實體類所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射檔案
spring:
application:
name: microservicecloud-dept # 對外暴露的微服務的名字(很重要)
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 目前資料源操作類型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驅動包
url: jdbc:mysql://localhost:3306/cloudDB01 # 資料庫名稱
username: root
password: hannong
dbcp2:
min-idle: 5 # 資料庫連接配接池的最小維持連接配接數
initial-size: 5 # 初始化連接配接數
max-total: 5 # 最大連接配接數
max-wait-millis: 200 # 等待連接配接擷取的最大逾時時間
eureka:
client: #用戶端注冊進eureka服務清單内
service-url:
defaultZone: http://localhost:7001/eureka #去注冊中心的位址
instance:
instance-id: microservicecloud-dept8001 #修改eureka的服務路徑名稱
修改之後,再重新啟動microservicecloud-provider-dept-7001的啟動類,再啟動microservicecloud-provider-dept-8001的啟動類
修改前
修改後
通路資訊有IP資訊提示
server:
port: 8001 # 目前微服務的端口
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置檔案所在路徑
type-aliases-package: com.yt.springcloud.entity # 所有餓entity實體類所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射檔案
spring:
application:
name: microservicecloud-dept # 對外暴露的微服務的名字(很重要)
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 目前資料源操作類型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驅動包
url: jdbc:mysql://localhost:3306/cloudDB01 # 資料庫名稱
username: root
password: hannong
dbcp2:
min-idle: 5 # 資料庫連接配接池的最小維持連接配接數
initial-size: 5 # 初始化連接配接數
max-total: 5 # 最大連接配接數
max-wait-millis: 200 # 等待連接配接擷取的最大逾時時間
eureka:
client: #用戶端注冊進eureka服務清單内
service-url:
defaultZone: http://localhost:7001/eureka #去注冊中心的位址
instance:
instance-id: microservicecloud-dept8001 #修改eureka的服務路徑名稱
prefer-ip-address: true #通路路徑可以顯示ip位址
修改前
修改後
微服務info内容詳細資訊
1.修改microservicecloud-provider-dept-8001項目工程的pom.xml檔案
<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>
<parent>
<groupId>com.yt.springcloud</groupId>
<artifactId>microservicecloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>microservicecloud-provider-dept-8001</artifactId>
<dependencies>
<!-- 引入自己已定義的api通用包,可以使用Dept部門Entity -->
<dependency>
<groupId>com.yt.springcloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- junit的jar包 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!-- mysql的jar包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid的jar包 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!-- mybatis的整合 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- springboot的整合jetty 微服務架構不釋出在tomcat下面,内嵌的父容器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!-- springboot的整合web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springboot的整合測試 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- 修改後立即生效,熱部署 (一修改,自動釋出,自動建構)-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- 将微服務provider側注冊進入eureka(引入eureka的client端) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- actuator監控資訊完善 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
2.修改總父工程microservicecloud的pom.xml添加建構build資訊
<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>com.yt.springcloud</groupId>
<artifactId>microservicecloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- cloud的主jar包 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- boot的主jar包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.9.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- mysql的驅動包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.4</version>
</dependency>
<!-- druid資料庫連接配接池的主jar包(不用c3p0) -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.8</version>
</dependency>
<!-- mybatis和boot整合的主jar包 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<!-- logback的主jar包 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<!-- junit的測試jar包 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- log4j的主jar包 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build><!-- 建構 -->
<finalName>microservicecloud</finalName>
<resources>
<resource>
<directory>src/main/resources</directory><!-- 允許通路所有src/main/resources下面的檔案 -->
<filtering>true</filtering><!-- 通路過濾開啟 -->
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId><!-- 負責解析和解讀 -->
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<delimiters>
<delimit>$</delimit><!-- 以$開頭 或者以$結尾的 在src/main/resources這個目錄下 -->
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
<modules>
<module>microservicecloud-api</module>
<module>microservicecloud-provider-dept-8001</module>
<module>microservicecloud-consumer-dept-80</module>
<module>microservicecloud-provider-dept-7001</module>
<module>demo</module>
<module>demp</module>
</modules>
</project>
3.修改microservicecloud-provider-dept-8001項目工程的application檔案
server:
port: 8001 # 目前微服務的端口
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置檔案所在路徑
type-aliases-package: com.yt.springcloud.entity # 所有餓entity實體類所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射檔案
spring:
application:
name: microservicecloud-dept # 對外暴露的微服務的名字(很重要)
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 目前資料源操作類型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驅動包
url: jdbc:mysql://localhost:3306/cloudDB01 # 資料庫名稱
username: root
password: hannong
dbcp2:
min-idle: 5 # 資料庫連接配接池的最小維持連接配接數
initial-size: 5 # 初始化連接配接數
max-total: 5 # 最大連接配接數
max-wait-millis: 200 # 等待連接配接擷取的最大逾時時間
eureka:
client: #用戶端注冊進eureka服務清單内
service-url:
defaultZone: http://localhost:7001/eureka #去注冊中心的位址
instance:
instance-id: microservicecloud-dept8001 #修改eureka的服務路徑名稱
prefer-ip-address: true #通路路徑可以顯示ip位址
info:
app.name: yt-microservicecloud
company.name: www.yt.com
build.artifactId: $project.artifactId$
build.version: $project.version$
修改前
修改後
修改後
對于注冊進eureka裡面的微服務,可以通過服務發現來活的該服務的資訊;
修改microservicecloud-provider-dept-8001工程的DeptController
package com.yt.springcloud.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.yt.springcloud.entity.Dept;
import com.yt.springcloud.service.impl.DeptService;
@RestController//整合了responceBody+Controller
public class DeptController {
@Autowired
private DeptService deptService;
/**
* 目前微服務的資訊
*/
@Autowired
private DiscoveryClient client;
@RequestMapping(value="/dept/add",method=RequestMethod.POST)
public boolean add(@RequestBody Dept dept) {
return deptService.add(dept);
}
@RequestMapping(value="/dept/get/{id}",method=RequestMethod.GET)
public Dept get(@PathVariable("id") Long id) {
return deptService.get(id);
}
@RequestMapping(value="/dept/list",method=RequestMethod.GET)
public List<Dept> list() {
return deptService.list();
}
@RequestMapping(value="/dept/discovery",method=RequestMethod.GET)
public Object discovery() {
List<String> list=client.getServices();//得到所有的微服務
System.err.println("***********"+list);
List<ServiceInstance> serList=client.getInstances("MICROSERVICECLOUD-DEPT");//找一個叫做部門的微服務
for(ServiceInstance element:serList) {//然後輸出這個微服務的相關資訊(info資訊的描述)
System.err.println(element.getServiceId()+"\t"+element.getHost()+"\t"+element.getPort()+"\t"+element.getUri());
}
return this.client;
}
}
DeptProvider8001_App主啟動類(添加一個注解@EnableDiscoveryClient)
package com.yt.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient//本服務啟動後會自動注冊進eureka服務中
@EnableDiscoveryClient//服務發現
public class DeptProvider8001_App {
public static void main(String[] args) {
SpringApplication.run(DeptProvider8001_App.class, args);
}
}
自測調用是否成功(先啟動7001項目工程,再啟動8001項目工程,測試路徑:http://localhost:8001/dept/discovery)
**修改microservicecloud-consumer-dept-80工程的DeptController_Consumer(添加一個調用提供者的資訊方法) **
package com.yt.springcloud.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.yt.springcloud.entity.Dept;
@RestController
public class DeptController_consumer {
private static final String REST_URL_PREFIX="http://localhost:8001";
/**
* 使用RestTemplate通路restful接口非常的簡單粗暴無腦
* (url,requestMap,ResponseBean.class)這三個參數分别代表
* REST請求位址,請求參數,HTTP響應轉換被轉換成的對象類型
*/
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value="/consumer/dept/add")
public boolean add(Dept dept) {
return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add", dept, boolean.class);
}
@RequestMapping(value="/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id, Dept.class);
}
@SuppressWarnings("unchecked")
@RequestMapping(value="/consumer/dept/list")
public List<Dept> list(Dept dept) {
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list", List.class);
}
@RequestMapping(value="/consumer/dept/discovery")
public Object discovery(Dept dept) {
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/discovery", Object.class);
}
}
啟動80,7001,8001等三個項目工程
消費者通路路徑:http://localhost/consumer/dept/discovery
總結
翻譯于尚矽谷周陽老師:https://www.bilibili.com/video/av22613028?from=search&seid=11377756339718254280