Eureka作为注册中心

本文详细介绍了Eureka服务注册中心的基础知识,包括服务注册与发现原理、搭建单机和集群EurekaServer,以及如何将服务提供者和消费者注册到注册中心。还探讨了自定义InstanceID和服务发现的实践,以及Eureka自我保护的设置和禁用技巧。
摘要由CSDN通过智能技术生成

Eureka

在这里插入图片描述

一、Eureka基础知识:

官网参考资料: https://docs.spring.io/spring-cloud-netflix/docs/current/reference/html/.

在这里插入图片描述

服务注册与发现:

我们先来看下什么是服务注册与服务发现?参考文档:https://zhuanlan.zhihu.com/p/161277955

服务注册,就是将提供某个服务的模块信息(通常是这个服务的ip和端口)注册到1个公共的组件上去(比如: zookeeper\consul)。(可以通俗的理解为,商家和消费者都注册到美团的服务平台上)

服务发现,就是新注册的这个服务模块能够及时的被其他调用者发现。不管是服务新增和服务删减都能实现自动发现。(商家的新注册和下架可以及时的被所有的消费者发现和看到)

你可以理解为:

//服务注册
NameServer->register(newServer);

//服务发现
NameServer->getAllServer();

每一个服务对应的机器或者实例在启动运行的时候,都去向名字服务集群注册自己,比如图中,User服务有6个docker实例,那么每个docker实例,启动后,都去把自己的信息注册到名字服务模块上去,同理Order服务也是一样。
在这里插入图片描述
对应的伪代码可以表示如下:

//给User服务申请1个独有的专属名字
UserNameServer = NameServer->apply('User');

//User服务下的6台docker实例启动后,都去注册自己
UserServer1 = {ip: 192.178.1.1, port: 3445}
UserNameServer->register(UserServer1);

......

UserServer6 = {ip: 192.178.1.6, port: 3445}
UserNameServer->register(UserServer6);

//给Order服务申请1个独有的专属名字
OrderNameServer = NameServer->apply('Order');

//开始注册
OrderServer1 = {ip: 192.178.1.1, port: 3446}
OrderNameServer->register(OrderServer1);

//给Search服务申请1个独有的专属名字
SearchNameServer = NameServer->apply('Search');

//开始注册
SearchServer1 = {ip: 192.178.1.1, port: 3447}
SearchNameServer->register(SearchServer1);

这样,每个服务的机器实例在启动后,就完成了注册的操作。注册的方式有很多的形式,不同的名字服务软件方式不一样,有HTTP接口形式,有RPC的方式,也有使用JSON格式的配置表的形式的。方式虽然不同,但是结果都是一样。

实例注册到名字服务上之后,接下来就是服务发现了。
我们看下,服务发现是怎么做的:service Cluster即服务集群:
在这里插入图片描述

在上图中,Order服务想要获取User服务相关的信息,首先向注册集群中心发送请求获取,然后就能收到User服务相关的信息。
//服务发现,获取User服务的列表
list = NameServer->getAllServer(‘User’); //获取所有的名字服务器中的服务列表(包含ip和端口号)

这样,我们获取了服务的IP信息后,就可以进行调用了,如图所示:
在这里插入图片描述

和服务注册的方式一样,服务发现的方式,不同的名字服务软件的方式也会不一样,有的是得自己发送HTTP接口去轮训调用,如果发现有更新,就更新自己本地的配置文件。有的是可以通过实时的sub/pub的方式实现的自动发现服务,当我订阅的这个服务内容发生了更新,就实时更新自己的配置文件。也有的是通过RPC的方式。方式虽然不同,但是结果都是一样。

这样一来,我们就可以通过服务注册和发现的方式,维护各个服务IP列表的更新,各个模块只需要向名字服务中心去获取某个服务的IP就可以了,不用再写死IP。整个服务的维护也变得轻松了很多。彻底解放了双手!

在这里插入图片描述

服务注册中心的一般原理

