SpringCloud(二)Eureka服务注册与发现

写在前面:

  • 你好,欢迎你的阅读!
  • 我热爱技术,热爱分享,热爱生活, 我始终相信:技术是开源的,知识是共享的!
  • 博客里面的内容大部分均为原创,是自己日常的学习记录和总结,便于自己在后面的时间里回顾,当然也是希望可以分享自己的知识。目前的内容几乎是基础知识和技术入门,如果你觉得还可以的话不妨关注一下,我们共同进步!
  • 除了分享博客之外,也喜欢看书,写一点日常杂文和心情分享,如果你感兴趣,也可以关注关注!
  • 微信公众号:傲骄鹿先生


说明:

1、专栏涉及到的源码已经同步至 https://github.com/SetAlone/springcloud2020(持续更新)

2、springcloud系列博文内容为学习《尚硅谷2020最新版SpringCloud(H版&alibaba)框架开发教程》的记录,此系列课程是目前看来个人觉得非常不错的资源,在此可以与大家进行分享。

3、个人收集到了课程源码和所需的脑图、笔记等资源,如需要私信我即可。查找资源不易,希望可以给个点赞和关注。
 

一、基础知识

1、什么是服务治理

Spring Cloud封装了Netflix公司开发的Eureka模块来实现服务治理。

在传统的RPC远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,所以需要使用 服务治理,管理服务与服务之间的依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。

2、什么是服务注册

Eureka采用了CS的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心。而系统中的其他服务,使用Eureka的额客户端连接到Eureka Server并维持心跳连接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行。

在服务注册和发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息以别名方式注册到注册中心上。另一方(消费服务提供者)以该别名的方式去注册中心上获取到实际的服务通讯地址,然后在实现本地RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理理念)。在任何的RPC远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))。

3、Eureka的两个组件

二、单机Eureka构建

1、IDEA生成EurekaServer端服务注册中心   

1)建moudle

在父工程上右键,new——>moudle,新建一个新的maven项目,不需要选择向导。命令为cloud-eureka-server7001。

2)改pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud2020</artifactId>
        <groupId>com.atguigu.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-eureka-server7001</artifactId>


    <dependencies>
        <!--eureka-server-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--boot web actuator-->
        <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>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>

</project>

3)写yml

在resources文件夹下创建application.yml文件

server:
  port: 7001

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

4)主启动类

package com.atguigu.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)测试

因为是服务注册中心,所以不需要编写业务类。进行测试:

在浏览器中输入http://localhost:7001/进行测试,如下为测试结果图:

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

1)选定8001模块

2)改pom,在8001模块的pom文件中添加依赖

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

3)写yml

server:
  port: 8001

spring:
  application:
    name: cloud-payment-service
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 当前数据源操作类型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驱动包
    url: jdbc:mysql://localhost:3306/db2020?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: root

eureka:
  client:
    #表示是否将自己注册进EurekaServer默认为true。
    register-with-eureka: true
    #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
    fetchRegistry: true
    service-url:
      #单机版
      defaultZone: http://localhost:7001/eureka
      
