博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringCloud服务注册与发现
阅读量:3967 次
发布时间:2019-05-24

本文共 23012 字,大约阅读时间需要 76 分钟。

博客参考学习视频: https://www.bilibili.com/video/BV18E411x7eT?from=search&seid=4388336378730572330

上一篇:

一、Eureka服务注册与发现

① Eureka 基础知识

1. 服务治理

​ SpringCloud 封装了 Netflix 公司开发的 Eureka 模块来实现服务治理。 在传统的 RPC 远程调用框架中, 管理每个服务与服务之间依赖关系比较复杂, 所以需要使用服务治理管理服务与服务之间依赖关系, 了以实现服务调用、 负载均衡、容错等, 实现服务发现与注册 。

2. 服务注册

image-20201008163431445

image-20201008163441176

3.Eureka 两组件

image-20201008163527932

② 单机 Eureka 构建步骤

1.IDEA生成EurekaServer端服务注册中心 类似物业公司

建Module

image-20201008163938347

改POM

org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
com.atguigu.springcloud
cloud-api-common
${project.version}
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test

1.X 和 2.X 的对比说明

image-20201008164348553

写 YML

server:  port: 7001eureka:  instance:    hostname: localhost #eureka服务端的实例名称  client:    register-with-eureka: false     #false表示不向注册中心注册自己。    fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务    service-url:      defaultZone: http://${
eureka.instance.hostname}:${
server.port}/eureka/

主启动

@SpringBootApplication@EnableEurekaServerpublic class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class, args); }}

注意:需要在启动类上配置注解 @EnableEurekaServer,开启注册中心

测试

http://localhost:7001/ ,效果页面

image-20201008165537963

2.EurekaClient 端 cloud-provider-payment8001 将注册进 EurekaServer 成为服务提供者 provider

改 POM ( cloud-provider-payment8001)

org.springframework.cloud
spring-cloud-starter-netflix-eureka-client

1.X 和 2.X 的对比说明

image-20201008170119489

写 YML

eureka:  client:      # 表示是否将自己注册进eurekaServer 默认为 true。    register-with-eureka: true    # 是否从EureaServer 抓取已有的注册信息,默认为true.单节点无所谓,集群必须设置true才能配合ribbon使用负载均衡    fetchRegistry: true    service-url:        defaultZone: http://localhost:7001/eureka

主启动

@EnableEurekaClient@SpringBootApplicationpublic class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class, args); }}

添加:注解 @EnableEurekaClient

测试

  • 先启动 EurekaServer http://localhost:7001/

image-20201008203122376

  • 微服务配置说明

image-20201008173128335

  • 自我保护机制

image-20201008173216519

3.EurekaClient 端 cloud-consumer-order80 将注册进EurekaServer 成为服务消费者 consumer

改POM

org.springframework.cloud
spring-cloud-starter-netflix-eureka-client

写 YML

spring:  application:    name: cloud-order-serviceeureka:  client:    register-with-eureka: true    fetchRegistry: true    service-url:      defaultZone: http://localhost:7001/eureka

主启动 @EnableEurekaClient

@SpringBootApplication@EnableEurekaClientpublic class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class, args); }}

测试

  • 先启动 EurekaServer, 7001 服务,在启动服务提供者 provider 8001 服务,在启动消费者 consumer 80

image-20201008204121007

  • http://localhost/consumer/payment/get/1

image-20201008204201760

BUG

image-20201008210724219

image-20201008210736191

③ Eureka 构建步骤

1.Eureka 集群原理说明

image-20201008210953089

**微服务RPC远程服务调用最核心的是什么 **

高可用

解决办法:搭建 Eureka 注册中心集群,实现负载均衡+故障容错

2.EurekaServer 集群环境构建步骤

新建 cloud-eureka-server7002 和 POM

​ 参考 cloud-eureka-server7001项目工程

修改映射配置

找到 C:\Windows\System32\drivers\etc 路径下的 hosts 文件 image-20201008213018672

修改映射配置添加进 hosts 文件

  • 127.0.0.1 eureka7001.com
  • 127.0.0.1 eureka7002.com