微服务原则上是应该有多个服务提供者的实例的,在通常情况下服务提供者的数量和分布往往是动态变化的,这样在传统的单体应用中的那种硬编码服务url进行远程调用的方式就不足取。服务注册中心就是为了解决服务之间的注册与发现而产生的。
服务注册中心本质上是为了解耦服务提供者和服务消费者。

在这里插入图片描述

服务注册中心的一般原理:

  1. 服务注册中心启动
  2. 服务提供者启动,并注册到服务注册中心
  3. 服务消费者从注册中心获取服务信息
  4. 服务消费者远程调用服务提供者

在这里插入图片描述

Eureka基础架构

在这里插入图片描述
Eureka 包含两个组件:Eureka Server 和 Eureka Client, Eureka Client是⼀个Java客户端,⽤于简化与Eureka Server的交互; Eureka Server提供服务发现的能⼒,各个微服务启动时,会通过Eureka Client向Eureka Server 进⾏注册⾃⼰的信息(例如⽹络信息),Eureka Server会存储该服务的信息;

详细流程如下:

  • 服务提供者向Eureka Server中注册服务, Eureka Server接受到注册事件会在集群和分区中进⾏数据同步,Application Client作为消费端(服务消费者)可以从Eureka Server中获取到服务注册信息,进⾏服务调⽤。微服务启动后,会周期性地向Eureka Server发送⼼跳(默认周期为30秒)以续约⾃⼰的信息
  • Eureka Server在⼀定时间内没有接收到某个微服务节点的⼼跳, Eureka Server将会注销该微服务节点(默认90秒)
  • 每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过复制的⽅式完成服务注册列表的同步
  • Eureka Client会缓存Eureka Server中的信息。即使所有的EurekaServer节点都宕掉,服务消费者依然可以使⽤缓存中的信息找到服务提供者

快捷记忆:心跳30s,注销90s

注意:在上图的三角形模式中,Eureka 服务就是注册中心,所以在搭建注册中心的时候我们用的是Eureka Server组件。
而Eureka Client(Eureka客户端) 有两方面角色的,一个是客户端消费者,一个是服务提供者。这两个客户端角色使用Eureka Client组件

通俗的理解,注册中心相当于美团平台,而商家和我们普通消费者对于美团平台来说,都是他的客户,即客户端,再细分一下客户端,又分为提供者和消费者,提供者相当于商家;商家把自己的商铺注册到美团平台上,告诉平台自己的商铺地址和门牌号等,然后定时的告诉平台我还在正常营业,没有关门大吉,然后平台保存下来商家信息;我们消费者这时候通过注册,也进入到美团平台,这时候,消费者和商家都在 一个平台上,消费者就可以刷一下手机,就可以获取/拉取附近的美食,娱乐,等商家的信息,然后消费者就可以远程的定外卖,定酒店等远程的调用商家的服务
在这里插入图片描述

二、搭建单机版EurekaServer:

同样搭建也是5个步骤:

在这里插入图片描述

搭建独立的 注册中心 微服务:

注意:Eureka作为注册中心,不需要下载额外的软件去后台启动,只需要在我们的项目中添加相应的依赖,然后配置即可。但是麻烦的是他需要额外搭建一个独立的注册中心的微服务,或者多个微服务注册中心作为注册中心集群使用

(1)建 模块:cloud-eureka-server7001
(2)改pom:如果此微服务作为注册中心,则使用依赖netflix-eureka-server。记住两个组件netflix-eureka-server和netflix-eureka-client。

创建一个注册中心本身,使用Eureka Server依赖,而其他微服务都是作为client客户端的。

<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

在这里插入图片描述
完整的pom:

 <dependencies>
        <!--eureka 注册中心server服务组件	-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</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-actuator</artifactId>
            <version>2.2.2.RELEASE</version>
        </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>
    </dependencies>

(3)写yml:即application.yml:只要是和注册中心(eureka)有关系的,都需要配置注册中心(eureka)的相关配置

server:
  port: 7001

