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)
边写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