目录
a.IDEA生成eurekaServer端服务注册中心 类似物业公司
b.EurekaClient端cloud-provider-payment8001将注册进EurekaServer成为服务提供者provider 类似学校对外提供授课服务
c.EurekaClient端cloud-consumer-order80将注册进EurekaServer成为服务消费者consumer 类似去超市购物的顾客
将支付服务8001微服务发布到上面2台Eureka集群配置中
一、Eureka基础知识
a.什么是服务治理 b.什么是服务注册
c.Eureka两组件
二、单机Eureka构建步骤
a.IDEA生成eurekaServer端服务注册中心 类似物业公司
1.建Module
cloud-eureka-server7001
2.改POM
在pom中添加:
<dependencies>
<!-- eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- 引用自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.aurora.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>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<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>
</dependencies>
3.写YML
在resources目录下新建application.yml文件
server:
port: 7001
eureka:
instance:
hostname: localhost #eureka服务端的实例名称
client:
#false表示不向注册中心注册自己(想注册也可以,不过没必要)
register-with-eureka: false
#false表示自己端就是注册中心,职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
#设置与eurekaServer交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
4.主启动
在java包下新建com.aurora.springcloud.EurekaMain7001
@SpringBootApplication
@EnableEurekaServer //表示此项目是Eureka的服务注册中心
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class,args);
}
}
5.测试
启动项目,在浏览器输入http://localhost:7001/ 看到Eureka表示安装成功
b.EurekaClient端cloud-provider-payment8001将注册进EurekaServer成为服务提供者provider 类似学校对外提供授课服务
cloud-provider-payment8001
1.改pom 添加依赖
<!-- eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.写yml 在yml文件中添加
eureka:
client:
#true表示向注册中心注册自己,默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
3.主启动 在主配置类上加上@EnableEurekaClient
注解,表示这个项目是eureka的客户端。
4.测试 启动8001项目,然后刷新页面,成功注册进注册中心。
在yml文件中application.name就是注册进注册中心时的应用名。
c.EurekaClient端cloud-consumer-order80将注册进EurekaServer成为服务消费者consumer 类似去超市购物的顾客
cloud-consumer-order80
1.改pom 添加依赖
<!-- eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.写yml 在yml文件中添加
spring:
application:
name: cloud-order-service
eureka:
client:
#表示是否将自己注册进EurekaServer 默认为true 如果不注册进 改为false即可
register-with-eureka: true
#是否从EurekaServer抓取已有注册信息,默认为true 单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
3.主启动 在主配置类上加上@EnableEurekaClient
注解,表示这个项目是eureka的客户端。
4.测试
启动80项目,然后先要启动EurekaServer,7001服务 再要启动服务提供者provider,8001服务 最后刷新页面,成功注册进注册中心。
三、集群Eureka构建步骤
Eureka集群原理说明
解决办法:搭建Eureka注册中心集群,实现负载均衡+故障容错
Eureka集群的注册原理:互相注册,相互守望。
EurekaServer集群环境构建步骤
1.建module参照cloud-eureka-server7001新建cloud-eureka-server7002
2.改pom 添加依赖
<dependencies>
<!-- eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- 引用自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.aurora.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>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<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>
</dependencies>
3.修改映射配置
找到C:\Windows\System32\drivers\etc路径下的hosts文件
修改映射配置添加进hosts文件
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
4.写yml(以前单机) 在resources目录下新建application.yml文件
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
register-with-eureka: false
fetch-registry: false
service-url:
#集群版 相互注册,相互守望
defaultZone: http://eureka7001.com:7001/eureka/ #互相注册,相互守望
5.修改7001的yml (互相注册,相互守望)
server:
port: 7001
eureka:
instance:
#hostname: localhost #eureka服务端的实例名称
hostname: eureka7001.com
client:
#false表示不向注册中心注册自己(想注册也可以,不过没必要)
register-with-eureka: false
#false表示自己端就是注册中心,职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
#设置与eurekaServer交互的地址查询服务和注册服务都需要依赖这个地址
#单机:
#defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
#集群版 相互注册,相互守望
defaultZone: http://eureka7002.com:7002/eureka/
#defaultZone: http://eureka7002.com:7002/eureka/, http://eureka7003.com:7003/eureka/
#defaultZone是固定写法,如果想自定义,需要按以下写法才行:
#region: eureka-server
#availability-zones:
#eureka-server: server1,server2
#service-url:
#server1: http://eureka7002.com:7002/eureka/
#server2: http://eureka7003.com:7003/eureka/
6.主启动
在java包下新建com.aurora.springcloud.EurekaMain7002
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7002 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7002.class,args);
}
}
启动7001 、7002 浏览器输入 http://eureka7001.com:7001/ http://eureka7002.com:7002/
将支付服务8001微服务发布到上面2台Eureka集群配置中
改8001的yml
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka #集群版
将订单服务80微服务发布到上面2台Eureka集群配置中
改80 yml 的defaultZone
测试01
先启动EurekaServer,7001/7002服务 再启动服务提供者provider,8001服务 再启动消费者,80
可以看到80、8001都已成功注册进7001、7002
查询参数信息 http://localhost/consumer/payment/get/31
支付服务提供者8001集群环境构建
1.参考cloud-provider-payment8001 新建cloud-provider-payment8002
2.改pom (跟8001的一致)
<dependencies>
<!-- eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 引用自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.aurora.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.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<!--子工程写了版本号,就使用子工程的版本号,如果没写版本,找父工程中规定的版本号-->
</dependency>
<!--mysql-connector-java-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>5.5.27</scope>
</dependency>
<!--jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<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>
</dependencies>
3.写yml
将8001的application.yml复制过来改一下端口即可
4.主启动
从8001下复制粘贴
5.业务类
从8001下复制粘贴
修改8001/8002的Controller
负载均衡
1.bug (订单服务访问地址不能写死)
自测都可通过 但是通过80端口访问支付服务 一直访问到的是8001
因为80的源程序地址是写死的 (单机版是没问题的)
现在不止一个服务 所以不要关注具体的ip和端口 只认服务名称
2.将服务名称改为:
public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
直接访问java找不到主机名称的异常 不止一个服务 不知道具体找哪一个
3.然后在消费者的ApplicationContextConfig里的restTemplate方法上加上@LoadBalanced
,开启负载均衡功能。
测试02
先要启动EurekaServer,7001/7002服务
再要启动服务提供者provider,8001/8002服务
浏览器输入:http://localhost/consumer/payment/get/31
结果:负载均衡效果达到 8001/8002端口交替出现
Ribbon和Eureka整合后Consumer可以直接调用服务而不用再关心地址和端口号,且该服务还有负载功能了
四、actuator微服务信息完善
主机名称:服务名称修改
修改cloud-provider-payment8001 / cloud-provider-payment8002 的 application.yml
instance:
instance-id: payment8001
修改前:
修改后:
访问信息有ip信息提示
当前没有ip提示
修改cloud-provider-payment8001 / cloud-provider-payment8002 的 application.yml
prefer-ip-address: true #访问路径可以显示ip地址
修改后
五、服务发现Discovery
对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息
修改提供者集群的controller
- 在主配置类上加上
@EnableDiscoveryClient
注解,启用发现客户端。 - 在两个提供者的PaymentController中加入:
@Resource
private DiscoveryClient discoveryClient; //springframework的DiscoveryClient(不要导错包了)
@GetMapping("/payment/discovery")
public Object discovery(){
//获取服务列表的信息
List<String> services = discoveryClient.getServices();
for (String element : services) {
log.info("*******element:" + element);
}
//获取CLOUD-PAYMENT-SERVICE服务的所有具体实例
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
for (ServiceInstance instance : instances) {
//getServiceId服务器id getHost主机名称 getPort端口号 getUri地址
log.info(instance.getServiceId() + "\t" + instance.getHost() + "\t" + instance.getPort() + "\t" + instance.getUri());
}
return this.discoveryClient;
}
}
3.8001/8002主启动类 加@EnableDiscoveryClient注解
4.自测
先要启动EurekaServer,7001/7002服务
再启动8001主启动类,需要稍等一会
再在浏览器输入:http://localhost:8001/payment/discovery
可以看到主启动的控制台有获取到服务信息和支付服务的实例信息
六、Eureka自我保护
导致原因:
一句话:某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的信息进行保存属于CAP里面的AP分支
只有在一定时间内丢失大量服务的心跳才开启自我保护模式。
怎么禁止自我保护(一般生产环境中不会禁止自我保护)
先把cloud-eureka-server7001和cloud-provider-payment8001都切回单机版测试禁止自我保护。
cloud-eureka-server7001的yml文件:
defaultZone: http://eureka7001.com:7001/eureka/
server:
#关闭自我保护,默认为true
enable-self-preservation: false
#心跳的间隔时间,单位毫秒
eviction-interval-timer-in-ms: 2000
显示自我保护机制已经关了
cloud-provider-payment8001的yml文件:
defaultZone: http://localhost:7001/eureka
#Eureka客户端向服务端发送心跳的时间间隔,单位秒(默认30秒)
lease-renewal-interval-in-seconds: 1
#Eureka服务端在收到最后一次心跳后等待的时间上限,单位秒(默认90秒),超时剔除服务
lease-expiration-duration-in-seconds: 2
启动注册中心7001和提供者8001: 7001上成功入驻了8001
停止掉8001假设出故障 7001上的实例马上消失 (因为此时自我保护机制关闭)
Eureka停更说明