eureka:
  instance:
    hostname: localhost #当前eureka实例的主机名
  client:
    register-with-eureka: false #false 表示不注册eureka,⾃⼰就是服务注册中心,不需要自己注册⾃⼰ 
    fetch-registry: false #etch-registry表示客户端从注册中心获取/拉取注册列表,false 表示不拉取注册列表,因为我本身就是注册中心
    service-url: #注册中心的默认地址:这里自己本身就是注册地址,则引用自己本身的主机名和端口号
    ## 集群模式下,defaultZone(默认区域)应该指向其它Eureka Server,如果有更多其它Server实例,逗号拼接即可
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/        #设置与Eureka Server注册中心交互的地址查询服务和注册服务都需要依赖这个地址。

springcloud之eureka配置——eureka.instance请参考:https://www.cnblogs.com/liaojie970/p/8807023.html

在这里插入图片描述

(4)主启动类:

package com.fan.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer//指明自己就是注册中心
public class EurekaMain7001 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaMain7001.class,args);
    }
}

然后启动主启动类进行测试。

(5)测试注册中心:

本地测试:localhost:7001

在这里插入图片描述
对界面上的信息进行说明:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

将提供者 注册 到注册中心:

(1)建模块:名字为cloud-provider-payment8001

(2)改pom:此微服务作为注册中心的一个客户端client来进行注册

修改成这样:8001作为一个注册中心的一个客户端,使用的依赖是client组件

<dependencies>
        <!--eureka注册中心的一个 客户-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--springboot-web 两个组件-->
        <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.2.2.RELEASE</version>
        </dependency>
        <!--druid -springboot-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.17</version>
        </dependency>
        <!--mysql数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mybatis-spring-boot-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </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>
    </dependencies>

在这里插入图片描述

(3)写yml:Eureka 之常用配置解析:https://www.cnblogs.com/zyon/p/11023750.html
类似于商家入驻美团线上平台:

注册中心的一些配置,凡是微服务都必须有此项配置,要么是注册到别人那里,要么自己就是注册中心

server:
  port: 8001  #服务端口号,建议一定有

spring:
  application:
    name: cloud-payment-service #微服务名称,建议有
  datasource: #数据库连接类似于DriverManager,DataSource中获取的连接来自于连接池中,而池中的连接根本也还是从DriverManager获取而来
    type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
    driver: com.mysql.cj.jdbc.Driver  #mysql驱动包
    url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
    username: root
    password: root

mybatis: #mybatis配置
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.fan.springcloud.entity #所在entity别名类所在的包

#注册中心的一些配置,凡是微服务都必须有此项配置,要么是注册到别人那里,要么自己就是注册中心。
eureka:
  client:
    register-with-eureka: true #true表示向注册中心注册自己。
    fetch-registry: true #true表示要抓取/拉取注册信息。
    service-url: #注册中心的默认地址
      defaultZone: http://localhost:7001/eureka

在这里插入图片描述

(4)主启动类:这里我们省略了业务逻辑。同样也可以启动起来看到注册到的服务。

对于eureka来说,8001是我们注册中心的一个 提供者的 客户端:

@SpringBootApplication
@EnableEurekaClient//指明自己是注册中心的一个客户:提供者端
public class PaymentMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentMain8001 .class,args);
    }
}

在这里插入图片描述
(5)测试:http://localhost:7001/

启动测试,注意先启动注册中心,然后才是其他商家的入驻。

微服务注册名称application.name的必需性:这里相当于我们在美团外卖上 注册的 (店铺/服务) 名字

在这里插入图片描述

将消费者 注册 到注册中心:

(1)建模块:cloud-consumer-eureka-order80
(2)改pom: 需要eureka-client的依赖,作为注册中心的一个客户

<dependencies>
        <!--注册中心的一个 客户-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--springboot-web 两个组件-->
        <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.2.2.RELEASE</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>
    </dependencies>

在这里插入图片描述

(3)写yml:必须包含注册中心的一些配置。是否注册到eureka,是否拉取注册列表,以及注册地址url.
必须包含注册中心的一些配置,凡是微服务都必须有此项配置,要么是注册到别人那里,要么自己就是注册中心

server:
  port: 80
spring:
	application:
		name: cloud-order-service

