springcloud 初级部分1:注册中心(Eureka、Zookeeper、Consul)
一、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.hr.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: register-with-eureka: false #false表示不向注册中心注册自己(想注册也可以,不过没必要) fetch-registry: false #false表示自己端就是注册中心,职责就是维护服务实例,并不需要去检索服务 service-url: #设置与eurekaServer交互的地址查询服务和注册服务都需要依赖这个地址 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
4、主启动
在java包下新建com.hr.springcloud.EurekaMain7001
@EnableEurekaServer //表示此项目是eureka的服务注册中心 @SpringBootApplication public class EurekaMain7001 { public static void main(String[] args) { SpringApplication.run(EurekaMain7001.class, args); } }
5、测试
启动项目,在浏览器输入http://localhost:7001/
二、配置EurekaClient端
// 将cloud-provider-payment8081子模块配置为EurekaClient端,并注册到EurekaServer,成为服务提供者
1、在cloud-provider-payment8081子模块POM中引入依赖
<!-- eureka-client --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
2、在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、启动项目,然后刷新Eureka页面,成功注册到注册中心。
// 备注:在yml文件中application.name就是注册到注册中心的应用名
// 同上:将 cloud-consumer-order8082 子模块配置为EurekaClient端,并注册到EurekaServer,成为服务提供者
三、搭建Eureka集群
// Eureka集群:相互注册、相互守望
1、参照cloud-eureka-server7001,新建cloud-eureka-server7002、cloud-eureka-server7003
2、修改hosts文件
// 在本地跑集群的时候,使用的地址是localhost,但是三个eureka都配置为localhost会集群失败,导致注册中心之间不会互相注册。 // 修改C:\Windows\System32\drivers\etc\hosts文件,将localhost映射成别的自定义域名。在hosts文件末尾添加: 127.0.0.1 eureka7001.com 127.0.0.1 eureka7002.com 127.0.0.1 eureka7003.com
3、修改7001的yml文件
eureka: instance: hostname: eureka7001.com #eureka服务端的实例名称 client: register-with-eureka: false fetch-registry: false service-url: # 单机 # defaultZone: http://${eureka.instance.hostname}:${server.port}/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/
4、修改7002的yml文件
eureka: instance: hostname: eureka7002.com #eureka服务端的实例名称 client: register-with-eureka: false fetch-registry: false service-url: #集群版 相互注册,相互守望 defaultZone: http://eureka7001.com:7001/eureka/, http://eureka7003.com:7003/eureka/
5、修改7003的yml文件
eureka: instance: hostname: eureka7003.com #eureka服务端的实例名称 client: register-with-eureka: false fetch-registry: false service-url: #集群版 相互注册,相互守望 defaultZone: http://eureka7001.com:7001/eureka/, http://eureka7002.com:7002/eureka/
6、启动三个EurekaServer,输入地址访问验证
http://eureka7001.com:7001
http://eureka7002.com:7002
http://eureka7003.com:7003
7、将子模块(Client端)发布到Eureka集群
把子模块yml文件中的defaultZone改为:
#集群版 defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
// 再次在EurekaServer集群中刷新、查看,验证。
四、微服务信息优化完善
1、修改三个微服务yml文件
// 8081
#添加eureka子元素instance,instance和client子元素对齐 instance: instance-id: payment8001 prefer-ip-address: true #访问路径可以显示ip地址
// 8082
#添加eureka子元素instance,instance和client子元素对齐 instance: instance-id: consumer8082 prefer-ip-address: true #访问路径可以显示ip地址
// 8083
#添加eureka子元素instance,instance和client子元素对齐 instance: instance-id: payment8083 prefer-ip-address: true #访问路径可以显示ip地址
修改后,效果:
五、服务发现Discovery
对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息。
// 修改提供者集群的controller
1、在主配置类上加上@EnableDiscoveryClient注解,启用发现客户端。
2、在两个提供者的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、测试
浏览器输入:http://localhost:8081/payment/discovery
五、Eureka自我保护
1、概述
保护模式主要用于一组客户端和 Eureka Server 之间存在网络分区场景下的保护。
一旦进入保护模式,Eureka Server 将会尝试保护其服务注册表中的信息,不在删除服务注册表中的数据,也就是不会注销任何微服务。
如果在Eureka Server的首页看到一下这段提示,则说明 Eureka 进入了保护模式。
// 翻译:紧急情况! EUREKA 可能不正确地声称实例已启动,但实际上并未启动。续订少于阈值,因此为了安全起见,实例不会过期。
默认情况下,如果 Eureka Server 在一定时间内没有收到某个微服务示例的心跳,Eureka Server 将会注销该示例(默认90秒)。但是,当网络分区故障发生(延时、卡顿、拥挤)时,微服务与Eureka Server 之间无法正常通信,以上行为可能变得非常危险——因为微服务本身其实是健康的,此时本不应该注销这个微服务。Eureka Server 通过“自我保护模式”来解决这个问题:当 Eureka Server 节点在短时间丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。
2、 禁止自我保护
先把cloud-eureka-server7001和cloud-provider-payment8081都切回单机版测试禁止自我保护。
cloud-eureka-server7001的yml文件:
# client # ... server与client对齐 server: #关闭自我保护,默认为true enable-self-preservation: false #心跳的间隔时间,单位毫秒 eviction-interval-timer-in-ms: 2000
cloud-provider-payment8001的yml文件:
#Eureka客户端向服务端发送心跳的时间间隔,单位秒(默认30秒) lease-renewal-interval-in-seconds: 1 #Eureka服务端在收到最后一次心跳后等待的时间上限,单位秒(默认90秒),超时剔除服务 lease-expiration-duration-in-seconds: 2
启动注册中心和提供者,访问Eureka页面:
然后关闭提供者(模拟网络延时),提供者直接被剔除。