前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《SpringCloud篇:001Eureka服务的注册与发现入门篇》

《SpringCloud篇:001Eureka服务的注册与发现入门篇》

作者头像
发布2020-11-13 14:18:53
3010
发布2020-11-13 14:18:53
举报
文章被收录于专栏:后端JavaEE后端JavaEE

一、SpringCloud介绍

1.1微服务架构

代码语言:javascript
复制
2.1.9  -  G-SR6

微服务架构的提出者:马丁福勒

https://martinfowler.com/articles/microservices.html

代码语言:javascript
复制
简而言之,微服务架构样式[1]是一种将单个应用程序开发为一组小服务的方法,
每个小服务都在自己的进程中运行并与轻量级机制(通常是HTTP资源API)进行
通信。这些服务围绕业务功能构建,并且可以由全自动部署机制独立部署。这些
服务的集中管理几乎没有,它可以用不同的编程语言编写并使用不同的数据存储
技术。

1、 微服务架构只是一个样式,一个风格。

2、 将一个完成的项目,拆分成多个模块去分别开发。

3、 每一个模块都是单独的运行在自己的容器中。

4、 每一个模块都是需要相互通讯的。 Http,RPC,MQ。

5、 每一个模块之间是没有依赖关系的,单独的部署。

6、 可以使用多种语言去开发不同的模块。

7、 使用MySQL数据库,Redis,ES去存储数据,也可以使用多个MySQL数据库。

总结:将复杂臃肿的单体应用进行细粒度的划分,每个拆分出来的服务各自打包部署。

1.2 SpringCloud介绍

代码语言:javascript
复制
- SpringCloud是微服务架构落地的一套技术栈。
- SpringCloud中的大多数技术都是基于Netflix公司的技术进行二次研发。
- SpringCloud的中文社区网站:http://springcloud.cn/
- SpringCloud的中文网:http://springcloud.cc/
- 八个技术点:
  - Eureka - 服务的注册与发现
  - Ribbon - 服务之间的负载均衡
  - Feign - 服务之间的通讯
  - Hystrix - 服务的线程隔离以及断路器
  - Zuul - 服务网关
  - Stream - 实现MQ的使用
  - Config - 动态配置
  - Sleuth - 服务追踪
  - SpringBoot对应SpringCloud版本:https://start.spring.io/actuator/info

二、服务的注册与发现-Eureka【重点】

2.1概述

搭建EurekaServerEureka就是帮助我们维护所有服务的信息,以便服务之间的相互调用

代码语言:javascript
复制
- 服务的调用方需要维护大量服务提供方的地址信息,维护成本是很高的。
- 如果服务提供方出现了宕机等问题,服务调用方无法感知。
- 使用Eureka来管理所有服务的地址信息以及是否存活,服务的注册与发现
在这里插入图片描述
在这里插入图片描述

2.2 搭建

2.2.1 创建EurekaServer

1…创建当前父工程的子工程:

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

父工程pom依赖

代码语言:javascript
复制
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <modules>
        <module>01-eureka</module>
        <module>02-provider</module>
        <module>03-consumer</module>
        <module>04-eureka-replicas</module>
        <module>05-provider</module>
        <module>06-zuul</module>
        <module>08-sidecar</module>
        <module>09-stream-send</module>
        <module>10-stream-listen</module>
    </modules>


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <!-- 修改packaging为pom ,删除src整个目录-->
    <packaging>pom</packaging>

    <groupId>com.qf</groupId>
    <artifactId>springcloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springcloud</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring.cloud-version>Greenwich.SR6</spring.cloud-version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.new一个module,此时是Maven的子项目 查看官方文档

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

在子工程项目导入依赖

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

3.构建子项目

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
package com.qf.springcloud.eurekaserver;

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

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerStarterApp {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerStarterApp.class,args);
    }

}

启动当前项目就可以了,运行结果如下(Eureka图形化界面)

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

2.3配置单机版Eureka(此时不是Eureka集群)

application.yml配置文件

代码语言:javascript
复制
server:
  port: 8761

eureka:
  client:
    # 不让当前eurekaServer尝试注册到其他Eureka,(单机版)
    fetch-registry: false
    register-with-eureka: false
    # 指定当前服务需要注册已经拉取信息的Eureka地址,默认就是http://localhost:8761/eureka/配置
    service-url:
      defaultZone: http://localhost:8761/eureka/

2.4准备服务提供方

pom依赖(client中本身并不带web依赖,所以要额外添加一个)

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
<?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>springcloud</artifactId>
        <groupId>com.qf</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>02-provider</artifactId>


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

</project>

启动类ProviderStarterApp

代码语言:javascript
复制
package com.qf.springcloud.provider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
//@EnableEurekaClient         // 代表要注册到Eureka的注册中心
//@EnableDiscoveryClient      // 代表要注册到注册中心上,可能是其他注册中心,Zookeeper,Nacos,Console,Redis , 服务的注册与发现
public class ProviderStarterApp {

    public static void main(String[] args) {
        SpringApplication.run(ProviderStarterApp.class,args);
    }

}

配置文件application.yml

代码语言:javascript
复制
spring:
  application:
    # 指定服务名称
    name: provider


#eureka:
#  client:
#    service-url:
      # 指定注册到的eureka的地址信息
#      defaultZone: http://admin:admin@localhost:8761/eureka/,http://admin:admin@localhost:8762/eureka/