eureka:
  client:
    register-with-eureka: true#false 表示不注册eureka,⾃⼰就是服务注册中心,不需要自己注册⾃⼰ 
    fetch-registry: true#etch-registry表示客户端从注册中心获取/拉取注册列表,false 表示不拉取注册列表,因为我本身就是注册中心
    service-url: #注册中心的默认地址:这里自己本身就是注册地址,则引用自己本身的主机名和端口号
    ## 集群模式下,defaultZone(默认区域)应该指向其它Eureka Server,如果有更多其它Server实例,逗号拼接即可
      defaultZone: http://localhost:7001/eureka        #设置与Eureka Server注册中心交互的地址查询服务和注册服务都需要依赖这个地址。

在这里插入图片描述
(4)主启动类:OrderMian80 ,主启动类上需要注解@EnableEureakeClient注解

@SpringBootApplication
@EnableEurekaClient//指明自己是注册中心的一个客户:提供者端
public class OrderMain80{
    public static void main(String[] args) {
        SpringApplication.run(OrderMain80.class,args);
    }
}

在这里插入图片描述

业务类controller:

package com.fan.springcloud.controller;

import com.fan.springcloud.entity.CommonResult;
import com.fan.springcloud.entity.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
@Slf4j
public class OrderController {

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

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/payment/create")
    public CommonResult<Payment> create(Payment payment)
    {
        return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class);
    }

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
        return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    }

}

(5)测试:localhost/consumer/payment/get/31
在这里插入图片描述

三、搭建集群版EurekaServer:

搭建 多台Eureka注册中心的集群 :

在这里插入图片描述
在这里插入图片描述

两台机器组成的注册中心 集群的原理:
在这里插入图片描述

在这里插入图片描述

(1)准备工作:
修改映射配置 :c:\Windows\System32\drivers\etc 路径下的host文件

在这里插入图片描述

hosts内容如下:假如我们的注册中心有三台机器,7001,7002,7003
如果是三台机器:文件末尾添加以下三行,如果是两台,则添加前两行

#enureka集群,这里用一个好记的主机名映射代替了主机的ip地址。
127.0.0.1  eureka7001.com
127.0.0.1  eureka7002.com
127.0.0.1  eureka7003.com


hosts文件的作用
Windows下的:\WINDOWS\system32\drivers\etc\hosts文件

用记事本打开hosts文件,它的作用是包含IP地址和Host name(主机名)的映射关系,是一个映射IP地址和Hostname(主机名)的规定,规定要求每段只能包括一个映射关系,IP地址要放在每段的最前面,空格后再写上映射的Host name(主机名)。对于这段的映射说明用“#”分割后用文字说明。

现在让我们来看看Hosts在Windows中是怎么工作的。

我们知道在网络上访问网站,要首先通过DNS服务器把网络域名(www.XXXX.com)解析成61.XXX.XXX.XXX的IP地址后,我们的计算机才能访问。要是对于每个域名请求我们都要等待域名服务器解析后返回IP信息,这样访问网络的效率就会降低,而Hosts文件就能提高解析效率。根据 Windows系统规定,在进行DNS请求以前,Windows系统会先检查自己的Hosts文件中是否有这个地址映射关系,如果有则调用这个IP地址映射,如果没有再向已知的DNS 服务器提出域名解析。也就是说Hosts的请求级别比DNS高。

知道了Hosts文件的工作方式,那在具体使用中它有哪些作用呢?

  1. 加快域名解析
    对于要经常访问的网站,我们可以通过在Hosts中配置域名和IP的映射关系,这样当我们输入域名计算机就能很快解析出IP,而不用请求网络上的DNS服务器。

  2. 方便局域网用户
    在很多单位的局域网中,会有服务器提供给用户使用。但由于局域网中一般很少架设DNS服务器,访问这些服务要输入难记的IP地址,对不少人来说相当麻烦。现在可以分别给这些服务器取个容易记住的名字,然后在Hosts中建立IP映射,这样以后访问的时候我们输入这个服务器的名字就行了。

  3. 屏蔽网站
    现在有很多网站不经过用户同意就将各种各样的插件安装到你的计算机中,有些说不定就是***或病毒。对于这些网站我们可以利用Hosts把该网站的域名映射到错误的IP或自己计算机的IP,这样就不用访问了。我们在Hosts写上以下内容:
    127.0.0.1 #屏蔽的网站
    0.0.0.0 #屏蔽的网站
    这样计算机解析域名就解析到本机或错误的IP,达到了屏蔽的目的。

  4. 顺利连接系统

    对于Lotus的服务器和一些数据库服务器,在访问时如果直接输入IP地址那是不能访问的,只能输入服务器名才能访问。那么我们配置好Hosts文件,这样输入服务器名就能顺利连接了。

    最后要指出的是,Hosts文件配置的映射是静态的,如果网络上的计算机更改了请及时更新IP地址,否则将不能访问。