image-20201008221924946

写 YML

  • 以前单机

image-20201008213246584

  • 7001
server:  port: 7001eureka:  instance:    hostname: eureka7001.com #eureka服务端的实例名称  client:    register-with-eureka: false     #false表示不向注册中心注册自己。    fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务    service-url:      defaultZone: http://eureka7002.com:7002/eureka/ #设置与 eureka server 交互的地址查询服务和注册服务都需要依赖这个地址
  • 7002
server:  port: 7002eureka:  instance:    hostname: eureka7002.com #eureka服务端的实例名称  client:    register-with-eureka: false     #false表示不向注册中心注册自己。    fetch-registry: false     #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务    service-url:      defaultZone: http://eureka7001.com:7001/eureka/ #设置与 eureka server 交互的地址查询服务和注册服务都需要依赖这个地址

主启动类 (参考cloud-eureka-server7001 的主启动类 )

@SpringBootApplication@EnableEurekaServerpublic class EurekaMain7002 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7002.class, args); }}

3.将支付服务 8001 微服务发布到上面 2 台 Eureka 集群配置中

YML

eureka:  client:    register-with-eureka: true    fetch-registry: true    service-url:      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 集群版

image-20201008214921087

4.将订单服务 80 微服务发布到上面 2 台 Eureka 集群配置中

YML

eureka:  client:    register-with-eureka: true    fetchRegistry: true    service-url:#      defaultZone: http://localhost:7001/eureka      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka  #集群版

image-20201008215358970

5.测试01

  • 先要启动 EurekaServer, 7001/7002 服务,再要启动服务提供者 provider, 8001 服务,再要启动消费者, 80

image-20201008222218619

  • http://localhost/consumer/payment/get/1

image-20201008222250676

6.支付服务提供者 8001 集群环境构建

新建 cloud-provider-payment8002 和 POM

​ 参考 cloud-provider-payment8001

写 YML

server:  port: 8002spring:  application:    name: cloud-payment-service  datasource:      type: com.alibaba.druid.pool.DruidDataSource      driver-class-name: com.mysql.cj.jdbc.Driver      url: jdbc:mysql://localhost:3306/db2019?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC      username: root      password: 6090mybatis:  mapperLocations: classpath:mapper/*.xml  type-aliases-package: com.oy.springcloud.entities # 所有Entity别名类所在包eureka:  client:    register-with-eureka: true    fetch-registry: true    service-url:      # 集群版      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

主启动

@EnableEurekaClient@SpringBootApplicationpublic class PaymentMain8002 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8002.class, args); }}

业务类 直接从8001 粘贴

image-20201008223430791

修改8001/8002的controller

@Value("${server.port}")private String serverPort;
  • 8001 和 8002
image-20201008223844291

7.负载均衡

Bug: 订单服务访问地址不能写死

原本:(cloud-consumer-order80

image-20201008224333187

更改:

public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";

使用@LoadBalanced注解赋予RestTemplate负载均衡的能力 (cloud-consumer-order80

image-20201008224958711

8.测试02

  • 先要启动 EurekaServer, 7001/7002 服务
  • 再要启动服务提供者 provider, 8001/8002 服务
  • 在启动 consumer 80 服务
  • http://localhost/consumer/payment/get/1 **负载均衡生效, 8001/8002 端口交替出现 **

image-20201008225822628

④ actuator 微服务信息完善

1.主机名称:服务名称修改

修改YML (cloud-provider-payment8001) 部分

instance:    instance-id: payment8001

image-20201009230434805

效果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3LshZHHm-1602487784697)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20201009230616274.png)]

2.访问信息有ip信息提示

​ 当前问题:没有ip提示

修改 cloud-provider-payment8001 YML部分

prefer-ip-address: true

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sRGagkv0-1602487784698)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20201009230941130.png)]

效果

image-20201009230917967

⑤ 服务发现 Discovery

1.对于注册进 eureka 里面的微服务,可以通过服务发现来获取服务的信息

2.修改cloud-provider-payment8001的Controller

