SpringCloud笔记三:Eureka服务注册与发现

什么是Eureka?

Eureka是一个服务的注册中心,有服务端和客户端。我举个栗子。

一个大型商场新建完毕,各种商家开始准备入住。需要的流程是:

  1. 商家去大型商场注册,交费,签合同
  2. 熙熙攘攘的人群在大型商场门口的导航牌看哪个店在几楼,然后去消费

在这个例子中,Eureka就是大型商场,就是一个服务中心。加了服务端注解@EnableEurekaServer之后就可以开启服务中心了,然后商家就是客户端,要加@EnableEurekaClient之后就可以去注册了。至于消费者,直接去消费

Eureka注册的三大步

第一步,引用Maven

想要使用Eureka,先引用Maven,服务端和客户端不一样

服务端:

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

客户端:

      <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>

必须要加版本号,不然第三步的注解不能生效的

第二步,配置yml

我们需要配置yml文件,告诉系统,服务端的Eureka调用地址是什么,客户端的Eureka访问地址是什么

服务端:

server:
  port: 7001

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

服务器端基本就是这样写的,没什么需要改的

客户端:

eureka:
  client: #客户端注册进eureka服务列表内
    service-url:
      defaultZone: http://localhost:7001/eureka
  instance:
    instance-id: provider-8001  #这个是修改Eureka界面的Status名称
    prefer-ip-address: true    #这个是设置鼠标放在status上的时候,出现的提示,设置ip地址显示

客户端的defaultZone是Eureka的注册中心的地址,这个是在服务端写的,服务端怎么写,这里就怎么写。

instance-id这个是Eureka页面的status的名称

prefer-ip-address这个是鼠标放在status上的时候显示的内容,把ip地址显示出来。

这里的具体,在第四步,我会截图。

第三步,开启Eureka注解

开启注解,告诉我的子项目,你有权限使用Eureka注册服务了,Maven已经下载了,yml也告诉你访问路径了,去使用它吧,在子系统的主方法上加就ok

服务端:

@EnableEurekaServer

客户端:

@EnableEurekaClient

新建Eureka子项目

我们来新建一个子项目,还是一样的,我起名为Eureka-7001 。我们需要在yml里面写上面的服务端的内容。然后在项目的主方法上加上@EnableEurekaServer注解。至此,加了服务端yml和注解的Eureka-7001项目就是服务中心了。

现在可以运行了,很简单,首先我们先运行Eureka-7001这个子工程

可以看到,我们的Eureka服务中心已经跑起来了,但是目前,还没有任何一个客户端来注册啊。商家呢?快来注册交费入驻。

把provider子项目变成服务端

我们要把provider项目改为Eureka的客户端,并且注册进我们的服务中心。

  1. 先改provider项目的yml,还是上面讲的客户端yml就是,复制
  2. 主方法加@EnableEurekaClient注解

这个时候,保持Eureka-7001服务中心运行的同时,我们再启动provider项目,你会发现

由于我上面客户端的yml写的

  instance:
    instance-id: provider-8001  #这个是修改Eureka界面的Status名称
    prefer-ip-address: true    #这个是设置鼠标放在status上的时候,出现的提示,设置ip地址显示

正是由于写了上面的这俩,所以我的图中的status就是我自己定义的,以及鼠标放上去时,左下角显示的内容,才会有ip显示出来。

最后,你点击status下面的名称试试,会出现一个info页面,不过是没啥内容的。我们希望,点击微服务的status的时候,可以显示出这个微服务的一些信息,比如版本号,公司名称。我们需要两步

  1. 在主工程加如下代码,这个作用是让resource文件可访问,而且版本号我们根据$符号来确定
    <build>
        <finalName>SpringCloud</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <delimiters>
                        <delimit>$</delimit>
                    </delimiters>
                </configuration>
            </plugin>
        </plugins>
    </build>
  1. 第二步,由于第一步已经设置了resource文件夹可访问了,所以我们在resource文件夹下的yml文件里添加info信息,现在在provider的yml增加如下内容
info:
  app.name: provider-8001
  company.name: www.vae.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$

有了这两步之后,你可以点击那个服务的status试试,结果应该是如下图所示的

Eureka的自我保护机制

这个服务中心,你等一会再打开,你会发现会出来一行红字,这并不是报错,这个就是因为Eureka的自我保护机制。

下面一起来做个例子,来看看自我保护机制,我们在provider项目的yml里面改一下status的名称,加个Vae,如下:

instance-id: provider-8001Vae 

热部署更新,可以不用重启,刷新浏览器,看看

status也变成Vae了,我们现在再把Vae删了,恢复原来的

instance-id: provider-8001

再热更新一下,刷新浏览器,你会发现,provider-8001Vae和provider-8001都有,都存在。

我的不知道为什么没有出来两个,我修改之后还是恢复为8001了

这就是Eureka的自我保护机制:

服务不会立即删除,Eureka会认为是网络延迟或者堵塞,反正就是不会立马删除服务,默认90秒之后如果还是没有心跳也就是回应,那才注销。默认自我保护机制是开启的,90s时间。

Eureka的发现

服务的注册很容易理解,服务的发现我不懂,据说是给消费者看看这个服务的作用用处的

首先,把provider提供者的Controller加一个方法

    @Autowired
    private DiscoveryClient client;
    @GetMapping(value = "/dept/discovery")
    public Object discovery()
    {
        List<String> list = client.getServices();
        System.out.println("**********" + list);

        List<ServiceInstance> srvList = client.getInstances("PROVIDER-DEPT");
        for (ServiceInstance element : srvList) {
            System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"
                    + element.getUri());
        }
        return this.client;
    }

然后主方法加个服务发现的注解@EnableDiscoveryClient

现在启动Eureka7001服务中心,再启动provider8001项目,输入http://localhost:8001/dept/discovery

消费者项目的Controller加个代码

    // 测试@EnableDiscoveryClient,消费端可以调用服务发现
    @RequestMapping(value = "/consumer/dept/discovery")
    public Object discovery()
    {
        return restTemplate.getForObject(REST_URL_PREFIX + "/dept/discovery", Object.class);
    }

然后启动项目,输入http://localhost/consumer/dept/discovery

Eureka集群

什么是集群?

所谓的集群,就是在不同的服务器上部署相同的服务。举个例子,淘宝,这么大的应用,不可能只有一个服务器,一个淘宝背后可能有上百台服务器支撑。

同样的,我们的Eureka,也不能只有一台服务器,万一这台服务器挂了怎么办?

新建Eureka集群

新建两个Eureka服务中心,一个是Eureka7002,一个是Eureka7003,新建和上面一样就不讲了,新建完成如下图

还记得我们Eureka服务中心的yml里面写的是localhost吧,现在有三个服务中心了,都写localhost就不合适了,但是我又没有多台电脑供我测试,只能修改host文件滥竽充数了。打开C:\Windows\System32\drivers\etc,找到host文件,添加下面三行

127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com

现在,开始修改我们的三个服务中心的yml吧

server:
  port: 7001

eureka:
  instance:
    hostname: eureka7001.com  #因为我修改了host文件,所以这里相当于还是localhost
#    hostname: localhost #eureka服务端的实例名称

  client:
    register-with-eureka: false    #false\u8868\u793A\u4E0D\u5411\u6CE8\u518C\u4E2D\u5FC3\u6CE8\u518C\u81EA\u5DF1\u3002
    fetch-registry: false           #false\u8868\u793A\u81EA\u5DF1\u7AEF\u5C31\u662F\u6CE8\u518C\u4E2D\u5FC3\uFF0C\u6211\u7684\u804C\u8D23\u5C31\u662F\u7EF4\u62A4\u670D\u52A1\u5B9E\u4F8B\uFF0C\u5E76\u4E0D\u9700\u8981\u53BB\u68C0\u7D22\u670D\u52A1
    service-url:
#       defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/        #\u8BBE\u
        defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/    #因为我的Eureka建立了集群,所以这里写上其他集群的地址
server:
  port: 7002

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

server:
  port: 7003

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


三个服务中心的yml完成了,别忘了7001里面的Maven的pom文件,复制到7002和7003里面去,其实就一个eureka-server这个需要引用而已。

现在修改一下provider的yml

server:
  port: 8001

mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml     #mybatis配置文件所在路径
  type-aliases-package: com.vae.springcloud.entity       #所有Entity别名类所在包
  mapper-locations: classpath:mybatis/mapper/**/*.xml    #mapper映射文件

spring:
  application:
    name: provider-dept
  datasource:
#   type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://localhost:3306/shuyunquan?serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123
    dbcp2:
      min-idle: 5                                           # 数据库连接池的最小维持连接数
      initial-size: 5                                       # 初始化连接数
      max-total: 5                                          # 最大连接数
      max-wait-millis: 200                                 # 等待连接获取的最大超时时间

eureka:
  client: #客户端注册进eureka服务列表内
    service-url:
#      defaultZone: http://localhost:7001/eureka
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: provider-8001  #这个是修改Eureka界面的Status名称
    prefer-ip-address: true    #这个是设置鼠标放在status上的时候,出现的提示,设置ip地址显示


info:
  app.name: provider-8001
  company.name: www.vae.com
  build.artifactId: $project.artifactId$
  build.version: $project.version$


就改了一个defaultZone,改成集群了。

我有一点还不明白,集群,服务中心的yml的defaultZone写的其他集群的地址,这要是有100个集群,我写100个?而且provider注册者的defaultZone也是写的所有集群的地址,也写100个?这里肯定有更好的方法,我还不知

启动eureka集群,也就是启动三个eureka项目,如图:

posted @ 2019-04-08 16:39  蜀云泉  阅读(1718)  评论(0编辑  收藏  举报