这里我们配置了两台注册中心:本机的7001和 其他好友的7002:
在这里插入图片描述
如果有配置项eureka.instance.instance-id(实例id)的值,则其决定了下图右侧红框中的显示内容:
status下显示的是实例id名。
在这里插入图片描述

同理,这里我们配置了两台注册中心:本机的7002和 其他好友的7001:
在这里插入图片描述

注意:这里配置了主机名hostname,这里我们的主机名字是127.0.0.1,但是我们配置了本机的hosts文件,用一个好记的名字映射代替了ip地址。

测试1:localhost:7001
在这里插入图片描述

测试2: http://eureka7001.com:7001/
在这里插入图片描述

测试三: http://eureka7002.com:7002/
在这里插入图片描述

总结 三台注册中心 组成的集群:

同理,当我们配置三台机器的时候这样做:
(1)修改映射配置 :c:\Windows\System32\drivers\etc 路径下的host文件中在最后添加以下内容:

#enureka集群,这里用一个好记的主机名映射代替了主机的ip地址。
127.0.0.1  eureka7001.com
127.0.0.1  eureka7002.com
127.0.0.1  eureka7003.com

(2)
yml文件配置Eureka集群地址:

server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com  #eureka注册中心的名称(这里相当于本人)
  client:
    register-with-eureka: false # register-with-eureka:注册到 eureka注册中心去,  false表示不向注册中心注册自己。
    fetch-registry: false #fetch-registry:抓取注册列表,false表示不抓取。
    service-url: # 注册中心地址 ,除了自己的其他成员地址,如果注册中心有三台,这里写另另外台地址(这里相当于其他好友)
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/        #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。

(3)其他两台机器类似配置:

server:
  port: 7002

eureka:
  instance:
    hostname: eureka7002.com  #eureka实例的主机名称(这里eureka存在于我们本地的主机中,eureka7002.com相当于本机ip:127.0.0.1)
  client:
    register-with-eureka: false  # register-with-eureka:注册到 eureka注册中心去,  false表示不向注册中心注册自己。
    fetch-registry: false  #fetch-registry:抓取注册列表,false表示不抓取。
    service-url:  # 注册中心地址 ,除了自己的其他成员地址,如果注册中心有三台,这里写另另外台地址(这里相当于其他好友)
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/        #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。

注意:这里我们一个127.0.0.1即localhost一下子映射出三个别名的eureka7001.com,eureka7002.com,eureka7003.com,这三个都代表本主机。所以为了区分不同的localhost的三台注册中心的服务,我们才使用了别名。否则都是localhost则无法区分。
(4)启动三个注册中心后的效果:

在这里插入图片描述
这里eureka实例的主机名是必须的。

将支付服务8001微服务发布到上面的两台Eureka集群中:

改yml

server:
  port: 8001  #服务端口号,建议一定有

spring:
  application:
    name: cloud-payment-service #微服务名称,建议有
  datasource: #数据库连接类似于DriverManager,DataSource中获取的连接来自于连接池中,而池中的连接根本也还是从DriverManager获取而来
    type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
    driver: com.mysql.cj.jdbc.Driver  #mysql驱动包
    url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
    username: root
    password: root

mybatis: #mybatis配置
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.fan.springcloud.entity #所在entity别名类所在的包