运行结果,Eureka图形化界面出现服务提供方provider

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

2.5准备服务调用方

pom依赖

代码语言:javascript
复制
<?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>springcloud</artifactId>
        <groupId>com.qf</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>03-consumer</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>
    </dependencies>

</project>

其实pom依赖如下图,没必要导入那么多(因为还没有用到SpringCloud的hystrix等其他功能)

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

启动类

代码语言:javascript
复制
package com.qf.springcloud.consumer;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
@EnableHystrixDashboard
@ServletComponentScan(basePackages = "com.qf.springcloud.consumer")
public class ConsumerStarterApp {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerStarterApp.class,args);
    }


    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }


//    @Bean
//    public IRule randomRule(){
//        return new RandomRule();
//    }
}

controller

代码语言:javascript
复制
package com.qf.springcloud.consumer.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.qf.springcloud.consumer.client.ProviderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

@RestController
public class ConsumerController {

    /*@Autowired
    private EurekaClient eurekaClient;*/

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ProviderClient providerClient;

    @GetMapping("/consumer/test")
    public String test() throws InterruptedException {
        /*//1. 通过Eureka获取PROVIDER服务的ip和port
        InstanceInfo provider = eurekaClient.getNextServerFromEureka("PROVIDER", false);
        String ip = provider.getIPAddr();
        int port = provider.getPort();

        //2. 通过RestTemplate调用provider的/provider/test
        String result = restTemplate.getForObject("http://" + ip + ":" + port + "/provider/test", String.class);*/

        /*
        //1. 访问目标服务
        String result = restTemplate.getForObject("http://PROVIDER/provider/test", String.class);
        */
        Thread.sleep(2000);
        System.out.println("test:" + Thread.currentThread().getName());
        String result = providerClient.test();
        //3. 返回结果
        return result;
    }


    @GetMapping("/param/test/{type}")
    /*
    @HystrixCommand(fallbackMethod = "paramTestFallback",commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "20"),
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "30000"),
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "10")

    })
    */
    public Map paramTest(@PathVariable Integer type) throws InterruptedException {
        System.out.println("paramTest:" + Thread.currentThread().getName());
        if (type == 1){
            // path
            return providerClient.path(123);
        }else if (type == 2){
            int i = 1 / 0;
            // param
            return providerClient.param("张老三",233);
        }else{
            // body
            Map map = new HashMap();
            map.put("abcdefg","hijklmn");
            return providerClient.body(map);
        }
    }


    public Map paramTestFallback(Integer type){
        System.out.println("paramTestFallback:" + Thread.currentThread().getName());
        Map map = new HashMap();
        map.put("msg","我的Consumer自己出现了问题");
        return map;
    }
}

运行结结果

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

小结:没有绝对的生产者和消费者,它们也可以相互调用

2.6Eureka的安全性

1.添加依赖

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

就是这个前面注释掉的

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

在启动类可以扫描的包下,新建一个config文件

代码语言:javascript
复制
@EnableWebSecurity
class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().ignoringAntMatchers("/eureka/**");
        super.configure(http);
    }
}

在application配置文件中修改用户名密码,就是注释掉的那个

代码语言:javascript
复制
spring:
  application:
    name: eureka
#  security:
#    user:
#      name: admin
#      password: admin

运行结果,再次进入需要输入用户名和密码

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

此时原来的服务信息小时了,因为现在有了用户名和密码,想要找到以前的信息,需要在provider重新注册路径

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

2.7Eureka的常见问题

通讯

代码语言:javascript
复制
EurekaServer如何和EurekaClient进行通讯:EurekaClient会每隔30s向
EurekaServer发送、拉取一次心跳请求,告诉EurekaServer我当前服务的生存情况
,配置方式:lease-renewal-interval-in-seconds

确认宕机

代码语言:javascript
复制
EurekaServer如何确定一个服务已经宕机,并从注册信息列表中移除:如果
EurekaClient90s还没有正常的发送心跳请求,EurekaServer把当前服务从
注册列表中移除,配置方式:lease-expiration-duration-in-seconds

自我保护机制

代码语言:javascript
复制
Eureka的自我保护机制:15min内,超过85%的心跳请求不正常,EurekaServer
会认为自己出现了问题,EurekaServer就会开启自我保护机制,不会从注册列表
上删除任何一个服务,直到网络恢复正常,才会关闭自我保护机制,并且从其他
Eureka上同步数据。

CAP定理/原则/悖论:

代码语言:javascript
复制
- C:一致性(保证多个节点之间数据一致后,才会对外提供功能)
- A:可用性(一定会对外提供功能,但是不保证数据的一致性)
- P:分区容错性(在分布式系统中,分区容错性是必须容忍的)

Eureka是很标准的AP
Zookeeper是很标准的CP
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-11-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、SpringCloud介绍
    • 1.1微服务架构
      • 1.2 SpringCloud介绍
        • 2.2.1 创建EurekaServer
    • 二、服务的注册与发现-Eureka【重点】
    • 2.1概述
    • 2.2 搭建
    • 2.3配置单机版Eureka(此时不是Eureka集群)
    • 2.4准备服务提供方
    • 2.5准备服务调用方
    • 2.6Eureka的安全性
    • 2.7Eureka的常见问题
    相关产品与服务
    微服务引擎 TSE
    微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档