mybatis:
  mapperLocations: classpath:mapper/*.xml
  type-aliases-package: com.atguigu.springcloud.entities    # 所有Entity别名类所在包


4)主启动

在主启动类PaymentMain8001中添加@EnableEurekaClient注解

package com.atguigu.springcloud;

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

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

5)测试

启动Eureka Server,然后进行测试。http:localhost:7001

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

1)选定cloud-consumer-order80模块

2)改pom,在80模块的pom文件中添加依赖

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

3)写yml

server:
  port: 80

spring:
  application:
    name: cloud-payment-service

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

4)主启动

在主启动类OderMain8001中添加@EnableEurekaClient注解

package com.atguigu.springcloud;

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

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

5)测试

三、集群Eureka构建

1、Eureka集群原理说明

服务注册:将服务信息注册到注册中心

服务发现:从注册中心上获取到服务信息

其实质就是:key-value形式的。Key:服务的名字 value:服务调用地址

执行步骤:

1、先启动eureka注册中心

2、启动服务提供者(我们这里的服务提供者就是payment支付服务)

3、服务提供者在启动后会把自身的信息(如服务地址,以别名方式注册到)注册到eureka中

4、消费者(我们这里是order服务)在需要调用接口的时候,使用服务别名去注册中心获取到实际的RPC远程调用地址

5、消费者获取到调用地址后,底层实际是利用HttpClient技术实现远程调用的

6、消费者获得服务地址后会缓存在本地的JVM内存中,默认每隔30秒更新移除服务调用地址

如果我们的注册中心只有一个,在发生故障的情况下,就会导致整个的服务不可用,我们可以通过搭建Eureka注册中心集群的方式,实现负载均衡和故障容错。

原理说明:

前面我们实现了单机Eureka搭建,既然是集群搭建,就意味着有多个。比如我们现在单台的eureka端口是7001,假设还有一台服务是7002.那么7001的注册地址应该是7002,7002的注册地址是7001.这样就相互注册了。7001会每30s给7002同步一次心跳,同理7002也会的。所以就相互守望了。因此我们可以用一句话进行概括:互相注册,互相守望

2、集群Eureka构建步骤

1)建moudle

按照上面构建cloud-eureka-server7001的构建步骤,进行cloud-eureka-server7002的构建

2)改pom

复制7001moudle的pom文件即可

3)修改映射配置文件

当我们有两个应用进行相互注册相互守望时,eureka服务端的实例名称不能重复,因此需要修改映射配置文件,找到C:\Windows\System32\drivers\etc路径下的hosts文件,对其进行修改,增加两个虚拟的域名:

修改完成后刷新host文件,打开cmd命令窗口,进行如下的操作:

出现上面的界面则说明我们的映射配置文件已修改成功了。

4)写yml(依次修改7001和7002的yml文件)

7001:

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

7002:

server:
  port: 7002
spring:
  application:
    name: cloud-eureka-service2
eureka:
  instance:
    hostname:  eureka7002.com
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/
 

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

修改8001的yml文件,将原来的单机版修改为集群版即可。

#单机版
# defaultZone: http://localhost:7001/eureka
# 集群版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

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

修改80的yml文件,将原来的单机版修改为集群版即可。

#单机版
# defaultZone: http://localhost:7001/eureka
# 集群版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka

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

1)参考cloud-provider-payment8001,新建cloud-provider-payment8002

2)复制pom文件

3)复制yml文件,修改里面的端口号

4)复制主启动类

5)复制业务类

分别修改8001和8002的controller文件,

6)测试

 

我们可以看到CLOUD-PAYMENT-SERVICE是有两台机器。分别是8001和8002

再来分别访问8001和8002的服务:

我们可以看到把对应服务的端口号返回到页面上了。

再使用消费者order80测试:

 

 

 

我们发现无论我们怎么刷新访问的端口都是8001。但是,我们payment确实启动了两个项目8001和8002啊。那么为什么呢?

 

查看OderController,我们可以看到访问服务的连接是写死的,既然后面启动了两个服务,我想要既可以访问8001的端口也要访问8002的端口,那么怎么做呢?

6、负载均衡

如果我们修改成服务名称呢?那么服务名称是什么?服务名称就是我们在eureka集群注册的application列表下的名称。

 

那么我们直接把CLOUD-PAYMENT-SERVICE这个服务名字复制到PAYMENT_URL中可以吗?

 

重启完成之后,我们重新访问:

 

重新访问的时候,我们看到提示信息是说:java.net.UnknownHostException: CLOUD-PAYMENT-SERVICE。没有找到这个host异常。

为什么呢?我们知道,这个服务是注册到eureka的服务的别名,而不是真实存在的。如果要想访问到,这里就需要使用到负载均衡了。

怎么修改呢?需要修改RestTemplate的配置类中添加@LoadBalanced注解赋予RestTemplate负载均衡的能力。

修改如下:

在order80项目中,ApplicationContextConfig类里面getRestTemplate方法上面添加@LoadBalance注解即可。如下图:

 

修改完成之后,再次访问页面,然后刷新页面,我们可以看到端口是8001和8002来回切换的。

7、测试

四、actuator微服务信息完善

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

主机名称:服务名称修改
当前问题:服务注册含有主机名称,要想按照规范的要求,只暴露服务名,不要出现主机名。

在这里插入图片描述
分别找到8001和8002的yml文件,添加配置即可:

在这里插入图片描述


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

我们可以通过如下的配置,将我们微服务的ip地址进行显示,方便我们进行调试和排错。分别在8001和8002的yml文件中进行添加:

修改完成后效果如下:

在这里插入图片描述

五、服务发现Discovery

对于注册eureka里面的微服务,可以通过服务发现来获得该服务的信息,具体的步骤如下:

修改cloud-provider-payment8001的Controller

在8001的主启动上添加注解@EnableDiscoveryClient

六、eureka自我保护

我们暂时将7001和8001模块还原到eureka的单机模式用以eureka自我保护的测试:

在7001的yml文件中进行配置:

在8001的yml文件中进行配置:

在启动7001和8001后,停止8001来模仿故障,就会出现如下的结果:其服务

其服务马上就会被删除了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

傲骄鹿先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值