eureka:
  client:
    register-with-eureka: true #false表示不向注册中心注册自己。
    fetch-registry: true #是否抓取注册信息。
    service-url:
      #defaultZone: http://localhost:7001/eureka  #单机版只写自己本身
      # 集群版  写注册中心所有的  机器地址 (有2台机器的注册中心集群 就写两个地址)
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

注意:如果是三台注册中心的集群,则在defaultZone:后用逗号拼接地址。

在这里插入图片描述

其他不变即可。

同理,支付服务的微服务 8002或者8003同样在yml中修改
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
此行即可。

将订单服务80微服务发布到上面的2台Eureka集群中:

微服务目录结构:
在这里插入图片描述

yml配置:

server:
  port: 80  #消费端  ,建议一定有

spring:
  application:
    name: cloud-order-consumer #微服务名称,建议有

eureka:
  client:
    register-with-eureka: true #true表示向注册中心注册自己。
    fetch-registry: true #true要抓取/拉取注册信息。
    service-url: #  将自己注册到 哪些默认注册中心 中
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

在这里插入图片描述

测试:http://localhost/consumer/payment/get/1
consumer/payment/get/1
在这里插入图片描述
在这里插入图片描述
Replicas:副本

DS Replicas:集群副本
由以上代码和展示,我总结出,是说明该服务器,从哪里同步数据。

比如节点peer1 设置是从8762和8763端口的节点同步数据,所以peer1中的DS Replicas是8762和8763端口所对应的名字peer2和peer3,以此类推,可知这个属性是什么意思了~

支付服务提供者8001集群环境搭建

在这里插入图片描述
在这里插入图片描述
将8001的mapper的sql文件复制过来到8002

说明:基础业务逻辑的编写在本篇文章中:https://blog.csdn.net/weixin_38568503/article/details/116718959

在这里插入图片描述
在这里插入图片描述
修改8001的controller:

package com.fan.springcloud.controller;

import com.fan.springcloud.entity.CommonResult;
import com.fan.springcloud.entity.Payment;
import com.fan.springcloud.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;


@RestController
@Slf4j
public class PaymentController {

    @Value("${server.port}")//读取到8001端口号
    private String serverPort;

    @Resource
    private PaymentService paymentService;

    @PostMapping("/payment/create")
    public CommonResult create(@RequestBody Payment payment){
        int result = paymentService.create(payment);
        log.info("插入的结果是{}",result);
        if(result > 0){
            return new CommonResult(200,"插入成功,返回结果"+result+"\t"+"服务端口:"+serverPort,payment);
        }else {
            return new CommonResult(444,"插入数据失败",null);
        }
    }

    @GetMapping("payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id") Long id){
        Payment payment = paymentService.getPaymentById(id);
        log.info("服务端接口————》插入的结果{}",payment);
        if(payment != null){
            return new CommonResult(200,"查询成功,serverPort:"+serverPort,payment);
        }else {
            return new CommonResult(444,"没有对应的记录,查询id"+id,null);
        }
    }

    @GetMapping("payment/lb")
    public String getPort(){
       return serverPort;
    }
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

依次启动每个服务:并测试:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

自测:发现服务不能轮循:
在这里插入图片描述

修改订单模块(重点):订单80服务端配置负载均衡注解
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


import com.fan.springcloud.entity.CommonResult;
import com.fan.springcloud.entity.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
@Slf4j
public class OrderController {

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

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/payment/create")
    public CommonResult<Payment> create(Payment payment)
    {
        return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class);
    }

    @GetMapping("/consumer/payment/get/{id}")
    public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
        return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
    }

}


编写负载均衡的组件注解@LoadBalanced,此注解配合消费端controller中的服务名public static final String PAYMENT_URL = “http://CLOUD-PAYMENT-SERVICE”;来实现服务端的负载均衡。

注意:此注解在消费端80编写:

package com.fan.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;