@Resourceprivate DiscoveryClient discoveryClient;@GetMapping(value = "/payment/discovery")public Object discovery(){
List
services = discoveryClient.getServices(); for (String element : services) {
log.info("**** element:"+ element); } List
instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE"); for (ServiceInstance instance : instances) {
log.info(instance.getServiceId()+"\t"+instance.getHost()+"\t"+instance.getPort()+"\t"+instance.getUri()); } return this.discoveryClient;}

3.8001 主启动类

@EnableDiscoveryClient

@EnableEurekaClient@EnableDiscoveryClient // 服务发现@SpringBootApplicationpublic class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class, args); }}

4.测试

  • 先启动 EurekaServer, 7001/7002 服务,再启动 8001 主启动类,需要稍等一会

    http://localhost:8001/payment/discovery

image-20201010153131926

⑥ Eureka 自我保护

1.故障现象

image-20201010153351564

2.导致原因

image-20201010153435587

image-20201010153445964

image-20201010153524632

image-20201010153542491

总结某时刻某一个微服务不可用了,Eureka 不会立即清理,依旧会对该服务的信息进行保存,属于CAP 里的 AP分支

3.怎么禁止自我保护(一般生产环境中不会禁止自我保护)

注册中心 eureakeServer 端 7001: 出 厂 默 认 , 自 我 保 护 机 制 是 开 启的:eureka.server.enable-self-preservation = true

  • 使用 eureka.server.enable-self-preservation = false 可以禁用自我保护模式

  • 在 eurekaServer 端 7001 处设置关闭自我保护机制

image-20201010154122092

效果图:

image-20201010154441508

生产者客户端 eureakeClient 端 8001

默认:

eureka.instance.lease-renewal-interval-in-seconds=30 单位为秒( 默认是 30 秒)eureka.instance.lease-expiration-duration-in-seconds=90 单 位 为 秒( 默认是 90 秒)

配置:

image-20201010154942881
instance:    instance-id: payment8001    prefer-ip-address: true    #Eureka客户端向服务端发送心跳的时间间隔,单位为秒(默认是30秒)    lease-renewal-interval-in-seconds: 1    #Eureka服务端在收到最后一次心跳后等待时间上限,单位为秒(默认是90秒),超时将剔除服务    lease-expiration-duration-in-seconds: 2

4.测试

  • 7001 和 8001 都配置完成
  • 先启动 7001 再启动 8001 ,先关闭 8001 ,马上被删除了

image-20201010163755231

二、Zookeeper 服务注册与发现

① Eukeka 停止更新了怎么办

​ https://github.com/Netflix/eureka/wiki

② SpringCloud 整合 Zookeeper 代替 Eureka

1.注册中心zookeeper

  • zookeeper 是一个分布式协调工具,可以实现注册中心功能

使用docker 快速创建 zookeeper 容器

  • 关闭 Linux 服务器防火墙后启动 zookeeper 服务器

CentOS 7 关闭防火墙指令

// 查看当前防火墙状态如果防火墙处于开启状态,firewalld.service前面的点是高亮的,Active:active(开启))systemctl status firewalld.service//关闭当前的防火墙(仅对本次开机有效,重启后防火墙会再次启用)systemctl stop firewalld.service//永久关闭防火墙(重启后防火墙依然关闭)systemctl disable firewalld.service// 启动防火墙 systemctl start firewalld
  • zookeeper 服务器取代 Eureka 服务器,zk作为服务器注册中心

2.服务提供者

新建 cloud-provider-payment8004

POM

clould
com.oy
1.0-SNAPSHOT
4.0.0
cloud-provider-payment8004
Zookeeper服务提供者
com.oy
cloud-api-commons
${project.version}
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-zookeeper-discovery
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test

YML

server:  # 8004表示注册到zookeeper服务器的支付服务提供者端口号  port: 8004spring:  application:    # 服务别名---注册zookeeper到注册中心的名称    name: cloud-provider-payment  cloud:    zookeeper:      connect-string: 116.63.177.72:2181

