1.Eureka基础知识
1.1什么是服务治理
Springcloud封装了Netflix公司开发的Eureka模块来进行服务治理
在传统的rpc远程框架调用中,每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要服务治理,管理服务与服务之间依赖关系,可以实现服务调用,负载均衡,容错等,实现服务发现与注册。
1.2 什么是服务注册与发现
1.3Eureka包括两个组件
2.单机版的Eureka实地应用
2.1.EurekaServer(cloud-eureka-server7001)服务注册中心
1.建model
2.改pom
前置知识:
<dependencies>
<!--Eureka服务注册中心依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>com.xiaoqi.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<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-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>
3.写YML
server:
port: 7001
eureka:
instance:
hostname: localhost #eureka服务端的实例名称
client:
# false表示不向注册中心注册自己
register-with-eureka: false
# false 表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
# 设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone:http://${eureka.instance.hostname}:${server.port}/eureka/
4.主启动
![在这里插入图片描述](https://img-blog.csdnimg.cn/5a7c7cdb45f341209fc69c2c6e819728.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6I-c6bifeGlhb3Fp,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
5.测试
原因:服务注册中心还没有注册任何的服务,因此会出现异常
2.2EurekaClient(cloud-provider-payment8001)端服务注册
2.2.1:改子项目中的pom文件,加入Eureka客户端依赖
org.springframework.cloud spring-cloud-starter-netflix-eureka-client #### 2.2.2:在yml配置文件中添加Eureka配置信息 # Eureka服务注册中心配置 eureka: client: # 表示是否将自己注册进EurekaServer默认为true register-with-eureka: true # 是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡 fetch-registry: true service-url: defaultZone: http://localhost:7001/eureka #### 2.2.3:主启动 在主启动类上加入@EnableeurekaClient注解,将此服务注入到服务注册中心中 #### 2.2.4: 测试 注意: 1.必须先启动Eureka服务注册中心 测试成功:我们的服务已经成功注册到服务注册中心 2.我们在子项目中设定的服务名称必须和服务注册中心的配置信息一致 3.集群版的Eureka 原理:1.EurekaServer集群构建步骤
参考cloud-eureka-server7001:
1.建model
2.改pom
<dependencies>
<!--Eureka客户端服务注册中心依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>com.xiaoqi.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<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-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
3.修改映射配置
在本机的C:\Windows\System32\drivers\etc目录下的hosts文件中配置集群信息
localhost name resolution is handled within DNS itself.
127.0.0.1 localhost
::1 localhost
127.0.0.1 transact.netsarang.com
13.225.159.110 plugins.jetbrains.com
127.0.0.1 activate.navicat.com
########SpringCloud2020.1.2##########
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com
4.写YML
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
# false表示不向注册中心注册自己
register-with-eureka: false
# false 表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
# 设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://eureka7001.com:7001/eureka/
5.主启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7002 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7002.class,args);
}
}
6.测试
2.将支付服务8001微服务发布到上面两台Eureka集群配置中
1.改yml
将原来的单机版改成集群版
#此微服务端口号
server:
port: 8001
#服务名称
spring:
application:
name: cloud-payment-service
#配置数据源
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源擦操作类型
driver-class-name: com.mysql.jdbc.Driver #mysql驱动包
url: jdbc:mysql://localhost:3306/cloud_payment?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 140489lu
#mybatis
mybatis:
mapper-Locations: classpath:mapper/*.xml
type-aliases-package: com.xiaoqi.springcloud.entities # 所有Entity别名类所在的包
#Eureka服务注册中心配置
eureka:
client:
# 表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
# 是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
# defaultZone: http://localhost:7001/eureka 单机版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
3.将订单服务80微服务发布到上面2台Eureka集群配置中
1.改yml
server:
port: 80
#服务名称
spring:
application:
name: cloud-order-service
Eureka服务注册中心配置
eureka:
client:
表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用
fetch-registry: true
service-url:
单机版
defaultZone: http://eureka7001.com:7001/eureka
集群版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
2.加入负载均衡(如果不加会出现一个bug)
出现的问题
问题描述:
初学 SpringCloud 架构,配置ribbon消费者服务,启动该服务时候报出标题中的错误,导致程序启动失败。
完整的错误信息如下:
Field restTemplate in com.cloud.ribbon_consumer.project.service.HelloService required a bean of type ‘org.springframework.web.client.RestTemplate’ that could not be found.
其中,“com.cloud.ribbon_consumer.project.service.HelloService”是我的示例中使用RestTemplate实例的路径。
具体问题见下图:
我的代码示例:
原因分析:
spring cloud 架构开发中,有两种消费的方式:RestTemplate+ribbon,feign。
两者最大的区别就是区别就是:
feign 消费是通过注解的方式进行的消费模式,它默认打开了负载均衡;
而 ribbon 消费需要手动配置负载均衡;
其中,使用“RestTemplate + ribbon”方式配置消费时,当我们将 RestTemplate 通过 @Autowired 注解注入到一个类中,启动服务就可能会报该(标题中的)错误。
【原因在于】:
在 Spring Boot 1.3版本中,会默认提供一个RestTemplate的实例Bean,而在 Spring Boot 1.4以及以后的版本中,这个默认的bean不再提供了,我们需要在Application启动时,手动创建一个RestTemplate的配置。
这样,我们在类中通过注解 @Autowired 使用 TestTemplate 的时候,程序就可以找到被实例化的 TestTemplate,就不会出现上述的报错了。
解决方案:
在 Spring Boot 项目启动类 xxxApplication 中,设置手动引入 RestTemplate 相关配置,代码如下:
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
示例如下:
解决方法
@Configuration
public class ApplicationContextConfig {
// 配置一个组件
@Bean
@LoadBalanced // 配置负载均衡
RestTemplate restTemplate(){
return new RestTemplate();
}
}
4.测试
1.先要启动EurekaServer,7001/7002服务
2.在启动提供者服务,provider,8001
3.再要启动消费者,80
4.http://localhost/consumer/payment/get/1
5.支付服务者8001集群环境搭建
1.创model
cloud-provider-payment8002
2.改pom
springcloud-course
com.xiaoqi.springcloud
1.0-SNAPSHOT
4.0.0
<artifactId>cloud-provider-payment8002</artifactId>
<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>
<version>2.5.3</version>
</dependency>
<!--自定义组件依赖-->
<dependency>
<groupId>com.xiaoqi.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!--springboot起步依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!--druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>2.5.3</version>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--Eureka客户端服务注册中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
3.写yml
#此微服务端口号
server:
port: 8002
#服务名称
spring:
application:
name: cloud-payment-service
#配置数据源
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源擦操作类型
driver-class-name: com.mysql.jdbc.Driver #mysql驱动包
url: jdbc:mysql://localhost:3306/cloud_payment?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 140489lu
#mybatis
mybatis:
mapper-Locations: classpath:mapper/*.xml
type-aliases-package: com.xiaoqi.springcloud.entities # 所有Entity别名类所在的包
#Eureka服务注册中心配置
eureka:
client:
# 表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
# 是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka 单机版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
4.主启动
// 主启动类
@SpringBootApplication
@EnableEurekaClient // 将这个服务注册进服务注册中心
public class PaymentMain8002 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8002.class,args);
}
}
5.业务类
可以复制cloud-provider-payment8001业务
7.测试
先要启动EurekaServer:7001/7002
4.actuator微服务信息完善
1.主机名称:服务名称修改
1.当前问题
2.修改cloud-provider-payment
#Eureka服务注册中心配置
eureka:
client:
# 表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
# 是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka 单机版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
instance:
instance-id: payment8002
3.修改之后
2.访问信息有ip信息提示
1.当前问题
当我们对地址进行访问的时候不显示出应用地址
2.修改cloud-provider-payment
我们可以加上prefer-ip-address:true配置显示出ip地址
eureka:
client:
# 表示是否将自己注册进EurekaServer默认为true
register-with-eureka: true
# 是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
# defaultZone: http://localhost:7001/eureka 单机版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版
instance:
instance-id: payment8001
prefer-ip-address: true # 访问路径可以显示IP地址
3.修改之后
5.服务发现Discovery
对于注册进Eureka里边的微服务,可以通过服务发现来获取该服务的信息
修改cloud-provider-payment8001的Controller
注入对象
// 服务发现
// @Resource
// private DiscoveryClient discoveryClient;
@GetMapping("/payment/discovery")
public Object getDiscoveryClient() {
// 获取所有的服务
List services = discoveryClient.getServices();
for (String s:services) {
log.info(“s”+s);
}
List instancesById = discoveryClient.getInstancesById(“CLOUD-PAYMENT-SERVICE”);
for (InstanceInfo i: instancesById) {
log.info(i.getHostName()+" “+ i.getPort() +” " + i.getHomePageUrl());
}
return this.discoveryClient;
}
8001主启动类
// 主启动类
@SpringBootApplication
@EnableEurekaClient // 将这个服务注册进服务注册中心
@EnableDiscoveryClient // 服务发现客户端
public class PaymentMain8002 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8002.class,args);
}
}
自测
6.Eureka自我保护
某一时刻,某一个微服务不能用了,Eureka并不会立刻清理掉该微服务,依旧会对该微服务的信息进行保存。
属于CAP里边的AP分支
1.什么是自我保护模式?
默认情况下,如果EurekaServer在一定的时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒),但是当网络分区故障发生(延时,卡顿,拥挤)时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了–因为微服务本身其实是健康的,此时兵不应该注销掉该微服务。Eureka通过“自我保护机制”来解决这个问题,当EurekaServer在短时间内丢失过多微服务客户端时,就会进入自我保护机制。
2.Eureka自我保护的原理
2.怎么禁用自我保护
1.注册中心eurekaServer端7001
2.生产者客户端eurekaClient端8001