@Configuration
public class ApplicationContextConfig
{
    @Bean
    @LoadBalanced  //开启负载均衡的
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

然后再次测试:
http://localhost/consumer/payment/get/1

发现端口号变换:
在这里插入图片描述

在这里插入图片描述

四、actuator微服务信息完善:

参考:https://www.cnblogs.com/liaojie970/p/8807023.html

eureka的常用配置请参考:https://blog.csdn.net/qq_34553637/article/details/86081457

在这里插入图片描述

在这里插入图片描述

自定义 Eureka 的 InstanceID

客户端在注册时,服务的 Instance ID 的默认值的格式如下:
${spring.cloud.client.hostname}:${spring.application.name}:${spring.application. instance_id:${server.port}}

翻译过来就是“主机名:服务名称:服务端口”。当我们在 Eureka 的 Web 控制台查看服务注册信息的时候,就是这样的一个格式:
user-PC:eureka-client-user-service:8001

很多时候我们想把 IP 显示在上述格式中,此时,只要把主机名替换成 IP 就可以了,或者调整顺序也可以。可以改成下面的样子,用“服务名称:服务所在 IP:服务端口”的格式来定义:
eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}

定义之后我们看到的就是 eureka-client-user-service:192.168.31.245:8001,一看就知道是哪个服务,在哪台机器上,端口是多少。

我们还可以点击服务的 Instance ID 进行跳转,这个时候显示的名称虽然变成了 IP,但是跳转的链接却还是主机名。

所以还需要加一个配置才能让跳转的链接变成我们想要的样子,即使用 IP 进行注册,如下图 所示:

eureka.instance.prefer-ip-address=true #实例优先使用ip地址 来注册:true表示是 ,prefer优先的意思

在这里插入图片描述

刚刚我们通过配置实现了用 IP 进行注册,当点击 Instance ID 进行跳转的时候,就可以用 IP 跳转了,跳转的地址默认是 IP+Port/info



总结如何使用ip注册:

第一步:覆盖默认的实例id,在配置文件显示的设置eureka.instance.instance-id=payment8001(或者取值方式也可以)
第二步:访问路径显示ip地址:配置文件设置prefer-ip-address: true (优先使用实例ip地址注册和显示连接),即不使用主机名来定义注册中心的地址,而使用IP地址的形式,如果设置了eureka.instance.ip-address 属性,则使用该属性配置的IP,否则自动获取除环路IP外的第一个IP地址

经验:以后就可以不用设置eureka.instance.hostname主机名称了,直接使用上面两项配置代替即可



详细做法如下:

默认的客户端实例id:主机名:服务名称:服务端口,如下图所示

在这里插入图片描述

解决方法:找到application.yml,添加配置,同理给8002也添加类似的配置:实例id: payment8002
在这里插入图片描述
这样就成功,效果:
在这里插入图片描述

(2)访问信息有IP信息显示
当前问题:鼠标放在①上,在左下角②中没有IP显示。后续的话,这些微服务可能部署到几号机器上的,服务端口是多少,比如192.168.11.133机器上的8002端口,在调错或排错的时候,几号机器几号端口微服务名称就很明了。

在8002中添加:
在这里插入图片描述

同理在8001中也添加.

在这里插入图片描述
上图:Eureka实例信息IP链接

五、服务发现Discovery:

(1)要想使用 Eureka 的服务发现机制,首先我们需要在客户端的主启动类上加上一个注解 @EnableDiscoveryClient :
在这里插入图片描述

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

(2)在控制器PaymentController中,我们首先要注入 org.springframework.cloud.client.discovery 包下的 DiscoveryClient 实体类:
在这里插入图片描述
(3)然后在PaymentController中写一个映射:

在这里插入图片描述

@GetMapping(value = "/payment/discovery")
public Object discovery() {
    List<String> services = discoveryClient.getServices();//获取所有服务
    for (String service : services) {
        log.info("****service: " + service);
    }
    List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");//某一个实例下有哪些id
    for (ServiceInstance instance : instances) {
        log.info(instance.getServiceId() + "\t" + instance.getHost() + "\t" + instance.getPort() + "\t" + instance.getUri());
    }
    return this.discoveryClient;
}

测试:

在这里插入图片描述

六、Eureka自我保护:

故障信息:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

怎么禁止自我保护:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值