主启动类

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@EnableDiscoveryClient@SpringBootApplicationpublic class PaymentMain8004 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8004.class, args); }}

Controller

@RestController@Slf4jpublic class PaymentController {
@Value("${server.port}") private String serverPort; @GetMapping(value = "/payment/zk") public String paymentzk(){
return "springcloud with zookeeper:"+serverPort+"\t"+ UUID.randomUUID().toString(); }}

启动 8004 注册进 zookeeper

image-20201010185203951

注意:启动后问题存在下面问题

image-20201010185426339

Why:

  • 解决 zookeeper 版本 jar 包冲突问题:

image-20201010185547065

  • 排出 zk 冲突后的新 POM:
cloud2020
com.atguigu.springcloud
1.0-SNAPSHOT
4.0.0
cloud-provider-payment8004
Zookeeper服务提供者
org.springframework.cloud
spring-cloud-starter-zookeeper-discovery
org.apache.zookeeper
zookeeper
org.apache.zookeeper
zookeeper
3.4.9
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test

测试

  • 在Linux 上查询 和 浏览器上(http://localhost:8004/payment/zk )

image-20201010190241945

  • 获得 json 串后用在线工具查看试试 (dokcer 容器)

    image-20201010190621628

image-20201010190802924

思考: 服务节点是临时节点还是持久节点——是临时节点

3.服务消费者

新建 cloud-consumerzk-order80

POM

cloud2020
com.atguigu.springcloud
1.0-SNAPSHOT
4.0.0
cloud-consumerzk-order80
com.atguigu.springcloud
cloud-api-common
${project.version}
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-starter-zookeeper-discovery
org.apache.zookeeper
zookeeper
org.apache.zookeeper
zookeeper
3.4.9
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test

YML

server:  port: 80spring:  application:    # 服务别名    name: cloud-consumer-order  cloud:    zookeeper:      # 注册到zookeeper地址      connect-string: localhost:2181

主启动

@SpringBootApplication@EnableDiscoveryClientpublic class OrderZkMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderZkMain80.class, args); }}

主业务类

  • bean
package com.springcloud.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;/** * @Author OY * @Date 2020/10/10 */@Configurationpublic class ApplicationContextConfig {
@Bean public RestTemplate restTemplate(){
return restTemplate(); }}
  • controller
package com.springcloud.controller;import lombok.extern.slf4j.Slf4j;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;/** * @Author OY * @Date 2020/10/10 */@RestController@Slf4jpublic class OrderZkController {
@Resource private RestTemplate restTemplate; public static final String INVOKE_URL = "http://cloud-provider-payment"; @GetMapping("/consumer/payment/zk") public String paymentInfo() {
return restTemplate.getForObject(INVOKE_URL + "/payment/zk", String.class); }}

验证测试

image-20201010193246059

访问测试地址

​ http://localhost/consumer/payment/zk

image-20201010193352456

三、Consul 服务注册与发现

① Consul 简介

1.是什么:https://www.consul.io/intro/index.html

image-20201011204018659

image-20201011204039409

2.能干嘛:

image-20201011204121943

  • 服务发现: 提供HTTP 和 DNS 两种发现方式
  • 健康检查: 支持多种协议,HTTP、TCP、Docker、Shell脚本定制化
  • KV存储: Key,Value的存储方式
  • 多数据中心: Consul支持多数据中心
  • 可视化Web界面

3.下载

https://www.consul.io/downloads.html

4.怎么玩

https://www.springcloud.cc/spring-cloud-consul.html

② 安装并运行 Consul

1.官网安装说明

https://learn.hashicorp.com/consul/getting-started/install.html

2.下载完成后只有一个consul.exe 文件,硬盘路径下双击运行,查看版本信息

image-20201011205359901

3.使用开发者模式启动

consul agent -dev

image-20201011205619155

通过以下地址可以访问 Consul 的首页:http://localhost:8500/

image-20201011205709239

③ 服务提供者

新 建 Module 支 付 服 务 provider8006

cloud-providerconsul-payment8006

POM

