文章目录
前言
想学习本博客案例,需要先看下上一篇的博客:
SpringCloud 学习二、Maven的模块化创建、Restful请求格式学习、RestTemplate请求框架;以为父工程的创建,Rest微服务架构案例工程模块创建
因为案例的都是循序渐进的。案例的顺序:
- 微服务讲诉->
- 父工程maven的module建立和rest风格的请求->
- eureka的学习、三大组件,服务注册与消费->
- eureka的集群操作 ->
- ribbon的负载均衡。
- feign的负载均衡
- Hystrix断路器
- Zuul路由网关
- SpringCloud Config分布式配置中心
一、 是什么
Eureka是**Netflix的一个子模块,也是核心模块之一。Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移。服务注册与发现对于微服务架构来说是非常重要的,有了服务发现与注册,只需要使用服务的标识符,就可以访问到服务,而不需要修改服务调用的配置文件了。功能类似于dubbo的注册中心,比如Zookeeper**。
- Netflix在设计Eureka时遵守的就是CAP原则:
- CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得
二、 原理讲解
1. Eureka的基本架构
Spring Cloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务注册和发现(请对比Zookeeper)。
Eureka 采用了 C-S 的设计架构。Eureka Server 作为服务注册功能的服务器,它是服务注册中心。
而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server并维持心跳连接。这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行。SpringCloud 的一些其他模块(比如Zuul)就可以通过 Eureka Server 来发现系统中的其他微服务,并执行相关的逻辑。
请注意和Dubbo的架构对比
Eureka架构图
Eureka包含两个组件:Eureka Server和Eureka Client
Eureka Server提供服务注册服务
各个节点启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到
EurekaClient是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)
2. 三大角色
- Eureka Server 提供服务注册和发现
- Service Provider服务提供方将自身服务注册到Eureka,从而使服务消费方能够找到
- Service Consumer服务消费方从Eureka获取注册服务列表,从而能够消费服务
3. 盘点下目前我们的工程情况
三、 构建 1 :新建服务注册中心Module:microservicecloud-eureka-7001
新建microservicecloud-eureka-7001 module工程,此处同上。
目录:
1. POM文件
<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.atguigu.springcloud</groupId>
<artifactId>microservicecloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>microservicecloud-eureka-7001</artifactId>
<dependencies>
<!--eureka-server服务端 -->
<dependency>
<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>
2. 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交互的地址查询服务和注册服务都需要依赖这个地址。
3. EurekaServer7001_App主启动类
package com.atguigu.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer//EurekaServer服务器端启动类,接受其它微服务注册进来
public class EurekaServer7001_App
{
public static void main(String[] args)
{
SpringApplication.run(EurekaServer7001_App.class, args);
}
}
4. 放在启动类上的:@EnableEurekaServer
5. 测试
http://localhost:7001/
结果界面:
No application available 没有服务被发现 O(∩_∩)O
因为没有注册服务进来当然不可能有服务被发现
四、构建 2. 微服务注册:修改microservicecloud-provider-dept-8001,将已有的部门微服务注册进eureka服务中心
修改microservicecloud-provider-dept-8001,将已有的部门微服务注册进eureka服务中心
以下都是修改microservicecloud-provider-dept-8001
1. POM
1) 修改部分
<!-- 将微服务provider侧注册进eureka -->
<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>
2) 完整部分
<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.atguigu.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.atguigu.springcloud</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 将微服务provider侧注册进eureka -->
<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>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<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</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>
2. YML
1) 修改部分
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://localhost:7001/eureka
2) 完整内容
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml #mybatis所在路径
type-aliases-package: com.atguigu.springcloud.entities #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
url: jdbc:mysql://localhost:3306/cloudDB01
username: root
password: 123456
dbcp2:
min-idle: 5
initial-size: 5
max-total: 5
max-wait-millis: 200
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://localhost:7001/eureka
3. DeptProvider8001_App主启动类
package com.atguigu.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);
}
}
4. 放在启动类上的:@EnableEurekaClient
5. 测试
1) 先要启动EurekaServer
2) http://localhost:7001/
看下面即可;
3) 微服务注册名配置说明
五、构建 3. 完善 actuator与注册微服务信息
1. 主机名称:服务名称修改
1) 当前问题
含有主机名称。
2) 修改microservicecloud-provider-dept-8001 工程
- YML 修改部分
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://localhost:7001/eureka
instance:
instance-id: microservicecloud-dept8001 #自定义修改 服务名称信息, 这个名称会在 eureka 客户端界面上 微服务工程的 右边显示
- 修改之后
2. 访问信息有IP信息提示
1) 当前问题
没有IP提示
2) 修改microservicecloud-provider-dept-8001
- YML添加
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://localhost:7001/eureka
instance:
instance-id: microservicecloud-dept8001 #自定义服务名称信息
prefer-ip-address: true # 访问路径(上面的instance-id 的路径,当鼠标放在上面,左下角会显示 访问路径)可以显示IP地址
- 修改之后
3. 微服务info内容详细信息
1) 当前问题
超链接点击服务报告ErrorPage
2) 修改microservicecloud-provider-dept-8001
*POM添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
3) 总的父工程microservicecloud修改pom.xml添加构建build信息
- POM添加
<build>
<finalName>microservicecloud</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<delimiters>
<delimit>$</delimit>
</delimiters>
</configuration>
</plugin>
</plugins>
</build>
4) 修改microservicecloud-provider-dept-8001
- YML添加
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml #mybatis所在路径
type-aliases-package: com.atguigu.springcloud.entities #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
url: jdbc:mysql://localhost:3306/cloudDB01
username: root
password: 123456
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 #自定义服务名称信息
prefer-ip-address: true #访问路径可以显示IP地址
info:
app.name: atguigu-microservicecloud
company.name: www.atguigu.com
build.artifactId: $project.artifactId$
build.version: $project.version$
六、构建 4. eureka自我保护
1. 演示Case
- 故障现象
2. 导致原因
一句话:某时刻某一个微服务不可用了,eureka不会立刻清理,依旧会对该微服务的信息进行保存
3. 处理方法
不建议处理!!!
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交互的地址查询服务和注册服务都需要依赖这个地址。
# 禁用自我保护模式。
server:enable-self-preservation: false
七、构建 5.服务发现module Discovery: microservicecloud-provider-dept-8001
服务发现:对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息
1. 修改microservicecloud-provider-dept-8001工程的DeptController
/**
* 注入 服务发现 客户端请求
*/
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping(value = "/dept/discovery", method = RequestMethod.GET)
public Object discovery()
{
List<String> list = discoveryClient.getServices();
System.out.println("**********" + list);
List<ServiceInstance> srvList = discoveryClient.getInstances("MICROSERVICECLOUD-DEPT");
for (ServiceInstance element : srvList) {
System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"
+ element.getUri());
}
return this.discoveryClient;
}
2. DeptProvider8001_App主启动类
@SpringBootApplication
@EnableEurekaClient //本服务启动后会 自动注册 进eureka服务中
@EnableDiscoveryClient //开启 服务发现 功能, 可以通过请求 进而发现 所有的服务
public class DeptProvider8001_Application {
public static void main(String[] args) {
SpringApplication.run(DeptProvider8001_Application.class, args);
}
}
3. 自测
http://localhost:8001/dept/discovery
4. 修改microservicecloud-consumer-dept-80工程的DeptController_Consumer
/**
* 测试 @EnableDiscoveryClient ,消费端可以调用服务发现
* @return
*/
@RequestMapping(value="/consumer/dept/discovery")
public Object discovery()
{
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/discovery", Object.class);
}
5. 消费者测试
http://localhost/consumer/dept/discovery