clould
com.oy
1.0-SNAPSHOT
4.0.0
cloud-providerconsul-payment8006
org.springframework.cloud
spring-cloud-starter-consul-discovery
com.oy
cloud-api-commons
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test

YML

server:  port: 8006spring:  application:    name: consul-provider-payment  cloud:    consul:      host: localhost      port: 8500      discovery:        service-name: ${
spring.application.name}

主启动类

@EnableDiscoveryClient@SpringBootApplicationpublic class PaymentMain8006 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8006.class, args); }}

主业务类 Controller

@RestController@Slf4jpublic class PaymentController {
@Value("${server.port}") private String serverPort; @GetMapping(value = "/payment/consul") public String paymentConsul(){
return "SpringCloud with consul:" + serverPort + "\t"+ UUID.randomUUID().toString(); }}

验证测试

​ http://localhost:8006/payment/consul

image-20201011211341291

④ 服务消费者

新 建 Module 消 费 服 务 order8006

​ cloud-consumerconsul-order80

POM

clould
com.oy
1.0-SNAPSHOT
4.0.0
cloud-consumerconsul-order80
org.springframework.cloud
spring-cloud-starter-consul-discovery
com.oy
cloud-api-commons
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test

YML

server:  port: 80spring:  application:    name: consul-consumer-order  cloud:    consul:      host: localhost      port: 8500      discovery:        service-name: ${
spring.application.name}

主启动类

package com.oy.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;@SpringBootApplication@EnableDiscoveryClientpublic class OrderConsulMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderConsulMain80.class, args); }}

配置Bean

package com.oy.springcloud.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;@Configurationpublic class ApplicationConfig {
@LoadBalanced // 负载均衡 @Bean public RestTemplate restTemplate(){
return new RestTemplate(); }}

Controller

package com.oy.springcloud.controller;import lombok.extern.slf4j.Slf4j;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;/** * @Author OY * @Date 2020/10/11 */@RestController@Slf4jpublic class OrderConsulController {
public static final String INVOME_URL = "http://consul-provider-payment"; @Resource public RestTemplate restTemplate; @GetMapping("/consumer/payment/consul") public String payment(){
String result = restTemplate.getForObject(INVOME_URL+"/payment/consul",String.class ); return result; }}

验证测试

image-20201011214858615

访问测试地址:http://localhost/consumer/payment/consul

image-20201011215016107

⑤ 三个注册中心异同点

1.CAP

  • C: Consistency (强一致性)
  • A: Availability (可用性)
  • P: Partition tolerance (分区容错)

CAP 理论关注粒度是数据, 而不是整体系统设计的策略

2.经典 CAP 图

image-20201011215345966

image-20201011215809145

AP(Eureka) 架构

当网络分区出现后,为了保证可用性,系统B可以返回值,保证系统的可用性。

结论:违背了一致性C的要求,只满足可用性和分区容错,即AP

image-20201011220139399

CP(Zookeeper/Consul) 架构

image-20201011220325077

如果有帮助的话动动小手,留个赞呗!!!

转载地址:http://exbki.baihongyu.com/

你可能感兴趣的文章
source insight的疑问
查看>>
source insight的疑问
查看>>
Linux输入子系统 input_dev 概述
查看>>
Linux输入子系统 input_dev 概述
查看>>
A new I/O memory access mechanis…
查看>>
A new I/O memory access mechanis…
查看>>
s3c2410时钟信号:FCLK、HCL…
查看>>
s3c2410时钟信号:FCLK、HCL…
查看>>
自旋锁与信号量(转载)
查看>>
自旋锁与信号量(转载)
查看>>
主函数main中变量(int argc…
查看>>
主函数main中变量(int argc…
查看>>
转载--request_irq() | 注册…
查看>>
转载--request_irq() | 注册…
查看>>
深入分析request_irq的dev_i…
查看>>
深入分析request_irq的dev_i…
查看>>
wait_event_interruptible()
查看>>
wait_event_interruptible()
查看>>
linux中断底层硬件操作方法…
查看>>
linux中断底层硬件操作方法…
查看>>